Switch for Zigbee controlled radiator

Hi all,

I am using Zigbee2MQTT to control various things in my home including some radiator valves. I am no real expert when it comes to transformations, but so far I managed to get everything working with some basic setup. However here is a challenge I need some help with:

I configure my Zigbee2MQTT things via file configuration, here is how the radiator looks like:

   Thing topic RadiatorLiving "RadiatorLiving" @ "Wohnzimmer" {
  Channels:
	Type number : position "RadiatorLiving_Position" [stateTopic="zigbee2mqtt/RadiatorLiving", transformationPattern="JSONPATH:$.position"]
	Type number : local_temperature "RadiatorLiving_Local_Temperature" [ stateTopic="zigbee2mqtt/RadiatorLiving", transformationPattern="JSONPATH:$.local_temperature"]
	Type number : current_heating_setpoint "RadiatorLiving_Current_Heating_Setpoint" [ stateTopic="zigbee2mqtt/RadiatorLiving", commandTopic="zigbee2mqtt/RadiatorLiving/set", transformationPattern="JSONPATH:$.current_heating_setpoint", min="5", max="35", transformationPatternOut="JS:setcurrentheatingsetpoint.js"]
	Type string : preset "RadiatorLiving_Preset"[ stateTopic="zigbee2mqtt/RadiatorLiving", transformationPattern="JSONPATH:$.preset"]
	Type switch : boost "RadiatorLiving_Boost"[ stateTopic="zigbee2mqtt/RadiatorLiving", commandTopic="zigbee2mqtt/RadiatorLiving/set", transformationPattern="JSONPATH:$.state", transformationPatternOut="JS:setboostmode.js"]
  }

My problem is with the last channel “boost” which is set using a self-written transformation script: setboostmode.js as follows:

(function(x) {
var result = new Object();
result.preset = "boost";
return JSON.stringify(result);
})(input)

As you can see it would set the MQTT variable “preset” to the string “boost”. Physically this means that the radiator valve opens up for a few minutes (boost mode) and then goes back to manual mode (“preset = manual”).

So here’s my thing: With setboostmode.js defined as above it works only one way: Whenever I activate the corresponding switch in my OpenHAB UI it sets “preset = boost” whic is fine… However when the radiator valve goes back to manual mode (“preset = manual”) after a few minutes, the switch stays on with is rather annoying from a usability perspective.

How do I need to define my transformation JS so that it will turn back off the switch when the preset is back to “manual”? Do I need to transform the TransformationPatternOut? Should I add a TransformationPatternIn???

I guess that’s not hard to do but I need to get a hint please :slight_smile:

Thanks
Jo

This seems overly complicated. Just use the “Outgoing Value Format” set to {"preset":"boost"}

Or even better, since this is a switch you can set the on value to that.

You can nothing in your state transformation or anywhere else in the Channel that tells it that “manual” means OFF. I bet you’re seeing lots of errors or warnings in the logs related to this.

If you have multiple states that should set the Switch to OFF, here you might need a JS transform (if you are on OH 3.4 better to use a SCRIPT transform) to interpret all states other than “boost” as OFF.

That’s not how transformations work. Each Channel has two transformations, one the transform the incoming message to something that is valid to use as the linked Item’s state (in this case ON or OFF) and a separate outgoing transformation that turns the Item’s command to a message the end device understands. You can’t use the same transformation for both.

And the MQTT binding also provides some alternative ways to transform the state without using a transformation including the Outgoing Value Format, ON state and OFF state properties (I don’t do .things files so you’ll have to look up what those translate to).

1 Like

Hi @rlkoshak ,

Thanks for your reply. You are of course right that my original transformation JS was basically doing nothing, I guess it was a remainder of previous attempts to get it working in the desired way.

My lack of understanding was exactly the point that I need 2 transformations, thanks for pointing this out. I got it working as expected now, this is what I did:

Thing definition:

Type switch : boost "RadiatorStudio2_Boost"[ stateTopic="zigbee2mqtt/RadiatorStudio2", commandTopic="zigbee2mqtt/RadiatorStudio2/set", transformationPattern="JS:getboostmode.js", transformationPatternOut="JS:setboostmode.js"

where getboostmode.js is

//Retrieves the value of 'preset' and sets the switch to off unless it's boost
(function(x){
    var result = "";
 
    var json = JSON.parse(x);  
    if (json.preset == "boost") 
    {
        result=1;
    } 
    else 
    {
        result=0;
    }
    return result;
    
})(input)

and setboostmode.js does the following:

//Sets preset to boost or manual depending on the state of the switch
(function(x) {
var result = new Object();
if (x == 1)
{
	result.preset = "boost";
}
else
{
	result.preset = "manual";
}
return JSON.stringify(result);
})(input)

That does the job, the switch and the value of preset are now connected in both ways. I haven’t tried alternative ways of transformations, so far I am only using JS transformations (in conjunction with JSON path transformations of course). Certainly worth to have a look at it.

Thanks again!

The reason why I say to use SCRIPT instead of JS transform if you are on 3.4 is because in 4.0 there is no JS transform. It’s been replaced with SCRIPT.