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.