[SOLVED] transformationPatternOut seems not to work, but why?

Hi,

i’m currently stuck on set a slider value via transformation to the device. While reading was easy, writing back sems to be not. It seems like the transformationPatternOut is not detected correctly. But i don’t see the reason for the error.

Platform information

Thing

Thing topic eurotronicspzb03 "thermostat study" {
Channels:
  Type number: local_temperature           [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.local_temperature" ]
  Type number: occupied_heating_setpoint   [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.occupied_heating_setpoint" ]
  Type number: unoccupied_heating_setpoint [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.unoccupied_heating_setpoint" ]
  Type number: pi_heating_demand           [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.pi_heating_demand" ]
  Type number: linkquality                 [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.linkquality", min=0, max=255 ]
  Type number: eurotronic_error_status     [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.eurotronic_error_status" ]
  Type number: battery                     [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.battery", min=0, max=100 ]
  Type number: current_heating_setpoint    [ stateTopic="zigbee2mqtt/eurotronicspzb03", commandTopic="zigbee2mqtt/eurotronicspzb03/set", transformationPattern="JSONPATH:$.current_heating_setpoint", transformationPatternOut="JS:eurotronics-current_heating_setpoint-openhab2mqtt.js", min=18.0, max=25.0, step=0.5 ]
  Type number: eurotronic_system_mode      [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.eurotronic_system_mode" ]
  Type string: system_mode                 [ stateTopic="zigbee2mqtt/eurotronicspzb03", transformationPattern="JSONPATH:$.system_mode" ]
}

Item

Number:Temperature eurotronicspzb03_local_temperature           { channel="mqtt:topic:Openhabian:eurotronicspzb03:local_temperature" }
Number:Temperature eurotronicspzb03_occupied_heating_setpoint   { channel="mqtt:topic:Openhabian:eurotronicspzb03:occupied_heating_setpoint" }
Number:Temperature eurotronicspzb03_unoccupied_heating_setpoint { channel="mqtt:topic:Openhabian:eurotronicspzb03:unoccupied_heating_setpoint" }
Number             eurotronicspzb03_pi_heating_demand           { channel="mqtt:topic:Openhabian:eurotronicspzb03:pi_heating_demand" }
Number             eurotronicspzb03_linkquality                 { channel="mqtt:topic:Openhabian:eurotronicspzb03:linkquality" }
Number             eurotronicspzb03_eurotronic_error_status     { channel="mqtt:topic:Openhabian:eurotronicspzb03:eurotronic_error_status" }
Number             eurotronicspzb03_battery                     { channel="mqtt:topic:Openhabian:eurotronicspzb03:battery" }
Number:Temperature eurotronicspzb03_current_heating_setpoint    { channel="mqtt:topic:Openhabian:eurotronicspzb03:current_heating_setpoint" }
Number             eurotronicspzb03_eurotronic_system_mode      { channel="mqtt:topic:Openhabian:eurotronicspzb03:eurotronic_system_mode" }
String             eurotronicspzb03_system_mode                 { channel="mqtt:topic:Openhabian:eurotronicspzb03:system_mode" }

Sitemap

Text  item=eurotronicspzb03_local_temperature label="Arbeitszimmer [%.1f %unit%]" icon="temperature"
Text  label="Arbeitszimmer Thermostat" icon="radiator" {
Frame label="Arbeitszimmer" {
  Text   item=eurotronicspzb03_local_temperature
  Text   item=eurotronicspzb03_occupied_heating_setpoint
  Text   item=eurotronicspzb03_unoccupied_heating_setpoint
  Text   item=eurotronicspzb03_pi_heating_demand
  Text   item=eurotronicspzb03_linkquality
  Text   item=eurotronicspzb03_eurotronic_error_status
  Text   item=eurotronicspzb03_battery
  Slider item=eurotronicspzb03_current_heating_setpoint label="Temperatur [%.1f %unit%]" icon="temperature" minValue=18 maxValue=25 step=0.5
  Text   item=eurotronicspzb03_eurotronic_system_mode
  Text   item=eurotronicspzb03_system_mode
}
}

Transformation

eurotronics-current_heating_setpoint-openhab2mqtt.js

(function(x) {
    return "{\"current_heating_setpoint\":" + x + "}";
})(input)

Log

23:21:20.255 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'eurotronicspzb03_current_heating_setpoint' received command 22.5 °C
23:21:20.264 [INFO ] [arthome.event.ItemStatePredictedEvent] - eurotronicspzb03_current_heating_setpoint predicted to become 22.5 °C
23:21:20.277 [ERROR] [rnal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.mqtt.generic.internal.handler.GenericMQTTThingHandler@1765438': null
java.lang.NumberFormatException: null
    at java.math.BigDecimal.<init>(BigDecimal.java:497) ~[?:1.8.0_222]
    at java.math.BigDecimal.<init>(BigDecimal.java:383) ~[?:1.8.0_222]
    at java.math.BigDecimal.<init>(BigDecimal.java:809) ~[?:1.8.0_222]
    at org.openhab.binding.mqtt.generic.values.NumberValue.update(NumberValue.java:91) ~[?:?]
    at org.openhab.binding.mqtt.generic.ChannelState.publishValue(ChannelState.java:333) ~[?:?]
    at org.openhab.binding.mqtt.generic.AbstractMQTTThingHandler.handleCommand(AbstractMQTTThingHandler.java:128) ~[?:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222]
    at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
    at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [bundleFile:?]
    at com.sun.proxy.$Proxy207.handleCommand(Unknown Source) [?:?]
    at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:74) [bundleFile:?]
    at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfile.java:48) [bundleFile:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222]
    at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
    at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:52) [bundleFile:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_222]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_222]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_222]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_222]
23:21:20.297 [INFO ] [smarthome.event.ItemStateChangedEvent] - eurotronicspzb03_current_heating_setpoint changed from 22.0 °C to 22.5 °C

This is not an answer to your question, but I would suggest looking at this:

This file name is a bit long, IMHO, but I think you need to remove the “-” and use “_” between eurotronics and current.

Filename seems not to be the problem, i’ve tried “blah.js” with the same result.

I will take a look into it. I have some concerns about log spamming (but solvable), null values (my innr smart plugs e.g. don’t send state when resetted - have to try…) and the possibility to send more than one value at once… (e.g. current_heating_setpoint and occupied_heating_setpoint (via rule or better via node red?)

@JimT:

I switched to the attribute option:

Thing topic eurotronicspzb03 "thermostat study" {
Channels:
  Type number: local_temperature           [ stateTopic="zigbee2mqtt/eurotronicspzb03/local_temperature" ]
  Type number: occupied_heating_setpoint   [ stateTopic="zigbee2mqtt/eurotronicspzb03/occupied_heating_setpoint" ]
  Type number: unoccupied_heating_setpoint [ stateTopic="zigbee2mqtt/eurotronicspzb03/unoccupied_heating_setpoint" ]
  Type number: pi_heating_demand           [ stateTopic="zigbee2mqtt/eurotronicspzb03/pi_heating_demand" ]
  Type number: linkquality                 [ stateTopic="zigbee2mqtt/eurotronicspzb03/linkquality", min=0, max=255 ]
  Type number: eurotronic_error_status     [ stateTopic="zigbee2mqtt/eurotronicspzb03/eurotronic_error_status" ]
  Type number: battery                     [ stateTopic="zigbee2mqtt/eurotronicspzb03/battery", min=0, max=100 ]
  Type number: current_heating_setpoint    [ stateTopic="zigbee2mqtt/eurotronicspzb03/current_heating_setpoint", commandTopic="zigbee2mqtt/eurotronicspzb03/current_heating_setpoint/set", min=18.0, max=25.0, step=0.5 ]
  Type number: eurotronic_system_mode      [ stateTopic="zigbee2mqtt/eurotronicspzb03/eurotronic_system_mode" ]
  Type string: system_mode                 [ stateTopic="zigbee2mqtt/eurotronicspzb03/system_mode" ]
}

But it doesn’t solve the problem:

 12:00:08.771 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'eurotronicspzb03_current_heating_setpoint' received command 20 °C
12:00:08.805 [INFO ] [arthome.event.ItemStatePredictedEvent] - eurotronicspzb03_current_heating_setpoint predicted to become 20 °C
12:00:08.821 [INFO ] [smarthome.event.ItemStateChangedEvent] - eurotronicspzb03_current_heating_setpoint changed from 18.5 °C to 20 °C
12:00:08.823 [ERROR] [rnal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.mqtt.generic.internal.handler.GenericMQTTThingHandler@13ba568': null
java.lang.NumberFormatException: null
    at java.math.BigDecimal.<init>(BigDecimal.java:497) ~[?:1.8.0_222]
    at java.math.BigDecimal.<init>(BigDecimal.java:383) ~[?:1.8.0_222]
    at java.math.BigDecimal.<init>(BigDecimal.java:809) ~[?:1.8.0_222]
    at org.openhab.binding.mqtt.generic.values.NumberValue.update(NumberValue.java:91) ~[?:?]
    at org.openhab.binding.mqtt.generic.ChannelState.publishValue(ChannelState.java:333) ~[?:?]
    at org.openhab.binding.mqtt.generic.AbstractMQTTThingHandler.handleCommand(AbstractMQTTThingHandler.java:128) ~[?:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222]
    at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
    at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [bundleFile:?]
    at com.sun.proxy.$Proxy142.handleCommand(Unknown Source) [?:?]
    at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:74) [bundleFile:?]
    at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfile.java:48) [bundleFile:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222]
    at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
    at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:52) [bundleFile:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_222]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_222]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_222]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_222]

Another thing that is bugging me is the slider which doesn’t show the new value when changing the position, is it normal?

I’m not sure those are compatible

If you change the item to

Number eurotronicspzb03_current_heating_setpoint    { channel="mqtt:topic:Openhabian:eurotronicspzb03:current_heating_setpoint" }

It would work, but I don’t know why it wouldn’t work with :Temperature.

Because the state isn’t 20, it’s 20 °C

o_O i’ve thought, it was just a visual formatting and the type of the thing is what is relevant.

From the docs:

Transformations used in the state/value part of labels are applied on the fly. While the transformed value will (for example) be visible on a Sitemap, the original value is stored in the Item.

So i’ve changed to:

Thing

Type number: current_heating_setpoint    [ stateTopic="zigbee2mqtt/eurotronicspzb03/current_heating_setpoint", commandTopic="zigbee2mqtt/eurotronicspzb03/set/current_heating_setpoint", min=18.0, max=25.0, step=0.5 ]

Sitemap

Slider item=eurotronicspzb03_current_heating_setpoint label="Temperatur [%.1f °C]" icon="temperature" minValue=18 maxValue=25 step=0.5

Item

Number             eurotronicspzb03_current_heating_setpoint    { channel="mqtt:topic:Openhabian:eurotronicspzb03:current_heating_setpoint" }

Now it works!

Just a question for best practices:
The Item Types i’ved used should help me to use [%unit%] in the sitemap, is this the best practice?

That’s fine

but

Linking an Item of different type to a channel intended for another type will likely bring problems.
If the binding supplies a channel of Number type, this is not a good fit for an Item of Number:Temperature type. The type is the whole name,

I’m pretty sure PaperUI won’t even let you do that, but it seems defining the link in xxx.items file allows you to force it.

Instead of using transformationPatternOut for outgoing message in things file, formatBeforePublish can be utilized, further simplifying configuration:

  Type number: current_heating_setpoint    [ stateTopic="zigbee2mqtt/eurotronicspzb03", commandTopic="zigbee2mqtt/eurotronicspzb03/set", transformationPattern="JSONPATH:$.current_heating_setpoint", formatBeforePublish="{ \"current_heating_setpoint\": %s }", min=18.0, max=25.0, step=0.5 ]
2 Likes