Ok the Simple Logic layer script is just that pretty basic but as I mentioned earlier is serves as a place to make changes to the system without taking the system down. It basically a buffer between the nodes in the house and the main controller thats doing all the switching.....
So to better understand what I am doing this picture is a better representation
So for the House at least its not all that complicated really. In this blog we will be dealing with the LogicScript....
The Code:
def on_message(mosq, obj, msg):
ts =datetime.datetime.now().strftime("%B, %d %Y %I:%M%p")
print ("---------------------------------------")
print ("TIME RECEIVED: ")+ ts
print ("FROM NODE: ") + (msg.topic)
print ("NODE MSG: ") + (msg.payload)
cli.publish('/HOUSE/Control/' , msg.payload) # <----- sends message to Controller (KIT1,1)
print ("Message forwarded to Controller")
print ("acknowledged @ ") + ts
print
cli.publish('/HOUSE/LogicClient/logicmsg/' , ' forwarded +( msg.payload)+ to Controller')
print ("MSG update sent to webserver")
if (msg.topic) == ("/ALARMS/Status"): # <-- leave off trailing / when comparing
print (Fore.WHITE + Back.RED + Style.BRIGHT + ("STATUS: ALARM! "))
print (Fore.RESET + Back.RESET + Style.RESET_ALL)
# --------------------------------------PopUp Message------------------------------------
subprocess.Popen(['notify-send', "System Message:",msg.payload])
return
else:
print ("STATUS: Normal")
print ("End of Event")
print ("---------------------------------------")
print
def on_publish(mosq, obj, mid):
pass
cli = mosquitto.Mosquitto("LogicClient")
cli.on_message = on_message
cli.on_publish = on_publish
cli.connect("192.168.30.4", 1883, 60)
cli.publish('/mainTopic/Announce/LogicClient/','Online')
cli.subscribe("/HOUSE/Kitchen/", 0)
cli.subscribe("/HOUSE/Livingroom/", 0)
cli.subscribe("/HOUSE/Bath/", 0)
cli.subscribe("/HOUSE/Bedrm1/", 0)
cli.subscribe("/HOUSE/Bedrm2/", 0)
cli.subscribe("/HOUSE/FrontPorch/", 0)
cli.subscribe("/HOUSE/Backporch/", 0)
cli.subscribe("/HOUSE/Garage1/", 0)
cli.subscribe("/HOUSE/Hallway/", 0)
cli.subscribe("/HOUSE/Office/", 0)
cli.subscribe("/HOUSE/Test/", 0)
cli.subscribe("/ALARMS/Status/" ,0)
while cli.loop() == 0:
pass
The script itself is a loop of sorts. It is constantly listening to the network waiting to hear messages that are being published to topis it has subscribed to. If I have tio add or remove anything, then I can edit this script off line and then save and restart. Down time is next to zero.
The script is pretty self explanatory. The output is to a terminal windows which I can comment out once I get everything done. I like to see whats going on visually as I test and finalize parts of the system. The only funky thing really is the subprocess code. This is for my Ubuntu box, so it wont work on Windows. If there is an alarm detected, this causes my linux box to throw up a OSD for 10 secs in the upper right corner. Ubuntu users will know what I mean. Its a way to get my attention should a node post to the Alarms topic
Also since Im currently using a web page for my system to monitor and display statuses, the line cli.publish('/mainTopic/Announce/LogicClient/','Online') posts to the webpage that this script is running. I still need to add a Last will and testament to this so if the script fails, then the MQTT server will post the testament message and Ill know something is wrong.
There are also some comments on here for me to remember. I found that the trailing "/" had to be ommited on the script or it would ignore messages published to topics....a "gotcha" I found out.
This is a typical output from the script to the termimal. FP1,1 is the message that the front porch light has been turned on.
and this is an alarm event
So thats it for the Logic Script. It will evolve and refine as I progress but its a start amd it is working well right now in the house.
We will look at the Trigger script and the MySQL update script in future posts. In the meantime
Happy Coding!
Wednesday, February 19, 2014
Tuesday, February 18, 2014
Logic Layer....
As I posted in the last blog, I discovered the wonderful world of databases. Actually I had used them in the past, but not programmed anything such as queries or even created them. I had to laugh, cause back in the OLD OLD days, we didnt have databases. In fact if you wanted to store stuff say when running a BASIC program, you had to open a file, write to the file and close it.....sound familiar.....yeah that what we do now with databases.....history repeats itself...
As I mentioned in the last blog as well it became obvious that adding a logic layer just made sense. It gave me one place to modify the system without creating much in the way of downtime, actually none really and I could add or remove just about anything from the system as I wanted.
The Logic Layer is nothing more than a python script. I really do love python, its a powerful language and even just using IDLE, easy to program. I have not come across anything I thought of that I could not do in python, short of creating a GUI, which I would love to do, but thats more learning for later. The Logic layer script you can think of is a "front end" to the controller. Basically the logic script subscribes to ALL the topics on the MQTT server.....all of them. The output of this script is MANY publication to ONE topic. As of right now there are nearly two dozen different topics on the MQTT server, of which about 17 are house related. This will of course grow as the system does. The logic script then listens to all 17 topics, acts on payloads received, and issues payloads to ONE topic in return. This one topic is the ONLY topic the main controller arduino listens to. As I explained, this allows me a simple way to add and remove nodes from the system without ever touching the controller firmware.
The Script..........since Ill assume that you know how to use python, youll need to add some modules to python. I prefer to use pip, with my linux box. Its simply just less headache and easy to use, I like less head aches.....
The top of the script shows the modules youll need....
import mosquitto
import datetime
from colorama import init
from colorama import Fore, Back, Style
import sys
init()
print chr(27) + "[2J"
print
print
print (Fore.CYAN + Back.BLACK+ " | MySQL DataBase Update Script |")
print
As I mentioned in the last blog as well it became obvious that adding a logic layer just made sense. It gave me one place to modify the system without creating much in the way of downtime, actually none really and I could add or remove just about anything from the system as I wanted.
The Logic Layer is nothing more than a python script. I really do love python, its a powerful language and even just using IDLE, easy to program. I have not come across anything I thought of that I could not do in python, short of creating a GUI, which I would love to do, but thats more learning for later. The Logic layer script you can think of is a "front end" to the controller. Basically the logic script subscribes to ALL the topics on the MQTT server.....all of them. The output of this script is MANY publication to ONE topic. As of right now there are nearly two dozen different topics on the MQTT server, of which about 17 are house related. This will of course grow as the system does. The logic script then listens to all 17 topics, acts on payloads received, and issues payloads to ONE topic in return. This one topic is the ONLY topic the main controller arduino listens to. As I explained, this allows me a simple way to add and remove nodes from the system without ever touching the controller firmware.
The Script..........since Ill assume that you know how to use python, youll need to add some modules to python. I prefer to use pip, with my linux box. Its simply just less headache and easy to use, I like less head aches.....
The top of the script shows the modules youll need....
import mosquitto
import datetime
from colorama import init
from colorama import Fore, Back, Style
import sys
init()
print chr(27) + "[2J"
print (Fore.CYAN + Back.BLACK+ " | MySQL DataBase Update Script |")
mosquitto module at least for ubuntu, can be gotten in the software center, I prefer synaptic, I even installed it back to my 12.10Ubuntu box after I installed ubuntu, its omitted in versions after 11.10 I think. I like synaptic, always have, and I dont have to deal with a bloated GUI of the software center. Since my production box doesnt have 40 cores, and 50GB of RAM, using synaptic is easier and faster. You can add it back to your ubuntu box by:
sudo apt-get install synaptic . Once you install it just pin it to the unity desktop bar
For Windows users, you can install all the python modules as you normally do. I work on both systems, however all my final work is done on a linux box.....
The module colorama, is totally unnecessary. Its a fun module that allows you to change the fore ground, back ground and make the font bold, or dim in a terminal window. Since I like to, in production, use terminal window outputs to monitor the stability of a script when testing, adding color to represent certain conditions is cool. For instance, if I get an alarm, I can turn the output test to a bold white font, with a red background....catches your eye. Again, totally unnecessary, and you can ignore the code lines referring to it.
Datetime youll need to add...cool module that allows you to format time and date stamps. It totally worth reading or at least glancing over the documentation for datatime. This module came in real handy for the trigger script. Also it will match exactly the DATETIME setting for the time stamps in MySQL.....cool..
The rest of the top of this script is easy. print chr(27) + "[2J" does nothing more than clear the terminal window when the script is started, and then a script header. This just prints to th screen what script I am running, nothing more.
So now you know what modules to grab........next blog we will get into the nuts and bolts of the code...
Happy coding!
Wow time flies.....
Well after getting over the flu, FINALLY, I have been back at the coding for this winter. Here is a little of some of the additions I have been working on:
Version3 is done and put to bed. I decided on the protocol I am going to use from now on for all the MQTT topics, and subscriptions. I kept changing the way I was posting stuff to the MQTT server, through many revisons, it was time to decide on a standard.
For Room nodes posting to the server I have decided on the standard of /SYSTEM/ROOM/node. Therefore if Kitchen light #1 in the house is activated, the the posted topic is /HOUSE/Kitchen/KIT1/. For the Engineering space. the all nodes post to /ENG/SYSTEM/Node. I know this seems silly maybe but I found out on version 3 that a small change one place creates a ripple effect cause you to change the published topics for nearly everything to reflect the change....SO Lesson learned when planning a system, decide on a protocol early on, stick with it.
Since version 3 is done, the improvements to version 4 included database integration. I HATE database admin stuff, but it soon because a necessary evil. I checked out many be decided of for the open souce database MySQL. I had to educate myself in the use, writing queries, and the proper creation of the database and the associated tables. In all reality, I had given databases a bad wrap, it was quite easy to learn and now I have one large database, with several tables.
The reason for database usage was quite simple. though the nodes can publish to the MQTT server, and other nodes can subscribe to topics and act on the published data, I needed places where nodes could pull current stored data. I am also working on what happens in the event of a power loss at the house. Its my intention that I will eventually be able to restore the house to the pre- loss of power state, once power is restored, by pulling the last data set out of the database. That part hasnt not been implemented yet, but will.
With the new found use of my database, it was necessary to update the table with new data in real time. A little funky for me really since I was relying on MQTT to do all the work. Also with using arduino based MQTT libraries, I discovered that there is no way to pass a "last will and testament" to the MQTT server.Wills arent not currently implemented in the latest MQTT libraries for arduinos.....SO what happens then if a node drops offline? The solution of course is time stamping the data, and then I can check the last time stamps against when I last heard the node....surpass a predetermined time frame, I have to assume the node is not communicating with the MQTT server.......
Finally I have decided on adding a couple of python scripts to the MQTT server. One of these scripts now acts as a logic layer. This script will also channel information between all of the room nodes in the house, to the Controller arduino thats actually switching lights on and off. I decided this was simpler. Adding this "logic layer" allows me to modify virtually anything, without the need to touch the Controller arduino. So for instance of I add something to the system, the logic script can be modified offline, saved and restarted as the new logic script. It provides one place to make changes in the system without the need to pull out the laptop, start up the arduino IDE and program the house control arduino. I will discuss this script in more detail in the next post.
I also added a second python script to the server computer. This script, called "trigger" merely is a simple script, basically running in an endless loop. It monitors the servers clock, and issues "triggers" based on time. So for instance, at 7:30pm I want the front porch light to come on, daily, I simply add the trigger to the script. If I was to modify the script, again I can do it offline, adding what I want, and then save it and restart the script to apply the new trigger. No need for additional RTC shields for arduinos, as all of the triggers fire off MQTT publications to the master controller arduino on the same topic the logic script does. Thus, at 7:30pm, the script will tell the controller to turn on the front porch light.......Ill discuss trigger script in more detail as well in a later post.
So I have been busy, and Ill start sharing more on the new revision in the near future.
In the meantime, happy coding!
Version3 is done and put to bed. I decided on the protocol I am going to use from now on for all the MQTT topics, and subscriptions. I kept changing the way I was posting stuff to the MQTT server, through many revisons, it was time to decide on a standard.
For Room nodes posting to the server I have decided on the standard of /SYSTEM/ROOM/node. Therefore if Kitchen light #1 in the house is activated, the the posted topic is /HOUSE/Kitchen/KIT1/. For the Engineering space. the all nodes post to /ENG/SYSTEM/Node. I know this seems silly maybe but I found out on version 3 that a small change one place creates a ripple effect cause you to change the published topics for nearly everything to reflect the change....SO Lesson learned when planning a system, decide on a protocol early on, stick with it.
Since version 3 is done, the improvements to version 4 included database integration. I HATE database admin stuff, but it soon because a necessary evil. I checked out many be decided of for the open souce database MySQL. I had to educate myself in the use, writing queries, and the proper creation of the database and the associated tables. In all reality, I had given databases a bad wrap, it was quite easy to learn and now I have one large database, with several tables.
The reason for database usage was quite simple. though the nodes can publish to the MQTT server, and other nodes can subscribe to topics and act on the published data, I needed places where nodes could pull current stored data. I am also working on what happens in the event of a power loss at the house. Its my intention that I will eventually be able to restore the house to the pre- loss of power state, once power is restored, by pulling the last data set out of the database. That part hasnt not been implemented yet, but will.
With the new found use of my database, it was necessary to update the table with new data in real time. A little funky for me really since I was relying on MQTT to do all the work. Also with using arduino based MQTT libraries, I discovered that there is no way to pass a "last will and testament" to the MQTT server.Wills arent not currently implemented in the latest MQTT libraries for arduinos.....SO what happens then if a node drops offline? The solution of course is time stamping the data, and then I can check the last time stamps against when I last heard the node....surpass a predetermined time frame, I have to assume the node is not communicating with the MQTT server.......
Finally I have decided on adding a couple of python scripts to the MQTT server. One of these scripts now acts as a logic layer. This script will also channel information between all of the room nodes in the house, to the Controller arduino thats actually switching lights on and off. I decided this was simpler. Adding this "logic layer" allows me to modify virtually anything, without the need to touch the Controller arduino. So for instance of I add something to the system, the logic script can be modified offline, saved and restarted as the new logic script. It provides one place to make changes in the system without the need to pull out the laptop, start up the arduino IDE and program the house control arduino. I will discuss this script in more detail in the next post.
I also added a second python script to the server computer. This script, called "trigger" merely is a simple script, basically running in an endless loop. It monitors the servers clock, and issues "triggers" based on time. So for instance, at 7:30pm I want the front porch light to come on, daily, I simply add the trigger to the script. If I was to modify the script, again I can do it offline, adding what I want, and then save it and restart the script to apply the new trigger. No need for additional RTC shields for arduinos, as all of the triggers fire off MQTT publications to the master controller arduino on the same topic the logic script does. Thus, at 7:30pm, the script will tell the controller to turn on the front porch light.......Ill discuss trigger script in more detail as well in a later post.
So I have been busy, and Ill start sharing more on the new revision in the near future.
In the meantime, happy coding!
Subscribe to:
Comments (Atom)


