JS: get the "source" of the last value change of an item

running OH5.1.4 on docker.

I’d like to get the source of the last value change of an item in a rule. in the logs it’s clear:

  • If I changed the light via a switch: source: org.openhab.core.thing$knx:device:THING:CHANNEL
  • I the light was turned ON/OFF via a script: source: org.openhab.automation.jsscripting$rule:SOME_RULE_NAME

Is it possible to get this information form an item? my use case would be to not touch the light with the rule, if it was last changed manually, but change it if there was no human interaction.

Not from an Item, no. This information is part of an event. Within a js rule, you can access that information through the event object as event.eventSource. Here’s an example rule I use:

console.debug(`Possible sensor override`)
console.trace(JSON.stringify(event))
let switchName = event.itemName
let ovrItemName = ([...switchName.split("_").slice(0,2),"Override"]).join("_")
let ovrItem = items.getItem(ovrItemName, true)

if (!ovrItem) {
  console.warn(`No override for item: ${switchName}`)
  return
}

if (event.newState == "OFF") {
  ovrItem.sendCommand("OFF")
}
else if (event.eventSource != "org.openhab.core.autoupdate.optimistic") {
  console.debug(`Sensor override: ${ovrItemName} ${event.newState.toLowerCase()}`)
  ovrItem.sendCommand(event.newState)
}

I have numerous light switches controlled by presence/motion sensors, but I don’t want those sensors to be able to change the switch if it was last turned on manually. As long as auto-update is active for an Item then commands that come from the binding will ultimately change the Item via the autoupdate source, so this source is agnostic as to the binding that causing the change but still represents a change that comes from a source outside OH (as opposed to a script change or a UI driven change).

So, my rule triggers whenever one of the light switches that should override a sensor changes. It checks for a separate override item associated with that switch (and stops the rule if there is none). If the switch has been turned off then the override is turned off regardless of where the OFF command came from. Otherwise, it checks the event source. If the event came from autoupdate (and therefore from a binding) then the override Item is turned on (and in separate rules, as long as an override item is turned on that switch will ignore changes in the sensor that controls it).

I don’t want to add so many “empty” proxy items. Perhaps I’ll have them run through a rule “onChange” and fill cache variables with it. That way I don’t have to add all those additional items (ok, no restoreOnStartup, but that’s ok).

Item metadata survives a restart of OH as the values are stored in the registry. I use that instead of proxy Items. Though I implemented my override logic years before there ever was a cache or any source information in the events. It’s kind of a misuse of Item metadata too, since metadata should be stuff about the Item (configuration) and so so much the state of the Item. But it works for the most part.