Item Command To Thing Transformation - discard command doesn't work

I have the following “Item Command To Thing Transformation” for an Item to Channel link.

(function(data) {
  const carChargerState = items.getItem("CarChargerOn").state;
  
  console.error(`CarCharger TransformCmdInfo: ${data} CarChargerOnState: ${carChargerState}`);
  console.error(`CarCharger C1: ${data === "OFF"} C2: ${carChargerState === "ON"}`);
  
  if (data === "OFF" && carChargerState === "ON") { //Later on we will monitor the current, if it is above 9A, we will denie switch off
    console.error("CarCharger TransformInfo - denied");
    return null;
  } else {
    console.error("CarCharger TransformInfo - passed");
    return data;
  }
  
})(input);

but the logs are not what I expected, despite the function returning null, the item processes the command and becomes “ON”.

Is your item set to autoupdate?

yes auto-update is enabled. If I disable it, the behaviour is, rsp i dont understand the behavior.

I seems that nothing happens, when I toggle the Switch Off, even the

"CarCharger TransformInfo - passed"

is missing. Here, the log of toggling the switch on, toggling the switch off, doesn’t generate any logs.

@jimtng is more of an expert on this than I am but it’s always been my understanding that you cannot suppress a command or an update using the transformation profile. Something must be returned and if you return null the untransformed input is what passes through the transformation.

To “suppress” an update or a command in this way you must return the current state of the Item, or NULL or UNDEF (the latter two can only be used for updates, not commands). That prevents a change but you’ll still get the command/update.

Since you didn’t post your config, I have to make some guesses.

I assume that you’re talking about script transformation profile that you apply to item to channel link, like this one below:

Switch CarChargerOn { channel="blahblah" [ profile="transform:JS", commandFromItemScript="yourscript.js" ] }

The documentation for this is here: Transformations | openHAB

In this case, returning null should discard the command and not propagated to the channel / handler / binding. So the binding will never see the command.

This is the exact line that checks for that: openhab-core/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/profile/ScriptProfile.java at 0e1883bdaefb1d892b4942aee0b982bacf882b67 · openhab/openhab-core · GitHub


So you’re saying it’s not working? Firstly, what is the channel/binding involved, and did the command still activate (turn off?) the physical device?

You can try / test it by having your script like this:

(function(data) {
  return null
})(input);

If that still doesn’t work, then we have a bug in openhab.

If that works in preventing the command from propagating to the binding → physical device, then there’s a logic error in your code.

Here is more information about my configuration.

I have tried this code:

(function(data) {
  return null
})(input);

Then I set the switch to “On” in the GUI. And the switch in the GUI becomes true and stays true. I thought with Auto-Update set to false, the item in the GUI should remain false, but I’m not sure if I have understood that correctly.

The log shows that the command was received, and it appears to have been discarded, the hardware behind the channel remains definitely off.
image

When I toggle the switch back to off in the GUI, nothing happens. I would expect to receive a ‘CarChargerOn’ command OFF.
but nothing happens. Maybe because we have an asynchronous state between item and GUi?

Then I changed the code to:

(function(data) {
  return;
})(input);

and

(function(data) {
  return data;
})(input);

The behavior remains the same, the command is still not passed to the item, this concerns the ON and OFF command. Now I’m confused.

And here’s some background on what I’m trying to accomplish:

The Item controls a Shelly relay. The Shelly controls the charger of an electric vehicle, I want to block all “off” commands from GUI and other scripts when the current is >=8A.

I think one approach could be to solve this with transformation scripts, another approach could be to use a proxy item.

That extra bit of information helps!

So when the shelly relay is OFF, and you send an ON command to it, the Shelly didn’t physically turn on? If you haven’t tried it, can you please try it? Feel free to use your original script as you posted in the original post above. I believe it should work.

There is another problem: the state update coming from the binding to the item is being discarded because you haven’t specified a script for it.

To fix this, create a pasthrough script that just returns the input.

Or just enter this in that input field: |input

Thats helps me a lot.

But one question, would should I do with:
“Item To Thing Transformation (DEPRECATED)” leave it empty or “|input” ?
First, I want to create a configuration that just passes everything through?
Is this the right configuration?

And now I’m testing this:

config:js:CarChargerItemCommandToThingTransformation:

(function(data) {
  const carChargerState = items.getItem("CarChargerOn").state;
  
  console.error(`CarCharger TransformCmdInfo: ${data} CarChargerOnState: ${carChargerState}`);
  console.error(`CarCharger C1: ${data === "OFF"} C2: ${carChargerState === "ON"}`);
  
  if (data === "OFF" && carChargerState === "ON") { //Later on we will monitor the current, if it is above 9A, we will denie switch off
    console.error("CarCharger TransformInfo - discarded");
    return null;
  } else {
    console.error("CarCharger TransformInfo - passed");
    return data;
  }

  
})(input);

I started with a switch off device.

Then I set the switch to “On” in the GUI. And the switch in the GUI becomes true and stays true. Everything works as expected. The transformation script has been called, and has passed the command.

Then I set the switch to “Off” in the GUI, the switch in the GUI becomes false.
The TransformationScripts discards the command, and the Item stays “ON”.

The problem is, that the switch in the GUI becomes false, so we have an asynchronous state between the GUI and the Item.
An further “switch On” from the gui doesn’t invoke an “ON command”, the logs remain empty.

I think the transformation script works fine, but the problem is the gui.

You can do either, because if you specified “command from item”, the “item to thing (deprecated)” will be ignored. So you might as well leave it empty.

yes

I would probably leave “Item state to Thing” empty so it gets discarded. It shouldn’t normally be used. It shouldn’t affect you in this instance though, unless you manually update the item’s state, in which case you must leave it empty.

And also leave the deprecated one empty as explained above.

For clarity, I would probably rename data to command. Your code will read better that way.

This is when you really need to set the item to autoupdate="false".

BTW When you say Item I’m interpreting that as the “openHAB Item”, but I suspect you meant the “Physical device”.

This is where I can’t help much since I don’t use the UI that much. @rlkoshak ?

What happens when you send the ON command from say Karaf console, or from a script? E.g. you can create a Script in the UI (e.g. using RulesDSL)

CarChargerOn.sendCommand("ON")

Then try running that script. Does that send an ON command?

In this case though the device is still ON right? Because your OFF command earlier was discarded?

good idea, I just did it

it was already set to false during all tests today.

You are right, I will try to be more precise:

I started with a switch off device.

Then I set the switch to “On” in the GUI. And the switch in the GUI becomes true and stays true. Everything works as expected. The transformation script has been called, and has passed the command.

Then I set the switch to “Off” in the GUI, the switch in the GUI becomes false.
The TransformationScripts discards the command, and the Item stays “ON”.
I’ve tested this, with this short script:

console.error(`CarCharger  Item Status: ${items.getItem("CarChargerOn").state} `); 

image
summarized

  • GUI becomes false and remains false even after refreshing the website
  • Item in Openhab remains true
  • physical device remains true/on

ON and OFF Commands are handled correctly. When an OFF Command is discarded, the gui stays correctly ON.

The remaining problem is that a discarded OFF command leads to an asynchronous state between the item (also the physical device) and the GUI.

@florian-h05 do you know why it behaves like this? I would think that at the very least, when refreshing, UI should show the actual state of the item (which is ON)

@ML1982 can you test it with BasicUI?

sitemap test {
  Switch item= CarChargerOn
}

I think I made a mistake, sorry for that. I’ve just tried it again.

after refreshing the state in the GUi is corrected, I tested it with

  • IPAdress:8443/settings/model/
  • IPAdress:8443/locations#card=Keller
  • iPhone App

It would be nicer if I didn’t have to refresh, but for my use case it’s fine.

The problem here is a conceptual one: when flipping the switch or using any other control, the client (app or web page) sends a command to the respective item. There is no way for the client to know about the result of that command (whether it was applied successfully, was discarded or got lost in the binding due to some failure). This is why the clients can not update the switch in the latter two cases.
Fixing this would require sending events about the command result (including result and current item state) to the clients. Certainly possible to do, but quite a bit of work.

NB: since I have an RF actor that somethings is flaky die to poor signal, id appreciate such a mechanism too :wink:

AFAIK, in BasicUI, it would send the command, but its state remains unchanged. Its state changes depend on the SSE / state updates from the server. - EDIT this was incorrect

How should that work? Taking the switch as example, what would trigger sending the command if not the user flipping it to another state?

Oops I was wrong! I just tested this and BasicUI also flicked the UI switch to off even though the actual item is still ON.

  • Item state: ON, UI State: ON
  • Click UI to turn it off → UI State: OFF, Item State: ON (not auto updated)

So to make UI state ON:

  • Item.postUpdate(OFF), Item.postUpdate(ON) → UI updates its state to ON
  • Make sure the item channel link is vetoing the “stateFromItem” by leaving it blank or always returning null so this doesn’t get propagated to the thing handler.

The UI should show the state received from SSE, just checked the code. I am currently on the way home from FrOSCon (where openHAB had a booth), so can‘t have a closer look, but I cannot see an issue with the code right away. TBH I haven‘t seen this behaviour before.

@florian-h05 did you see this:

It was my fault, I was too stupid to press F5 correctly :frowning:

Last night my mqtt was broken, so when I turned off a switch on basicui, the actual light didn’t turn off, and my item is not autoupdate.

When I turned it off on basicui, the UI changed to off but then immediately switched back to on like I originally said above.