Robware Software by Rob

The start of DIY home automation: replacing the thermostat, part 2

My DS18B20 sensors arrived the other day. Using Adafruit's tutorial on the sensor I was able to get a reading out of it in a matter of minutes. During Friday evening I was able to knock up a quick thermostat script.

import time;
import sys;
import RPi.GPIO as GPIO;

targetTemp = 21;
sendPin = 24;
sendAttempts = 3;
tempSensor = '28-03157469ceff';
onCode = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1];
offCode = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1];


def sendSignal(code):
	signal = False;
	for t in range(sendAttempts):
		for i in code:
			signal = not signal;
			if (signal):
				GPIO.output(sendPin, 1);
			else:
				GPIO.output(sendPin, 0);
			time.sleep(0.00045 * i);
		GPIO.output(sendPin, 0);
		time.sleep(1);


def readTempSensor(sensor):
	file = open('/sys/bus/w1/devices/' + sensor + '/w1_slave');
	lines = file.readlines();
	file.close();
	return lines;


def readTemp():
	sensorOutput = readTempSensor(tempSensor);

	if sensorOutput[0].strip()[-3:] != 'YES':
		return targetTemp;

	delimiterPos = sensorOutput[1].find('t=');
	if (delimiterPos < 0):
		return targetTemp;

	tempReadingString = sensorOutput[1][delimiterPos + 2:];

	return float(tempReadingString) / 1000.0;


try:
	GPIO.setmode(GPIO.BCM);
	GPIO.setup(sendPin, GPIO.OUT);
	prevTemp = targetTemp;
	while True:
		currentTemp = readTemp();
		print currentTemp;
		if currentTemp < targetTemp and currentTemp < prevTemp:
			print 'on';
			sendSignal(onCode);
		elif currentTemp > targetTemp and currentTemp > prevTemp:
			print 'off';
			sendSignal(offCode);
		prevTemp = currentTemp;
		time.sleep(1);
except:
	pass;
GPIO.cleanup();

This basically watches the temperature and sends the on or off signal based on the following conditions:
- If we are below target temperature, then turn on
- If we are above target temperature, then turn off
- If we are below target temperature and still falling, then keep sending the on signal
- If we are above target temperature and still rising, then keep sending the off signal
For the most part this works, however there seems to be a problem as the receiver isn't flipping the relay sometimes. This is odd, since when I used the script from my previous post it was flawless. I figure it's down to 2 things:
1) the aerial is insufficient
2) the signal timings are out
My first step to will be to solder on an aerial properly, instead of propping a wire in the antenna hole. If that fails I'll add a random fudge factor in to the timings each time the signal is sent. If that fails then I'll have to think of something else.

For now, however, I'm going to work on code to communicate what the thermostat is doing. I need this eventually so doing it now should save me hassle in the long run.

Posted on Saturday the 12th of March 2016