This tutorial will show how I connected my conventional doorbell to Openhab in order to monitor when the doorbell button is pressed causing the doorbell to ring and to be able to mute the doorbell. The latest comes in handy when sleeping durig daytime for example when working in night shifts or having young kids.
As I have a doorbell which is working as expected I don’t want to change to much to the doorbell, furthermore I also want the doorbell to keep functioning when openhab is not working/off.
Altough it is possible to use the GPIO binding of openhab I didn’t used it. The main reason for this is that I don’t want a hard coupling of Openhab running on the raspberry pi. Instead I used nodejs and mqtt for reading the GPIO pin and sending status updates via the mqtt messagebus. This makes it possible for me to have openhab running on another system than where the doorbell is connected to. Next to the decoupling another advantage of this approach is the fact that multiple programs can listen to the messagebus and not only openhab as actor for the doorbell.
###prerequisite
installed packages:
Openhab
InfluxDB en grafana
Openhab MQTT binding
Mosquitto (mqtt messagebroker)
- sudo apt-get install mosquitto mosquitto-clients python-mosquitto
- sudo systemctl enable mosquitto
- sudo systemctl start mosquitto
- systemctl status mosquitto
nodejs (Upgrade to newer version nodejs)
- sudo apt-get remove nodejs
- wget https://nodejs.org/dist/v6.10.0/node-v6.10.0-linux-armv6l.tar.xz
- sudo mv node-v6.10.0-linux-armv6l.tar.xz /opt
- cd /opt
- sudo tar xf node-v6.10.0-linux-armv6l.tar.xz
- sudo mv node-v6.10.0-linux-armv6l nodejs
- sudo rm node-v6.10.0-linux-armv6l.tar.xz
- sudo ln -s /opt/nodejs/bin/node /usr/bin/node
- sudo ln -s /opt/nodejs/bin/node /usr/bin/nodejs
- sudo ln -s /opt/nodejs/bin/npm /usr/bin/npm
Install the nodejs gpio and mqtt module
- sudo npm install onoff
- sudo npm install mqtt
situation before making the doorbell smart:
1x 230 AC to 8AC transformer
1x Doorbell
1x Doorbell push button
Doorbell Monitor
The doorbell monitor will give an event everytime the doorbell button is pressed. I used an optocoupler to seperate the voltage circuit of the Doorbell with the voltage circuit of the Raspberry Pi. When the doorbell is signalled with an 8AC voltage the Raspberry Pi will also get a signal via the OptoCoupler.
###components used:
D1 = 1n4001 diode
R1 = 680 ohm limitting current resistor
R2 = 10K pull up resistor
R3 = 2k2 protection resistor (to prevent damaging the GPIO when by accicent configured as output)
U1 = 4n35 Optocoupler
Raspberry Pi
###Node js code doorbell_ring.js:
This scripts monitors the GPIO pin and sends a message on the MQTT bus every time the doorbell is pressed. As I saw some false detections I only sent a message when the GPIO pin is detecting 4 falling signals of the 50 Hz sinus signal. 2 successive button presses are noticed when 2 timestamps is bigger than 250 ms.
sudo vim /home/pi/doorbell_ring.js
and add:
var Gpio = require('onoff').Gpio,
door_bell_button = new Gpio(18, 'in', 'falling');
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://localhost:1883')
global.LastRingTime = Date.now()
global.nrOfTriggersWithin100ms = 0
global.HundredMsThreshold = Date.now()
door_bell_button.watch(function(err, value) {
if (err) exit();
RingTimeNow = Date.now()
//console.log('registered falling GPIO18: %s', RingTimeNow);
if (RingTimeNow - global.LastRingTime > 250)//20 ms should be enough but somehow the first ring shows around 230 ms delay
{
global.nrOfTriggersWithin100ms = 1
global.HundredMsThreshold = RingTimeNow + 100
}
if ( (global.nrOfTriggersWithin100ms < 4) && (RingTimeNow < global.HundredMsThreshold ) )
{
global.nrOfTriggersWithin100ms++
if (global.nrOfTriggersWithin100ms == 4)
{
client.publish('myHome/doorbell/ring', 'ON')
console.log('Someone rings the doorbell: %s', RingTimeNow);
}
}
global.LastRingTime = RingTimeNow
});
function exit() {
console.log('doorbell_ring.js exit');
process.exit();
}
process.on('SIGINT', exit);
###Install doorbell_ring.js as a service
The following make the nodejs code to be restarted at systemstart.
Create service script: /etc/systemd/system/doorbell_ring.service
sudo vim /etc/systemd/system/doorbell_ring.service
with content:
[Unit]
Description=Doorbell_ring
[Service]
ExecStart=/usr/bin/nodejs /home/pi/doorbell_ring.js
Restart=always
User=pi
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/home/pi
[Install]
WantedBy=multi-user.target
Change file permissions:
sudo chmod 755 /etc/systemd/system/doorbell_ring.service
Start it with:
sudo systemctl start doorbell_ring
Enable it to run on boot with:
sudo systemctl enable doorbell_ring
Configure openhab MQTT items
Now the hardware is inplace and events are being sent on the MQTT message bus, we want to transform the mqtt message into an event in OpenHAB. This is done via an item. The item “doorbell_ring” of type switch is binded onto the mqtt channel
sudo vim /etc/openhab2/items/mqtt.items
Add:
Switch doorbell_ring {mqtt="<[mosquitto:myHome/doorbell/ring:state:default]"}
Persistence in openhab
I use Influx as persistence service in openhab
Edit:
sudo vim /etc/openhab2/persistence/influxdb.persist:
Add:
doorbell_ring : strategy = everyUpdate, restoreOnStartup
Doorbell mute
The doorbell mute functionality will be used to switch off the actuall ringing of the bell and in such acting as a mute function for the doorbell.
I used a 5V 2 channel relay module to control the signal comming from the button to the doorbell with a raspberry pi. By default the relay is closed causing the doorbell to function as normall. When switching the relay the closed circuit to the doorbell is interupted causing the doorbell NOT to ring. Hence a mute function has been created.
Nodejs code doorbell_mute.js
Now the hardware is connected to the RPI we want to have software inplace to control the relay. I chose to use nodejs and mqtt for this. NodeJS is an easy to use and is based on an event driven model. In the script we listen to events on the MQTT message bus and transform this event to toggle the relay and thus toggeling the doorbel mute on/off
sudo vim /home/pi/doorbell_mute.js
and add:
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://localhost:1883')
var Gpio = require('onoff').Gpio,
relay1 = new Gpio(23, 'out'), //GPIO23, PIN16
client.on('connect', function () {
client.subscribe('myHome/doorbell/mute')
})
client.on('message', function (topic, message) {
// message is Buffer
// message is 1 when mute active, 0 when mute is inactive
relay1.writeSync(message.toString().trim() === '1' ? 0 : 1); //low active so sending 1 for 0 and 0 for 1
console.log(message.toString())
})
Install doorbell_mute.js as a service
The following make the nodejs code to be restarted at systemstart.
Create service script: /etc/systemd/system/doorbell_mute.service
sudo vim /etc/systemd/system/doorbell_mute.service
with content:
[Unit]
Description=Doorbell_mute
[Service]
ExecStart=/usr/bin/nodejs /home/pi/doorbell_mute.js
Restart=always
User=pi
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/home/pi
[Install]
WantedBy=multi-user.target
Change file permissions:
sudo chmod 755 /etc/systemd/system/doorbell_mute.service
Start it with:
sudo systemctl start doorbell_mute
Enable it to run on boot with:
sudo systemctl enable doorbell_mute
Configure openhab MQTT items
Now the hardware is inplace and the nodejs script is listening to events on the MQTT message bus, we want to transform the OpenHAB events into a message on the MQTT messagebus. This is done via an item. The item “doorbell_mute” of type switch is binded onto the mqtt channel causing a message to be sent on every switch of the openhab item.
Edit:
sudo vim /etc/openhab2/items/mqtt.items
Add:
Switch doorbell_mute {mqtt=">[mosquitto:myHome/doorbell/mute:command:ON:1],>[mosquitto:myHome/doorbell/mute:command:OFF:0]"}
Persistence in openhab
I use Influx as persistence service in openhab
Edit:
sudo vim /etc/openhab2/persistence/influxdb.persist
Add:
doorbell_mute : strategy = everyChange, restoreOnStartup
Add doorbell mute button to sitemap
To be able to control the doorbell mute functionality a button needs to be added to a sitemap:
Edit
sudo vim /etc/openhab2/sitemaps/doorbell.sitemap
Add:
sitemap doorbell label="doorbell"
Switch item=doorbell_mute
if you use HABPanel adding the sitemap is not necessary as the openhab item can be chosen directly as a configuration item with for example a button.
Doorbell monitor & mute
situation after making the doorbell smart:
Connecting the monitor functionality before the relayboard to the doorbell makes it possible to monitor the doorbell even when the doorbell is muted.
As I used a 2 channel relay board the 2nd relay could be used to control the doorbell programmatically, by connecting the N/O and COM parallel over the doorbell_button and connecting the IN2 to an RPI GPIO pin.