Help with creating a rule too tell if a smart socket {RELAY} failed too operate (SOLVED)

hi everyone

I have noticed a problem with my TP-Link smart sockets sometimes the socket gets stuck in the on position the relay fails to operate but all signs like openhab,kasa,led’s say the device is off

so this could be dangerous when controlling devices like electric blankets etc so i have decided too replace my hs100 sockets for hs110 with energy monitoring to give openhab the ability to tell if the load has powered down.

I obviously need a rule for this and this is where i need your help

i would like too resend the off command a few times and then receive a notification if a load has failed too power off so it can be manually fixed

i have tried too use a while loop but its not working how i would like it while loops never work as i expect

I think i also need too create an item that adds one too itself after its tried again i’m unsure how too do this

Here’s what i have got so far any suggestions and pointers appreciated

rule "PLUG9 Saftey"
when
    Item PLUG9_Switch_MBED_EBlanket received update OFF 
then
logInfo("NOTE", "PLUG9 Saftey Running")
createTimer(now.plusSeconds(10), [| // Wait for load to lower
if ( PLUG9_Power_MBED_EBlanket.state == 0) { // load has gone do noting
    return;
}
if( PLUG9_Power_MBED_EBlanket.state != 0) { // load has not lowered 
    logWarn("WARN", "PLUG9 Saftey Load did not power OFF AUTO RETRY")
    while ( PLUG9_Power_MBED_EBlanket.state == != 0 && safeteyretry.state <= 3 ) { 
    createTimer(now.plusSeconds(25), [| 
    PLUG9_Switch_MBED_EBlanket.sendCommand ("OFF") // try again
    safeteyretry.sendCommand (+1)  // ?? add 1 too try counter ??
    }
    logError("WARN", "CANT POWER OFF SOCKET") 
    SystemWarning.sendCommand ("ON") // set warning too on   this item also handles the notification seperatly
}
} 
    ]) 
end

What your while loop currently does, is that it creates one timer, but the normal code doesn’t wait for the timer to run out, so after it creates the timer, which, for the sake of the argument, takes like 10 ms, it will create another 25 second timer, and so on. Because in that 10 ms, the state probably won’t change and the safeteyretry item definitely will not change. So what you will then have is a huge number of 25 second timers that run out 10 milliseconds after each other.
Apart from that you have a number of errors in your code that make it hard to read and impossible for OpenHAB to execute:

  • You are opening 2 lambdas (createTimer(now.plusSeconds(10), [| and createTimer(now.plusSeconds(25), [|) but you are only closing one (just before the end)
  • In your while loop you have a bit too many comperators: PLUG9_Power_MBED_EBlanket.state == != 0 should probably be PLUG9_Power_MBED_EBlanket.state != 0
  • This safeteyretry.sendCommand (+1) will not work, this however will: safeteyretry.sendCommand (safeteyretry.state + 1) (it should be “safetyretry” by the way)

For the safetyretry you could also use a variable and instead of the while loop, I would just have the rule run again. So my take at this, without testing, would be something like this:

var Number SafetyRetry = 0
var Timer SafetyCheck = null
rule "PLUG9 Safety"
when
    Item PLUG9_Switch_MBED_EBlanket received update OFF or
    Item PLUG9_Switch_MBED_EBlanket received command OFF
then
    logInfo("NOTE", "PLUG9 Safety Running")
    createTimer(now.plusSeconds(10))[| // Wait for load to lower
        if ( PLUG9_Power_MBED_EBlanket.state == 0) { // load has gone do nothing
            return;
        }else if(SafetyRetry <= 3) { // load has not lowered, and haven't tried 3 times yet
            logWarn("WARN", "PLUG9 Saftey Load did not power OFF AUTO RETRY")
            createTimer(now.plusSeconds(25))[| 
                PLUG9_Switch_MBED_EBlanket.sendCommand ("OFF") // try again, this will trigger this rule again
                SafetyRetry = SafetyRetry + 1 // add 1 to try counter
            ]
            logError("WARN", "CANT POWER OFF SOCKET") 
        }else{ // already retried 3 times, just give up. (?)
            SafetyRetry = 0 // reset variable for another time
            SystemWarning.sendCommand ("ON") // set warning to on  this item also handles the notification seperatly
        }
    ]
end

Edit2: now that I think of it, you might as well remove the second createTimer altogether, but that might also be a personal preference, so I left it in, and leave it to you to decide.

2 Likes

Hi RolfV thanks for the reply

your rule looks alot better than mine

as i said i can never get a while loop working they just don’t behave how i expect

I wasn’t sure how too do this it was added as an example of what i was trying too do

i had been editing the rule alot trying too get something too work i then commented out the rule and only just picked it back up when i posted my bad

Thanks for that

i would prefere not too use a while loop as they never work as i expect that wlll make editing the rule at a later date harder i like your version you sent

The idea behind that timer was too stop openhab from sending commands too the socket in quick succession cant sending fast commands too a relay cause a fire ?

i would try more times but at some point you have got too give up how many retrys would you recomend the idea is this rule tries too turn the socket off if it cant it just gives up and sets a warning flag

With my version of the rule that is not happening anymore anyway. When the item receives an OFF update or OFF command, it will wait 10 seconds any way to check anything. If after 10 seconds there is still energy consumption, it will send another OFF command, which again triggers the same rule, and it sets the Retry counter 1 higher.

and that’s exactly what i wanted too achieve it just wasen’t coming together

do you have any idea if its a common problem for relays too get stuck ?

i will test your rule shortly

I have never seen it happen in practice myself, but generally speaking the question is of course if it is the device that is the issue, or the communication with the device.

On that note, as I noticed you use when Item received update OFF, can you show the rule that you use to turn the device off?

its definitely not communication issues although i have got some network instability atm that im trying too fix i think adding all the smarthome devices has damaged my network too many devices or too many wifi devices i get strange lockups

my computer was connected too smart socket and i noticed the computer was still powered after the socket was turned off by openhab

i know the socket was off as the led on the socket was off , pressing the button on the socket did noting other than make a quieter that usual click , the mobile app too the socket also reported off and so did openhab it was a stuck relay the only thing that solved it was unplugging the socket worked fine after

i have quite a few rules that can control this device

heres one

rule "Master Bedroom"
when
    Item Bed_Trigger changed to ON // When Going to Bed
then
    if( now.getHourOfDay >=  22 || now.getHourOfDay <=  5 ) {
        if( Away_from_home.state == OFF ) { // if somebodys home
            if( MBed_Temp.state >= 21.00 ) { // if Bedroom temperature is above 21C
                Plug2_Switch_MBED_Fan.sendCommand (ON) // Turn Fan ON
                logInfo("NOTE", "MB FAN ON")
            }
        if( MBed_Temp.state <= 15.00 ) { // if Bedroom temperature is below 15C
            PLUG9_Switch_MBED_EBlanket.sendCommand (ON)
            logInfo("NOTE", "MB BLANKET ON")
        }    
    }
logInfo("RULE", "Master Bedroom FINISHED (Climate Control.rules)")  
    }

end

Good, so you use sendCommand. Then in your “Plug9 Safety” rule you should also use received command OFF, that I added in my version of the rule, and you only had received update OFF.

Furthermore your device sounds like it is faulty, which to me would be a reason not to use it anymore, especially in the case of an electric blanket.

I returned the effected socket too tp link for a replacement the problem is that I didnt notice for a few days there was a problem with the socket and there was no warning there was a problem so a preemptive peice of code for the sockets is the best solution if anymore go bad openhab will tell me I would obviously add all sockets too the rule in the future

I’m in the process of swapping the non energy moniter ones for energy moniter versions too protect from this type of thing again i can’t jepodise people’s safety for automation

I’m having some trouble with the rule you sent me works OK when the socket powers off as expected but when it doesent it doesent behave how I expected

The rule keeps going and doesent stop after 3 attempts and it also sets the system warning too on too early it does this on the first fail but should set this when it has given up

Any ideas iv been trying too fix it myself no luck

I have been testing with a number item linked instead of the plugs power too simulate how the rule runs when power didn’t lower

Hard to say from here, there is a few options I think. To check what the issue is, please add some logging, something like this:

var Number SafetyRetry = 0
var Timer SafetyCheck = null
rule "PLUG9 Safety"
when
    Item PLUG9_Switch_MBED_EBlanket received update OFF or
    Item PLUG9_Switch_MBED_EBlanket received command OFF
then
    logInfo("NOTE", "PLUG9 Safety Running")
    createTimer(now.plusSeconds(10))[| // Wait for load to lower
        logInfo("Plug9.Debug", "PLUG9 10 seconds waiting over")
        if ( PLUG9_Power_MBED_EBlanket.state == 0) { // load has gone do nothing
            logInfo("Plug9.Debug", "PLUG9 Power is 0")
            return;
        }else if(SafetyRetry <= 3) { // load has not lowered, and haven't tried 3 times yet
            logInfo("Plug9.Debug", "PLUG9 Power is not 0 yet: " + PLUG9_Power_MBED_EBlanket.state + " and SafetyRetry is " + SafetyRetry.toString)
            logWarn("WARN", "PLUG9 Saftey Load did not power OFF AUTO RETRY")
            createTimer(now.plusSeconds(25))[| 
                logInfo("Plug9.Debug", "25 seconds waiting is over, turn OFF again and increase counter")
                PLUG9_Switch_MBED_EBlanket.sendCommand ("OFF") // try again, this will trigger this rule again
                SafetyRetry++ // add 1 to try counter
            ]
            logError("WARN", "CANT POWER OFF SOCKET") 
            SystemWarning.sendCommand ("ON") // set warning to on  this item also handles the notification seperatly
        }else{ // already retried 3 times, just give up. (?)
            logInfo("Plug9.Debug", "Retried more than 3 times already, SafetyRetry = " + SafetyRetry.toString)
            SafetyRetry = 0 // reset variable for another time
            // You might also want to issue another warning here, potentially combined with a sendBroadcastNotification()
        }
    ]
end

using your rule exactly with couple of changes

I had too remove this the rule was running on its own removing this solved that

i also had too change this too an item i can actually control a simple number item for testing purposes

do i need too create an item for this or is it handled as a variable another thing i know little about

will run your rule now and post results

when power/load has lowered:

2019-01-05 20:11:12.214 [ome.event.ItemCommandEvent] - Item 'PLUG9_Switch_MBED_EBlanket' received command ON
2019-01-05 20:11:37.118 [ome.event.ItemCommandEvent] - Item 'PLUG9_Switch_MBED_EBlanket' received command OFF
2019-01-05 20:11:38.405 [INFO ] [.eclipse.smarthome.model.script.NOTE] - PLUG9 Safety Running
2019-01-05 20:11:48.413 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 10 seconds waiting over
2019-01-05 20:11:48.424 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 Power is 0

When power failed too lower:

2019-01-05 20:17:24.144 [ome.event.ItemCommandEvent] - Item 'Testpower' received command 46 // me setting the test power too simulate failure
2019-01-05 20:17:28.862 [ome.event.ItemCommandEvent] - Item 'PLUG9_Switch_MBED_EBlanket' received command ON // me powering the socket
2019-01-05 20:17:37.851 [ome.event.ItemCommandEvent] - Item 'PLUG9_Switch_MBED_EBlanket' received command OFF // me sending off command too trigger rule
2019-01-05 20:17:37.873 [INFO ] [.eclipse.smarthome.model.script.NOTE] - PLUG9 Safety Running
2019-01-05 20:17:37.874 [vent.ItemStateChangedEvent] - PLUG9_Switch_MBED_EBlanket changed from ON to OFF
2019-01-05 20:17:47.880 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 10 seconds waiting over
2019-01-05 20:17:47.907 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 Power is not 0 yet: 46 and SafetyRetry is 0
2019-01-05 20:17:47.914 [WARN ] [.eclipse.smarthome.model.script.WARN] - PLUG9 Saftey Load did not power OFF AUTO RETRY
2019-01-05 20:17:47.933 [ERROR] [.eclipse.smarthome.model.script.WARN] - CANT POWER OFF SOCKET
2019-01-05 20:17:47.948 [ome.event.ItemCommandEvent] - Item 'SystemWarning' received command ON
2019-01-05 20:17:47.963 [vent.ItemStateChangedEvent] - SystemWarning changed from OFF to ON
2019-01-05 20:18:12.922 [INFO ] [e.smarthome.model.script.Plug9.Debug] - 25 seconds waiting is over, turn OFF again and increase counter // try 1
2019-01-05 20:18:12.948 [ome.event.ItemCommandEvent] - Item 'PLUG9_Switch_MBED_EBlanket' received command OFF
2019-01-05 20:18:12.954 [nt.ItemStatePredictedEvent] - PLUG9_Switch_MBED_EBlanket predicted to become OFF
2019-01-05 20:18:12.975 [INFO ] [.eclipse.smarthome.model.script.NOTE] - PLUG9 Safety Running
2019-01-05 20:18:23.056 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 10 seconds waiting over
2019-01-05 20:18:23.091 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 Power is not 0 yet: 46 and SafetyRetry is 0
2019-01-05 20:18:23.096 [WARN ] [.eclipse.smarthome.model.script.WARN] - PLUG9 Saftey Load did not power OFF AUTO RETRY
2019-01-05 20:18:23.118 [ERROR] [.eclipse.smarthome.model.script.WARN] - CANT POWER OFF SOCKET
2019-01-05 20:18:23.147 [ome.event.ItemCommandEvent] - Item 'SystemWarning' received command ON
2019-01-05 20:18:48.105 [INFO ] [e.smarthome.model.script.Plug9.Debug] - 25 seconds waiting is over, turn OFF again and increase counter
2019-01-05 20:18:48.122 [ome.event.ItemCommandEvent] - Item 'PLUG9_Switch_MBED_EBlanket' received command OFF
2019-01-05 20:18:48.140 [nt.ItemStatePredictedEvent] - PLUG9_Switch_MBED_EBlanket predicted to become OFF
2019-01-05 20:18:48.168 [INFO ] [.eclipse.smarthome.model.script.NOTE] - PLUG9 Safety Running
2019-01-05 20:18:50.963 [ome.event.ItemCommandEvent] - Item 'Testpower' received command 0
2019-01-05 20:18:58.225 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 10 seconds waiting over
2019-01-05 20:18:58.231 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 Power is 0

also received this error while the rule was running

2019-01-05 20:30:05.114 [INFO ] [.eclipse.smarthome.model.script.NOTE] - PLUG9 Safety Running

2019-01-05 20:30:05.163 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.2019-01-05T20:30:05.081Z: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)

  <XFeatureCallImplCustom>.sendCommand(<XStringLiteralImpl>)

  <XFeatureCallImplCustom> ++

} ] threw an exception.

org.quartz.SchedulerException: Job threw an unhandled exception.

	at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]

	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]

Caused by: java.lang.reflect.UndeclaredThrowableException

	at com.sun.proxy.$Proxy182.apply(Unknown Source) ~[?:?]

	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]

	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]

	... 1 more

Caused by: org.eclipse.smarthome.model.script.engine.ScriptExecutionException: Unknown variable or command '++'; line 20, column 17, length 13

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:147) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:902) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:226) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:447) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:228) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:190) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]

	at com.sun.proxy.$Proxy182.apply(Unknown Source) ~[?:?]

	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]

	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]

	... 1 more

I already suggesties to do so, so I can only agree.

Makes sense.

Ah in that case replace SafetyRetry++ with SafetyRetry = SafetyRetry + 1.

that now increases it by one as expected up too 3

the log then returns

2019-01-05 21:05:43.251 [INFO ] [e.smarthome.model.script.Plug9.Debug] - PLUG9 10 seconds waiting over
2019-01-05 21:05:43.261 [INFO ] [e.smarthome.model.script.Plug9.Debug] - Retried more than 3 times already, SafetyRetry = 4

but it still turns system warning on on the first try

Oh it shouldn’t? That wasn’t clear to me. In that case, move the system warning to the else statement.

1 Like

@RolfV

Works perfectly now thanks for the help on that you helped alot

Here is the final rule

var Number SafetyRetry = 0
var Timer SafetyCheck = null

rule "PLUG9 Safety"
when
    Item PLUG9_Switch_MBED_EBlanket received command OFF
then
    logInfo("NOTE", "PLUG9 Safety Running")
    createTimer(now.plusSeconds(10))[|
        if ( PLUG9_Power_MBED_EBlanket.state == 0.0) {
            return;
        }else if(SafetyRetry <= 3) {
            logWarn("WARN", "PLUG9 Saftey Load did not power OFF AUTO RETRY")
            createTimer(now.plusSeconds(25))[| 
                PLUG9_Switch_MBED_EBlanket.sendCommand ("OFF")
                SafetyRetry = SafetyRetry + 1
            ]
            logError("WARN", "CANT POWER OFF SOCKET") 
        }else{
            SafetyRetry = 0
            SystemWarning.sendCommand ("ON")
        }
    ]
end

Good to hear, I’m happy I could have been of help and hope it keeps the family safe from faulty devices :slight_smile:

1 Like

something like this should be hardcoded into the actual sockets.

devices that are supposed too be operated remotely from anywhere in the world should have protection features built in a faulty relay could easily cause a fire but as i described the socket thinks its off when its not so i don’t know how the basic model would detect something like this but the energy mon versions should be checking this by themselves maby tp-link will add it with a firmware update

Thanks for the help again