Samsung SmartThings: rule working only once

Hello,

I have a rule that’s propperly executed only once. As I assume that’s related to the SmartThings binding I post my question here:

My environment:

  • openHAB 2.5 running in a Docker container on a QNAP TS-131P
  • SartThingsBinding 2.5.5
  • SmartThings Hub (firmware 000.032.00010)
  • Osram Plug X3 (it’s a ZigBee outlet, firmware 0x01020509 - according to the hub it’s the latest version)

The rule:

var Timer BHTimer = null

rule “SSD_1 ausschalten”
when
Item SchaltSteckDose_1_AnAus received update
then
logInfo(“SSD_1.rules”, “SSD_1 status update triggered”)
if (SchaltSteckDose_1_AnAus.state == ON) {
logInfo(“SSD_1.rules”, “SSD_1 status ON”)
BHTimer = createTimer(now.plusMinutes(1), [|
SchaltSteckDose_1_AnAus.sendCommand(OFF)
logInfo(“SSD_1.rules”, “SSD_1 switched off”)
BHTimer = null
])
}
end

Purpose: when the plug is switched on manually it should be switched off by openHAB 1 hour later (currently it’s set to 1 minute in the rule).

The first time after a container restart it works very well:

openhab.log:

2020-10-19 11:38:54.957 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status update triggered
2020-10-19 11:38:54.962 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status ON
2020-10-19 11:39:54.984 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 switched off
2020-10-19 11:39:55.030 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status update triggered
2020-10-19 11:39:55.223 [INFO ] [s.internal.SmartthingsHandlerFactory] - Sent message “{“capabilityKey”: “switch”, “deviceDisplayName”: “SSD 1”, “capabilityAttribute”: “switch”, “value”: “off”}” with path “/update” to the Smartthings hub, recieved HTTP status 202 (This is the normal code from Smartthings)
2020-10-19 11:39:55.619 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status update triggered

events.log:

2020-10-19 11:38:54.754 [vent.ItemStateChangedEvent] - SchaltSteckDose_1_AnAus changed from OFF to ON
2020-10-19 11:39:54.994 [ome.event.ItemCommandEvent] - Item ‘SchaltSteckDose_1_AnAus’ received command OFF
2020-10-19 11:39:55.003 [vent.ItemStateChangedEvent] - SchaltSteckDose_1_AnAus changed from ON to OFF

SmartThings hub events:

But on the 2nd attempt it’s not switched off.

openhab.log:

2020-10-19 11:54:36.042 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status update triggered
2020-10-19 11:54:36.056 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status ON
2020-10-19 11:55:36.063 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 switched off
2020-10-19 11:55:36.136 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status update triggered
2020-10-19 11:55:36.341 [INFO ] [s.internal.SmartthingsHandlerFactory] - Sent message “{“capabilityKey”: “switch”, “deviceDisplayName”: “SSD 1”, “capabilityAttribute”: “switch”, “value”: “off”}” with path “/update” to the Smartthings hub, recieved HTTP status 202 (This is the normal code from Smartthings)

Plug switched off manually

2020-10-19 12:15:36.544 [INFO ] [e.smarthome.model.script.SSD_1.rules] - SSD_1 status update triggered

events.log:

2020-10-19 11:54:36.016 [vent.ItemStateChangedEvent] - SchaltSteckDose_1_AnAus changed from OFF to ON
2020-10-19 11:55:36.103 [ome.event.ItemCommandEvent] - Item ‘SchaltSteckDose_1_AnAus’ received command OFF
2020-10-19 11:55:36.141 [vent.ItemStateChangedEvent] - SchaltSteckDose_1_AnAus changed from ON to OFF

SmartThings hub events:

On PaperUI and the app I can switch on and off the plug without any problem.

Any input appreciated.

Reinhold

You should consider using the Expire binding for something like this.

Anyway, the logs indicate that the rule is triggered every time that SchaltSteckDose_1_AnAus updates (you should really use changed for a Rule like this. So the binding and Items and rule triggering are working.

It’s really hard to tell because you didn’t How to use code fences, but it looks like the creation of the Timer is inside the if statement. That means the timer will only vbe created when SchaltSteckDose_1_AnAus changes to ON. The rule does nothing except logging that “SSD_1 status update triggered”, which we can see in the second set of logs.

So the rule is doing what you told it to. When it turns ON it sets the timer. When you turn it OFF, it just logs the change and then does nothing.

Hi Rich,

thanks for your answer. I apologize for the mess with the code fence, I’m still in the learning phase.

I enjoyed your hint because it simplified the rule. Now it looks like this:

var Timer BHTimer = null

rule "SSD_1 ausschalten"
when
    Item SchaltSteckDose_1_AnAus changed from OFF to ON
then
    SchaltSteckDose_1_AnAus.postUpdate(ON)
    BHTimer = createTimer(now.plusMinutes(1), [|
        SchaltSteckDose_1_AnAus.sendCommand(OFF)
        SchaltSteckDose_1_AnAus.postUpdate(OFF)
        BHTimer = null
    ])
end

But the result it the same. After a recycle of the openHAB container the rule works perfectly an the first execution:

I see in the openHAB logs that it was switched on and I see in both, the openHAB logs and the SmartThings event, that it was switched off one minute later.

On the second execution I see in the openHAB logs that it was switched off. And I see in the openhab logs that it was supposed to be switched off 1 minute later. But on the second execution I don’t see that a command was transferred ot SmarThings.

I made another test. I created 2 rules to switch the outlet on every 10 minutes, and iwas switched off by the rule in question 1 minute later and this for hours.

So this brings me to the conclusion that pressing the On/Off switch on the outlet is not handled correctly. And at this point I’m lost.

Reinhold

Don’t do that, you know it’s already ON

Don’t do that, this is two wildly different things.
Commands to an Item are what invokes the binding to do its thing and talk to target device.
Updates to an Item are generally produced by a device talking to binding and invoking an Item state update.

There are many good reason to update Items from rules, none of them apply here when you want to hear what the device has to tell you.

So, simplified -

var Timer BHTimer = null

rule "SSD_1 ausschalten"
when
    Item SchaltSteckDose_1_AnAus changed from OFF to ON
then
    BHTimer = createTimer(now.plusMinutes(1), [|
        SchaltSteckDose_1_AnAus.sendCommand(OFF)
        BHTimer = null
    ])
end

(the null stuff is unnecessary at this stage, but if you get it working roughly as wanted we can help you use that for rescheduling - later)

Please may we see your events.log as well?

This might well be the case, let’s find out.

You have explicitly written your rule to trigger only when the light changes from OFF to ON. As you describe it here, the Item changed from ON to OFF. So the rule didn’t trigger. If you want it to run when the light turns ON and when it turns OFF you need to write the rule trigger to run the rule in both of those cases.

Item SchaltSteckDose_1_AnAus changed

This is basically the same problem as with the original except moved from the if statement to the rule trigger. You are telling it to only run when the Item changes to ON and not do anything when it changes to OFF.

Hello,

thanks a lot for your support. It was a strange problem and I found a strange solution.

Knowing from my tests the second and subsequent execution of the rule failes when the power button on the plug was sitched manually, but it worked fine several times when the plug was switched on by another rule, I had the idea trying to “reset” the item by expanding the rule to switch off and on the time again. Sounds crazy, but it works for me.

So this is the current rule:

var Timer BHTimer = null

rule "SSD_1 ausschalten"
when
    Item SchaltSteckDose_1_AnAus changed from OFF to ON
then
    if (BHTimer == null) {
        BHTimer = createTimer(now.plusMinutes(10), [|
            SchaltSteckDose_1_AnAus.sendCommand(OFF)
            Thread::sleep(100)
            SchaltSteckDose_1_AnAus.sendCommand(ON)
            Thread::sleep(100)
            SchaltSteckDose_1_AnAus.sendCommand(OFF)
            BHTimer = null
        ])
    }
end

Thanks again and have a great time.

Reinhold

This has the feel of a binding or hub bug. We do not have enough info, but on the face of it I would guess the binding, or the hub, does not act on a command OFF if it thinks the device is already OFF.

Hello,

That’s also my feeling.

I simplified the rule as it’s just enough to send an ON again:

var Timer   BHTimer  = null

rule "SSD_1 ausschalten"
when
    Item SchaltSteckDose_1_AnAus changed from OFF to ON
then
    SchaltSteckDose_1_AnAus.sendCommand(ON)
    BHTimer = createTimer(now.plusMinutes(60), [|
        logInfo("SSD 1", "BHTimer fired")
        SchaltSteckDose_1_AnAus.sendCommand(OFF)
        BHTimer = null
    ])
end

And I added a second rule to cancel the timer when the outlet is switched off manually:

rule "SSD_1 Timer loeschen"
when
    Item SchaltSteckDose_1_AnAus changed from ON to OFF
then
    BHTimer.cancel()
    BHTimer = null
    logInfo("SSD 1", "BHTimer cancelled after plug switched off")
end

This way you can switch on and off the plug manually several times and only the last timer survives.

Thanks again for all the comments.

Reinhold