Detect online/offline state of ikea zigbee bulb

C’mon! The thread is about zigbee2mqtt integration. Sometimes its better to read before commenting.

please behave.
in the first place was I tagged, and responded to that.
secondly this thread is not about zigbee2mqtt, there’s another thread about that indeed. not here. title is self explanatory.
thirdly, I was trying to help.

hope you will find your answer.

2 Likes

@santik Did you ever get this solved? I have the exact same issue. I have several IKEA Tradfri bulbs and used them with the Gateway. I got rid of the Gateway by moving to zigbee2mqtt and indeed the only states I get for a light now are either on or off.

I used to get unavailable as a state when using the Gateway instead of zigbee2mqtt. I set up my IKEA Tradfri bulbs manually in YAML using the configuration at the bottom of e.g. the following page: https://www.zigbee2mqtt.io/devices/LED1545G12.html.

In my zigbee2mqtt configuration.yaml I have all of my devices (in this specific case we’re talking about light bulbs) use the retain attribute set to false. Thinking it wouldn’t keep the on state when the regular in-wall switch is turned off, but change to unavailable. It didn’t.

If you haven’t solved this yet, I’m going to check out the zigbee2mqtt Github issues page (which I haven’t done yet), since it seems to be an issue with that library. Perhaps someone has had the same issue there. If not, I’ll create an issue.

Unfortunately no. I tried many things including custom scripts but nothing helped. Would be nice if they can update library.

A dirty way to figure if it’s unavailable, is to try and switch it on. Zigbee2mqtt by default doesn’t mark a bulb unavailable, it just keeps it’s last state. But if the bulb is actually unavailable (or out of reach) it will try to turn it on and after 1 second it will show turned off again. So you could use an automation like
Turn on the lamp
Wait 1 second
Check if lamp is turned on. If it’s still on, turn it off. If not, mark it unavailable.

I tried that but failed. Do you have working example of this automation?

Here’s an automation that will notify you when the bulb is unavailable.

- alias: Test bulb at night
  trigger:
    - platform: time
      at: "04:00:00" 
  action:
    - entity_id: light.0x000b57fffe9151b8_light
      service: light.turn_off
    - delay:
      milliseconds: 400
    - entity_id: light.0x000b57fffe9151b8_light
      service: light.turn_on
    - delay:
      seconds: 2
    - service: notify.android
      data_template: 
        message: >
          {% if is_state('light.0x000b57fffe9151b8_light', 'off')
          Bulb is offline
          {% else %}
          Bulb is online
          {% endif %} 
    - entity_id: light.0x000b57fffe9151b8_light
      service: light.turn_off       

This is just to notify you on your phone if the bulb is online or offline.
Keep in mind that with this automation and zigbee2mqtt, unavailable will also mean out of reach! So either if the bulb is off by the switch, or the gateway can’t reach the bulb due to wireless coverage, the result will be the same.
The only thing that zigbee can detect is the response from the bulb when it’s turned on. That means that if the last state of the bulb was on, you can turn it off from home assistant with no problems as it doesn’t wait for a response. But when you turn it on, the gateway will either get a response and mark it on, or it won’t and switch back to off. You can test this in lovelace if you have the switch. When the bulb is online and you turn the lovelace switch on, the light next to it will also light up. But if it’s offline or out of reach, the switch will turn on for 0,5 to 1 second, the light next to it will never light up and it will return to off by itself.
Also, you cannot set the state of the device to unavailable, but you can set a binary sensor to do that. Seems like an overkill to me.
If you don’t use brightness and just use it as a regular bulb (meaning only on/off), just install a sonoff wifi switch. It will do the same job and keep states properly.

1 Like

Solution doesn’t work if bulb was cut off from the electricity in ON state. So it keeps ON state all the time.
But idea is great, I will try to do something based on it.

If you noticed, the first command is to turn off the bulb. It’s exactly for that reason. If it was cut in ‘on’ state and turned on later, then it will first try to turn_off, then turn_on and then check if it’s online

Hmmm, just noticed that after the last update of zigbee2mqtt, if the bulb loses power and regains it, hass is informed.
I have probably same setup as you. I have a cc2531 as a coordinator, zigbee2mqtt and an ikea e27(i think) bulb(the bulb surely acts as a router too). With previous versions I had the same problem but didn’t mind as I have an IKEA button too so I did it manually.
I literally noticed 1 minute ago that currently if I cut power in off state and restore power(in which the bulb starts at ‘on’ state), hass entity is also turned on! Maybe check that out? If that’s the case, then the configuration I posted earlier is spot on!

your configuration works in general
I made some changes and it can detect the state as I want
now the problem is that it needs to blink to detect the state
trying to figure it out

Ok, did some more digging with my setup. So, in reality, when the lamp is cut off from mains in EITHER state, hassio can’t know it. BUT. If it’s cut in off state and it’s turned on, it also informs hass of that and the switch is turned on. If it’s cut in on state and returns, the value stays the same. But I’ve noticed something else that the Hass does. In EITHER state it was cut from mains, it can’t switch state as long as it’s offline!
So, a new type of “dirty”(again!) automation would be:

    - service: variable.set_variable
      data_template:
        variable: ikeacheck
        value: >
          {% if is_state('light.0x000b57fffe9151b8_light', 'off')
          0
          {% else %}
          1
          {% endif %} 
   - entity_id: light.0x000b57fffe9151b8_light
     service_template: >
          {% if is_state('light.0x000b57fffe9151b8_light', 'off')
          light.turn_on
          {% else %}
          light.turn_off
          {% endif %}
     data:
        brightness: 1
   - delay:
      seconds: 2
   - service: notify.android
      data_template: 
        message: >
          {% if is_state('light.0x000b57fffe9151b8_light', 'off' ) and is_state('variable.ikeacheck', '1') %}
          Bulb is online
          {% elif  is_state('light.0x000b57fffe9151b8_light', 'on' ) and is_state('variable.ikeacheck', '0') %}
          Bulb is online
          {% else%}
          Bulb is offline
          {% endif %} 
    - entity_id: light.0x000b57fffe9151b8_light
      service: light.turn_off       

I may have some typos, kindly check the code if it’s ok. I’ve added a variable too, so if you don’t already have it, install from https://github.com/rogro82/hass-variables. It will come in handy in many occasions you’ll need to store a value (either for tts, for checking entities against previous states etc).
So, what it does is:

  • Check the current state of the lamp and store it on a variable
  • Turn on or off, depending on state. Note that I added a brightness value to 1 so it will come on in minimum brightness so it won’t bother much. BUT when the light is already on and tries to turn off, it will show an error in logs! Be aware of that. It will still continue to run the automation, just reports an error because it cannot set brighness when turning off.
  • Wait 2 secs
  • Check the current state against the previous state stored in the variable. If it changed state, it means the lamp is working. If not, it’s offline or out of reach.
    And last, if the bulb was off and we turned it on with the automation, turn it off again.

Hope it helps. Just seems a LOT for checking just a light. Maybe a better solution is to replace your current lamp switch (button? I can’t recall how it’s named!) with a wifi one. That way, anytime someone presses the switch, making the lamp offline, you can have your automations check the state of the switch and act accordingly. It will be a way more clean way that trying to turn on and off the lamp.

1 Like

Thank you very much for your scripts.
I came almost to the same solution but with binary sensor for storing initial state.
It works perfectly for switched OFF bulb.
But if it is switched ON it will blink for around 3-4 seconds. (delay * 2)

Unfortunately hassio doesn’t return back brightness to the previous state if bulb is offline.
So you can not instead of switching ON and OFF change brightness to 1 step.

My final script is

- alias: Test bath bulb if on
  trigger:
    platform: time_pattern
    minutes: '/1'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: binary_sensor.bathroom_motion
        state: 'off'
      - condition: state
        entity_id: light.bathroom_light
        state: 'on'
  action:
    - entity_id: light.bathroom_light
      service: light.turn_off
    - delay:
        seconds: 2
    - service_template: >
        {% if is_state('light.bathroom_light', 'on') %}input_boolean.turn_off{% else %}input_boolean.turn_on{% endif %}
      entity_id: input_boolean.bath_bulb
    - entity_id: light.bathroom_light
      service: light.turn_on

If bulb has state ON, does’t matter cutoff or online, it checks every minute if it is online. But I don’t want the bulb blinking when someone is in the bathroom. So I check only if my motion sensor is in “off” state. I don’t care much about the delay so this automation works for me.
Special and huge thanks to @pvakerlis !!

1 Like

Nice!
I would change

- service_template: >
     {% if is_state('light.bathroom_light', 'on') %}input_boolean.turn_off{% else %}input_boolean.turn_on{% endif %}

to

- service_template: >
    {% if is_state('light.bathroom_light', 'on') %}
    input_boolean.turn_off
    {% else %}
    input_boolean.turn_on
    {% endif %}

Just to look clean, no other reason. If you’re fine with it, doesn’t matter anyway!
Did you check it with power cuts etc? Is it working properly?
Also, why do you turn on the light in the last line as long as noone is in the bathroom?

Works properly in all cases.
My light and ventilation has weird connections. It is really hard to change that, don’t ask why. So fixing hardware issues with the software.
All that code is to be able to use ventilation not only when the light is on, but also when humidity is high.

1 Like

Haha tell me about it! I got a similar issue but not with hardware, but a girlfriend! In the end I figured it’s easier to write extra 10 automations and train Home Assistant to react accordingly than train my girl! xD
Glad I could help!

1 Like

Hi guys,
I had the exactly same problem as you and I think I have found a solution… It is built into the zigbee2mqtt configuration but not available from the hassio add on config… Doesn’t require any scripts.
See https://community.home-assistant.io/t/zigbee2mqtt-light-still-showing-up-even-when-powered-off/140167

or, if you like clean templates:

- service_template: >
    input_boolean.turn_{{'off' if is_state('light.bathroom_light', 'on') else 'on'}}
1 Like

I actually got this to work without any automation. Just zigbee2mqtt configuration and correct implementation of the MQTT sensor in Home Assistant. The important part of the zigbee2mqtt configuration which I needed was as follows:

availability_timeout: 60

The above will make zigbee2mqtt ping your battery powered devices (IKEA light bulbs) every minute. Change it to something else if this is too often. More information about that here: https://www.zigbee2mqtt.io/information/availability.html

In the Home Assistant configuration I had to add the following to my MQTT sensor:

availability_topic: 'zigbee2mqtt/<your_device>/availability'

For my kitchen light, I use the following:

platform: mqtt
name: kitchen
state_topic: 'zigbee2mqtt/light_kitchen'
command_topic: 'zigbee2mqtt/light_kitchen/set'
availability_topic: 'zigbee2mqtt/light_kitchen/availability'
json_attributes_topic: 'zigbee2mqtt/light_kitchen'
brightness: true
schema: json

Turning the light on with the normal wall switch and having it on (virtually) in Home Assistant and than turning it off using the wall switch will… in Home Assistant it will still be on, but after (at most) 60 seconds when the light is pinged, it will turn into ‘unavailable’ in Home Assistant.