Jump to content

implementing a hardware heartbeat check when using a Raspberry Pi with ISY


EPalisoc

Recommended Posts

I wrote a python script some time ago, when I was working on a way to get my Honeywell alarm panel to work in concert with the ISY994i.  Since version 5.x and support for node servers materialized, in conjunction with the excellent NodeLink tools and interface, I've begun to port over to using Nodelink.
 
The changeover didn't remove my dependency on a Raspberry Pi3 for certain duties, and one of the critical things is to have a way to know if the Pi3 had frozen or stalled for any reason.  The best way to do this is to establish a "heartbeat" to test for activity on the Pi3, and if there's no change in a variable state, then we know that something has gone wrong.  The ISY can then text or email a notification so you can handle the issue.
The following is a compact and efficient way to implement a heartbeat on the Pi and have the ISY work with it.  Note that this is fully dependent on the fact that the ISY 994i runs an event driven OS, so the logic flow is different.
 
The script that's run on the Pi3 is as follows.  It uses a python library I came across on the forums in order to communicate with the ISY, and can be installed using PIP.  The URL for the library is https://github.com/automicus/PyISY
 
There are two files that you will need, the script as follows, and a settings text file (set permissions to 640 or better!) that contains one item per line the ISY address, port, username, and password for accessing the ISY. The other file is the script, that's also set up to autorun when the Pi3 starts:
 
The python script (I saved it as a file named Pi-ISY-hb.py):
 
#-------------------------------------------------------------------------------
# Initialize some things
#-------------------------------------------------------------------------------
import time
import PyISY
#-------------------------------------------------------------------------------
# Load ISY Settings.  Text file must be in the directory as the python script.
#-------------------------------------------------------------------------------
f = open('PyISY.settings.txt', 'r')
ADDR = f.readline().strip()
PORT = f.readline().strip()
USER = f.readline().strip()
PASS = f.readline().strip()
f.close()
#-------------------------------------------------------------------------------
# Connect to ISY
#-------------------------------------------------------------------------------
isy = PyISY.ISY(ADDR, PORT, USER, PASS)
#-------------------------------------------------------------------------------
# Message to Confirm the ISY is indeed connected
#-------------------------------------------------------------------------------
print ('--------')
print ('Did we have a successful connection to the ISY?'), (isy.connected)
print ('--------')
#-------------------------------------------------------------------------------
# Set up the Heartbeat variable for ISY. 
# Value a in isy.variables[a] is a 1 for an integer variable and 2 for a state variable.
# Value b in isy.variables[a] is the ID of the variable in ISY that you are manipulating.
# (The ones in the next line are unique to my setup)
#-------------------------------------------------------------------------------
HeartBeat = isy.variables[2][7]
#-------------------------------------------------------------------------------
# Main routine
#-------------------------------------------------------------------------------
def main():
    """
    Application that sets the HEartbeat variable in ISY.
    """
    try:
    print (Heartbeat is running...')
       while True:
#-------------------------------------------------------------------------------
# Generate a heartbeat to let the ISY know if it's still running.
#-------------------------------------------------------------------------------
    HeartBeat.val = 1
      time.sleep(5)
     HeartBeat.val = 0
      time.sleep(5)
    except Exception as ex:
        print('Exception:', ex)
if __name__ == '__main__':
    main()

On the ISY, I set up a STATE variable named 'Pi_Heartbeat'.  I also have a habit of creating constant integer variables so that programs can use a more natural language approach, so I made a cTrue = 1 and a cFalse = 0 so I can use those terms in the ISY program code.
 
In concert with that I also set up under EMails/Notifications/settings/Groups the way to send an email and an SMS message if there's an issue.
The program that I then put together was:
 
Pi Check - [iD 001E][Parent 0019][Run At Startup]
If
        $Pi_Heartbeat is $cTrue
 
Then
        Wait  1 minute and 15 seconds
        Send Notification to 'Text Me' content 'Pi Failure'
 
Else
        Wait  1 minute and 15 seconds
        Send Notification to 'Text Me' content 'Pi Failure'
 
The way this works is somewhat elegant that I attest to my son working out (he was 12, lol).  Since the ISY is EVENT driven, it's important to realize that the instant a state variable changes, it triggers a condition to re-evaluate.  If you look at the python code, the lines 'time.sleep(5)' alternate between state variable changes (Heartbeat.val = x).  This makes the toggling between 1 and 0 (true and false) occur about every 30 seconds. When it comes to the ISY program though, every time the variable then is changed, it causes the line '$Pi_Heartbeat is $cTrue' to be evaluated, REGARDLESS of where in the program the code is currently at.  As you can see, each time it changes it will either process the 'THEN' or the ELSE, which (on purpose) is identical.  The key line is the first line of code in each instance, namely the 'Wait 1 minute and 15 seconds'.  During this WAIT, if the variable toggles (as it should if the Pi is running), the IF will re-evaluate, and therefore NEVER REACH THE NEXT LINE, where it would send a notification.  IF the Pi3 was in fact stuck, then the WAIT command in EITHER condition(the then or the else) would actually finish, and therefore the next line would execute, and send a message.  The sending of the message would then mean that the Pi3 in fact froze, and could not toggle the variable.
 
You can set the sleep(x) value to whatever length of time you want, you just have to make sure that the WAIT in the ISY program is LONGER than the sleep interval, or else it will complete the WAIT cycle before the Pi3 toggles the state variable.
 
In the console for the ISY, you can actually see it in action graphically, as the color of the program icon will cycle between green and red based on the state of the variable test condition.
 
I hope this helps someone that's looking at a way to integrate a Pi and needs  a way to ensure that it's doing it's duties.
Link to comment

I'm not using nodelink with the panel at the moment, as I am now waiting for the EVL to arrive on Monday, so the heartbeat function in Nodelink (as far as I know) is not functional to me...yet?

 

Are you saying that simply having nodelink offers this function, or only when I have the panel device implemented (which I read to mean it's tied to the EVL4 working, not necessarily Nodelink itself?  I have other things running on the Pi, where the Pi itself is important to monitor.  There's the chance that nodelink could crash, yet the other programs running on the Pi would be operating normally.

 

But the larger picture is, the post was for people that wanted a heartbeat function, who would/may NOT be using nodelink.

Link to comment

Each device (almost all) in NodeLink setup a heartbeat which toggles a bit in the ISY based on whether it's communicating with the end device.  So it will tell you that the device, the Pi, and NodeLink are operational.

 

post-1310-0-06147700-1504960389_thumb.jpg

 

If you want to do it with NodeLink without a device, install the ISY Data module and watch for the Minutes This Year to increment.

Link to comment

Archived

This topic is now archived and is closed to further replies.


×
×
  • Create New...