MQTT Item update problem for Color HSB Item (Tasmota RGB Bulb)

This is related to a Tasmota RGB bulb, that is connected using the MQTT Binding.

When changing the colour on the bulb using its app, it sends a JSON update that produces warning in the log, and the Item linked to the channel does not get updated.

Item

Color   BedroomRGBLampColour "Bedroom RGB lamp colour" (InternalState) {channel="mqtt:topic:44092da7f6:598434b618:Colour"}

Channel config in Thing:

  - id: Colour
    channelTypeUID: mqtt:colorHSB
    label: Colour
    configuration:
      commandTopic: cmnd/tasmota_4BA7A4/HSBColor
      transformationPatternOut: JS:noTransform.js
      stateTopic: stat/tasmota_4BA7A4/RESULT
      transformationPattern: JS:extractHSBColor.js

I am using a JavaScript transform to parse the incoming JSON:
extractHSBColor.js

(function(jsonString) {
    try {
        // Log the raw incoming payload for debugging purposes
        console.log("Incoming HSBColor payload:", jsonString);

        var data = JSON.parse(jsonString);
        if (data && data.HSBColor != undefined) {
            console.log("Extracted HSB Color field:", data.HSBColor);
            return data.HSBColor;
        }
    } catch (e) {
        // Log or handle the parsing error if needed
        console.log("Error parsing JSON or missing HSB Color field:", e);  // Log error details
    }
    return ""; // Returning an empty string prevents the Item from being updated
})(input)

This is the warning received in the log (even though it is just a warning, my linked Item does not get updated):

2024-11-30 17:57:04.084 [INFO ] [org.openhab.automation.script       ] - Incoming HSBColor payload: {"POWER":"ON","Dimmer":100,"Color":"5CFFC10000","HSBColor":"157,64,100","White":0,"CT":450,"Channel":[36,100,76,0,0]}

2024-11-30 17:57:04.085 [INFO ] [org.openhab.automation.script       ] - Extracted HSB Color field: 157,64,100

2024-11-30 17:57:04.086 [WARN ] [transport.mqtt.internal.Subscription] - A subscriber of type 'class org.openhab.binding.mqtt.generic.ChannelState' failed to process message '7B22504F574552223A224F4E222C2244696D6D6572223A3130302C22436F6C6F72223A2235434646433130303030222C22485342436F6C6F72223A223135372C36342C313030222C225768697465223A302C224354223A3435302C224368616E6E656C223A5B33362C3130302C37362C302C305D7D' to topic 'stat/tasmota_BC463F/RESULT'.

You can see that the HSB Colour values are stripped successfully from the payload, and returned by the transformation script.

The long hex number in the log is simply the payload encoded in hex.

Other Items on the Thing, such as Dimmer, and CT are working fine using a similar config; the issue is just with the Color Item.

Any ideas why this isn’t working?

This is another channel…

(log)... to topic 'stat/tasmota_BC463F/RESULT'

versus

stateTopic: stat/tasmota_4BA7A4/RESULT

Well spotted! Sorry, that was a ‘cut and paste’ problem. I have three of these bulbs, all configured the same, and copied the log entry for one of the others.

The log for the bulb for which config details I’ve posted is:

2024-11-30 18:51:30.226 [INFO ] [org.openhab.automation.script       ] - Incoming CT payload: {"POWER":"ON","Dimmer":100,"Color":"FFFFFF0000","HSBColor":"261,0,100","White":0,"CT":153,"Channel":[100,100,100,0,0]}

2024-11-30 18:51:30.232 [INFO ] [org.openhab.automation.script       ] - Extracted CT field: 153

2024-11-30 18:51:30.239 [INFO ] [org.openhab.automation.script       ] - Incoming HSBColor payload: {"POWER":"ON","Dimmer":100,"Color":"FFFFFF0000","HSBColor":"261,0,100","White":0,"CT":153,"Channel":[100,100,100,0,0]}

2024-11-30 18:51:30.241 [INFO ] [org.openhab.automation.script       ] - Extracted HSB Color field: 261,0,100

2024-11-30 18:51:30.244 [WARN ] [transport.mqtt.internal.Subscription] - A subscriber of type 'class org.openhab.binding.mqtt.generic.ChannelState' failed to process message '7B22504F574552223A224F4E222C2244696D6D6572223A3130302C22436F6C6F72223A2246464646464630303030222C22485342436F6C6F72223A223236312C302C313030222C225768697465223A302C224354223A3135332C224368616E6E656C223A5B3130302C3130302C3130302C302C305D7D' to topic 'stat/tasmota_4BA7A4/RESULT'.

2024-11-30 18:51:30.248 [INFO ] [org.openhab.automation.script       ] - Incoming Dimmer payload: {"POWER":"ON","Dimmer":100,"Color":"FFFFFF0000","HSBColor":"261,0,100","White":0,"CT":153,"Channel":[100,100,100,0,0]}

2024-11-30 18:51:30.250 [INFO ] [org.openhab.automation.script       ] - Extracted dimmer field: 100

2024-11-30 18:51:30.252 [INFO ] [org.openhab.automation.script       ] - Incoming POWER payload: {"POWER":"ON","Dimmer":100,"Color":"FFFFFF0000","HSBColor":"261,0,100","White":0,"CT":153,"Channel":[100,100,100,0,0]}

2024-11-30 18:51:30.253 [INFO ] [org.openhab.automation.script       ] - Extracted POWER field: ON

I’ve included some extra log lines so you can see the other fields are handled OK.

Ah. So the bulb doesn’t always send proper json but sometimes encodes to hex (which is really strange) Or maybe it’s the other way around… sometimes the broker doesn’t decode from hex to string.

Did you already restart openHAB as well as mosquitto (I guess the broker is mosquitto)?

Are there any other mqtt channels, which are subscribed to these topics as well?

I’m not sure why the hex is there, unless that’s just how that warning logs the problem.

I think the device is always returning a valid string, as what I am logging in each of the JS transforms is correct. I assume that, once received, the same JSON is sent to each of the channels that are listening to the stat/…/RESULT message anyway, so it should always be the same.

I’ve tried restarting both OH and mosquitto.

Nothing else is subscribed to the same topics (each bulb only has one Thing associated, and there is only one Color Item).

There is also this error in the log:

==> /var/log/openhab/openhab.log <==

2024-11-30 19:53:35.923 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.mqtt.generic.internal.handler.GenericMQTTThingHandler@31edd067': class org.openhab.core.types.UnDefType cannot be cast to class org.openhab.core.library.types.HSBType (org.openhab.core.types.UnDefType and org.openhab.core.library.types.HSBType are in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @13f0959d)

java.lang.ClassCastException: class org.openhab.core.types.UnDefType cannot be cast to class org.openhab.core.library.types.HSBType (org.openhab.core.types.UnDefType and org.openhab.core.library.types.HSBType are in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @13f0959d)

	at org.openhab.binding.mqtt.generic.values.ColorValue.parseCommand(ColorValue.java:85) ~[?:?]

	at org.openhab.binding.mqtt.generic.values.ColorValue.parseCommand(ColorValue.java:1) ~[?:?]

	at org.openhab.binding.mqtt.generic.ChannelState.publishValue(ChannelState.java:371) ~[?:?]

	at org.openhab.binding.mqtt.generic.AbstractMQTTThingHandler.handleCommand(AbstractMQTTThingHandler.java:153) ~[?:?]

	at jdk.internal.reflect.GeneratedMethodAccessor139.invoke(Unknown Source) ~[?:?]

	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]

	at java.lang.reflect.Method.invoke(Method.java:569) ~[?:?]

	at org.openhab.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:147) [bundleFile:?]

	at org.openhab.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [bundleFile:?]

	at jdk.proxy589.$Proxy714.handleCommand(Unknown Source) [?:?]

	at org.openhab.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:95) [bundleFile:?]

	at org.openhab.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfile.java:49) [bundleFile:?]

	at jdk.internal.reflect.GeneratedMethodAccessor138.invoke(Unknown Source) ~[?:?]

	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]

	at java.lang.reflect.Method.invoke(Method.java:569) ~[?:?]

	at org.openhab.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:147) [bundleFile:?]

	at org.openhab.core.internal.common.Invocation.call(Invocation.java:52) [bundleFile:?]

	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]

	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]

	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]

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

I think it may be caused by the behaviour of the bulb following an on/off switching command. For those, it just returns a simple payload with only the Power state:

2024-11-30 19:53:32.730 [DEBUG] [qtt.generic.AbstractMQTTThingHandler] - Successfully published value ON to topic cmnd/tasmota_4BA7A4/POWER

2024-11-30 19:53:32.766 [INFO ] [org.openhab.automation.script       ] - Incoming HSBColor payload: {"POWER":"ON"}

2024-11-30 19:53:32.768 [INFO ] [org.openhab.automation.script       ] - Incoming POWER payload: {"POWER":"ON"}

2024-11-30 19:53:32.769 [INFO ] [org.openhab.automation.script       ] - Extracted POWER field: ON

2024-11-30 19:53:32.772 [INFO ] [org.openhab.automation.script       ] - Incoming Dimmer payload: {"POWER":"ON"}

2024-11-30 19:53:32.774 [INFO ] [org.openhab.automation.script       ] - Incoming CT payload: {"POWER":"ON"}

The reason for my JS transforms is for the other channels (Dimmer etc.) to gracefully handle (ignore) the messages when the JSON does not contain their related field.

My understanding was returning an empty string from the JS transform would mean that the Item does not get updated.

OK, I think I have fixed this now. I have abandoned the JavaScript transformations and gone back to JSONPATH. I had tried this earlier, with a REGEX to prevent parsing of the MQTT status messages that only contain POWER status. However, at the time it did not work, because at that point I didn’t realise I had to install Regex as an add-on (!).

Strangely, the other thing I had to change was to make the Color type RGB for the Color channel rather than HSB. If I left it as HSB, the colour picked from the Colorpicker in the Sitemap did not match in any way to the colour that the bulb displayed.

Here is my revised (and working) Thing configuration:

UID: mqtt:topic:44092da7f6:db9a3b9e52
label: Lounge RGB Bulb
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:44092da7f6
location: Lounge
channels:
  - id: PowerSwitch
    channelTypeUID: mqtt:switch
    label: PowerSwitch
    configuration:
      commandTopic: cmnd/tasmota_BC463F/POWER
      stateTopic: stat/tasmota_BC463F/RESULT
      transformationPattern: REGEX:(.*\"POWER\".*)∩JSONPATH:$.POWER
  - id: Dimmer
    channelTypeUID: mqtt:number
    label: Dimmer
    configuration:
      commandTopic: cmnd/tasmota_BC463F/Dimmer
      stateTopic: stat/tasmota_BC463F/RESULT
      transformationPattern: REGEX:(.*\"Dimmer\".*)∩JSONPATH:$.Dimmer
  - id: ColourTemperature
    channelTypeUID: mqtt:number
    label: ColourTemperature
    configuration:
      commandTopic: cmnd/tasmota_BC463F/CT
      min: 153
      stateTopic: stat/tasmota_BC463F/RESULT
      transformationPattern: REGEX:(.*\"CT\".*)∩JSONPATH:$.CT
      max: 500
  - id: Colour
    channelTypeUID: mqtt:colorRGB
    label: Colour
    configuration:
      commandTopic: cmnd/tasmota_BC463F/Color
      stateTopic: stat/tasmota_BC463F/RESULT
      transformationPattern: REGEX:(.*\"HSBColor\".*)∩JSONPATH:$.HSBColor

So, in summary, to fix this I had to:

  1. Remove all transformationPatternOut entries (they aren’t needed).
  2. Install Regex add-on.
  3. Use Regex filtering with the intersection operator (∩) to prevent the {“POWER”:“ON”} only status messages from causing issues with the CT, Dimmer, and HSBColor channels.
  4. Change ‘channelTypeUID:’ from ‘mqtt:colorHSB’ to ‘mqtt:colorRGB’.