Circadian light with Philips Hue, independent from world clocks ;-)

REST service to update the HUE scenes:

rest_command:
  set_dynamic_hue_scene:
    url: "http://192.168.1.33/api/<YOUR_API_CODE_HERE>/scenes/{{scene_id}}/lightstates/{{light_id}}"
    method: "put"
    content_type: "application/json"
    payload: '{"on":true,"bri":{{states.sensor.circadian_brightness.state}},"ct":{{states.sensor.circadian_color_temp.state}}'

The service updates both color_temp and brightness for which I have another sensor defined. Unfortunately you have to update each single light within a scene and cannot update the whole scene with one call… :slightly_frowning_face:
Reference: https://developers.meethue.com/documentation/scenes-api#43_modify_scene

This automation kicks in every 10 minutes and sets the color_temp to the up-to-date value:

automation:
  - alias: "Update Hue Circadian Scenes"
    trigger:
      - platform: time
        minutes: "/10"
        seconds: 05
      
    action:
      - service: rest_command.set_dynamic_hue_scene
        data_template:
          scene_id: "mkaM4wCS0zTytUr"
          light_id: 1
      - service: rest_command.set_dynamic_hue_scene
        data_template:
          scene_id: "mkaM4wCS0zTytUr"
          light_id: 2

This automation updates all active lights every 10 minutes with the current color_temp value:

automation:
  - alias: "Update Circadian Lights"
    trigger: 
      - platform: time
        minutes: "/10"
        seconds: 00
      
    action:     
      - service: light.turn_on
        data_template:
          entity_id: >-
            {% for lamp in states.light if lamp.state == 'on' -%}
              {% if lamp.attributes.color_temp %}
                {% set currentvalue = lamp.attributes.color_temp %}
              {% elif lamp.attributes.xy_color %}
                {% set currentvalue = (-449*((lamp.attributes.xy_color[0]-0.332)/(lamp.attributes.xy_color[1]-0.1858))**3)+(3525*((lamp.attributes.xy_color[0]-0.332)/(lamp.attributes.xy_color[1]-0.1858))**2)-(6823.3*((lamp.attributes.xy_color[0]-0.332)/(lamp.attributes.xy_color[1]-0.1858)))+(5520.33) %}
                {% set currentvalue = (1 / currentvalue) * 1000000 %}
              {% else %}
                {% set currentvalue = 0 %}
              {% endif %}
              {% if (currentvalue - states.sensor.circadian_color_temp.state|float)|abs < 15 %}
                {{lamp.entity_id}},
              {% endif %}
            {% endfor -%}
            light.dummy
          color_temp: "{{ states.sensor.circadian_color_temp.state }}"
          transition: 3

As also other users have noticed, Hue lights may have either a color_temp attribute in HA or an xy color attribute, depending on the last action performed on them. So I have to check which one is defined. If it is xy, I have to convert it to Kelvin and then to mired. I found one formula here (although there seem to be also others): https://developers.meethue.com/comment/3046#comment-3046

Combining all lamps whose current values do not differ too much from the sensor value into one list is just beyond my programming skills, so I compose a list that always contains one dummy light. I would really appreciate if someone could show me a cleaner way to handle this (and also cater with the case that no light at all shall be updated)!

3 Likes