Nightmare! Stop OH2 turning on my relays


(Kris K) #1

Hi All

I thought it was the sonoff doing this, but when OH2 restarts and comes up, its triggering sonoff relay via MQTT and opening my garage door!

Why I dont know but this is really really stressing me out as Ive dogs that have just got out. Luckily I have a tradesman at home who locked them inside.

My relays have poweronstate 0, and with the wifi, if it looses that it doesnt trigger the relay either so this is definitely related to OH2 as it only does it when the server is reset.

How can I absolutely ensure that OH2 does NOT trigger my sonoff relays.

Thanks!!

Majorly stressed out here :frowning:


(Rossko57) #2

You should probably tell us how openHAB normally operates the relays. I guess you have Item(s) linked to Sonoff in some way, switches perhaps?

What do you see in events log for these Items? Maybe the rules that control them are triggered by other Items establishing themselves. Which ones are subject to restore on startup, which ones read or calculate new values after system boot?


(Kris K) #3

Hi rossko57,

the items are linked to MQTT channels and are indeed switches

Switch Gate_full      "Fully"                         [ "Lighting" ]   { mqtt=">[broker:cmnd/gate/POWER1:command:*:default], <[broker:stat/gate/POWER1:state:default]", autoupdate="false" }
Switch Gate_partial   "Partial"                       [ "Lighting" ]   { mqtt=">[broker:cmnd/gate/POWER2:command:*:default], <[broker:stat/gate/POWER2:state:default]", autoupdate="false" }

there are no rules involved but here is the log at startup


2019-03-12 12:01:38.677 [vent.ItemStateChangedEvent] - Gate_full changed from NULL to OFF
2019-03-12 12:01:44.136 [ome.event.ItemCommandEvent] - Item 'Gate_full' received command ON
2019-03-12 12:01:44.256 [vent.ItemStateChangedEvent] - Gate_full changed from OFF to ON
2019-03-12 12:01:45.167 [vent.ItemStateChangedEvent] - Gate_full changed from ON to OFF

Cheers


(Rossko57) #4

That didn’t come from nowhere. It’s a full six seconds after a presumed status from the real device. It comes from a rule, or a UI, or a linkage to some binding, or possibly something external sending REST

I’ve not heard of any of the UIs spontaneously generating commands, say in response to a flood of start-up changes.

It’s worth using REST API to search your things for mention of Item name - few bindings will generate commands, but some do.


(Kris K) #6

When you say search the REST API, I can absolutely find the item Gate_full. But I guess Im wanting to search rules for occurrences of Gate_full?

Ive searched and I have a Zwave Remote which has a function to open the gate. Could that be it?

Case 8.0


rule "Remotec ZRC-90 - Fridge"
when
    Item LivingRoom_Zrc_Remote received update
then
    var int sceneNumber = LivingRoom_Zrc_Remote.state as DecimalType

    switch (sceneNumber) {
        case 1.0 : {
            if (KitchenBarSw1.state == OFF) {
            KitchenBarSw1.sendCommand(ON)
            }
            else if (KitchenBarSw1.state == ON) {
            KitchenBarSw1.sendCommand(OFF)
            }
        }
        case 1.3 : {
            logInfo("ZRC90-Fridge", "Button 2 Double press: " + sceneNumber)
        }
        case 2.0 : {
            if (KitchenSw1.state == OFF) {
            KitchenSw1.sendCommand(ON)
            }
            else if (KitchenSw1.state == ON) {
            KitchenSw1.sendCommand(OFF)
            }
        }
        case 2.3 : {
            logInfo("ZRC90-Fridge", "Button 2 double press: " + sceneNumber)
        }
        case 3.0 :  {
            if (BackEveSw1.state == OFF) {
            BackEveSw1.sendCommand(ON)
            }
            else if (BackEveSw1.state == ON) {
            BackEveSw1.sendCommand(OFF)
            }
        }
        case 3.3 : {
            logInfo("ZRC90-Fridge", "Button 3 double press: " + sceneNumber)
        }
        case 4.0 : {
            if (CarportSw1.state == OFF) {
            CarportSw1.sendCommand(ON)
            }
            else if (CarportSw1.sate == ON) {
            CarportSw1.sendCommand(OFF)
            }
        }
        case 4.3 :  {
            logInfo("ZRC90-Fridge", "Button 4 double press: " + sceneNumber)
        }
        case 5.0 : {
            logInfo("ZRC90-Fridge", "Button 5 short press: " + sceneNumber)
            Aircon.sendCommand('AirconOn')
        }
        case 5.3 :  {
            logInfo("ZRC90-Fridge", "Button 5 double press: " + sceneNumber)
            Aircon.sendCommand('AirconOff')
        }
        case 6.0 : {
            logInfo("ZRC90-Fridge", "Button 6 short press: " + sceneNumber)
             if (Main_Zone_Power.state == OFF) {
               Main_Zone_Power.sendCommand('ON')
               Zone_1_Input.sendCommand('Spotify')
               spotify_current_device_id.sendCommand("f48564e5be42c184009e18b2d771af1a225d22c4")
               spotify_action.sendCommand('transfer_playback')
               spotify_action.sendCommand('play')
               }
             if (Main_Zone_Power.state == ON) {
               Zone_1_Input.sendCommand('Spotify')
               spotify_current_device_id.sendCommand("f48564e5be42c184009e18b2d771af1a225d22c4")
               spotify_action.sendCommand('transfer_playback')
               spotify_action.sendCommand('play')
               }
        }
        case 6.3 :  {
            logInfo("ZRC90-Fridge", "Button 6 double press: " + sceneNumber)
            Main_Zone_Power.sendCommand('OFF')
        }
        case 7.0 : {
         logInfo("ZRC90-Fridge", "Button 7 single press: " + sceneNumber)
         Zone_1_Volume.sendCommand('INCREASE')
        }
        case 7.3 : {
        logInfo("ZRC90-Fridge", "Button 7 double press: " + sceneNumber)
        Zone_1_Volume.sendCommand('DECREASE')
        }
        case 8.0 : {
        logInfo("ZRC90-Fridge", "Button 8 single press: " + sceneNumber)
        Gate_full.sendCommand('ON')
        }
        case 8.3 : {
        logInfo("ZRC90-Fridge", "Button 8 double press: " + sceneNumber)
        spotify_action.sendCommand('previous')
        }

}
end


(Jürgen Baginski) #7

IMHO this rule is run on every startup since the item LivingRoom_Zrc_Remote will get an update on systemstart.
I guess you have all Items with the strategy “restoreonstartup”, that way the LivingRoom_Zrc_Remote will be reset to the last value before shot down. In your case the last state was probably 8!
Add a change to a state that has no effect ( 0 ?) at the end of the rule, that way the rule will do no harm after a restart.


(Kris K) #8

Hi opus, yes I have this in my persistance file:



Strategies {
    everyHour   : "0 0 * * * ?"
    everyDay    : "0 0 0 * * ?"

    default = everyChange
}

Items {
    * : strategy = everyChange, everyDay, restoreOnStartup
}

Right, so some kind of catch all to set the case to 0 at the end.


(Kris K) #9

Like so?

rule "Remotec ZRC-90 - Fridge"
when
    Item LivingRoom_Zrc_Remote received update
then
    var int sceneNumber = LivingRoom_Zrc_Remote.state as DecimalType

    switch (sceneNumber) {
        case 1.0 : {
            if (KitchenBarSw1.state == OFF) {
            KitchenBarSw1.sendCommand(ON)
            }
            else if (KitchenBarSw1.state == ON) {
            KitchenBarSw1.sendCommand(OFF)
            }
        }
        case 1.3 : {
            logInfo("ZRC90-Fridge", "Button 2 Double press: " + sceneNumber)
        }
        case 2.0 : {
            if (KitchenSw1.state == OFF) {
            KitchenSw1.sendCommand(ON)
            }
            else if (KitchenSw1.state == ON) {
            KitchenSw1.sendCommand(OFF)
            }
        }
        case 2.3 : {
            logInfo("ZRC90-Fridge", "Button 2 double press: " + sceneNumber)
        }
        case 3.0 :  {
            if (BackEveSw1.state == OFF) {
            BackEveSw1.sendCommand(ON)
            }
            else if (BackEveSw1.state == ON) {
            BackEveSw1.sendCommand(OFF)
            }
        }
        case 3.3 : {
            logInfo("ZRC90-Fridge", "Button 3 double press: " + sceneNumber)
        }
        case 4.0 : {
            if (CarportSw1.state == OFF) {
            CarportSw1.sendCommand(ON)
            }
            else if (CarportSw1.sate == ON) {
            CarportSw1.sendCommand(OFF)
            }
        }
        case 4.3 :  {
            logInfo("ZRC90-Fridge", "Button 4 double press: " + sceneNumber)
        }
        case 5.0 : {
            logInfo("ZRC90-Fridge", "Button 5 short press: " + sceneNumber)
            Aircon.sendCommand('AirconOn')
        }
        case 5.3 :  {
            logInfo("ZRC90-Fridge", "Button 5 double press: " + sceneNumber)
            Aircon.sendCommand('AirconOff')
        }
        case 6.0 : {
            logInfo("ZRC90-Fridge", "Button 6 short press: " + sceneNumber)
             if (Main_Zone_Power.state == OFF) {
               Main_Zone_Power.sendCommand('ON')
               Zone_1_Input.sendCommand('Spotify')
               spotify_current_device_id.sendCommand("f48564e5be42c184009e18b2d771af1a225d22c4")
               spotify_action.sendCommand('transfer_playback')
               spotify_action.sendCommand('play')
               }
             if (Main_Zone_Power.state == ON) {
               Zone_1_Input.sendCommand('Spotify')
               spotify_current_device_id.sendCommand("f48564e5be42c184009e18b2d771af1a225d22c4")
               spotify_action.sendCommand('transfer_playback')
               spotify_action.sendCommand('play')
               }
        }
        case 6.3 :  {
            logInfo("ZRC90-Fridge", "Button 6 double press: " + sceneNumber)
            Main_Zone_Power.sendCommand('OFF')
        }
        case 7.0 : {
         logInfo("ZRC90-Fridge", "Button 7 single press: " + sceneNumber)
         Zone_1_Volume.sendCommand('INCREASE')
        }
        case 7.3 : {
        logInfo("ZRC90-Fridge", "Button 7 double press: " + sceneNumber)
        Zone_1_Volume.sendCommand('DECREASE')
        }
        case 8.0 : {
        logInfo("ZRC90-Fridge", "Button 8 single press: " + sceneNumber)
        Gate_full.sendCommand('ON')
        }
        case 8.3 : {
        logInfo("ZRC90-Fridge", "Button 8 double press: " + sceneNumber)
        spotify_action.sendCommand('previous')
        }
       LivingRoom_Zrc_Remote.postUpdate(0)
}
end

Like the above? Im not entirely sure this would fix the issue.


(Jürgen Baginski) #10

Yes, that is correct.
If you want to be sure that such was the case and the issue is solved by the line in the code you could add at least one logInfo line in the rule in order to know if the rule is run.
Something like this after the 2var int sceneNumber…" - line.

logInfo ("Remotec ZRC-90 - Fridge", "Started!")

In the log you will have a line each time the rule is run.


(Kris K) #11

Ill test this tonight at home when I can make sure the dogs dont run out the gate when it opens accidentally!!! gasp


(Jürgen Baginski) #12

Let’s hope you can keep the dogs IN.


(Kris K) #13

Just reboot the system again , without any modifications to rules and it did not trigger.

There is only the instance of the item in the remote.rules as above


kris@openhab2:/etc/openhab2/rules$ grep -r Gate_full
remotes.rules:        Gate_full.sendCommand('ON')


(Mark) #14

wHO let the dogs out :clown_face:


(Rossko57) #15

Having exorcised your ghost, it is perhaps worth now spending a little time considering why you would want to persist and restore absolutely everything.

Especially for Pi/SSD users, it generates unwanted overheads.

Restoring some sensor states is counterproductive. No good being reassured by openHAB that all doors are closed when in fact it has no idea yet.

Persisting a remote button press is a different case - but do you care what the button last pressed before reboot was?

It’s sometimes implemented as a lazy way to avoid Items being NULL or UNDEF in rules. It all depends, but rules can be rewritten to deal sensibly with ‘missing’ values and that may be more desirable than using old stale values.
Quite often there’s a bonus effect from that effort that will bring graceful responses to in-flight failures.

That’s a decision best made early in rules development. I’ve very few persisted/restored Items, and am fed up with typing
if (myItem.state != NULL && myItem.state !=UNDEF)
but I bet I get less surprises :smiley:

Changes can be quite subtle sometimes, !=ON is not the same as ==OFF for example.

Just food for thought.

That’s probably a good idea - once the button event is dealt with, clear it away.

switch-case also has a default: option, by the by,

switch (sceneNumber) {
        case 1.0 : {
            ...
            }
	default : {logInfo("myrule", "Unexpected Button!")}	
	}

(Kris K) #16

Hi rossko57, im not convinced its gone at all! Quite the opposite in fact.

re: persistence, im on a grunty machine so I have no real resource constraints. I will tune it down at some stage though!

My rule is now:


        case 8.3 : {
        logInfo("ZRC90-Fridge", "Button 8 double press: " + sceneNumber)
        spotify_action.sendCommand('previous')
        }
        default : {
        logInfo("ZRC90-Fridge", "Default Button")
        }
    }
        LivingRoom_Zrc_Remote.postUpdate(0)
end




(chrishiscox) #17

This is a familiar prob for me to. I solved it by changing the relays to be high not low active. I don’t use sonoff for them, but do use mqtt.
If your mqtt server is on the same unit as OH try using mqtt persitance when publishing. I can’t remember how of the top of my head.
The most important part of my garage setup is the open close switches, which tells OH the state of the door, and a rule to indicate an open door.


(John Schmitz) #18

I think a lot people start with the example of restore on startup in the installation guide which shows everything being restored:

Strategies {
  default = everyUpdate
}

Items {
  * : strategy = everyChange, restoreOnStartup
}

Perhaps we should change that documentation with a better example or explain there why this might not be a good idea?


(Rossko57) #19

Go ahead, docs don’t belong to me :smiley:


(John Schmitz) #20

What do you think of this?


The following example persists two items on every change and restores them at startup:

Strategies {
  default = everyUpdate
}

Items {
  item1, item2 : strategy = everyChange, restoreOnStartup
}

It is usually not necessary to restore all Items since there is a good chance that they are no longer accurate (switches may have been toggled, sensor values are likely to have changed), and the restoration may result in unwanted rule actions. Rules can be coded to detect UNDEF or NULL and behave appropriately. The * can be used for all Items if desired.

I will propose this change if you think it is good.


(Rossko57) #21

Can probably simplify a bit. The doc describes * earlier on, so we needn’t do it again. And rule tweaking is out of scope - we could just say

It is usually not necessary to restore all Items since there is a good chance that they are no longer accurate (switches may have been toggled, sensor values are likely to have changed), and the restoration may result in unwanted rule actions.

There is actually an earlier line to fix up for OH2 as well

When restarting your openHAB installation you may find there are times when your logs indicate some Items have the state, UNDEF

should now be

When restarting your openHAB installation you may find there are times when your logs indicate some Items have the state, NULL