I then created a new Item and bound it to that Channel using PaperUI. When using it in Control (for easy testing), I encountered two problems:
The step is completely ignored. The Bindings sends messages like { "brightness" : 107.68 } to the Broker while it should be only integers when step=1 is used, right? (at least the formatBeforePublish seems to work as it should).
Incoming messages like {"brightness": 54} result in screwed up floating point percentages like
I tried your configuration, but the result stayed the same. But even if it worked in the Sitemap, I would still have the problem with incoming values not being properly transformed.
Nevertheless, I tried setting min and max in the Sitemap like
but it didnāt went well with the Dimmer seeming to expect percentages [0, 100] only. The steps, both in the Sitemap and PaperUI Control, are ā1ā, though (I can choose every integer between 0 and 100).
Okay, thatās odd. I narrowed the problem down to the Binding type dimmer. If I switch from Type dimmer to Type number the step parameter works as expected. Might be a bug, what would you say?
Not sure if itās a bug, as dimming is normally defined from 0 to 100 %. The good thing about OH is the flexibility that allows you to change the item to a Number and make it work.
The problem comes from the fact that a dimmer works in 0-100% so if you set it to 50 it sends a value equal to half your max settingā¦so 129 in the case of a 254 max.
Iām also using Zigbee2MQTT and had it setup the exact same way you did.
In the end I installed the legacy MQTT V1 binding so I could use some more complex Javascript transformations that could convert the 0-100 slider to 0-255 rounding all the numbers to remove the decimal point. Another feature of the Javascript transformation was I could configure it to also except āONā and āOFFā commands that way I can have a slider or a switch tied to the same item in OpenHAB. This also allows me to share that single item with Alexa. If I tell Alexa to set lights to 50 they dim to half, if I say off they turn off and if I say on they come back at there previous brightness.
Good to know Iām neither alone nor just too stupid to set this up
Iām not too deep into this yet. So can you please tell me what the MQTT v1 Binding allows in terms of transformation that canāt be realized with transformationPatternOut and transformationPatternOut?
the V2 binding allows you to use the JSON transformation on the incoming data to pick out the info you want like the brightness value. You can then use the FormatBeforePublish to convert a value you are sending into a JSON format that Zigbee2MQTT can use.
The V1 binding allows you to use a Javascript script to transform the data however you want. Iāve yet to personally see any drawbacks of doing the transformation via a Javascript script.
You can use the V1 binding as well as the V2. I have both installed and used the V2 for most things until I worked out how powerful the Javascrtipt transformation could be.
Hereās what I have setup
There is no āThingā for V1, once installed you configure the binding to connect to your broker though the mqtt.cfg file you can find details here https://www.openhab.org/addons/bindings/mqtt1/
The above item is using two Javascript fils to transform the message being sent and recieved. setZigbeeBrightness.js and getZigbeeBrightness.js.
You need to install the Javascript Transformation service in PaperUI and place these files within the Transform folder.
setZigbeeBrightness.js - Iāve added some comments to show what the script does.
(function(x){ //Read incomming message into x
var result = new Object(); //Make JSON object ready to send out
if (x == "ON") { //If incomming command is ON set "state" = ON in JSON message
var state = "ON"
result.state = state;
} else if (x == "OFF") { //If incomming command is OFF set "state" = OFF in JSON message
var state = "OFF"
result.state = state;
}else if (x < 1) { //If incomming command is 0 (i.e Slider set to off) set "state" = OFF in JSON message
var state = "OFF"
result.state = state;
} else{ //Otherwise command must be brightness value between 1-100
var brightness = x*255/100; //Change 0-100 range to 0-255 range
result.brightness = brightness.toFixed(); //set "brightness" = <VALUE> in JSON message without any decimals
}
return JSON.stringify(result); //Return finished JSON objest to be sent to MQTT broker
})(input)
getZigbeeBrightness.js
(function(x){ //Read incomming message into x
var brightness; //Define var's to be used in script
var state;
var result;
var json = JSON.parse(x); //Parse x into json var
brightness = json.brightness * 100 / 255; //Read brightness value into var and convert 0-255 range into 0-100 range
state = json.state; //Read state value into var
if (brightness < 1 || state == "OFF") { //If brightness = 0 or state = OFF set result to 0
result = 0;
} else {
result = brightness.toFixed(); //else set result to brightness value without decimals
}
return result; //Send result into OpenHAB MQTT state.
})(input)
Please donāt make your sentences sound like facts if you are not sure yourself. Mqtt2 allows to use all as in ALL transformation exactly like mqtt1 and there is not a single documentation line that supports your guess.
The background is that Mqtt1 will not live forever and if you make people migrate back to v1 weāll have more unhappy users in the end when mqtt1 dies.
Avoid JavaScript transformations
If possible try to use mapping and jaonpath transformations and if necessary output formatter. JavaScript transformations are very expensive for the core to perform.
step
The step is actually working correctly. It has a different semantic than you thought it has. It is meant to be used for UIs so that they offer a stepped slider widget. The step value is not for converting a floating point number to an integer value.
The documentation only mentiones the FormatBefoerPublish which would allow me to format the outgoing message to JSON but wouldnāt allow me to change the message the same way the script can.
Could you point me in the right direction how to have the funcionality from the script in MQTT V2?
The value form the dimmer needs to be converted into a JSON message like the following.
{"state":"ON","brightness":255}
Using the Min, Max and FormatBeforePublish I was able to send brightness levels but I need to be able to send a state of OFF if dimmer is set to 0 as not all bulbs respond correctly to setting a brightness of 0 hence why I followed examples elsewhere to use the Javascript transformation.
Iāve been having a play and Iāve got a partially working system by using a rule to format a JSON message based on a dimmer value and pass that to the MQTT item that I have set as a string.
Is this how I should be doing it or is there a better way to create the JSON message?
Well it might be over complicated but I have got this working.
Basically Iāve changed the MQTT item into a string and I have a separate dimmer item that isnāt directly connected to the MQTT item and I have replicated the functionality of the Javascript file within a rule.
So if a number is set on the dimmer unit it converts the 0-100 to 0-255 and sends the value as the brightness key in the JSON message. If the dimmer is set to 0 it sends a State = OFF in the JSON message.
The reason for using the state is some of my bulbs didnāt consistently turn off when sent a brightness = 0 and they always reported back a state = ON and brightness = 1 even if they did actually go off. If I send a state = OFF they always go off and report back that the state = off.
If the dimmer receives a ON or OFF command it also just send the state value. This means that if I toggle the light it comes back on at itās previous brightness and not full.
There might be an easier way of doing it but I didnāt find it and this is working.
That does mean that if you didnāt care about the bulb remembering the previous brightness level when turning off and on you could do it with a single MQTT dimmer item with a min of 0 and max of 255.
Could you please post your config? I have exactly the same problem with a Hue Bulb. Linkquality and On/Off works fine, unfortunately it doesnāt dim. Thatās how it looks with me at the moment:
Things file:
//Hue Lampe Esszimmer1 0x001788010248565d
Thing mqtt:topic:0x001788010248565d "Hue Lampe Esszimmer1" @ "MQTT"{
Channels:
Type switch : huelamp "Hue Lampe Esszimmer1" [
stateTopic="zigbee2mqtt/0x001788010248565d",
transformationPattern="JSONPATH:$.state",
commandTopic="zigbee2mqtt/0x001788010248565d/set",
on="ON", off="OFF" ]
Type number : link "Verbindung" [
stateTopic="zigbee2mqtt/0x001788010248565d",
transformationPattern="JSONPATH:$.linkquality"
]
Type dimmer : dimmer "Dimmer" [
stateTopic="zigbee/0x001788010248565d",
commandTopic="zigbee/0x001788010248565d/set",
transformationPattern="JSONPATH:$.brightness",
formatBeforePublish="{\"brightness\":%s}",
min=1,
max=254,
step=1 ]
}
Then I use these three transformation files, placed in ā/etc/openhab2/transformā, also make sure you have js transformation service installed via PaperUI.
getZigbeeBrightness.js for getting the brightness:
(function(x){
var result;
var json = JSON.parse(x);
result = json.brightness * 100 / 255;
return result;
})(input)
setZigbeeBrightness.js for setting the brightness level:
(function(x){
var brightness = x * 255/100;
var result = new Object();
result.brightness = brightness;
return JSON.stringify(result);
})(input)
setZigbeeState.js for setting the state:
```csv
(function(x){
var result = new Object();
result.state = x;
return JSON.stringify(result);
})(input)