JSON payload in MQTTController entities actions (+ reverse color mapping to RGB)
-
Some background
I'm trying to integrate a Zigbee device into the MSR using zigbee2mqtt bridge and MQTTController. The device in question is a cheap mood light that has following properties that I'd like to control:- switch (on/off)
- brightness
- color
I'v already managed to get the switch part working and can toggle the light on/off. Also the brightness value is mapped back to MSR. In zigbee2mqtt it has a value range from 0 to 254, so this the reason for the expression:
expr: 'payload.brightness / 254'
Here's the entity definition (don't know whether the type should be something else than the Switch)
zigbee-lidl-mood-light: name: 'Lidl Mood Light' friendly_name: 'Mood Light' type: Switch uses_template: lidl-moodlight
And the corresponding template (NOTE: rgb_color has not been defined in this example):
lidl-moodlight: init: "zigbee2mqtt/%friendly_name%/get/state" query: "zigbee2mqtt/%friendly_name%/get/state" capabilities: - power_switch - toggle - dimming primary_attribute: power_switch.state events: "zigbee2mqtt/%friendly_name%": "power_switch.state": json_payload: true expr: 'upper(payload.state) == "ON"' "dimming.level": json_payload: true expr: 'payload.brightness / 254' actions: power_switch: "on": topic: "zigbee2mqtt/%friendly_name%/set/state" payload: 'ON' "off": topic: "zigbee2mqtt/%friendly_name%/set/state" payload: 'OFF' set: topic: "zigbee2mqtt/%friendly_name%/set/state" payload: expr: "parameters.state ? 'ON' : 'OFF'" type: raw toggle: topic: "zigbee2mqtt/%friendly_name%/set/state" payload: 'TOGGLE'
The problem
In order to control the brightness or the RGB color values, I would have send a JSON payload in corresponding actions. But I have no idea how to define it in the template. The reason why the switch part is working is that the zigbee2mqtt accepts also plain ON / OFF / TOGGLE string payloads in that case.But the brightness should be controlled with the following payload:
{"brightness": 196}
And the RGB color like:
{"color":{"rgb":"46,102,150"}}
Here's the link for the documentation (the Exposes part defines the messages).
So how should I define the JSON payload for example for the dimming action? It definitely should be some sort of expressions since I have to map the MSR real value (0...1) to (0...254) for the zigbee2mqtt.
actions: dimming: set: topic: "zigbee2mqtt/%friendly_name%/set" payload: expr: ????? type: json
Another problem is the RGB value. I could use the rgb_color capability for the setting but the problem is that the zigbee2mqtt only reports the current color in hue/saturation or xy coordinates.
Here's an example of published message after setting the color:
Topic: zigbee2mqtt/Mood Light QoS: 0 { "brightness":254, "color":{ "hue":240, "saturation":100, "x":0.1355, "y":0.0399 }, "color_mode":"xy", "color_temp":574, "linkquality":96, "state":"ON" }
I would have to map those values back to RGB, but is it even possible with existing constructs in MQTTController's templates?
Help would be appreciated @toggledbits
br,
mgvra -
Some background
I'm trying to integrate a Zigbee device into the MSR using zigbee2mqtt bridge and MQTTController. The device in question is a cheap mood light that has following properties that I'd like to control:- switch (on/off)
- brightness
- color
I'v already managed to get the switch part working and can toggle the light on/off. Also the brightness value is mapped back to MSR. In zigbee2mqtt it has a value range from 0 to 254, so this the reason for the expression:
expr: 'payload.brightness / 254'
Here's the entity definition (don't know whether the type should be something else than the Switch)
zigbee-lidl-mood-light: name: 'Lidl Mood Light' friendly_name: 'Mood Light' type: Switch uses_template: lidl-moodlight
And the corresponding template (NOTE: rgb_color has not been defined in this example):
lidl-moodlight: init: "zigbee2mqtt/%friendly_name%/get/state" query: "zigbee2mqtt/%friendly_name%/get/state" capabilities: - power_switch - toggle - dimming primary_attribute: power_switch.state events: "zigbee2mqtt/%friendly_name%": "power_switch.state": json_payload: true expr: 'upper(payload.state) == "ON"' "dimming.level": json_payload: true expr: 'payload.brightness / 254' actions: power_switch: "on": topic: "zigbee2mqtt/%friendly_name%/set/state" payload: 'ON' "off": topic: "zigbee2mqtt/%friendly_name%/set/state" payload: 'OFF' set: topic: "zigbee2mqtt/%friendly_name%/set/state" payload: expr: "parameters.state ? 'ON' : 'OFF'" type: raw toggle: topic: "zigbee2mqtt/%friendly_name%/set/state" payload: 'TOGGLE'
The problem
In order to control the brightness or the RGB color values, I would have send a JSON payload in corresponding actions. But I have no idea how to define it in the template. The reason why the switch part is working is that the zigbee2mqtt accepts also plain ON / OFF / TOGGLE string payloads in that case.But the brightness should be controlled with the following payload:
{"brightness": 196}
And the RGB color like:
{"color":{"rgb":"46,102,150"}}
Here's the link for the documentation (the Exposes part defines the messages).
So how should I define the JSON payload for example for the dimming action? It definitely should be some sort of expressions since I have to map the MSR real value (0...1) to (0...254) for the zigbee2mqtt.
actions: dimming: set: topic: "zigbee2mqtt/%friendly_name%/set" payload: expr: ????? type: json
Another problem is the RGB value. I could use the rgb_color capability for the setting but the problem is that the zigbee2mqtt only reports the current color in hue/saturation or xy coordinates.
Here's an example of published message after setting the color:
Topic: zigbee2mqtt/Mood Light QoS: 0 { "brightness":254, "color":{ "hue":240, "saturation":100, "x":0.1355, "y":0.0399 }, "color_mode":"xy", "color_temp":574, "linkquality":96, "state":"ON" }
I would have to map those values back to RGB, but is it even possible with existing constructs in MQTTController's templates?
Help would be appreciated @toggledbits
br,
mgvra@mgvra You're on the right track. For an action like
dimming.set
, where a JSON payload is to be sent, you set thejson
type as you've done, and then you just need to make sure that the payload value is an object.actions: dimming: set: topic: "zigbee2mqtt/%friendly_name%/set" payload: type: json expr: > { "brightness": parameters.level * 255 }
That last line evaluates to an expression language object data type containing a single key
brightness
whose value is the result of the subexpression, which in this case is the parameter valuelevel
given to the action scaled up to the device's units (I guessed; do what works here).The important thing to realize here is that the expression is producing an object, not a string that looks like JSON. The
type: json
flag will cause MQTTController to convert the object to its JSON representation, whatever that requires.Don't forget you can set MQTTController's log level to 5 while doing this work to troubleshoot what you are doing and see more clearly what is ultimately being sent.
I do have functions for converting between HS(L), RGB, and XY. Currently they are only available to HubitatController, but I can easily extend them to MQTTController as well. The trick there, however, is that your device's implementation is the same (e.g. for HSL 0° is red, 120° is green, 240° is blue, etc.). There's a de facto standard, but some devices have their own way.
-
@mgvra You're on the right track. For an action like
dimming.set
, where a JSON payload is to be sent, you set thejson
type as you've done, and then you just need to make sure that the payload value is an object.actions: dimming: set: topic: "zigbee2mqtt/%friendly_name%/set" payload: type: json expr: > { "brightness": parameters.level * 255 }
That last line evaluates to an expression language object data type containing a single key
brightness
whose value is the result of the subexpression, which in this case is the parameter valuelevel
given to the action scaled up to the device's units (I guessed; do what works here).The important thing to realize here is that the expression is producing an object, not a string that looks like JSON. The
type: json
flag will cause MQTTController to convert the object to its JSON representation, whatever that requires.Don't forget you can set MQTTController's log level to 5 while doing this work to troubleshoot what you are doing and see more clearly what is ultimately being sent.
I do have functions for converting between HS(L), RGB, and XY. Currently they are only available to HubitatController, but I can easily extend them to MQTTController as well. The trick there, however, is that your device's implementation is the same (e.g. for HSL 0° is red, 120° is green, 240° is blue, etc.). There's a de facto standard, but some devices have their own way.
Thanks for yet another quick reply! I'll start playing with the expressions and JSON payloads now that I know the proper syntax.
expr: > { "brightness": parameters.level * 255 }
So it is this implicit parameters object that contains the value (level) to be set.
In the case of step dimming, is this the notation?expr: > { "brightness": parameters.step * 255 }
Don't forget you can set MQTTController's log level to 5 while doing this work to troubleshoot what you are doing and see more clearly what is ultimately being sent.
Good point!
I do have functions for converting between HS(L), RGB, and XY. Currently they are only available to HubitatController, but I can easily extend them to MQTTController as well. The trick there, however, is that your device's implementation is the same (e.g. for HSL 0° is red, 120° is green, 240° is blue, etc.). There's a de facto standard, but some devices have their own way.
Well that would be really nice if it doesn't require too much effort. A new release of the MSR or just the MQTTController?
The trick there, however, is that your device's implementation is the same (e.g. for HSL 0° is red, 120° is green, 240° is blue, etc.). There's a de facto standard, but some devices have their own way.
Well I think those functions should exist even if they don't work with all possible devices. It's sure better than nothing and chances are that they work just fine.
br,
mgvra -
Thanks for yet another quick reply! I'll start playing with the expressions and JSON payloads now that I know the proper syntax.
expr: > { "brightness": parameters.level * 255 }
So it is this implicit parameters object that contains the value (level) to be set.
In the case of step dimming, is this the notation?expr: > { "brightness": parameters.step * 255 }
Don't forget you can set MQTTController's log level to 5 while doing this work to troubleshoot what you are doing and see more clearly what is ultimately being sent.
Good point!
I do have functions for converting between HS(L), RGB, and XY. Currently they are only available to HubitatController, but I can easily extend them to MQTTController as well. The trick there, however, is that your device's implementation is the same (e.g. for HSL 0° is red, 120° is green, 240° is blue, etc.). There's a de facto standard, but some devices have their own way.
Well that would be really nice if it doesn't require too much effort. A new release of the MSR or just the MQTTController?
The trick there, however, is that your device's implementation is the same (e.g. for HSL 0° is red, 120° is green, 240° is blue, etc.). There's a de facto standard, but some devices have their own way.
Well I think those functions should exist even if they don't work with all possible devices. It's sure better than nothing and chances are that they work just fine.
br,
mgvra@mgvra said in JSON payload in MQTTController entities actions (+ reverse color mapping to RGB):
So it is this implicit parameters object that contains the value (level) to be set.
Yes,
parameters
will contain the values of any parameters the action requires/defines.@mgvra said in JSON payload in MQTTController entities actions (+ reverse color mapping to RGB):
In the case of step dimming, is this the notation?
expr: > { "brightness": parameters.step * 255 }
Well, from the look of it, no. I think your device is going to set the brightness to whatever value is in
step
, not increment or decrement the brightness by that amount. If your device offers another topic to increment or decrement, you will need to use that instead.If your device doesn't have up/down brightness topics, you need to emulate them by using what we already know about the device. The entity has the current brightness level on it, so emulating step dimming is a matter of doing the math. Here's an example with fixed 10% up/down. The
entity
object is loaded with the action's subject entity, so we can access the current dimming level using its attribute:actions: dimming: up: topic: "zigbee2mqtt/%friendly_name%/set" payload: type: json expr: > { "brightness": min(1, entity.attributes.dimming.level + 0.1) * 255 } down: topic: "zigbee2mqtt/%friendly_name%/set" payload: type: json expr: > { "brightness": max(0, entity.attributes.dimming.level - 0.1) * 255 }
Note that the
dimming
capability does not have any parameters for theup
anddown
actions. -
MQTTController 23116 is now available for download; it has
hsltorgb(hue,sat,lev)
andrgbtohsl(r,g,b)
functions available in expressions. -
MQTTController 23116 is now available for download; it has
hsltorgb(hue,sat,lev)
andrgbtohsl(r,g,b)
functions available in expressions.@toggledbits related to this topic, I'm trying to set color with exactly the same lamp using the following configuration (MSR build is latest-24152-3455578a, MQTT version is 24142):
reactor.yaml
"zigbee2mqtt_smartmood": name: 'Smart Mood Light' friendly_name: 'Lidl smart mood' include: ["lidl_moodlight", "lidl_moodlight_rgb"]
local_mqtt_devices.yaml
("lidl_moodlight" part is omitted as it's not relevant here)lidl_moodlight_rgb: capabilities: ["rgb_color"] actions: rgb_color: set: false set_rgb: topic: "zigbee2mqtt/%friendly_name%/set" payload: type: json expr: '{"color": {"r": parameters.red, "g": parameters.green, "b": parameters.blue} }'
The problem is that MQTT message is sent with null values, example below.
{ "color": { "r": null, "g": null, "b": null } }
which is kinda expected, as MSR UI does not "ask" for these values when you select "rgb_color.set_rgb" action
Any hints what could be changed in the configuration?
-
OK. First of all, great post. That gave me all the information right out of the gate to replicate enough of your configuration to duplicate the problem.
Found and fixed. Try MQTTController build 24162.
-
OK. First of all, great post. That gave me all the information right out of the gate to replicate enough of your configuration to duplicate the problem.
Found and fixed. Try MQTTController build 24162.
@toggledbits thanks! First it seemed that this fix isn't working, but worked as expected after I deleted the old entity...
-
It's the same for
dimming.set and power_switch.setall.set
, an entity rebuild solves those too with 24162.(@toggledbits Mantis ID 372)
-
T toggledbits locked this topic on