Mqtt 2.4 and dimmer 0-255

Hi,
I have a dimmer which exposes this json through mqtt
for read state:

sonoff4chpror2/light/sonoff_4ch_blue_led/state
{
  "state": "ON",
  "brightness": 66
}

for input command:

sonoff4chpror2/light/sonoff_4ch_blue_led/command
{
  "brightness": 66
}

in my mqtt.things i have

 Type dimmer : ledDimmer "Leddimmer" [stateTopic="sonoff4chpror2/light/sonoff_4ch_blue_led/state", transformationPattern="JSONPATH:$.brightness", transformationPatternOut="JSONPATH:$.brightness", min=0, max=255, step=1, commandTopic="sonoff4chpror2/light/sonoff_4ch_blue_led/command", min=0, max=255, step=1]

items

Dimmer led_dimmer "led strip [%d %%]" {channel="mqtt:topic:myOpenhabBroker:sonoff4chpror2:ledDimmer", autoupdate="false"}

sitemap

  Text item=led_dimmer
  Slider item=led_dimmer label="led strip [%d %%]"

With these configurations I have a slider that shows the exact percentage
example, if the state is:
{
“state”: “ON”,
“brightness”: 127
}
the slider show 50%

the problem is that if I move the slider to 100% for example, openhab sends as a payload:
{
“brightness”: 100
}

while it should convert (as it does inbound) 100 with 255 and send
{
“brightness”: 255
}

Is it possible to do this without resorting to external functions (JS transform)?

Hi, I use rules instead of transformations, maybe the dimmer type thing doesn’t support higher than 100 values.
I use code from Bruh’s mqtt led strip project), the thing type is string, but finally I didn’t link with the item. My brightness item is a standalone dummy dimmer, and capture it’s changes via rule file, where you can directly edit the published message.

Here are my config snippets:
Thing:

Type string : kLEDIntensity1    "Kitchen1 LED Intensity"    [ stateTopic="konyha_led1", commandTopic="konyha_led1/set", transformationPattern="JSONPATH:$.brightness"]

Item:

Dimmer kLED1_Intensity "Kitchen LED 1 Intensity" (gKitchenled_Intensity)

And finally the rule itself:


rule "LED Strip kitchen JSON Intensity"
    when Item gKitchenled_Intensity received update
    then 
        prev_kLED_Intensity.postUpdate(gKitchenled_Intensity.state)
        val actions = getActions("mqtt", "mqtt:broker:sentinel")
        actions.publishMQTT("konyha_led1/set", "{\"brightness\":" + (gKitchenled_Intensity.state as Number) * 255 / 100 + "}")
         Thread::sleep(100)
         actions.publishMQTT("konyha_led2/set", "{\"brightness\":" + (gKitchenled_Intensity.state as Number) * 255 / 100 + "}")

         logInfo("Test", "Led group intensity command executed, new value : " + gKitchenled_Intensity.state + "%")

end

I hope it helps.

thank you so much
but what I don’t understand is why the transformation happens when it reads the values ​​in input, but it doesn’t perform it when it sends the values ​​in output

You mean, why are state and command transformations different things? Because commands and states are different things. You can command “brighter” and get a state “75%” for example.

On a practical level you are wanting two different transforms anyway. Input, you scale 0-255 into 0-100. Output, you’ll want 0-100 scaled to 0-255, no?

Exactly,
I would like to scale 0-100 in 0-255 also in output and in fact in the mqtt.thing file after the “commandTopic=” command I entered “min = 0, max = 255”

Version 2.4 supports only inbound transformation yet. That’s why I moved this rules based config, when I upgraded mqtt from 1.x to 2.x. I use snapshot version currently, theoreticaly here is outbound xform already, but I did not try yet. I use rules and mqtt actions for every mqtt based items.

Version 2.5 already convert outgoing value according max and min, but it do not solve the problem (for me) because it put decimal point and 1 digit after it in value and value is string, such outgoing format

{“brightness”:%s}

produce:

{“brightness”:74.1}

(which switch ikea lamp off because it can not parse the brightness)
using any other format (%d in hope to make it integer for example) produce just a number, probably it is reaction on formats and data incompatibility.

So I use such solution to minimise code for each lamp:

val Procedures$Procedure2<String,Number> lpBrightness = [thisLamp, thisPercent |
    var value= (thisPercent * 255 / 100).intValue()
    var String dest = "zigbee2mqtt/"+thisLamp+"/set"
    val mqttActions = getActions("mqtt","mqtt:systemBroker:embedded-mqtt-broker")
    logInfo("XXX", "Set: " + dest + " brightness: " + value  )
    mqttActions.publishMQTT(dest, "{\"brightness\":" + value + "}")
]
rule "lamp_01_dimmer_changed"
when
    Item lamp_01_dimmer received command
then
    lpBrightness.apply("lamp_01", receivedCommand as Number)
end

1 Like