Serial Relay Control

From SifWiki
Jump to: navigation, search



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


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

        msg = sys.argv[1]
        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)
        #print "Sent status %s to host %s on port %s" % (msg, host, port)
        statusfile = file('/tmp/ch_status', 'w')
        print >> statusfile, "%s" % fileVal
Personal tools

Google AdSense