Test if Tradfri light is available/reachable?

I just tried switching the light off using the wall switch and in the ikea app, the light is disabled. So I guess it’s possible to find out if a device is reachable. Please file an issue in the pytradfri repo, it has to be added there first before it can be put into hass.

exacly, that’s what I experience in the app, an why I thought it should be possible and asked. This the place to be: https://github.com/ggravlingen/pytradfri/issues ? consider it done: https://github.com/ggravlingen/pytradfri/issues/196

also, would it be an option to change the sensor into a remote? It now defaults to being a sensor.tradfri_switch, which is somewhat confusing since its accompanies the switch.tradfri_outlet…

I know the remote is in fact a switch, still, I feel it would be just that bit more intuitive if you’d call it a sensor.tradfri_remote, and make it consistent white the other remotes in Ha.

anyways, thx for considering!

I had this issue with Tradfri Lights not showing Unavailable HA seems to hold the last state the bulbs were in when the power is lost.

You can force the bulbs to show unavailable in HA if you issue any commands to them from HA when the lights are unavailable. I use tradfri bulbs with Xioma aqura light switches and I issue a 20 second delayed toggle command to the tradfri bulbs when the switch is turned off. I can then test for unavailable using the following template sensor which shows if the bulbs are in sync or not. So I know when I can issue commands to them as they take 60 seconds to show the correct state to HA when power is returned.

lrsync:
        friendly_name: 'Livingroom Light Sync'
        value_template: >-
          {% if is_state('light.lr1_2', 'unavailable') 
          and is_state('light.lr2', 'unavailable') 
          and is_state('light.lr3_2', 'unavailable') 
          and is_state('light.dr1', 'unavailable') 
          and is_state('light.dr2', 'unavailable') 
          and is_state('light.dr3', 'unavailable')  %}
            off
          {% elif not is_state('light.lr1_2', 'unavailable') 
          and not is_state('light.lr2', 'unavailable') 
          and not is_state('light.lr3_2', 'unavailable') 
          and not is_state('light.dr1', 'unavailable') 
          and not is_state('light.dr2', 'unavailable') 
          and not is_state('light.dr3', 'unavailable')  %}
            on
          {% else %}
            unknown
          {% endif %}

thanks, we established that indeed, see: Test if Tradfri light is available/reachable? · Issue #196 · home-assistant-libs/pytradfri · GitHub

not sure I understand your sensor though… I don’t use switches for the lights, there’s an automatic external light sensor cutting power.

btw, they do change automatically to their true state when power is re-instated. So I only need a sensor (for now, hope my issue tracker will be used to change HA communication with the lights to show unavailable automatically…) to check if they are reachable or not.

@ggravlingen Test if Tradfri light is available/reachable? · Issue #196 · home-assistant-libs/pytradfri · GitHub suggested this:

could trigger an automation that sends the last observed brightness level every five minutes or so? Just to trigger the unavailable state.

which is 1 option, but maybe some template sensor could do it too? Any thoughts on preferability?

simply creating a value_template {{states(‘light.outside’)}} or even {{state_attr(‘light.outside’,‘brightness’)}} doesn’t work, it keeps showing the last state or brightness setting. I guess we need to send a command for it to show unavailable

My issue is trying to keep the tradfri lights in sync. They are my main living room lights lights ( 6 bulbs) so I have a physical switch, so they behave as normal lights in case all my HA fails. I need to know what states the lights are in so I can delay any commands sent until they are ready. Sending command to early means some bulbs do not get dim commands and ends up in a mess

I too would like HA to state when unavailable. My main interface is Alexa so I can at least get alexa to state via voice and the sensor the lights are not ready to receive the dim commands. So a poll every 5 mins would help a little , but i’m try to sync 6 bulbs they take about 1 min to be ready once powered on via the switch.

that’s another good point indeed.
made a dedicated post for creating a automation for all lights see Create template for loop to set individual state per entity?

and rebuild this:

  - alias: "Dummy set Tradfri light to show unavailable"
    id: "Dummy set Tradfri light to show unavailable"
    #initial_state: 'on'
    trigger:
      platform: time
      minutes: '/5'
      seconds: 00
    condition: 
      condition: template
      value_template: >
        {{ states('light.outside') != 'unavailable'}}
    action:
      service: light.turn_on
      data_template:
        entity_id: light.outside
        brightness: >
          {{ state_attr('light.outside','brightness') | int}}

to work for all tradfri lights

HI,
giving this another thought: since Tradfri sends its states to HA autonomously (being a main difference with Hue, which has to be polled) shouldn’t showing unavailable be handled in the Tradfri part too?

The fact we can force it to happen (show unavailable) by issuing a command when power is cut, seems to indicate that also? HA relies on Tradfri to be correct about its states…

Unfortunately. I cannot get my aging brain to understand and code HA Automations . All my coding for this problem is in Python using Appdeamon. Hopefully, there is something useful in the code you can adapt.

Just a rundown on my setup

6 Tradfri lights in two sets of 3 connected to a single xiaomi aqara (ZigBee) switch
3 bulbs are in light group light.living_room_lights
3 bulbs are in light group light.dining_room lights

I use the above combination as xiaomi aqara does not support dimming. I did try using a wireless switch and leaving the tradfri bulbs permanently on and tried to avoid the whole issue. As they are the main lights they have to work, so after a couple of failure in HA I abandoned the wireless switch.

To keep things simple I have 3 predetermined dim modes Dark, relaxed and Bright. All controlled via Alexa or HA via an input select.

light_state:
    name: Living Room Light State
    options:
     - "Off"
     - Dark
     - Relaxed
     - Bright
    initial: "Off"
    icon: mdi:lightbulb

The first thing I needed was a reliable sensor to tell the automations the state of lights. With that you know if you can issue instructions to the lights or if you need to wait. So I use a template sensor.

lrsync:
        friendly_name: 'Livingroom Light Sync'
        value_template: >-
          {% if is_state('light.lr1_2', 'unavailable') 
          and is_state('light.lr2', 'unavailable') 
          and is_state('light.lr3_2', 'unavailable') 
          and is_state('light.dr1', 'unavailable') 
          and is_state('light.dr2', 'unavailable') 
          and is_state('light.dr3', 'unavailable')  %}
            off
          {% elif not is_state('light.lr1_2', 'unavailable') 
          and not is_state('light.lr2', 'unavailable') 
          and not is_state('light.lr3_2', 'unavailable') 
          and not is_state('light.dr1', 'unavailable') 
          and not is_state('light.dr2', 'unavailable') 
          and not is_state('light.dr3', 'unavailable')  %}
            on
          {% else %}
            unknown
          {% endif %}

As I have multiple lights in a two light groups, the sensor can only trigger in sync when all the lights are available. If any lights fail the test the sensor is in an Unknown state or if all fail it is off.

So when I issue a Dim command from Alexa or the Lovelace UI. I first check the sensor to see if I can issue the command. If the sensor is in sync no problem just issue the command to set the input select. If the lights are off I just abandon the actual call to the lights, but I set up the logic as if I turned on the lights ( set input select to dark, relaxed or bright ) and turn on the light switch and wait.

In Appdemon API not only can you trigger when an entity changes but you can determine it’s previous state. So when my Sync sensor triggers on. The first thing I do is test if its previous state was off or unknown, if so I know I must complete the command abandoned above.

So here are code fragments.

The physical light switch

# Program to sync Tradfri lights to Physical switch
import appdaemon.plugins.hass.hassapi as hass
class LRswitch(hass.Hass):
    def initialize(self):
        self.handle = None
        self.listen_state(self.lrswitch,"switch.wall_switch_158d00016cf4bc")
    def lrswitch(self, entity, attribute, old, new, kwargs):
        if new == "on" :
# if switch turned on ensure light group is turn on .There is a bug if lights are turned off and on quickly group is still off so lights appear off
            self.turn_on("light.all_living_room_lights")
            self.cancel_timer(self.handle)
            self.log("Living Room Light on ")
        if new == "off" :
# if switch is off . Turn off light group and ensure timer is turned off in case light switched toggled quickly 
            self.handle=self.run_in(self.switchoff,10)
            self.select_option("input_select.light_state","Off")
            self.log("Living Room Light Off")
# routine to force Tradfri lights into unavaliable 
    def switchoff(self,kwargs):
        if self.get_state("switch.wall_switch_158d00016cf4bc") == "off" :
            self.log("force lights unavailable")
# ensure all lights are toggled to force unavailable 
            self.toggle("light.living_room_lights")
            self.toggle("light.dining_room_lights")

Item select

 #
# This program actions an  Item select (Off Dark, Relaxed and bright ) on two set of Tradfri lights (living room and Dinning  3 in each set) 
#These bulbs are located  the same pysical room (open plan dining and living room)
# The program will  change  the brightness and colur temperture of both sets of lights or one set if the other set of bulbs is off.
#
#

import appdaemon.plugins.hass.hassapi as hass
class LRselector(hass.Hass):
    def initialize(self):
# Triggered if the superset of bulbs has changed state on or off
        self.listen_state(self.lrselect,"input_select.light_state")
    def lrselect (self, entity, attribute, old, new, kwargs):
#  Variable holds the default superset  of bulbs (6 bulbs) 
        self.ent = "light.all_living_room_lights"
        la = self.get_state(self.ent)
        lr = self.get_state("light.living_room_lights")
        dr = self.get_state("light.dining_room_lights")
# check to see if one subset of bulbs is on or off. If so changes the variable to the correct subset
        if lr == "on" and dr != "on" :
            self.ent = "light.living_room_lights"
        if lr != "on" and dr == "on" :
            self.ent = "light.dining_room_lights"
#check to sse which item of the item select has been selected
        if new == "Off" :
# resets item select and ensures all switches used by Alexa to change bulb state is off
            self.turn_off("switch.wall_switch_158d00016cf4bc")
            self.turn_off("input_boolean.dark")
            self.turn_off("input_boolean.relaxed")
            self.turn_off("input_boolean.bright")
# if switch is off no power to tradfri bulbs. Once power applied unstable for 60 seconds so delay selection util bulbs ready 
        if new != "Off" and self.get_state("switch.wall_switch_158d00016cf4bc") == "off" :
            self.turn_on("switch.wall_switch_158d00016cf4bc")
            self.log("switch triggered")
        if new == "Dark" :
# Selects dark settings and applys to all bulbs or subset. Set switch on for Alexa 
            if self.get_state("sensor.lrsync") == "on" :
                self.dark()
            else :
                self.log("talk sync")
                self.talk_sync()
            self.turn_on("input_boolean.dark")
        if new == "Relaxed" :
            if self.get_state("sensor.lrsync") == "on" :
                self.relaxed()
            else :
                self.log("talk sync")
                self.talk_sync()
            self.turn_on("input_boolean.relaxed")
# Selects relaxed settings and applys to all bulbs or subset. Set switch on for Alexa 
        if new == "Bright" :
            if self.get_state("sensor.lrsync") == "on" :
                self.bright()
            else :
                self.log("talk sync")
                self.talk_sync()
            self.turn_on("input_boolean.bright")
# Selects bright  settings and applys to all bulbs or subset. Set switch on for Alexa 

# routines to select bulbs warmth and brightness 
    def dark(self):
        self.call_service("light/turn_on", entity_id = self.ent, brightness = 25, transition = 6 , color_temp = 450)
        self.log("dark triggered")
    def relaxed(self):
        self.call_service("light/turn_on", entity_id = self.ent, brightness = 203, transition = 6 , color_temp = 367)
        self.log("relaxed triggered")
    def bright(self):
        self.call_service("light/turn_on", entity_id = self.ent, brightness = 254, transition = 6 , color_temp = 250)
        self.log("bright triggered")
    def talk_sync(self):
        self.call_service('media_player/alexa_tts', entity_id= "media_player.lr_dot", 
        message="Lights ar still syncronizing,please wait a moment before issuing further commands") 

Sync lights if unavailable

# Program to sync Tradfri lights when power restored
import appdaemon.plugins.hass.hassapi as hass
class LRsync(hass.Hass):
    def initialize(self):
        self.handle = None
        self.listen_state(self.lrsync,"sensor.lrsync",new="on")
    def lrsync(self, entity, attribute, old, new, kwargs):
# ensure sync only triggered if previous state was unknown ie just turned on
        if old == "unknown" :
            self.log("sync triggered")
# if triggered by switch turned on,  default lights to relaxed 
# Also ensure Alexa is silent as not invoked by mood item select
            if self.get_state("input_select.light_state") == "Off" :
                self.select_option("input_select.light_state", "Relaxed")
# run delayed option from item select now lights are in sync
            if self.get_state("input_select.light_state") == "Dark":
                self.dark()
            if self.get_state("input_select.light_state") == "Relaxed" :
                self.relaxed()
            if self.get_state("input_select.light_state") == "Bright":
                self.bright()
# default setting for dark ,relaxed and bright 
    def dark(self):
        self.call_service("light/turn_on", entity_id = "light.all_living_room_lights", brightness = 25, transition = 6 , color_temp = 450)
        self.log("dark triggered")
    def relaxed(self):
        self.call_service("light/turn_on", entity_id = "light.all_living_room_lights", brightness = 203, transition = 6 , color_temp = 367)
        self.log("relaxed triggered")
    def bright(self):
        self.call_service("light/turn_on", entity_id = "light.all_living_room_lights", brightness = 254, transition = 6 , color_temp = 250)
        self.log("bright triggered")

This works for me as I have control of the power source , I know when the lights are off.

Hope this helps

Perhaps the new force update service in the upcoming release would be helpful here?

yep it would save me setting up a timer to force the update . The trick is how quickly will HA update the state . My routines take about 25 seconds to get the state updated . The real pain is the length of time it takes when power is restored. 6 bulbs about 50 seconds to come “alive” and update all the groups with their state

I found a way to “force” a manually turned off IKEA trådfri bulb to show up as ‘unavailable’.

I have an automation that periodically runs.

If the state of the bulb in HA is on it will quickly turn off and then on again.
The bulb will then show as ‘unavailable’ if it was manually turned off and not reachable.

There is one drawback though that the light will quickly ‘pulse’ if it is actually turned on.

I also found out that it can stay in the ‘off’ state in HA even though it was successfully turned off and then on. I solved this by adding an extra turn on with a delay of a few seconds after the first turn on.

not really sure, but I find none of these ‘downsides’ using this:

  - alias: "Dummy set Tradfri light to show unavailable"
    id: "Dummy set Tradfri light to show unavailable"
    #initial_state: 'on'
    trigger:
      platform: time
      minutes: '/5'
      seconds: 00
    condition: 
      condition: template
      value_template: >
        {{ states('light.outside') != 'unavailable'}}
    action:
      service: light.turn_on
      data_template:
        entity_id: light.outside
        brightness: >
          {{ state_attr('light.outside','brightness') | int}}

Do I understand you correctly that if an IKEA bulb is listed in HA as on and you send turn on, it will change to unavailable if the power was previously cut with a manual wall switch?

Maybe it is the brightness part that do the trick? I will try that.

just to be precise, it will turn to unavailable if the power IS cut. Not if it WAS cut and is restored…

setting the brightness is a bit of a trick which comes in useful when turning the light on when it already is on and you don’t want to change it.

The |int is a second trick needed when the light is actually off (but is powered), for then is doesn’t have a brightness and is in fact None. Making it an int in that case allows the same automation to run.

the condition is obvious: if it has already been diagnosed as unavailable, there’s no need to run the automation to say so :wink:

I’ve added a little customization to show on the group of lights, making it clear in the frontend the group has no power:

group.parking_lights:
  templates:
    icon_color: >
      if (state === 'on') return 'rgb(251, 210, 41)';
      return 'rgb(54, 95, 140)';
    _stateDisplay: >
      if (entities['light.parking_light'].state === 'unavailable') return 'Power off';
      return '';

Thanks for the input. Setting the brightness did the trick.

Just to clarify regarding my use case.

I want the lights to go to unavailable as soon as the wall switch turn them off.
This works by periodically send on and brightness to the bulb if it has state on in HA. Then it will switch to unavailable if it is not reachable by HA.

If the wall switch turns them on again, HA automatically catches this and set the correct state without any automations involved.

Thanks again!

since your explaining an automation in your first line, how can you stop doing so in the second line? Im really interested how you’ve setup that, could you please share your code here?

With my testing once HA has the state unavailable , this will stay in this state until power is returned to the lights. You only need to force HA to get the unavailable state once.

So HA will remember the last state of the lights when power is cut . if you attempt to change the bulb state in HA when power is cut , it will then change the state of the bulb to unavailable. this stays in thiat state until power is restored and the lights resync with the tradri gateway hub. I have the advantage that I use a smart switch so I know when power is off , so I just wait 20 seconds and if the switch is still off i issue a light toggle to light group to force unavailable.

I use a template sensor (see above) and query this before I issue a command. If the sensor shows off I know there is no point in issuing the command as the lights are off. again with a smart switch I can just turn the lights on wait till they sync then issue the dim commands.

Without a smart switch you can run an automation against the template sensor . If the template sensor is on , you can prove they are on by changing brightness by 1% and back . If the lights are off , this will force unavailable. Therefore if the sensor is off the lights are really are off and you don’t need to test .

What we really need is HA to work this out for itself so the template sensor is always accurate.

exactly, so true.
I’ve tried to convey that to the Ikea dev team . Would be best, and should be rather easily done, since Tradfri pushes its states to HA (unlike Hue, which has to be polled)

Anyways, I think you are right with your above techniques establishing unavailable, though it seems rather complicated, and, needs a smart powerswitch.

Theres no need to change the brightness. Try my automation and you’ll see it works just fine, and nobody notices anything :wink:

1 Like

This is my configuration. It will with this timer configuration manage to set the bulb to unavailable within 30 seconds if the power is cut manually.

- id: '1542230014070'
  alias: Check Ikea Kitchen
  trigger:
  - hours: /1
    minutes: /1
    platform: time
    seconds: /30
  condition:
  - condition: state
    entity_id: light.kitchen_1
    state: 'on'
  action:
  - data_template:
      entity_id: light.kitchen_1
      brightness: >
        {{ state_attr('light.kitchen_1','brightness') | int}}
    service: light.turn_on

When the power comes back the light shows up as on again in HA without any custom automations.

2 Likes

sorry, but i don’t understand that would work given the condition you have:

  - condition: state
    entity_id: light.kitchen_1
    state: 'on'

state won’t be on if the light is unavailable, hence the action won’t trigger? Ive tried many situations, and ended using !=‘unavailable’… working in any situation