[SOLVED] Zigbee binding out of sync

Hi,

I have a couple of IKEA Tradfri bulbs linked to an Ember-based zigbee stick, using the generic Zigbee binding. It works fine, most of the time. I have a modern house, with lots of reinforced concrete, which is always difficult for any radio based solution. So every now and then, a Zigbee message seems to get lost. This results e.g. in one of the bulbs not turning off, if I give an off command to a group of bulbs. I’m afraid there’s not much I can do to improve the situation.

However, I notice the behavior of OpenHAB is not ideal for my situation. In the above example, if that one bulb stays on, after a couple of minutes, the communication between OpenHAB and the bulb restores. Then OpenHAB notices that the state of the bulb is different from the state of the Item. It then updates the Item. In other words: the state of the bulb overrides the state of the item. Only when I manually reset the state of the Item again, the bulb finally goes off.

I want my bulbs to go on and off according to a schedule. That means I won’t be there to manually put the bulb off when this happens. Is there a simple way to change the behavior of OpenHAB, so that it always let the Item state override the bulb state? That way, it the above situation, the bulb would go off at the moment the communication with OpenHAB is restored.

Any suggestions would be highly appreciated!

Best regards,
Bart Kummel

Is problem always associated with group commands? You may need to allow a little time between individual commands. I don’t know how clever the binding is about managing that for you.
This thread involves gateways but may be similar symptoms

Nope.

You could construct a rule to retry sending a command if the target is not at the desired state after a short delay. It’s not a trivial job.

How would I do that? How can a rule know what the desired state is? As soon as there is communication with the bulb, and thus the first opportunity to compare the actual state with the desired state, the binding updates the Item’s state, so I cannot use the Item state to compare with. The only thing I can think of is to create a “shadow” Item for each bulb, that keeps track of the desired state. To accomplish that, I’d hav to create a rule that updates the “shadow” Item, if the “real” item changes, but only if this is caused by a manual command or by a timer. Is thee a way of knowing what the cause of a state change is in a rule?

That’s the tricky part in an event-driven system. You can kick the process off by looking for a command to a device. But you then need some means to “remember” what the command was, if you’re going to check for results later.

One way is to make sure only interesting things can cause changes. Disable autoupdate for the target Item - you don’t want openHAB helpfully predicting the hoped-for effect of a command, you want the real state of the end device.
Providing you have no rules messing with postUpdate, the state only gets changed by binding.

psuedocode retry rule

when ItemX received command
start a timer, capturing command
when timer executes, compare current state with expected.
if different, reissue command.
(which will go around this whole business again)

In real life, you might want to implement a max tries counter to avoid endless loops if e.g. you’ve physically taken a bulb away.

Thanks, @rossko57! I’ll try to implement such a rule. I’ll let you know how it went.

For now, I went for a relatively simple solution: I already have a rule that puts the light off once a “virtual” item goes off due to an expired timer.

This is how the virtual item is defined in my .items file:

Switch WoonkamerLicht10min { expire="10m,command=OFF"} 

There are two rules: one to put the lights on (or keep them on) and one to put the lights off once the timer expires:

var Timer timer = null
var repeat = 3
val interval = 5 //minutes

rule "Woonkamerlicht aan voor 10 min"
when
    Item WoonkamerLicht10min received update ON
then
    val dimmer = gWoonkamer_Dimmer.state as DecimalType
    if ((dimmer as Number) <= 0) {
        logInfo("woonkamerlicht", "Licht in woonkamer AAN voor 10 min.")
        sendCommand(gWoonkamer_Dimmer, 100)
    } else {
        logInfo("woonkamerlicht", "Licht in woonkamer is al aan, gaat over 10 min. uit.")
    }
end

rule "Woonkamerlicht uit"
when
    Item WoonkamerLicht10min received update OFF
then
    logInfo("woonkamerlicht", "Licht in woonkamer gaat weer UIT, de 10 min. zijn voorbij.")
    sendCommand(gWoonkamer_Dimmer, 0)
    timer = createTimer(now.plusMinutes(interval), [ |
        if(repeat <= 0) {
            logInfo("woonkamerlicht", "Aantal herhalingen bereikt, hopelijk zijn de lampen nu echt uit.")
            timer = null
        } else {
            logInfo("woonkamerlicht", "Volgende poging om het licht uit te doen. Pogingen over: " + (repeat-1))
            sendCommand(gWoonkamer_Dimmer, 0)
            repeat -= 1
            timer.reschedule(now.plusMinutes(interval))
        }
    ])
end

I have extended the second rule to repeatedly put the lights off, with an interval of 5 minutes. This way the chances are pretty high that the lights are really put off, while the rule is still relatively simple. I don’t need to compare real states with desired states. I chose this solution, because I realized that comparing states is actually more complicated: during the time the bulb doesn’t receive commands, OpenHAB is not aware of that. Thus it seems everything is fine and the lamp is off… I cannot think of a solution to overcome that.

I hope this solution might help others. Also, I’m open for suggestions for improvement!

Best regards,
Bart