openHAB and zigbee2mqtt Tutorial for Beginners

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

  1. Flash openHABian v1.5 to an SD Card with Etcher
    https://www.openhab.org/docs/installation/openhabian.html

  2. 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.

  3. Open a terminal session to the Raspberry (I use SolarPutty) with the IP address you assigned, the default username (openhabian) and password (openhabian)

  4. 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.

  5. Applied improvements 11, 12, 13, 14 from openhabian config tool

  6. 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

  1. Using CC2531 USB Sniffer with zigbee2mqtt loaded

  2. Connected CC2531 to RPi3B+. It was necessary to reboot sudo reboot the Pi for the stick to be correctly recognized.

  3. 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
  1. 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}
  1. 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.

  1. 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.

  1. While running mosquitto_sub, I used the mosquitto_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

  1. 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.

  1. 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.

  1. 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

  1. 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.

image

Creation of .things File

  1. 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/blog/2018-12-16-mqtt-arrives-in-the-modern-openhab-2-x-architecture.html#configuration-via-text-files

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]

  1. 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

https://community.openhab.org/t/howto-use-zigbee2mqtt-with-openhab-removing-proprietary-bridges-gateways/48768

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 the transform 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

  1. Set the Default Sitemap to default via Paper UI, as described here towards the bottom:
    https://www.openhab.org/docs/tutorial/sitemap.html

  2. Create a new file named default.sitemap in the sitemaps folder of the network share.

  3. 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.

31 Likes

Why not use our Zigbee binding? Why add MQTT complexity?

Because zigbee2mqtt is a popular solution to add Zigbee capability.
I use it on a satellite pi in a cupboard in the very center of the house
My OH server is not located is a good place for any sort of wireless dongle.

1 Like

@z9th3 very nice contribution for a first time post! Thank you for a very well written step by step procedure and welcome to the OpenHAB community!

3 Likes

Hello altbau, unfortunately my knowledge is not enough to help you with your issue. Are you following my tutorial step by step or doing something different? I had issues when starting zigbee2mqtt the first time because I did not have an MQTT broker installed. Once I installed the Mosquitto broker and rebooted it worked fine.

Can you verify the correct version of both node and npm is correct? You can do this from command line by typing:
node --version
npm --version
Node version should be v10.x and npm 6.x

Did you install npm in the correct directory? Most examples (not sure where OP installed) will use /opt/zigbee2mqtt

EDIT:
Just checked the OP’s source for installing zigbee2mqtt and /opt/zigbee2mqtt is the correct location. Also you mentioned new system…what equipment are you using?

Very nice, having a link for all your sources is a major plus. Like Vincent I run zigbee2mqtt on a separate pi that’s centrally located. I’ve been using the same coordinator for over a year with no issues. I have no idea what the life expectancy of those things are but when buying from oversea’s it’s only $6 U.S.

Thanks again and welcome to the community!

I would start with step 2 Installing and repeat each step again. The one thing you will need to change is sudo chown -R pi:pi /opt/zigbee2mqtt. Unless using pi as user name you will need to change this.

Did you install openhab manually for use openhabian image? I’t been a while but I seem to recall that zigbee2mqtt works with rasbian strech and not so much with Jessie so check to see what your using.

Check what os release your using by typing cat /etc/os-release If your up to date you will see version 10 (buster) that is what I’m currently using. If you have something different then try to use sudo apt-get update and sudo apt-get upgrade but check again after the update and only upgrade if needed.

See Edit below before attempting the following suggestions
Reading back over previous post.

This is the location you should run npm install from home directory use cd /opt/zigbee2mqtt this will take you to the location for using npm install. If you followed the directions, and I’m sure you have, this has already been done. I’m just reiterating for my own clarity.:upside_down_face:

Since nothing else has worked try, from this location openhabian@openHABianPi:~$, typing sudo chgrp -R openhabian /opt/zigbee2mqtt. Does this help? If not we’ll move on to reviewing the logs.

So, looking at the logs posted above, I didn’t see an error related to the usb stick but it’s worth taking a look to make sure both the stick and flash are good. So back at the command line type dmesg scroll thru the output and look for a line similar to “cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device”. I think your port may be different than ACM0 but the output should reflect that. I wouldn’t think the stick is the issue for installing npm but it only takes a sec to check. Btw is openhab a member of the tty and dialout group? I’m running this on a separate device than my OH server so not really sure it makes a difference but it wouldn’t hurt to go ahead and add. Use sudo adduser openhab dialout and sudo adduser openhab tty Both of these commands work but I have read where others use sudo usermod openhab -a -G dialout but don’t ask what’s the difference b/c I’m not sure.:laughing: May as well check the port while your at it with test -w /dev/ttyACM0 && echo success || echo failure If it output failure then assign the port with sudo chown pi /dev/ttyACM0 *Remember to adjust the ACM0 to match your port.:wink:

Now the stick is verified let’s move to the error mentioned “Cannot find module zigbee-herdsman/dist/deprecated/ziee”. As this is really a zigbee2mqtt issue, rather than an openhab problem, I’ll need to check thru github issues to see what I can find. After giving the above suggestions a shot and still no luck you can read thru all the issues on github…like I’ll be going to do now.

If I find something that’s related to your posted log I’ll update you here. Also, please post if there are any changes in the log after going thru steps above.

Good luck.

EDIT
Looking thru issues I found where others have similar log errors due to the version of herdsman/dist. Check the version that got install by using cat /opt/zigbee2mqtt/package.json. Look toward the bottom of file, under dependencies, you will see “zigbee-herdsman” : “0.5.7” or some other version number. If not 0.5.7 then you will need to use text editor and change whatever you have to 0.5.7 You may need to manually install the package.json file again but before do that you can try a simple npm install again (from /opt/zigbee2mqtt directory) then ** npm audit fix** and hopefully you should be good.

If none of the above works then uninstall and reinstall a earlier version b/c the latest one seem to be the issue.

Great work @z9th3. I haven’t updated zigbee2mqtt for more than a year. Will probably ref. your doc after updating it.

On a separate note, has any tried to run two coordinators (on two separate PIs) in the house? Does that cause any inteference?

Please post what the solution was so that anyone else that has this issue can also find a resolution.

Thanks

a small FYI i leraned today, putting a CC2531 flashed in power socket will extend the network
i am waiting for my order to test it :slight_smile:

3 Likes

Curious to know how well it works, keep us posted.:+1:

Hello,

has someone added the xiaomi smoke detector with the new option to set selftest and sensitivity?

Also curious if anyone has some pointers on getting color bulbs to work correctly and/or with mqtt v2

Hi @Gad_Ofir I tested the CC2531 Router Firmware and it seems to work well to extend the range of the zigbee network simply plugged into a spare USB charger. I’m still struggling to output a network map to prove that the messages a going over the router, but since doing this the updates from my outdoor temp and humidity sensor are coming in much more consistently.

Wow great to hear :slight_smile:

i did not understand what is " output a network map" for monitor i just use grafana
i saw some zigbee network maps online for Home asstient and i was wondring if we can do it also?
this is my dashboard to track signal and power

1 Like

Hi, did you paire your router or simply flashed and power it?

Flashed with router firmware, powered it, and it paired automatically with the CC2531 coordinator.

1 Like