Part 1 is here <link>, and part 2 is here <link>.
I've been devoting my project time to the weather station, and completely forgot about finishing my testing of using HTTP to communicate between processes. It's time to finish the experiment and actually implement it for the various processes I have running on the Pi. As I mentioned before, I want to do this so I can move any of the processes to a different machine when I finally outgrow the single Raspberry PI. No, I'm not changing machines, I'm going to add others to the collection.
I started with the code that controls the Wemo light switches I have and let it run for a while to make sure there wasn't something weird going to pop up; it didn't. So now is the time to make corresponding changes to the code that sends signals to control the lights. Currently there are two places I do this: a process that runs and handles scheduled events around the house and the web interface I use to manually control and look at things. I'll start with the event controller since it's the easiest piece of code.
Basically, it's just a matter of sending an HTML request to the address and port number I assigned to the Wemo code. I use different port numbers so I can have multiple addresses on a single machine. This way, the regular web server watches on port 80 like all the web sites out there, and the control processes watch on whatever port I decided to put them on. To do this and maintain versatility, I put the address in my .houserc file and read it when the process first comes up. Here's the entry I have:
"wemocontrol":{
"ipAddress":"192.168.0.205",
"port": 51001},
Well, it's actually more than a fragment, This code will actually control my patio light. Each time I run it, it will toggle the switch. It turned out to be pretty simple when done in python, I just used the normal facilities for reading a web site. In there are also examples of how I read the address and port number from the .houserc file, and how I handle possible errors in the HTTP request. I came up with that huge set of error conditions as I was learning how to send and receive HTTP; there's a lot that can go wrong and I hated having to look up the errors each time I messed something up.
Now I need to understand how to do the same thing from php so I can command it with a request over the internet. I guess while I'm in there I'll add some code to read the .houserc file; here's how I send the HTML request to the Wemo control software:
This is how I read the .houserc file to get the address I assigned it:
Then in the case statement for controlling the lights I decode the JSON request and grab the address and port number I put in there.
The very last thing is to include the fragment above into the scheduled event process. This separate process handles events like: turn the outside lights on at 7PM; turn them off at 10PM, shut the pool motor off in case I forget, etc. I haven't talked about this process much previously because it had several things in it that I didn't want to put on the web. When I moved my various keys and such into the .houserc file, that problem disappeared, so this file has the changes above added to it and is called 'events.py' and is in the directory 'house' in the github page above.
So, one set of conrols is done. I'll have to visit each of the others over time and make similar changes to them, but I won't be limited to one machine anymore. To move a process to another machine, just change the address in the .houserc file; HTTP interactions don't care that the process is on another machine.
I've been devoting my project time to the weather station, and completely forgot about finishing my testing of using HTTP to communicate between processes. It's time to finish the experiment and actually implement it for the various processes I have running on the Pi. As I mentioned before, I want to do this so I can move any of the processes to a different machine when I finally outgrow the single Raspberry PI. No, I'm not changing machines, I'm going to add others to the collection.
I started with the code that controls the Wemo light switches I have and let it run for a while to make sure there wasn't something weird going to pop up; it didn't. So now is the time to make corresponding changes to the code that sends signals to control the lights. Currently there are two places I do this: a process that runs and handles scheduled events around the house and the web interface I use to manually control and look at things. I'll start with the event controller since it's the easiest piece of code.
Basically, it's just a matter of sending an HTML request to the address and port number I assigned to the Wemo code. I use different port numbers so I can have multiple addresses on a single machine. This way, the regular web server watches on port 80 like all the web sites out there, and the control processes watch on whatever port I decided to put them on. To do this and maintain versatility, I put the address in my .houserc file and read it when the process first comes up. Here's the entry I have:
"wemocontrol":{
"ipAddress":"192.168.0.205",
"port": 51001},
I just read the file using the code I already posted here <link> and set the Cherry Pi server to listen to it. Now I need to have some code to send to it. Here's the code fragment I came up with:
#! /usr/bin/python
import datetime
import time
import urllib2
import BaseHTTPServer
import os, sys
lib_path = os.path.abspath('../house')
sys.path.append(lib_path)
from houseutils import lprint, getHouseValues, timer, checkTimer
def openSite(Url):
#print Url
try:
webHandle = urllib2.urlopen(Url, timeout=5) #if it doesn't answer in 5 seconds, it won't
except urllib2.HTTPError, e:
errorDesc = BaseHTTPServer.BaseHTTPRequestHandler.responses[e.code][0]
print "Error: cannot retrieve URL: " + str(e.code) + ": " + errorDesc
raise
except urllib2.URLError, e:
print "Error: cannot retrieve URL: " + e.reason[1]
raise
except urllib2.HTTPError as e:
print e.code
print e.read()
raise
except: #I kept getting strange errors when I was first testing it
e = sys.exc_info()[0]
print ("Odd Error: %s" % e )
raise
return webHandle
def talktoWemo(ip, command):
website = openSite("HTTP://" + ip + '/' + command)
# now read the status that came back from it
websiteHtml = website.read()
# After getting the status from the little web server,
# strip off the trailing cr,lf
# and separate the values into a list that can
# be used to tell what is going on
return websiteHtml
# Get the ip address and port number you want to use
# from the houserc file
ipAddress=getHouseValues()["wemocontrol"]["ipAddress"]
port = getHouseValues()["wemocontrol"]["port"]
wemoController = ipAddress + ":" + str(port)
print(talktoWemo(wemoController, "status"))
print(talktoWemo (wemoController, "pCommand?command=patioToggle"))
Now I need to understand how to do the same thing from php so I can command it with a request over the internet. I guess while I'm in there I'll add some code to read the .houserc file; here's how I send the HTML request to the Wemo control software:
function ipControl($whichOne,$command){
echo "<br />";
echo "URL will be: $whichOne/$command";
$response = file_get_contents("http://$whichOne/$command");
return(true);
};
$config = file_get_contents("/home/pi/.houserc");
case "lights":
$wemoIp = json_decode($config,true)["wemocontrol"]["ipAddress"];
$wemoPort = json_decode($config,true)["wemocontrol"]["port"];
$c = $commandParts[1];
ipControl("$wemoIp:$wemoPort", "pCommand?command=$c");
break;
This set of changes is merged into my php script that handles web commands, 'command.php'. Yes, I managed to get it into github so you can grab the entire thing from there and see how it fits together.
The file is in the 'wwwsrc' directory and here's a link to the page <link>.The very last thing is to include the fragment above into the scheduled event process. This separate process handles events like: turn the outside lights on at 7PM; turn them off at 10PM, shut the pool motor off in case I forget, etc. I haven't talked about this process much previously because it had several things in it that I didn't want to put on the web. When I moved my various keys and such into the .houserc file, that problem disappeared, so this file has the changes above added to it and is called 'events.py' and is in the directory 'house' in the github page above.
So, one set of conrols is done. I'll have to visit each of the others over time and make similar changes to them, but I won't be limited to one machine anymore. To move a process to another machine, just change the address in the .houserc file; HTTP interactions don't care that the process is on another machine.