Howto use zigbee2mqtt with openHAB, removing proprietary bridges / gateways

The main problem with the new binding is that there is no way (or limited in some cases) to use the commandTopic with zigbee2mqtt.

See also: Need help to migrate to the mqtt binding v2 in openhab 2.4

and another tut: MQTT 2.4, ZigBee2MQTT, Xiaomi Aqara Sensors (sample config)

@job Is there already some progress regarding the OSRAM lamps?
I would like to add my Lightify RGBW Flex, but the only thing I can do right now, is to switch it off…

Hello!

I set up zigbee2mqtt with a aquara door contact. Zigbee2mqtt is publishing via mqtt, so its working. But i cant get it to work with OH. I am using @tebore sample and have installed the javascript transformation.

zigbee2mqtt.items:

Group gXiaoMiZigbee	"XiaoMi sensors"	<zigbee>

String Zigbee2MQTT_Pair		"Pairing Mode [$s]"	<qualityofservice>	{mqtt="<[mosquitto:zigbee2mqtt/config/permit_join:state:default], >[mosquitto:zigbee2mqtt/config/permit_join:command:*:default]"}

Group gXiaoMiZ2BContact	"Xiaomi Contact"	<zigbee>	(gXiaoMiZigbee)
Contact XAIOMI_CONTACT 	"Contact"  						(gXiaoMiZ2BContact)	{mqtt="<[mosquitto:zigbee2mqtt/Fenstersensor1:state:JS(getZigbeeContact.js)]"}
Number 	XAIOMI_VOLTAGE 	"Voltage [%d mV]" 	<battery>	(gXiaoMiZ2BContact)	{mqtt="<[mosquitto:zigbee2mqtt/Fenstersensor1:state:JSONPATH($.voltage)]"}
Number 	XAIOMI_BATTERY 	"Battery [%.1f %%]" <battery>	(gXiaoMiZ2BContact)	{mqtt="<[mosquitto:zigbee2mqtt/Fenstersensor1:state:JSONPATH($.battery)]"}

getZigbeeContact.js

(function(x){

    var result = "";
 
    var json = JSON.parse(x);  
    if (json.contact) 
    {
        result="CLOSED";
    } 
    else 
    {
        result="OPEN";
    }

    return result;
    
})(input)

Log:

2019-02-17 09:54:35.160 [WARN ] [.mqtt.internal.MqttMessageSubscriber] - Error processing MQTT message.

org.openhab.core.transform.TransformationException: An error occurred while loading script.

	at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:67) ~[212:org.openhab.core.compat1x:2.4.0]

	at org.openhab.binding.mqtt.internal.MqttMessageSubscriber.processMessage(MqttMessageSubscriber.java:133) [222:org.openhab.binding.mqtt:1.13.0]

	at org.openhab.io.transport.mqtt.internal.MqttBrokerConnection.messageArrived(MqttBrokerConnection.java:570) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.deliverMessage(CommsCallback.java:475) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:379) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:183) [223:org.openhab.io.transport.mqtt:1.13.0]

	at java.lang.Thread.run(Thread.java:748) [?:?]

2019-02-17 09:54:35.165 [WARN ] [.mqtt.internal.MqttMessageSubscriber] - Error processing MQTT message.

org.openhab.core.transform.TransformationException: Invalid path '$.voltage' in '{"contact":false,"linkquality":36}'

	at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:67) ~[212:org.openhab.core.compat1x:2.4.0]

	at org.openhab.binding.mqtt.internal.MqttMessageSubscriber.processMessage(MqttMessageSubscriber.java:133) [222:org.openhab.binding.mqtt:1.13.0]

	at org.openhab.io.transport.mqtt.internal.MqttBrokerConnection.messageArrived(MqttBrokerConnection.java:570) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.deliverMessage(CommsCallback.java:475) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:379) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:183) [223:org.openhab.io.transport.mqtt:1.13.0]

	at java.lang.Thread.run(Thread.java:748) [?:?]

2019-02-17 09:54:35.169 [WARN ] [.mqtt.internal.MqttMessageSubscriber] - Error processing MQTT message.

org.openhab.core.transform.TransformationException: Invalid path '$.battery' in '{"contact":false,"linkquality":36}'

	at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:67) ~[212:org.openhab.core.compat1x:2.4.0]

	at org.openhab.binding.mqtt.internal.MqttMessageSubscriber.processMessage(MqttMessageSubscriber.java:133) [222:org.openhab.binding.mqtt:1.13.0]

	at org.openhab.io.transport.mqtt.internal.MqttBrokerConnection.messageArrived(MqttBrokerConnection.java:570) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.deliverMessage(CommsCallback.java:475) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:379) [223:org.openhab.io.transport.mqtt:1.13.0]

	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:183) [223:org.openhab.io.transport.mqtt:1.13.0]

	at java.lang.Thread.run(Thread.java:748) [?:?]

his is the output ofmqtt.fx:

{"contact":false,"linkquality":34}

Please help me!

1 Like

Solved it partially. I put the *.js in the wrong directory…

But why isnt the battery status transmitted?

Edit: Also solved. The battery status is now submittet after a short press onthe button on the sensor

Can anybody help me with my request here:
Howto use zigbee2mqtt with openHAB, removing proprietary bridges / gateways (why do I get that warning/error message?)

here I asked for how to use the other aqara cube values:

My last question is, how can I display on HabPanel the times a sensor was last time triggered? I guess in some way by the openhab log… but how?

I thought I would share this in case anybody else finds it useful.

I have managed to get zigbee2MQTT working with an Innr and Ikea Tradfri bulb using the latest MQTT binding without using a javescript transformation, just a JSON one for the incoming message.

Things file.

Bridge mqtt:broker:myUnsecureBroker [ host="192.168.2.4", secure=false ]
{
    Thing topic zigbeeMQTT "Zigbee2mqtt" {
    Channels:
        Type switch : permitJoin         [ commandTopic="zigbee2mqtt/bridge/config/permit_join", on="true", off="false" ]
        Type dimmer : Test_Lamp "Test Lamp" [ stateTopic="zigbee2mqtt/Her_Lamp", commandTopic="zigbee2mqtt/Her_Lamp/set", min=1, max=254, step=1, transformationPattern="JSONPATH:$.brightness", formatBeforePublish="{   \"brightness\": %s }" ]
        //Main Study Lights
        Type dimmer : Main_Study_1 "Test Main Study 1" [ stateTopic="zigbee2mqtt/Main_Study_1", commandTopic="zigbee2mqtt/Main_Study_1/set", min=1, max=254, step=1, transformationPattern="JSONPATH:$.brightness", formatBeforePublish="{   \"brightness\": %s }" ]
        Type dimmer : Main_Study_2 "Test Main Study 2" [ stateTopic="zigbee2mqtt/Main_Study_2", commandTopic="zigbee2mqtt/Main_Study_2/set", min=1, max=254, step=1, transformationPattern="JSONPATH:$.brightness", formatBeforePublish="{   \"brightness\": %s }" ]
        Type dimmer : Main_Study_3 "Test Main Study 3" [ stateTopic="zigbee2mqtt/Main_Study_3", commandTopic="zigbee2mqtt/Main_Study_3/set", min=1, max=254, step=1, transformationPattern="JSONPATH:$.brightness", formatBeforePublish="{   \"brightness\": %s }" ]
    }
}

The ‘Min’ value is set to 1 as that’s what my bulbs report as off, ‘Max’ is 254 so the value can be between 1-255.

The ‘transformationPattern’ selects just the ‘Brightness’ value from the incoming JSON message. The ‘formatBeforePublish’ works to format the outgoing message into JSON format.

I have tested it with a couple of my lights and I am able to control them fine using Basic UI, HabPanel and through my Alexa.

2 Likes

@DarkZark, I’m no expert but this is how I am doing similar with a Xiaomi Button

Item

String CUBE_ACTION "Cube Action" {mqtt="<[broker:zigbee2mqtt/mqtt_aqara_cube:state:JSONPATH($.action)]"}

Then you can make a rule that will trigger when CUBE_ACTION is updated.

rule "Cube Action"
when
    Item CUBE_ACTION recieved update
then
    switch(CUBE_ACTION) {
        case "rotate_right":{
            //Do Something
        }
        case "shake": {
            //Do Something Else
        }
    }
end

You can add more case entries for each of the different actions the cube reports.

In terms of the error you are seeing about a motion sensor, can you confirm you have a file called “HM-Sen-MDIR-O-2.map” in you transform folder?

I have recently installed zigbee2mqtt with the help of this thread and I’m quite pleased - thanks to all of you.
But now I’m facing a problem where I need help.
I added my Xiaomi Mijja smoke sensors to zigbee2mqtt and that works quite well.
I added these to oh2:

Contact XIAOMI_SMOKE_EG1_STATE “Smoke [%s]” {mqtt="<[broker:zigbee2mqtt/xyz:state:JSONPATH($.smoke)]"}
Contact XIAOMI_SMOKE_EG_STATE “Smoke [%s]” {mqtt="<[broker:zigbee2mqtt/xyz:state:JS(getZigbeeSmoke.js)]" }
Number XIAOMI_SMOKE_EG_VOLTAGE “Smoke Volt [%d mV]” {mqtt="<[broker:zigbee2mqtt/xyz:state:JSONPATH($.voltage)]"}
Number XIAOMI_SMOKE_EG_BATTERY “Smoke BAT [%.1f %%]” {mqtt="<[broker:zigbee2mqtt/xyz:state:JSONPATH($.battery)]"}
Number XIAOMI_SMOKE_EG_LINK “Smoke Link [%d]” {mqtt="<[broker:zigbee2mqtt/xyz:state:JSONPATH($.linkquality)]"}

Both of the smoke state items do not work.
When i press the button on the smoke sensor i receive the following warning in the log:

2019-02-24 11:09:34.890 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn’t post update for ‘XIAOMI_SMOKE_EG1_STATE’
2019-02-24 11:09:35.426 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn’t post update for ‘XIAOMI_SMOKE_EG_STATE’

I have other json transformations that work quite well - so i guess it is not the transformation setup anyway this is the getZigbeeSmoke.js

(function(x){
var result = “”;
var json = JSON.parse(x);
if (json.smoke)
{
result=“ON”;
}
else
{
result=“OFF”;
}
return result;
})(input)

I’m really stuck here - so any help is highly appreciated
Thanks

@Bond1986
Not that I know of. But I also did not follow the development closely. I am currently at the limit, for each device I add, another one does not work anymore.

@hipohop
Could you show the message sent? Without it is impossible to help. It looks like the message does not contain that smoke attribute.

From the zigbee2mqtt log:

Feb 28 08:19:33 raspberrypi npm[400]: zigbee2mqtt:info 2019-2-28 08:19:33 MQTT publish: topic ‘zigbee2mqtt/0x…’, payload ‘{“battery”:100,“voltage”:3105,“linkquality”:35,“smoke”:false}’

Ahhh… Now I see. If you use a Contact item you need to use OPEN and CLOSED as states. If you like to use ON/OFF the item must be defined as a Switch.

1 Like

Ahhh … perfect! Thank you very much !

Just thought I would post this from the Zigbee2MQTT FAQ regarding device limits as it seems to confuse quite a few people, including myself.

I read that zigbee2mqtt has a limit of 15 devices, is this true?

Definitely not! The default zigbee2mqtt firmware indeed supports 15 devices connected directly to the coordinator. However, by having routers in your network the network size can be extended. Probably all AC powered devices e.g. bulbs serve as a router, you can even use another CC2530/CC2531 as a router (which has a limit of 21 devices). Various zigbee2mqtt users have reported that networks of 40+ nodes work without problems. Don’t want to buy a router? No problem! In that case an alternative firmware can be used which supported 44 devices directly connected to the coordinator.

Example

When using the default coordinator firmware + 2 CC2531 routers your device limit will be:

  • Coordinator: 15 - 2 routers = 13
  • Router 1: 21
  • Router 2: 21
  • Device limit of 55 devices

Also there has been mention about using instances of Zigbee2MQTT on several Raspberry Pi’s. The only way this would work would be to have each Pi running their own separate Zigbee network. I.e you would have an Upstairs network running from one Pi and a downstairs network running from the other Pi It’s not possible to have more than one coordinator(zigbee adaptor plugged into a Pi) per network .

As far as I can see there is no benefit of this whatsoever as all your Zigbee devices are designed to connect in a mesh network in increase single range. If you have too many end devices (Buttons, sensors) and not enough routers (Bulbs, sockets) it would be easier to follow the instructions in the Zigbee2MQTT documentation to make a router from a CC2530 or CC2531 than it would be to run multiple networks.

Hope this info can be of help.

Hi there,

I have successfully configured all my Aquara Temperature Sensors, but am not able to do the same for the door contacts.

Things File
Bridge mqtt:broker:myMQTTBroker [ host="pinky", secure=false]
{
    Thing topic zigbeeMQTT "Zigbee2mqtt" {
    Channels:
        Type switch : permitJoin         [ commandTopic="zigbee2mqtt/bridge/config/permit_join", on="true", off="false" ]
        Type string : state              [ stateTopic="zigbee2mqtt/bridge/state" ]
        //Type string : logType            [ stateTopic="zigbee2mqtt/bridge/log",  transformationPattern="JSONPATH:$.type" ]
        //Type string : logMessage         [ stateTopic="zigbee2mqtt/bridge/log",  transformationPattern="JSONPATH:$.message" ]
    }



    Thing topic zigbeeSensorWZ "Wohnzimmer Sensor" {
    Channels:
        Type number : temperature        [ stateTopic="zigbee2mqtt/Temperatur_WZ",  transformationPattern="JSONPATH:$.temperature" ]
        Type number : humidity           [ stateTopic="zigbee2mqtt/Temperatur_WZ",  transformationPattern="JSONPATH:$.humidity" ]
        Type number : pressure           [ stateTopic="zigbee2mqtt/Temperatur_WZ",  transformationPattern="JSONPATH:$.pressure" ]
        Type number : voltage            [ stateTopic="zigbee2mqtt/Temperatur_WZ",  transformationPattern="JSONPATH:$.voltage" ]
        Type number : battery            [ stateTopic="zigbee2mqtt/Temperatur_WZ",  transformationPattern="JSONPATH:$.battery" ]
        Type number : linkquality        [ stateTopic="zigbee2mqtt/Temperatur_WZ",  transformationPattern="JSONPATH:$.linkquality" ]
    }


    Thing topic zigbeeBK "Balkontuer" {
        Channels:
            Type string : status  
                [ commandTopic="zigbee2mqtt/Fenstersensor_BK", transformationPattern="JSONPATH:$.contact" ]
            Type number : voltage 
                [ commandTopic="zigbee2mqtt/Fenstersensor_BK", transformationPattern="JSONPATH:$.voltage" ]
            Type number : battery 
                [ commandTopic="zigbee2mqtt/Fenstersensor_BK", transformationPattern="JSONPATH:$.battery" ]
            Type number : linkquality 
                [ commandTopic="zigbee2mqtt/Fenstersensor_BK", transformationPattern="JSONPATH:$.linkquality" ]

    } 
}

Items file

Number ZigbeeSensorWZTemperature  "Sensor WZ Temperature [%.1f °C]"  <temperature>  (gZigbeeSensor) { channel="mqtt:topic:myMQTTBroker:zigbeeSensorWZ:temperature" }
Number ZigbeeSensorWZHumidity     "Sensor WZ Humidity [%.1f %%]"     <humidity>     (gZigbeeSensor) { channel="mqtt:topic:myMQTTBroker:zigbeeSensorWZ:humidity" }
Number ZigbeeSensorWZPressure     "Sensor WZ Pressure  [%d hPa]"     <pressure>     (gZigbeeSensor) { channel="mqtt:topic:myMQTTBroker:zigbeeSensorWZ:pressure" }
Number ZigbeeSensorWZLinkQuality  "Sensor WZ Link Quality [%d]"      <network>      (gZigbeeSensor) { channel="mqtt:topic:myMQTTBroker:zigbeeSensorWZ:linkquality" }
Number ZigbeeSensorWZVoltage      "Sensor WZ Voltage [%d mV]"        <energy>       (gZigbeeSensor) { channel="mqtt:topic:myMQTTBroker:zigbeeSensorWZ:voltage" }
Number ZigbeeSensorWZBattery      "Sensor WZ Battery [%.1f %%]"      <battery>      (gZigbeeSensor) { channel="mqtt:topic:myMQTTBroker:zigbeeSensorWZ:battery" }

String ZigbeeBKContact      "Balkontür Status [%s]"      <switch>      (gZigbeeSensor) 
    { channel="mqtt:topic:myMQTTBroker:zigbeeBK:status" }
Number ZigbeeBKLinkQuality  "Balkontür Link Quality [%d]"      <network>      (gZigbeeSensor) 
    { channel="mqtt:topic:myMQTTBroker:zigbeeBK:linkquality" }
Number ZigbeeBKVoltage      "Balkontür Voltage [%d mV]"        <energy>       (gZigbeeSensor) 
    { channel="mqtt:topic:myMQTTBroker:zigbeeBK:voltage" }
Number ZigbeeBKBattery      "Balkontür Battery [%.1f %%]"      <battery>      (gZigbeeSensor) 
    { channel="mqtt:topic:myMQTTBroker:zigbeeBK:battery" }

Does anybody find my error maybe?

regards

1 Like

I found the Problem, I accidently wrote commandTopic instead of stateTopic.

regards

1 Like

Thank you gforce!

I will try that rule! Looks like what I was searching for.

The file HM… I do not have in my transformation folder. What should I do?

In your post above where you set up the item MD_MOTION you then set the following:

"MD Motion [MAP(HM-Sen-MDIR-O-2.map):%s]"

The section [MAP(HM-Sen-MDIR-O-2.map):%s] is telling OpenHAB you want to transform the value that is returned based on a file map transformation file.

If you haven’t setup that file I am guessing you have copied it from somebody else’s example?

You can find more details of the Map transformation service here https://www.openhab.org/addons/transformations/map/

Because you are using the Javascript transformation I don’t believe there is any need for a Map transformation.

Set your item up like this.

 Switch MD_MOTION "MD Motion"  <motion> {mqtt="<[broker:zigbee/MD:state:JS(getZigbeeOccupancy2Switch.js)]" }

Your assumption is wrong.
The two transformations are on purpose. The JS transformation transforms the values into standard openhab Switch/Contact logic. The map transformation transforms the given Switch or Contact to human readable value. I use the same map transformation for motion detectors of all kind.

I see. Not had a need to use a Map transformation myself yet.

Thanks.