Raspberry pi Heating Boiler Control System Relay: Control gas boiler from raspberry pi GPIO with 5v relay by connecting it to room thermostat connection on gas boiler without passing any voltage to gas boiler or at least this is how i did it as my gas boiler had thermostat connector available. You need to check this with your boiler user/technical manual.
You can control high voltage electronic devices using relays modules that are readily available in the market. I am using the Sainsmart 2 channel 5v relay module, which has 2 relays. The high voltage side output connector has 3 pins, the middle one is the common pin. One of the two pins is normally open connection and the other one for normally closed connection and can be activated by raspberry pi. Make sure you have relay board with optocoupler ic to isolate your load from Raspberry pi.
“DO NOT MAKE ANY CHANGES TO YOUR HEATING SYSTEM UNTIL UNLESS YOU KNOW WHAT YOU ARE DOING, contents provided here are for information and education purpose only, I take no responsibility for any loss or damage to you or your property.”
All wiring connection from raspberry pi gpio to the relay board and voltage supply connection to relay board. On same note make sure you follow WiringPi gpio pin number as shown below table.
You need to make sure to have WiringPi installed as well on your raspberry pi and have correct WiringPi gpio pins configured for each zone and for gas boiler in boiler mysql/mariadb table. For troubleshooting i have done one php script to do some testing zone and boiler relay.
30 comments
I connected relay board with raspberry pi to test before I connect my zone valve but boiler.php isn’t doing anything to relay, is there anything else i have to do or am i missing some step?
Thank you
Hi Dan,
make sure you add gpio number for each zone/boiler
Admin
Hi
Just came across this – have been customising my heating with relays and switches – now is the time to change to something more modern.
I have a system where i use a plate heat exchanger to provide instant, unlimited, hot water – Ideally this needs an overrride so that when there is hot water demand, the heating circuits are temporarily shut off (possibly with time limit?). Can you suggest how to add this to a zone? IE, IF [zone x = ON] then [zones a…c] == off (please excuse my pseudocode)
@Alistair,
sorry i didnt understand your question, you have plate heat exchanger to provide hot water for central heating and hot water/bath etc.
if there is demand for hot water then heating circuit temporarily shut off, are you referring second heat source? you want to switch between heat source?
No – heat source (gas boiler) is the same for heating and hot water.
The issue is that when there is a demand for hot water (particularly showers), the boiler needs to divert all output to the heat exchanger to provide enough flow. This means that the supply to the heating needs to be paused during the DHW demand. However, if the weather was really cold, I would want to limit this condition for (say) a max of 5 minutes…
@Alistair,
have look in /cron/boiler.php file about line 178 to 194 all decision making is done there. (i can help you to add this line there) You can create another zone and put condition for that zone to have priority over other zone but how raspberry pi know that there is demand for water in shower? do you have any sensors attached to waster flow?
Thanks for the info – Yes, I have a hot water demand flow sensor. Works pretty well, but it switches 240v using a triac, so would need to be isolated and level-translated for GPIO. Can you suggest any nice interface boards that accept mains-in and GPIO-out? Same would be true for my room stats until i put in 1-wire wiring or WiFi temp probes. I could just use a bank of 240V relays, but a board/module that does this would be more elegant…
Thanks
Hi
One more question following on from the ‘instant hot water’ question before I ‘dive in’:
you mention various cron jobs for monitoring sensors and so on – can input(s) be configured as interrupts to provide immediate actions – such as the DHW demand?
Thanks
@Alistair
i searched around to find something to check 220voltage and then feed that into pi/arduino there are some boards that can do this for you, here are few of these examples:
stackexchange.com
edwinrobotics
raspberry pi forum
aliexpress
If i understand On your question of interrupts for immediate action: yes you can do that but is that interrupts comes from user via web? if yes then simple following two lines of code for raspberry pi gpio can this job for you.
Is there a way to run the boiler control relay off a different pi? I have a set of sensors currently connected to pi a, writing data to a mysql db. Pi B then checks the mysql and adjusts the relays as required.
The relay board i use is:
https://www.byvac.com/index.php/BV4627
and is used over i2c on the pi.
I have some scripts that allow the relay to turn on and off from command line/Python if wanted!
At present i have three zones – one is hot water, one is ufh (8 zones) and the third for radiators.
From my understanding, i can set each zone on its own in the system so i have 10 zones total – one dhw, and the rest as radiators.
@raju vora,
yes you can run boiler control relay from second pi, simply copy PiHome project on second pi but make sure you change database settings and point to one database server and remove all cronjobs and leave only boiler.php cronjob. unfortunately i dont have any knowledge on how to control i2c relay board or any script as i never owned any to test it, if you have any script that can control i2c relay you can share with rest of the world so others can benefit from it. you can setup any many zone as you want.
Thanks for confirming,
The relay board control requires this file:
http://www.byvac.com/downloads/py/easyi2c.py
and an example of how to use it is in:
http://www.byvac.com/downloads/BV4627/py/simple.py
basic steps are:
import easyi2c
dev = easyi2c.IIC(0x32,1) # 0x32 is the address of the relay board
dev.i2c([n,1,0,1],0) # on
dev.i2c([n,0,0,1],0) # off
each board has 8 relays, and if you change the address you can have 8 more!:
dev = easyi2c.IIC(0x32,1) # 0x32 is the address of the relay board0
dev1 = easyi2c.IIC(0x16,1) # 0x1 is the address of the relay board1
dev.i2c([10,1,0,1],0) # turn on relay 1 (aka 10) on board0
dev1.i2c([17,1,0,1],0) # turn on relay 8 on board1
dev.i2c([n,0,0,1],0) # turn off relay n on board0
dev1.i2c([n,0,0,1],0) # turn off relay n on board1
@Raju Vora,
thank you for sharing i see you have contributed to original code, do you own the code? if no i have to send email to byvac to ask for permission to add that code in PiHome.
Hi, I did work on the code, with some help from raspberrypi.org forum users, and submitted to byvac as their code broke with one of the is updates. It looks like it has since been updated again. To be safe please ask byvac, I’m sure they will be happy for you to include it!
@Raju Vora
so each board would have unique address or this is standard address so this needs to be amended by user? also can you break down following line
dev.i2c([10,1,0,1],0) # turn on relay 1 (aka 10) on board0
dev.i3c = call command for i2c
10 = is relay address?
0 = on/off (1 is on and 0 is off)?
0 = board 0?
etc…
Apologies – didnt see the update.
The boards are manufactured with the same address, if more are needed, the user has to re-program them with commands (i can share this if needed but could only get it to work with weezy not jessie!),
dev = easyi2c.IIC(0x32,1)
using the easyi2x lib, create a device dev which uses address 0x32.
each board has 8 relays – numbered 10,11,12,13,14,15,16,17
dev.i2c([10,1,0,1],0) # turn on relay 1 (aka 10)
so the dev.i2c is to call the i2c command of board called dev.
10 is the relay number 10
1 is to turn on,
0 i think is the number of bytes to read back,
1 is the delay (16 bit time – use 1 for no delay)
final 0 is number of bytes it returns – to turn on or off a relay its 0.
– if you wanted to know the current state you can read it back.
so for us to turn on or off would be:
dev.i2c([10,1,0,1],0) # turn on relay 1 (aka 10)
or
dev.i2c([10,0,0,1],0) # turn on relay 1 (aka 10)
and for a different relay number:
dev.i2c([11,1,0,1],0) # turn on relay 1 (aka 11 on)
dev.i2c([12,1,0,1],0) # turn on relay 1 (aka 12 on)
dev.i2c([13,0,0,1],0) # turn on relay 1 (aka 13 off)
Full datasheet is here if you want to see some of the other features (use delay, read back status etc)
http://www.byvac.co.uk/downloads/datasheets/BV4627%20DataSheet.pdf
Hi
the 0x32 and 0x16 is the i2c address for the board. They are default but user changeable. (eg if i want 16 relays i can change the address on one board so each board can be connected and used with its own i2c address.
dev = easyi2c.IIC(0x32,1) # 0x32 is the address of the relay board0
dev.i2c([10,1,0,1],0) # turn on relay 1 (aka 10) on board0
dev.i2c([10,1,0,1],0) calls the board defined in the dev= above
Each board has 8 relays numbered from 10 to 17
dev.i2c([10,1,0,1],0) defines which relay to adjust
dev.i2c([10,1,0,1],0) turns relay on (0 for off)
dev.i2c([10,1,0,1],0) is a 16 bit time format for delay in executing the command.
dev.i2c([10,1,0,1],0) is the number of bytes to read back – for turning the relay on and off this is not needed so can be 0, you do have the option of reading the value back – full datasheet is here:
If you want the details for the read then i will have to have a play and find out what the commands are.
For info step by step how to change the address
sudo i2cdetect -y 1
-- gives current i2c address default is 32
python
from notsmb import notSMB
bus = notSMB(1)
bus.detect()
-- this will give current id (50 by default)
bus.i2c(50,[82,66],0)
--(82 is to set new address, 66 is new value)
bus.i2c(50,[85],0)
--(resets the board)
bus.detect()
--(this will give new id (66 gives new address of 33) -
exit
sudo i2cdetect -y 1
-- gives new i2c address which is 21 for above settings.
Hi Admin, Can you give me a bit more detail for the following:
Is there a table in the states of the boiler are stored – im after something along the lines of, a select statement which tells the scripts that there is a zone that needs heat, a statement which shows which ones are currently on, and a statement which show which ones need to be turned off. Hopefully i can then put together a set of python scripts that can be called to run in the boiler.php for the board i use for realys
@Raju,
sorry for not getting back to you, on your 2ic request.
from this sample code, can i pass argument to this python? if so it should be easy enough without much modification. how good you are with python?
easyi2c.py
#!/usr/bin/env python
# Contributed by Raju and updated by Jim,)
#
# Use:
# import easyi2c
# dev = easyi2c.IIC(
# example
# dev = easyi2c.IIC(0x32,1)
# dev.i2c([10,1,0,1],1) # sends bytes 10,1,0,1 and returns 1 byte
# dev.close()
#
import io
import fcntl
I2C_SLAVE=0x0703
# linuxi2c.py
# 2017-03-19
# Public Domain
# Based on 'notSMB' for an easier way to access the i2c bus using just one
# function. The main difference between this and notSMB is that the bus
# here will be dedicated to 1 device address
class IIC:
def __init__(self, device, bus):
self.fr = io.open("/dev/i2c-"+str(bus), "rb", buffering=0)
self.fw = io.open("/dev/i2c-"+str(bus), "wb", buffering=0)
# set device address
fcntl.ioctl(self.fr, I2C_SLAVE, device)
fcntl.ioctl(self.fw, I2C_SLAVE, device)
def write(self, data):
if type(data) is list:
data = bytes(data)
self.fw.write(data)
def read(self, count):
s = ''
l = []
s = self.fr.read(count)
if len(s) != 0:
for n in s:
l.append(ord(n))
return l
def close(self):
self.fw.close()
self.fr.close()
def i2c(self,listin,nout):
rv=0
self.write(bytearray(listin))
if nout != 0:
rv = self.read(nout)
return rv
simple.py
#!/usr/bin/env python
# Simple test for BV4627 using RPi i2c
# use wget http://www.byvac.com/downloads/py/easyi2c.py
import easyi2c # have linuxi2c.py in same directory
from time import sleep
def main():
dev = easyi2c.IIC(0x32,1)
# click relays in turn one after the other
for n in range(10,18): # always 1 more than needed
print "Relay ",n
dev.i2c([n,1,0,1],0) # on
sleep(0.2)
dev.i2c([n,0,0,1],0) # off
sleep(0.2)
dev.i2c([18],0) # all off just in case
dev.close()
if __name__ == '__main__':
main()
if i can get some info on the zone and to turn on/off, then i can get the python code together – then just a matter of finding a way to execute the python from php… my current solution for heating is all done in python – the gui is non existent however and you have far more features so no point me re-writing what you have already done 🙂 happy to put together the python code
passing parameter wont wor directly, i can write something which will – any spec on what you will be passing? either php or python will need to convert the zone to relay number in some form of lookup table…
python can be executed from php script (/var/www/cron/boiler.php) this code will go to line 242 as of today.
$i2caddress = '0x16';
$relay = '11';
$status = '0';
exec("/var/www/cron/i2c.py ".$i2caddress." ".$relay." ".$status.");
let me know if you can put something together on python side.
give me a couple of days to put something together. With the relay, i guess this will be populated elsewhere to find the value – can be any value from 10 to 18 depending on the zone? and also status will be 0 to turn off, 1 to turn on
Hi, are these changes still in place? I can’t seem to find them in boiler.php?
Hi Raju,
if you get me python script that can take relay 12c address, relay number and status as input i can add this to boiler.php to have support for this type of relay boards. and you can do some testing.
files sent.