Serial Relay Control
In my previous home, I had a rather flakey boiler ("Furnace" for our American readers), which had a control system which didn't work when it felt like it (usually in the winter, of course). None of the thermostats on the market really met all my criteria, nor did I feel like paying the price for them that was being asked, I decided to build my own.
By using a Linux based system I was able to do more complex control of the heating such as turn the boiler off when my mobile phone (and therefore, I) wasn't at the house. It also gave me the ability to make use of my existing temperature sensors which were already being logged to and controlled by my Linux server.
This worked well for a number of years and significantly reduced my heating bills - probably just about paid for itself :)
The instructions below show the code required to interface with a simple IO kit, available in the UK from http://www.quasarelectronics.co.uk/Item/3108-8-channel-serial-relay-controller-isolated-io-board-kit
Because the IO board has 8 outputs and also 4 inputs, I decided that I'd want to use it for control and sensing of multiple systems and that the best way to handle this was to have one piece of software controlling the device, with multiple other clients able to send messages (switching requests) to the server.
The purpose of the daemon is twofold; 1) To monitor the status of the inputs and trigger an action if there's a status change. 2) To listen on the network for requests to change the status of a relay and then action that request.
This is an example of a client, it can be easily called from other scripts and has the sole purpose of sending the UDP message to the client to trigger the actioning of the relays.
#!/usr/bin/env python import socket, sys, getopt try: msg = sys.argv fileVal = 1 except IndexError: msg = hex(0x02) #default message = off fileVal = 0 livingroom = float(open('/tmp/28A5205C010000', 'r').read()) switch = int(open('/etc/ch_status', 'r').read()) bedroom = float(open('/tmp/286C0D5C010000', 'r').read()) external = float(open('/tmp/28F4FA5B010000', 'r').read()) room,limit = str(open('/etc/ch_room', 'r').read()).split(' ') reading = eval(room) currentstatus = int(open('/tmp/ch_status', 'r').read()) override = int(open('/etc/ch_override', 'r').read()) host = "localhost" port = 6820 buf = 1024 addr = (host,port) if switch == 1: if float(reading) < float(limit): # temperature threshold, under this we turn heating on. msg = hex(int(msg,16)|0x01) msg = hex(0x01) fileVal = 1 if override == 1: # if the override is set, we always turn the heating on. msg = hex(int(msg,16)|0x01) msg = hec(0x01) fileVal = 1 if currentstatus != fileVal: # if the same, no need to reset UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) UDPSock.sendto(msg,addr) #print "Sent status %s to host %s on port %s" % (msg, host, port) statusfile = file('/tmp/ch_status', 'w') print >> statusfile, "%s" % fileVal UDPSock.close()