Hello openHAB community.
Recently I made the mistake of updating my working openHAB setup to the latest version, and then nothing worked. Instead of trying to figure out what went wrong, I decided to start again from scratch, documenting each step to make it easier the next time or for the next person.
Before deciding to use openHAB for my home automation setup, I was not familiar with Linux, Java, MQTT, and many other pre-requisites. For noobs like me, the site Linux Journey is definitely a good initial resource.
Some basic programming and IT related knowledge is assumed. I am using Solar Putty for the terminal, and VisualStudio Code for text based configuration. Both are free.
There are likely many better ways to do a lot of the things listed below. I welcome constructive criticism and suggestions.
Initially this guide will cover just the setup with the INNR light bulb, but over time IKEA lights and Aqara sensors will be added as well.
Initial Steps
-
Flash openHABian v1.5 to an SD Card with Etcher
https://www.openhab.org/docs/installation/openhabian.html -
Put SD Card in Raspberry Pi 3B+, turn ON, and wait for it to appear on the network (20-30 minutes). Give it a fixed IP address from the router interface.
-
Open a terminal session to the Raspberry (I use SolarPutty) with the IP address you assigned, the default username (openhabian) and password (openhabian)
-
Launch openhabian Configuration Tool
sudo openhabian-config
and updated to latest testing (milestone) build (in my case openHAB 2.5.0~M4-1). With the 2.4.0 stable release version I remember having many issues with MQTT. -
Applied improvements 11, 12, 13, 14 from openhabian config tool
-
Installed optional components
- Fronttail log viewer (very useful!)
- Mosquitto broker
zigbee2mqtt will not start correctly if a broker is not previously installed.
The mosquitto configuration file is located in etc/mosquitto/mosquitto.conf
For this installation, the configuration file was not modified.
Zigbee2Mqtt Install
-
Using CC2531 USB Sniffer with zigbee2mqtt loaded
-
Connected CC2531 to RPi3B+. It was necessary to reboot
sudo reboot
the Pi for the stick to be correctly recognized. -
After reboot, followed zigbee2mqtt install instructions
https://www.zigbee2mqtt.io/getting_started/running_zigbee2mqtt.html
Had minor issue with the command sudo chown -R pi:pi /opt/zigbee2mqtt
pi:pi
had to be changed to openhabian:openhabian
to reflect my user.
When creating the .service file to run zigbee2mqtt in the background, remember to change the user in case it’s necessary.
[Unit]
Description=zigbee2mqtt
After=network.target
[Service]
ExecStart=/usr/bin/npm start
WorkingDirectory=/opt/zigbee2mqtt
StandardOutput=inherit
StandardError=inherit
Restart=always
**User=openhabian**
[Install]
WantedBy=multi-user.target
- Using
mosquitto_sub
tool in the terminal, checked correct operation of the Mosquitto broker and zigbee2mqtt HW / SW
mosquitto_sub -d -t zigbee2mqtt/#
This will subscribe to all mqtt topics starting with zigbee2mqtt
in debug mode. For more information see mosquitto_sub.
If all is well, you should see something like this:
Client mosqsub|1210-openhab sending CONNECT
Client mosqsub|1210-openhab received CONNACK (0)
Client mosqsub|1210-openhab sending SUBSCRIBE (Mid: 1, Topic: zigbee2mqtt/#, QoS: 0)
Client mosqsub|1210-openhab received SUBACK
Subscribed (mid: 1): 0
Client mosqsub|1210-openhab received PUBLISH (d0, q0, r1, m0, 'zigbee2mqtt/bridge/state', ... (6 bytes))
online
Client mosqsub|1210-openhab received PUBLISH (d0, q0, r1, m0, 'zigbee2mqtt/bridge/config', ... (99 bytes))
{"version":"1.6.0","commit":"e26ad2a","coordinator":20190223,"log_level":"info","permit_join":true}
- While still having
mosquitto_sub
active, paired an INNR GU10 RS 255 bulb to the Raspberry Pi by performing the standard reset procedure (turn the light OFF and ON 6 times, the ON time shorter than the OFF time).
This had the following result on the mosquitto_sub
terminal:
Client mosqsub|1210-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/0x00158d000324d57f', ... (47 bytes))
{"state":"ON","linkquality":68,"brightness":79}
Client mosqsub|1210-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/0x00158d000324d57f', ... (48 bytes))
{"state":"ON","linkquality":68,"brightness":254}
Client mosqsub|1210-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/bridge/log', ... (46 bytes))
{"type":"pairing","message":"device incoming"}
Note that it can take some time for this to appear, depending on the distance between the bulb and the Raspberry. In general for pairing it is recommended that the device is as close as possible to the coordinator.
- Modified the mosquitto configuration file to have a more friendly name than the super long hexadecimal identifier for the bulb.
sudo nano /opt/zigbee2mqtt/data/configuration.yaml
homeassistant: false
permit_join: true
mqtt:
base_topic: zigbee2mqtt
server: 'mqtt://127.0.0.1:1883'
serial:
port: /dev/ttyACM0
disable_led: true
devices:
'0x00158d000324d57f':
friendly_name: L_Hall3
retain: true
I also disabled the green LED on the CC2531 sniffer as it is brighter than the northern lights.
After saving the file (CRTL-o + ENTER) and exiting (CTRL-x) I rebooted the Raspberry (sudo reboot
) just in case, to make sure the changes in the configuration file were applied.
- While running
mosquitto_sub
, I used themosquitto_pub
tool in another terminal session, to check that the light could also be turned OFF and brightness changed.
mosquitto_pub -t zigbee2mqtt/L_Hall3/set -m '{"state":"OFF"}'
The corresponding message on mosquitto_sub
when successful:
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3/set', ... (15 bytes))
{"state":"OFF"}
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3', ... (49 bytes))
{"state":"OFF","linkquality":68,"brightness":254}
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3', ... (49 bytes))
{"state":"OFF","linkquality":55,"brightness":254}
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3', ... (49 bytes))
{"state":"OFF","linkquality":55,"brightness":254}
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3', ... (49 bytes))
{"state":"OFF","linkquality":55,"brightness":254}
mosquitto_pub -t zigbee2mqtt/L_Hall3/set -m '{"brightness":"50"}'
Corresponding mosquitto_sub
when successful:
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3/set', ... (19 bytes))
{"brightness":"50"}
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3', ... (47 bytes))
{"state":"ON","linkquality":55,"brightness":50}
Client mosqsub|1196-openhab received PUBLISH (d0, q0, r0, m0, 'zigbee2mqtt/L_Hall3', ... (47 bytes))
{"state":"ON","linkquality":55,"brightness":50}
It’s also possible to combine state and brightness in the published message.
mosquitto_pub -t zigbee2mqtt/L_Hall3/set -m '{"state":"ON","brightness":"50"}'
It took me a while to get the syntax right in mosquitto_pub
, but this was incredibly helpful for later, when formatting the data and commands in openHAB. All apostrophes, quotation marks, curly brackets, etc. are mandatory.
OpenHab Configuration
- Install the MQTT 2.5.0 Binding from Paper UI, under Add-ons → Bindings.
I tried doing this manually by copying the .jar file in the addons directory, but then I had issues with dependencies to other bundles which I didn’t have the patience to resolve. Therefore I opted to install the binding through Paper UI.
- Install the Javascript and JSONPath Transformation services from Paper UI, under Add-ons → Transformations.
This is important because some of the data needs to be transformed before sending or receiving. More on this later.
- Mounted the Samba network shares on my Windows 10 machine as described here:
https://www.openhab.org/docs/installation/linux.html#mounting-locally
My hostname was openhab
instead of openhab-device
My default username was openhabian
and password openhabian
- Opened Visual Studio Code, and added the newly mounted network share
openHAB-conf
as a workspace folder. The folder structure with icons, items, rules, sitemaps, and other folders should now appear in the VS Code Workspace.
Creation of .things File
- Now the connection to the MQTT broker (Mosquitto in my case) needs to be setup. I chose to do this via text files, as I wanted to have everything in one place.
-
First a text file with a .things extension needs to be created in the
things
folder of the network share. I did this through the VS Code interface. The filename itself is not important, although I would avoid using special characters or spaces. -
Next the connection to the MQTT broker needs to be defined. The best resources that I found for this are linked below.
https://www.openhab.org/docs/configuration/things.html#defining-bridges-using-files
My broker does not have user/password or any special configuration, so the connection configuration in the .things file is as follows:
Bridge mqtt:broker:mosquitto [host="localhost", secure=false]
- However, this alone is not enough. In the same .things file, the INNR light bulb that was previously paired (friendly name: L_Hall3) needs to be defined. It took me a while to get this right, and the following links were quite useful:
https://community.openhab.org/t/zigbee2mqtt-and-zigbee-bulbs-small-tutorial/72129
The complete .things file including the INNR bulb looks like this:
Bridge mqtt:broker:mosquitto [host="localhost", secure=false]
{
//Lights
Thing topic L_Hall3 @ "Casa" {
Channels:
Type switch : onoff "Luz Pasillo 3" [stateTopic="zigbee2mqtt/L_Hall3", transformationPattern="JSONPATH:$.state", commandTopic="zigbee2mqtt/L_Hall3/set", transformationPatternOut="JS:settradfristate.js"]
Type dimmer : dim "Dimmer Pasillo 3" [stateTopic="zigbee2mqtt/L_Hall3", transformationPattern="JSONPATH:$.brightness", commandTopic="zigbee2mqtt/L_Hall3/set", min=1, max=254, step=1, formatBeforePublish="{ \"brightness\" : %s }"]
}
}
The data being exchanged between the light bulb and coordinator is formatted as a JSON object. As we saw in the previous mosquito_sub
, for the light bulb the object looks like this:
{"state":"OFF","linkquality":55,"brightness":254}
In order to work with this data in openHAB, it is necessary to define which part of the JSON object corresponds to each channel. When the data is sent to the bulb, it must also be formatted correctly, which may require a transformation.
For the switch channel Luz Pasillo 3
we define that the state
field in the JSON object is the relevant data by using the transformationPattern="JSONPATH:$.state"
command. This data, despite having the values as text in the form of "ON"
or "OFF"
is interpreted by openHAB correctly.
However, when openHAB tries to set the state of the light bulb, for some reason it is sending either a numeric 0
or a 1
instead of "OFF"
or "ON"
, and this is not interpreted correctly by the bulb. Therefore, the outgoing data has to be transformed using the script JS:settradfristate.js
before being sent. The script is described in more detail in the next Section.
For the dimmer channel Dimmer Pasillo 3
we define that the brightness field in the JSON object is the relevant data by using the transformationPattern="JSONPATH:$.brightness"
command. This is a numeric value and is interpreted by openHAB correctly.
For the outgoing data, the minimum, maximum, and step values need to be defined. Additionally, the number needs to be formatted as a JSON object. This is done with the min=1, max=254, step=1, formatBeforePublish="{ \"brightness\" : %s }"
commands.
Creation of Transformation Patterns
To transform the numeric 0
and 1
into the text "OFF"
and "ON"
that the light bulb is expecting, a transformation script was created.
- A new text file named
settradfristate.js
was created in thetransform
folder of the openHAB network share. I used the VS code interface.
// Transforms an input value of 0 or 1 to "OFF" or "ON" respectively and formats as JSON
(function(x) {
var result = new Object();
if ((x == 1) || (x == "1")) {
result.state = "ON"
}
else if ((x == 0) || (x == "0")) {
result.state = "OFF"
}
else result.state = x
return JSON.stringify(result);
})(input)
Creation of .items File
To create a sitemap, first the items need to be defined. This was done by creating a new file with the .items extension in the items
folder of the network share.
The syntax for the .items file is well documented:
https://www.openhab.org/docs/configuration/items.html
Switch Light_Hall3 "Luz Pasillo 3" {channel="mqtt:topic:mosquitto:L_Hall3:onoff"}
Dimmer Dim_Hall3 "Dimmer Pasillo 3 [%d %%]" {channel="mqtt:topic:mosquitto:L_Hall3:dim"}
Sitemap Creation
-
Set the Default Sitemap to
default
via Paper UI, as described here towards the bottom:
https://www.openhab.org/docs/tutorial/sitemap.html -
Create a new file named
default.sitemap
in thesitemaps
folder of the network share. -
Add both of the previously created items to the sitemap. The syntax and elements of sitemaps is well documented:
https://www.openhab.org/docs/configuration/sitemaps.html
sitemap default label="My_Sitemap"
{
Switch item=Light_Hall3 label="Luz Pasillo 3"
Slider item=Dim_Hall3 label="Dimmer Pasillo 3 [%d %%]" sendFrequency=500
}
Now when accessing the Basic UI from your web browser, you should be able to see the Switch and Dimmer previously created.
I had to wait about one minute before toggling the switch and slider actually had a real effect on the light bulb, but after that the light could be monitored and controlled perfectly from the Basic UI.
System and Addons
openHAB 2.5.0~M4-1
Raspberry Pi 3B+
219 │ Active │ 80 │ 1.2.1 │ Paho MQTT Client
220 │ Active │ 80 │ 2.5.0.M4 │ openHAB Add-ons :: Bundles :: MQTT Broker Binding
221 │ Active │ 81 │ 2.5.0.M4 │ openHAB Add-ons :: Bundles :: MQTT Things and Channels
222 │ Active │ 82 │ 2.5.0.M4 │ openHAB Add-ons :: Bundles :: MQTT HomeAssistant Convention
223 │ Active │ 82 │ 2.5.0.M4 │ openHAB Add-ons :: Bundles :: MQTT Homie Convention
224 │ Active │ 80 │ 2.5.0.M4 │ openHAB Core :: Bundles :: MQTT Transport
225 │ Active │ 75 │ 2.5.0.M4 │ openHAB Add-ons :: Bundles :: Transformation Service :: JavaScript
226 │ Active │ 75 │ 2.5.0.M4 │ openHAB Add-ons :: Bundles :: Transformation Service :: JSonPath
Edits
2019-Oct-14 22:49 GMT+2: Changed descriptive text and image in Sitemap section to reflect the item description better and avoid confusion (ie Luz Pasillo 3
instead of Luz Sala
)
2019-Nov-15 23:05 GMT+1: Changed all from openHAB snapshot 2.5.0 build #1703 to milestone 2.5.0 M4, as I could not get persistence to work on the snapshot build #1703. Had to start from scratch, the good thing is that with the tutorial it was much faster than before and all steps are now confirmed. Many people have written this, and I can now also confirm: don’t use snapshot builds for production.