Rule Trigger, when user changed Item, not another rule

In short: How can I tell apart, if a Item changed due to a user interaction or from a rule. I need to tell those two apart.

I cant find the right search term - sorry for that, my issue must have been on the table before.

I do have a switch with three states “holiday”, “auto” and “manual”.
In auto, the temperature of heaters is changed on a time basis using sendCommand. But when someone changes the temperature manually via e.g. the app, the switch should to go manual and the time based triggers shall be inactive.

rule "Heizung geändert, gehe zu manual mode" when Item HeizungArbeitszimmer_SetpointTemperature changed or Item HeizungSchlafzimmer_SetpointTemperature changed or Item HeizungWohnzimmer_SetpointTemperature changed or Item$ then sendCommand(behaviour,3) // goes to manual end

The issue is, that the above rule is also triggered, when the auto mode executes a sendcommand.

Many thanks!

Welcome to the openHAB forum.

Check the previousState ( which is an implicit variable for each rule having a changed trigger) , if it was “Auto”.

Welcome to the community!

Please use code fences to post configs and logs. It’s the paper icon left of gear icon above.

Thanks

See Design Pattern: Manual Trigger Detection

2 Likes

You can’t. You also cannot tell if it was binding that changed an Item state.

What you can do is segregate your Items.
You might have, say, a dummy temperature Item in your UI.
When the user commands that, you know exactly who has done it becase you have provided no other way for that to happen.
So you can have a rule that does whatever it is you want with that - like for instance, copying the command to a real device.
And probably the inverse - a rule that copies incoming real device updates to the dummy, for display.

This is approach #3 in the Manual Trigger Detection above.

Dear all,
many thanks for your help! Excellent design pattern post - the image within is just perfect. I have to read all of the design pattern posts, that will help for sure. On this topic I was hoping for a more out of the box solution, but I’ll go for #3.

Almost got it working with #3, but as I want to control a heater, I don’t use Switch items, but Number:Temperature. From the code it looked to me, that I only need to adapt the item definitions to make it work with a number:temperature. The heater_device gets the command, but never “gets it done”. I double checked, and I think all variables are numbers, but I guess the error lies somewhere in a type conversion.

Rule
rule "Heater control received command"
when
    Member of Heizung_SetpointTemperature received command
then
    // Get access to all the relevant Items
    val lightName = triggeringItem.name.split("_").get(0) + "_" + triggeringItem.name.split("_").get(1) // because I added additional _ in the variable name, not effcient, but work$
    val source = triggeringItem.name.split("_").get(2)

    logInfo("heater",lightName)
    logInfo("heater",source)

    val proxy =  Heizung_SetpointTemperature.members.findFirst[ l | l.name == lightName + "_Proxy" ]
    val device =  Heizung_SetpointTemperature.members.findFirst[ l | l.name == lightName + "_Device" ]
    val ui =  Heizung_SetpointTemperature.members.findFirst[ l | l.name == lightName + "_UI" ]
    val rules =  Heizung_SetpointTemperature.members.findFirst[ l | l.name == lightName + "_Rules" ]

    // The Proxy Item should never receive a command
    if(source == "Proxy") {
        logWarn("light", "Received command on " + triggeringItem.name + ", this should not occur, ignoring.")
        return;
    }

    // When a command comes in from any source not the Device, a command gets sent to the Device
    // This let's us skip this command so we don't end up in an infinite loop.
    if(source == "Device") {
        logInfo("light","sleeping")
        Thread::sleep(150) // experiment, may not be needed, may need to be longer, give the Item registry time to update the proxy
        if(receivedCommand == proxy.state) {
            logInfo("light","returning, because rec and proxy are equal")
            return;
        }
        logInfo("light","continuing")
    }

    // Detect whether the light was triggered manually or automatically and do what needs to be done
    if(source == "Device" || source == "UI") {
        logInfo("light","manual event")
    }
    else {
    }

    // Forward the new state to those Items that are not already in the new state. Use sendCommand
    // for the device so the light actually turns on/off.
    if(proxy.state != receivedCommand) proxy.postUpdate(receivedCommand)
    if(ui.state != receivedCommand) ui.postUpdate(receivedCommand)
    if(rules.state != receivedCommand) rules.postUpdate(receivedCommand)
    if(device.state != receivedCommand) device.sendCommand(receivedCommand)
    logInfo("light","---")
end
Logfile
2020-01-03 18:54:11.880 [ome.event.ItemCommandEvent] - Item 'HeizungArbeitszimmer_SetpointTemperature_UI' received command 5.5
2020-01-03 18:54:11.890 [vent.ItemStateChangedEvent] - HeizungArbeitszimmer_SetpointTemperature_UI changed from 5.0 °C to 5.5 °C

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:11.892 [INFO ] [clipse.smarthome.model.script.heater] - HeizungArbeitszimmer_SetpointTemperature
2020-01-03 18:54:11.894 [INFO ] [clipse.smarthome.model.script.heater] - UI
2020-01-03 18:54:11.953 [INFO ] [eclipse.smarthome.model.script.light] - manual event
2020-01-03 18:54:11.962 [INFO ] [eclipse.smarthome.model.script.light] - ---

==> /var/log/openhab2/events.log <==
2020-01-03 18:54:11.973 [ome.event.ItemCommandEvent] - Item 'HeizungArbeitszimmer_SetpointTemperature_Device' received command 5.5
2020-01-03 18:54:11.988 [vent.ItemStateChangedEvent] - HeizungArbeitszimmer_SetpointTemperature_Proxy changed from 5.0 °C to 5.5 °C
2020-01-03 18:54:11.990 [vent.ItemStateChangedEvent] - HeizungArbeitszimmer_SetpointTemperature_Rules changed from 5.0 °C to 5.5 °C
2020-01-03 18:54:11.992 [nt.ItemStatePredictedEvent] - HeizungArbeitszimmer_SetpointTemperature_Device predicted to become 5.5

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:11.992 [INFO ] [clipse.smarthome.model.script.heater] - HeizungArbeitszimmer_SetpointTemperature
2020-01-03 18:54:11.993 [INFO ] [clipse.smarthome.model.script.heater] - Device

==> /var/log/openhab2/events.log <==
2020-01-03 18:54:12.018 [vent.ItemStateChangedEvent] - HeizungArbeitszimmer_SetpointTemperature_Device changed from 5.0 °C to 5.5 °C

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:12.029 [INFO ] [eclipse.smarthome.model.script.light] - sleeping
2020-01-03 18:54:12.181 [INFO ] [eclipse.smarthome.model.script.light] - continuing
2020-01-03 18:54:12.183 [INFO ] [eclipse.smarthome.model.script.light] - manual event
2020-01-03 18:54:12.188 [INFO ] [eclipse.smarthome.model.script.light] - ---

==> /var/log/openhab2/events.log <==
2020-01-03 18:54:12.190 [ome.event.ItemCommandEvent] - Item 'HeizungArbeitszimmer_SetpointTemperature_Device' received command 5.5
2020-01-03 18:54:12.199 [nt.ItemStatePredictedEvent] - HeizungArbeitszimmer_SetpointTemperature_Device predicted to become 5.5

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:12.205 [INFO ] [clipse.smarthome.model.script.heater] - HeizungArbeitszimmer_SetpointTemperature
2020-01-03 18:54:12.207 [INFO ] [clipse.smarthome.model.script.heater] - Device
2020-01-03 18:54:12.237 [INFO ] [eclipse.smarthome.model.script.light] - sleeping
2020-01-03 18:54:12.389 [INFO ] [eclipse.smarthome.model.script.light] - continuing
2020-01-03 18:54:12.390 [INFO ] [eclipse.smarthome.model.script.light] - manual event
2020-01-03 18:54:12.397 [INFO ] [eclipse.smarthome.model.script.light] - ---

==> /var/log/openhab2/events.log <==
2020-01-03 18:54:12.398 [ome.event.ItemCommandEvent] - Item 'HeizungArbeitszimmer_SetpointTemperature_Device' received command 5.5
2020-01-03 18:54:12.406 [nt.ItemStatePredictedEvent] - HeizungArbeitszimmer_SetpointTemperature_Device predicted to become 5.5

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:12.411 [INFO ] [clipse.smarthome.model.script.heater] - HeizungArbeitszimmer_SetpointTemperature
2020-01-03 18:54:12.413 [INFO ] [clipse.smarthome.model.script.heater] - Device
2020-01-03 18:54:12.444 [INFO ] [eclipse.smarthome.model.script.light] - sleeping
2020-01-03 18:54:12.596 [INFO ] [eclipse.smarthome.model.script.light] - continuing
2020-01-03 18:54:12.598 [INFO ] [eclipse.smarthome.model.script.light] - manual event
2020-01-03 18:54:12.603 [INFO ] [eclipse.smarthome.model.script.light] - ---

==> /var/log/openhab2/events.log <==
2020-01-03 18:54:12.605 [ome.event.ItemCommandEvent] - Item 'HeizungArbeitszimmer_SetpointTemperature_Device' received command 5.5
2020-01-03 18:54:12.614 [nt.ItemStatePredictedEvent] - HeizungArbeitszimmer_SetpointTemperature_Device predicted to become 5.5

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:12.617 [INFO ] [clipse.smarthome.model.script.heater] - HeizungArbeitszimmer_SetpointTemperature
2020-01-03 18:54:12.619 [INFO ] [clipse.smarthome.model.script.heater] - Device
2020-01-03 18:54:12.647 [INFO ] [eclipse.smarthome.model.script.light] - sleeping
2020-01-03 18:54:12.800 [INFO ] [eclipse.smarthome.model.script.light] - continuing
2020-01-03 18:54:12.803 [INFO ] [eclipse.smarthome.model.script.light] - manual event
2020-01-03 18:54:12.814 [INFO ] [eclipse.smarthome.model.script.light] - ---

==> /var/log/openhab2/events.log <==
2020-01-03 18:54:12.819 [ome.event.ItemCommandEvent] - Item 'HeizungArbeitszimmer_SetpointTemperature_Device' received command 5.5
2020-01-03 18:54:12.836 [nt.ItemStatePredictedEvent] - HeizungArbeitszimmer_SetpointTemperature_Device predicted to become 5.5

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:12.843 [INFO ] [clipse.smarthome.model.script.heater] - HeizungArbeitszimmer_SetpointTemperature
2020-01-03 18:54:12.846 [INFO ] [clipse.smarthome.model.script.heater] - Device
2020-01-03 18:54:12.899 [INFO ] [eclipse.smarthome.model.script.light] - sleeping
2020-01-03 18:54:13.052 [INFO ] [eclipse.smarthome.model.script.light] - continuing
2020-01-03 18:54:13.053 [INFO ] [eclipse.smarthome.model.script.light] - manual event
2020-01-03 18:54:13.059 [INFO ] [eclipse.smarthome.model.script.light] - ---

==> /var/log/openhab2/events.log <==
2020-01-03 18:54:13.060 [ome.event.ItemCommandEvent] - Item 'HeizungArbeitszimmer_SetpointTemperature_Device' received command 5.5
2020-01-03 18:54:13.068 [nt.ItemStatePredictedEvent] - HeizungArbeitszimmer_SetpointTemperature_Device predicted to become 5.5

==> /var/log/openhab2/openhab.log <==
2020-01-03 18:54:13.120 [INFO ] [clipse.smarthome.model.script.heater] - HeizungArbeitszimmer_SetpointTemperature
2020-01-03 18:54:13.122 [INFO ] [clipse.smarthome.model.script.heater] - Device
2020-01-03 18:54:13.144 [INFO ] [eclipse.smarthome.model.script.light] - sleeping
items

The device items are defined in the paper UI, but they are Number:Temperature items for sure.

Number:Temperature HeizungArbeitszimmer_SetpointTemperature_Proxy (Heizung_SetpointTemperature)
Number:Temperature HeizungArbeitszimmer_SetpointTemperature_UI (Heizung_SetpointTemperature)
Number:Temperature HeizungArbeitszimmer_SetpointTemperature_Rules (Heizung_SetpointTemperature)

But you want a “Number:Temperature” , not a number. A QuantityType, with units.

5.5 what, thinks the Number:Temperature
Degrees C, or F, or Kelvin? Multiples of body temperature?
The units are a required part of a QuantityType

You’d need that to be commanding 5.5 °C or suchlike.

Many thanks for your patience! I changed the line

    if(device.state != receivedCommand) device.sendCommand(receivedCommand)

to

    if (receivedCommand.toString.contains("°")){
        if(device.state != receivedCommand) device.sendCommand(receivedCommand)
    }else{
        if(device.state != receivedCommand) device.sendCommand(receivedCommand + " °C")
    }

Now I’m happy =)

1 Like