Dear all,
first of all sorry if I am opening my topic in the wrong section.
I am new with OpenHab and have an issue with some rules and scenes I am trying to schedule.
I have 2 sonoff touch (tasmota flash) in the same room that turn on/off the light.
I have scheduled a scene1 that turn on both sonoff’s and a scene2 that turn off both sonoff’s.
Then I have created 2 rules.
First one that turn on the light:
when sonoff1 changed from OFF to ON and sonoff2 changed from OFF to ON then execute the scene1.
Second rule that turn of the light:
when sonoff1 and sonoff2 changed from ON to OFF then execute scene2.
Everything works fine at 99 % when sonoff1 or sonoff2 are pushed, the issue happen only when both sonoff’s are pushed in the same time, in that case the system turn on and off flickering the light in seconds, it start a loop of turn on and turn off.
How can I avoid this scenario? Who know better then me openhab have any proposal to do it differently what I am trying to do?
I tried also to do it ony with rules without scenes but had the same result.
Thanks for your help
Hi, welcome to the community.
Can you post your rules?
Hello Jim,
sure below code of first rule that turn the light on:
configuration: {}
triggers:
- id: "1"
configuration:
itemName: Luci_Sala_Luce_Tavolo
state: ON
previousState: OFF
type: core.ItemStateChangeTrigger
- id: "3"
configuration:
itemName: Luce_Balcone_Sala_Triplo_Luce_Tavolo
state: ON
previousState: OFF
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
considerConditions: true
ruleUIDs:
- LuceTavoloON
type: core.RunRuleAction
the same is for turn off light change only state from OFF to ON
and this one?
That is the scene. that only put in ON state the 2 items.
items:
Luce_Balcone_Sala_Triplo_Luce_Tavolo: ON
Luci_Sala_Luce_Tavolo: ON
triggers: []
conditions: []
This is a tricky one. Without testing it, I think you could benefit from the new “A Minimum interval is met” condition to ensure that your rules don’t get executed in rapid succession.This feature is only available in 5.0, so you can try 5.0 Milestone 2 perhaps?
There are probably other solutions to this problem though.
Please show the other scenes and rules too as well as an extract from events.log showing the events that cause the rules to go into a loop.
I’m struggling to see how it gets into the loop and the root cause might show other potential approaches. The only way I can see it going into a loop is if one switch changes to ON and the other changes to OFF at the same time and the scenes also change the states of the triggering switches.
Thanks for your solution, I have the 4.3.3 version installed, and what you suggest is not yet available.
What I don’t understand, if a double click is set considering both sonoff’s it should execute at least only 2 times the scenes and not to go in loop on/off. I am missing something for sure.
Here also codes of rules and scenes that switch in off.
configuration: {}
triggers:
- id: "1"
configuration:
itemName: Luce_Balcone_Sala_Triplo_Luce_Tavolo
state: OFF
previousState: ON
type: core.ItemStateChangeTrigger
- id: "3"
configuration:
itemName: Luci_Sala_Luce_Tavolo
state: OFF
previousState: ON
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
considerConditions: true
ruleUIDs:
- LuceTavoloOFF
type: core.RunRuleAction
scene OFF code:
items:
Luce_Balcone_Sala_Triplo_Luce_Tavolo: OFF
Luci_Sala_Luce_Tavolo: OFF
triggers: []
conditions: []
I will simulate and send the log file too. Thanks
OK, seeing all the rules and the scenes I think I can see how it gets into the loop.
This is a common problem when trying to keep Items in sync. I’m not 100% certain @jimtng’s approach will solve the root problem. It will avoid the loop (I think) but what ends up happening to the lights will be somewhat random depending on timing.
It is usually best to centralize this sort of synchronization into a single rule where you can check the state of things in relation to the incoming change and only make the changes necessary. That is usually enough to avoid a loop.
So you would eliminate the scenes. Change the triggers to just be if the Items changed. We dont’ care if it changed to ON or OFF, we’ll handle both cases.
Then you’ll need a script action. The action will:
- get the new state from the triggering Item
- look at the Items and if they are not the same state as the new state of the triggering Item, command it to the new state
In JS it would look something like (there are ways to make this simpler but I’m making the code more explicit for understandability and to make it easier to translate to other rules languages which don’t have sendCommandIfDifferent()
or the equivalent):
if(items.Luce_Balcone_Sala_Trilo_Luce_Tavolo.state != event.itemState.toString()) {
items.Luce_Balcone_Sala_Trilo_Luce_Tavolo.sendCommand(event.itemState.toString();
}
if(items.Luci_Sala_Luce_Tavolo.state != event.itemState.toString()) {
items.Luci_Sala_Luce_Tavolo.sendCommand(event.itemState.toString());
}
This should be easy to translate to Blockly or any other scripting language of choice.
The trick is that the Item is not commanded if it’s already in the new state. This prevents the Item that triggered the rule from being commanded again. The other trick is that becuase it’s all handled by one rule instead of four, you never suffer from timing issues where one rule is running at the same time as another which can cause them to interact with each other.
Dear Rich, thanks a lot for your time and your help.
It works perfect.
There was only a written mistake in your code on name of item and you forgot to close the bracket.
If needed below the full code maybe can help someone else in this community.
configuration: {}
triggers:
- id: "1"
configuration:
itemName: Luci_Sala_Luce_Tavolo
type: core.ItemStateChangeTrigger
- id: "2"
configuration:
itemName: Luce_Balcone_Sala_Triplo_Luce_Tavolo
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "3"
configuration:
type: application/javascript
script: >-
if(items.Luce_Balcone_Sala_Triplo_Luce_Tavolo.state !=
event.itemState.toString()) {
items.Luce_Balcone_Sala_Triplo_Luce_Tavolo.sendCommand(event.itemState.toString());
}
if(items.Luci_Sala_Luce_Tavolo.state != event.itemState.toString()) {
items.Luci_Sala_Luce_Tavolo.sendCommand(event.itemState.toString());
}
type: script.ScriptAction