Zigbee2mqtt revisited: No more ugly transformations

Hi all,
I know this is an old one but i think this is the best topic for my problem:

I’ve switched from deconz to zigbee2mqtt and most devices are working fine.

The one im struggling with is a LED Strip Controller Miboxer FUT038Z which i cant get to work.

Error Entry from openhab.log

 [ab.binding.mqtt.generic.ChannelState] - Command '{hue=123, saturation=100, x=0.1704, y=0.709}' from channel 'mqtt:topic:cf94322e0a:0c66bc9c5d:MyDeviceColorXY' not supported by type 'ColorValue': {hue=123, saturation=100, x=0.1704, y=0.709} is not a valid string syntax

I’ll guess that the channel want only x, y but i cant figure out how to transform this into the correct format.

My Channel Config:

  - id: LEDMyDeviceColorXY
    channelTypeUID: mqtt:color
    label: LEDMyDeviceColorXY
    description: null
      commandTopic: zigbee2mqtt/LEDMyDevice/set
      postCommand: true
      colorMode: XYY
      stateTopic: zigbee2mqtt/LEDMyDevice
      transformationPattern: JSONPATH:$.color

And here is a MQTT Explorer Value copy of that topic:


So if anyone could give me a hint whats going on and how could i fix this would be really appreciated :slight_smile:

Reason for your issue is, that the mqtt message from z2m is not in the format OH will expect.

From my understanding you have 2 options:

  1. based on rules or transformation you can parse the message to get the correct state in the right format

  2. if it’s only OH that’s working with z2m together and you do not have any other software changing the state of your light directly via mqtt, than you maybe don’t need to read the current state, as OH will always store the state within the item by itself and it is sufficient to only send a command to z2m

1 Like

To elaborate on option 1:

You would have to transform





  • (x, y) is a point in CIE 1931 color space.
  • Brightness max is 255 (200/255=78.43…).

(as Incoming Value Transformation for the Color Channel; untested) puts the parameters in the right order, but it cannot normalize the brightness to [0…100], so you would have to use a JS Transformation.

For HSB color space the REGEX would look like
(untested; again without normalization of brightness to [0…100]).

IIUC, a MQTT Color Channel in CIE mode accepts xyY values, but it converts the CIE 1931 color point to HSB (after application of the Incoming Value Transformation).

Use an analog Outgoing Value Transformation to transform the three HSB values into JSON (don’t forget to de-normalize the brightness) for the MQTT Command Topic.

Use option 2. :slight_smile:

1 Like

Nice! Thanks for pointing me in the right direction. I hope I can figure this out how this works.

I just cp your example in the transformation field but got still the same error about the colorvalue… i know this cloud be not working but at least i didnt get an error about the regex :wink:

I will remove and readd the channel as I tried a lot already. Maybe I messed something up.

Will report back later today.

But thanks again!

I’ve got the first part working!

So here is the channel with the regex transformation

configuration: {}
bridgeUID: mqtt:broker:cf94322e0a
  - id: LEDKochinselHSB
    channelTypeUID: mqtt:color
    label: LEDKochinselHSB
    description: ""
      commandTopic: zigbee2mqtt/LEDKochinsel/set
      colorMode: XYY
      formatBeforePublish: "%s"
      stateTopic: zigbee2mqtt/LEDKochinsel
      transformationPattern: REGEX:s/\{"brightness":(.*?),"color":\{(?<=)"hue":(.*?),"saturation":(.*?)(?=),"x":(.*?),"y":(.*?)\},.*\}/$4,$5,$1/g

I did need to extend the regex but extract only brightness ($1) x($4) and y ($5).

Next I need to get the outgoing stuff working and add the brightness conversion … Man is that difficult to get this stuff working.

I will create an issue on the zigbee2mqtt git as I think they expose the wrong values or at least mix of xyY and HSB…

Update: DONE!
So here are the working channels:

  - id: LEDKochinselXY
    channelTypeUID: mqtt:color
    label: LEDKochinselXY
    description: null
      commandTopic: zigbee2mqtt/LEDKochinsel/set
      colorMode: XYY
      formatBeforePublish: '{"color":{"x":"%1$s","y":"%2$s"}}'
      stateTopic: zigbee2mqtt/LEDKochinsel
      transformationPattern: REGEX:s/\{"brightness":(.*?),"color":\{(?<=)"hue":(.*?),"saturation":(.*?)(?=),"x":(.*?),"y":(.*?)\},.*\}/$4,$5,$1/g
  - id: LEDKochinselBrightness
    channelTypeUID: mqtt:dimmer
    label: LEDKochinselBrightness
    description: ""
      commandTopic: zigbee2mqtt/LEDKochinsel/set
      min: 0
      formatBeforePublish: '{"brightness":"%s"}'
      stateTopic: zigbee2mqtt/LEDKochinsel
      transformationPattern: JSONPATH:$.brightness
      max: 254
  - id: LEDKochinselColorTemp
    channelTypeUID: mqtt:dimmer
    label: LEDKochinselColorTemp
    description: null
      commandTopic: zigbee2mqtt/LEDKochinsel/set
      min: 153
      formatBeforePublish: '{"color_temp":"%s"}'
      stateTopic: zigbee2mqtt/LEDKochinsel
      transformationPattern: JSONPATH:$.color_temp
      max: 500

Works for my liking. The only thing that is bothering me is that i cant get the brightness contol in the color picker working as it is a diffrent channel - but thats for future me i guess :wink:

1 Like

Well my previous “solution” was bad as it does not convert the brightness part to the correct values as @anon71759204 pointed out earlier :wink: So here is what i came up with which now everything is working as expected: (Also most parts are c + p from other community members which i’m really glad that they share thier findings with us.)

openHAB channel config:

  - id: LEDKochinselXY
    channelTypeUID: mqtt:color
    label: LEDKochinselXY
    description: null
      commandTopic: zigbee2mqtt/LEDKochinsel/set
      colorMode: XYY
      transformationPatternOut: JS:zigbeeColorOUT.js
      formatBeforePublish: "%"
      stateTopic: zigbee2mqtt/LEDKochinsel
      transformationPattern: JS:zigbeeColorIN.js

transformation scripts:


	// convert 100% to 254 Steps of brightness
	var bright = Number(color.split(/[,:]/)[2]) * 2.54;
	// example output to mqtt: {"brightness":239,"color":{"x":0.601297,"y":0.311017}}
	return '{"brightness":' + bright.toFixed(0) + ',"color":{"x":' + color.split(/[,:]/)[0] + ',"y":' + color.split(/[,:]/)[1] + '}}';


// example input: {"brightness":50,"color":{"hue":359,"saturation":100,"x":0.6942,"y":0.2963},"color_mode":"xy","color_temp":158}
	// convert 254 Steps to 100% of brightness
	var bright = Number(color.split(/[,:]/)[1]) / 2.54;
	// example output to openHAB: x,y,brightness - f.e.: 0.6942,0.2963,50
	return color.split(/[,:]/)[8] + "," + color.split(/[,:}]/)[10] + "," + bright.toFixed(0);

i tried to integrate a Hue color bulb connected with Zigbee2Mqtt into OH3 and had no luck so far.
I have the channel config and the .js scripts from the link in this post. The .js files are in the conf/transform folder. I still dont get any color information in my Channel/item.
Through the UI i created the channel and the item.

  • id: MQQTTZ2MColorCh1
    channelTypeUID: mqtt:color
    label: MQQTTZ2MColorCh1
    description: “”
    commandTopic: zigbee2mqtt/0x0017880106788d39/set
    colorMode: XYY
    transformationPatternOut: JS:zigbeeColorOUT.js
    formatBeforePublish: “%”
    stateTopic: zigbee2mqtt/0x0017880106788d39
    transformationPattern: JS:zigbeeColorIN.js

I created an item type: color.
I dont get any Info on that channel/item:

I also tried to text config the channel and the item:

    Type color : farbe "MQTT Hue WhiteColor1 Color" [ stateTopic="zigbee2mqtt/0x0017880106788d39/color", commandTopic="zigbee2mqtt/0x0017880106788d39/set/color", transformationPattern="JS:zigbeeColorIN.js", transformationPatternOut="JS:zigbeeColorOUT.js"]
Color Farbe "Mqtt hue white color1 color" {channel="mqtt:topic:MyMQTTBroker:MQTTHueWhiteColor1:farbe"}

With the Text File configuration i get this result:

Does anyone have a tip for me? I think there can only be something small i am missing.
Thnx in advance

Hey @Airmr,

We need a bit more Infos to try to figure out what’s wrong. So here are some steps your cloud do:

  • make sure zgbee2mqtt is sending messages to openhab (i.e. broker config). Use the WebUI from zigbee2Mqtt and then use the expose feature (device > expose) to change the color or turn on the bulb.

  • Use f.e. MQTT Explorer to see the messages that are received and send via your broker

  • check your syntax like 10 times. And then again :slight_smile: It could be just a space or so to render everything not working

  • check openhab.log : maybe enable debug log for mqtt

  • check if all add-ons and services you want to use are installed and working

  • post the context of your JavaScript transform files

  • also check the device support site on zigbee2mqtt - there might be some useful hints on how everything needs to be formatted, which color type use have to use and so on.

  • also check if you enabled the attribute_json output in zigbee2mqtt. Not sure if really needed but I have it turned on :wink:

Good luck :crossed_fingers:

Hi Andre, thnx for the quick answer.
Z2M is sending messages out.

MQTT publish: topic 'zigbee2mqtt/0x0017880106788d39', payload '{"brightness":53,"color":{"hue":359,"saturation":100,"x":0.6942,"y":0.2963},"color_mode":"xy","color_temp":158,"color_temp_startup":341,"linkquality":61,"power_on_behavior":"off","state":"ON","update":{"state":"available"}}'

MQTT Explorer:


Syntax is just copied from your post with the friendly name changed. Checked the Syntax many times.
I dont really know how to enable a debug log for mqtt
The JavaScript transform files are the ones you posted saved in the transform directory.

I couldnt find any working examples on the Z2M device site.
And i couldnt find the attribute_json output in Z2M. I use the Frontend and am not editing the yaml file.

I think there is something not right in the way i created the Thing in the .things file…but i cant figure it out…
Shouldn’t the UI created Thing at least work when using your code you posted with my friendly name?


Hm, that wired. You could enable debug by following How to debug MQTT2 Binding issues? f.e.

Could you post the manufacturer and model name of the device?
Also the device should show up as supported and there should be a link behind the model like this:

Also the Output Setting is configurable via the webGUI:

Well, I created everything in openHAB via the Webinterface (I don’t like Textfiles anymore :slight_smile: ) so this should be fine.

Maybe try to give the device in z2m a friendly name which is shorter…

Hi Andre, thnx for the time your spending on this.
Here is a Screenshot from the device:

I also changed the MQTT output type.

I made 2 other channels with this bulb and everything is working correct:

And i made a String item:

The result shown is the payload:


The only thing i can think of is the .js Scripts. I checked them 10 times and they are just as yours are.
The example you give in the zigbeeColorIN.js :

example input: {"brightness":50,"color":{"hue":359,"saturation":100,"x":0.6942,"y":0.2963},"color_mode":"xy","color_temp":158}

differs from the text i read in Licht Büro Text, thats the only difference i see.
I Have the Java Script, Regex and Json Path transformation installed.

The Channel:

  • id: MQQTTZ2MColorCh1Test
    channelTypeUID: mqtt:color
    label: LEDKochinselXY
    description: null
    commandTopic: zigbee2mqtt/0x0017880106788d39/set
    colorMode: XYY
    transformationPatternOut: JS:zigbeeColorOUT.js
    formatBeforePublish: “%”
    stateTopic: zigbee2mqtt/0x0017880106788d39
    transformationPattern: JS:zigbeeColorIN.js

I created an item with no profile:

Anything i missed ? I am going crazy :slight_smile:

MUHAHAHAHA I got it working :slight_smile:

Well at least i can control the color etc. from the Thing/item in the UI.
I still have to try to get it going in the Openhab UI. But that is another adventure.

After cleaning up all the Channels and items i have tried with and adding the “attribute and json” Output type it works.
I will test if it really works with the “attribute and json” option or if i just messed up everything, even with checking 100 times there must be something that was still wrong.
At the end i learned a lot.

Thank you Andre for helping me out here and spending your time on my issue.!! Big Thank You!!!
If you ever happen to be near Frankfurt/Germany give me a buzz and i will pay you a coffee or beer.
If my investigation turns out that i really missed something even though i checked many times, it will be more than 1 beer :slight_smile:

1 Like

Sure - your welcome. I just spotted the missing “{” at your example input. But glad you could figure this out :clap:t3:

And if I in that region in the near future I may be getting back to you :slight_smile:

Also, there are some pre made widgets for color and stuff. Just search for it - should also be fairly easy to implement :+1:


I recently bought a GIDEALED ZC05M RGBW LED strip and use it with Z2M (in attribute output mode). After reading this thread, I managed to send HSB values through openHAB (via the colorpicker) to Z2M. This works so far. However, I can’t get openHAB to receive external state updates originating e.g. from the Z2M Web UI. The strip changes colors, but the openHAB HSB color item still keeps the value set via openHAB. Here’s the relevant config:


Thing mqtt:topic:LightbandStairs "Lichtband Treppe" (mqtt:broker:mosquitto) @ "Treppe" {
    Type number   : hue         [ stateTopic="zigbee2mqtt/Lightband_Stairs/color-hue", commandTopic="zigbee2mqtt/Lightband_Stairs/set/color-hue", min=0, max=360 ]
    Type dimmer   : saturation  [ stateTopic="zigbee2mqtt/Lightband_Stairs/color-saturation", commandTopic="zigbee2mqtt/Lightband_Stairs/set/color-saturation", min=0, max=100 ]
    Type number   : brightness  [ stateTopic="zigbee2mqtt/Lightband_Stairs/brightness", commandTopic="zigbee2mqtt/Lightband_Stairs/set/brightness", min=0, max=254 ]
    Type color    : color_hsb   [ stateTopic="zigbee2mqtt/Lightband_Stairs/color-hsb", commandTopic="zigbee2mqtt/Lightband_Stairs/set", formatBeforePublish="{\"color\":{\"hue\":%s,\"saturation\":%s},\"brightness\":%s}", onBrightness=50 ]
    Type dimmer   : color_temp  [ stateTopic="zigbee2mqtt/Lightband_Stairs/color_temp", commandTopic="zigbee2mqtt/Lightband_Stairs/set/color_temp", min=153, max=500 ]
    Type switch   : state       [ stateTopic="zigbee2mqtt/Lightband_Stairs/state", commandTopic="zigbee2mqtt/Lightband_Stairs/set/state" ]


Number LightbandStairsHue        "Licht Treppe (Hue)"                              { channel="mqtt:topic:LightbandStairs:hue" }
Dimmer LightbandStairsSaturation "Licht Treppe (Saturation)"                       { channel="mqtt:topic:LightbandStairs:saturation" }
Number LightbandStairsBrightness "Licht Treppe (Brightness)"                       { channel="mqtt:topic:LightbandStairs:brightness" }
Switch LightbandStairs           "Licht Treppe [MAP(de.map):%s]"                   { channel="mqtt:topic:LightbandStairs:state" }
Dimmer LightbandStairsColorTemp  "Licht Treppe Farbtemperatur [%s]"                { channel="mqtt:topic:LightbandStairs:color_temp" }
Color  LightbandStairsColorHSB   "Licht Treppe Farbe (HSB) [%s]"                   { channel="mqtt:topic:LightbandStairs:color_hsb" }

Strip state example from (Z2M Web UI):

  "brightness": 100,
  "color": {
      "hue": 359,
      "saturation": 100,
      "x": 0.6942,
      "y": 0.2963
  "color_mode": "xy",
  "color_temp": 158,
  "color_temp_startup": 65535,
  "last_seen": "2023-01-24T16:19:34+01:00",
  "linkquality": 29,
  "power_on_behavior": "off",
  "state": "OFF"

As I said, sending HSB color updates through MQTT works. However, I have to use the above formatBeforePublish. If I use the proposed/default {“color”: “hsb”: “%s,%s,%s”}, the brightness won’t be updated. As a fix for the “openHAB doesn’t get external changes” problem, I introduced a rule to sync hue, saturation and brightness to the openHAB HSB color item, if the three attributes are changed externally, because these (attribute) changes are picked up by openHAB:

rule "Compensate for broken MQTT color state topic updates"
  Item LightbandStairsHue changed or
  Item LightbandStairsSaturation changed or
  Item LightbandStairsBrightness changed
  LightbandStairsColorHSB.postUpdate(LightbandStairsHue.state + "," + LightbandStairsSaturation.state + "," + LightbandStairsBrightness.state)

Now, I can change colors using openHAB, Z2M or MQTT and everyone is happy - i.e. the states in sync. But is there a way to get rid of the rule fix? I’d even go the “output attribute_and_json route”, if the solution is more elegant. For example, I don’t know if the stateTopic for color_hsb is right. No matter what I’ve tried so far (no postfix, color, color-hsb), nothing changes. Maybe there’s some magic hidden somewhere that I’m not aware of?

IIUC, there are two problems:

  1. Setting brightness doesn’t work. Try {"color":{"hsb":"360,100,100"}} instead of {"color":{"hue":360,"saturation":100},"brightness":100}
  2. openHAB gets out of sync. Use a transformationPattern to transform the state message from Zigbee2MQTT into H,S,B, see Zigbee2mqtt revisited: No more ugly transformations - #201 by AndreHimSelf .
1 Like

Thanks for the hint, @anon71759204! #1 (setting brightness) wasn’t a problem, that already worked. The link in #2, however, did it. I changed Z2M’s output type to “attribute_and_json” and wrote javascript transformations for reading and writing hsb color values. Now I don’t need to manually sync hue, saturation and brightness with the HSB color.

1 Like

so what’s the best settings too use now?

output attribute&json
home assistant on?

output attribute
home assistant off
add things with files

For me, it was a mix of the above things:

  • enable Attribute & JSON in ZigBee2Mqtt
  • HomeAssist off in ZigBee2Mqtt (don’t know if nessesarry)
  • Add thing manually in openHAB
  • Use JS For Conversion of Values in openHAB Thing
1 Like

Hello, i’m trying to get the effect channel working that zigbee2mqtt uses for lightbulbs such as philips hue, tradfri etc…

z2mqtt mode:

   output: attribute

From the zigbee2mqtt docs
Philips Hue White bulb:

To write (/set) a value publish a message to topic zigbee2mqtt/FRIENDLY_NAME/set with payload {"effect": NEW_VALUE}. The possible values are: blink, breathe, okay, channel_change, finish_effect, stop_effect

I’m using attribute mode no json transform should be needed.

// Philips White 1
Thing topic Test_BULB_1 "Ligthbulb (Philips)"{
        Type string : effect "Effekt" [stateTopic="zigbee2mqtt/Philips_WHITE_BULB_1/effect", commandTopic="zigbee2mqtt/Philips_WHITE_BULB_1/set/effect"]


String Philips_White_BULB_1_EFFECT "Lightbulb Effekt [%s]" {channel="mqtt:topic:mosquitto:Test_BULB_1:effect"}



Openhab log looks good:

2023-04-29 19:52:42.556 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'Philips_White_BULB_1_EFFECT' received command okay
2023-04-29 19:52:42.562 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'Philips_White_BULB_1_EFFECT' predicted to become okay

However the bulb does nothing and zigbee2mqtt log shows:

error 2023-04-29 19:54:32: Invalid message 'null', skipping...

The manual way via terminal:

mosquitto_pub -h localhost -t zigbee2mqtt/Philips_WHITE_BULB_1/set/effect -m okay

leads to success and the bulb is blinking as it should.

Is the DSL .sendCommand function formatting the string in some other way than raw as zigbee2mqtt log shows ‘null’ ? An example would be nice in case someone has as working setup using attribute mode only in zigbee2mqtt because i quite wasted some time today :grinning:.

Thank you, winux