Hi all,
I am finished with the initial implementation of the “Follow Me Lights” automation and wanted to share the solution for those who may be interested in a similar setup.
Use Case:
When only one person is present in the house, we want the lights to “follow” the person as they move around the house and only be ON in the room where person is located. As they enter a particular room, the lights in that room turn ON and lights in every other room in the house immediately turn OFF. Thus it will feel as the lights follow the person around the house.
General Implementation Description:
Prerequisites :
- You have motion sensors in every room you want covered in the automation.
- You have already implemented presence detection in your HA (either router or own tracks, or others)
General Solution Description:
Using our presence detection sensors, we will determine how many people are present in the house. If we can detect only ONE person in the house, we will trigger “follow me lights” mode ON. Once we detect more than ONE person in the house, we will trigger “follow me lights” mode OFF.
When “follow me lights” mode is ON, the following will occur : Every time we detect motion in a particular room, we will trigger a script that will turn a specific light in this room ON and will compute the list of lights to turn off. It will then turn off all “other” lights in the house. At this moment, I have a hard-coded list of “all lights” I want to be affected. It is very easy to turn that list into a dynamic list pulled from one of those “light.all” groups , but I only wanted to affect some main ceiling lights in my house and ignore the small lights that also exist.
Finally, the automation presented also use a secondary condition of “motion detection” switch being ON and sun being under horizon. So, follow me lights is a secondary condition to “motion detection” being ON. When Motion detection is OFF, the lights don’t respond to movement around the house at all. I turn off motion detection from a different automation when we sit to watch movies and I don’t want lights to come ON if anybody moves off the couch to fetch something.
Automation Code:
First we create a couple of “input_boolean” switches. These are used to enable/disable motion detection and follow me lights mode:
motion_detection:
name: Motion Detection
initial: on
icon: mdi:car
follow_me_lights:
name: Follow Me Lights
initial: off
icon: mdi:lightbulb
Next we create a template sensor that determines how many people are home.
Note here we assume you already setup your device_trackers and can determine when somebody is home.
This sensor will automatically be set to “everybody” when both people are home and to “somebody” when only one person is home.
- platform: template
sensors:
eveybody_home:
friendly_name: 'Everyone Home'
value_template: >-
{% if is_state("device_tracker.dmitry", "home") and is_state("device_tracker.eileen", "home") -%}
everybody
{% elif is_state("device_tracker.dmitry", "home") or is_state("device_tracker.eileen", "home") -%}
somebody
{%- else -%}
nobody
{%- endif -%}
Next we create an automation to flip the “follow me lights” input_boolean to ON, when everybody_home sensor changes it’s state to “somebody” and we flip the input_boolean to OFF when it changes to “everybody” or “nobody”
- alias: 'Follow Me Lights Mode On'
trigger:
platform: state
entity_id: sensor.eveybody_home
to: 'somebody'
action:
service: input_boolean.turn_on
data:
entity_id: input_boolean.follow_me_lights
- alias: 'Follow Me Lights Mode Off'
trigger:
platform: state
entity_id: sensor.eveybody_home
to: 'everybody'
action:
service: input_boolean.turn_off
data:
entity_id: input_boolean.follow_me_lights
Next we create a script to turn ON a specific light, which is passed into a script as a parameter:
follow_me_lights_on:
sequence:
- service: homeassistant.turn_on
data_template:
entity_id: >
{{ light_id }}
- service: switch.turn_off
data_template:
entity_id: >
{%- set light_remove = [ light_id ] %}
{%- set all_lights = ['switch.bedroom_ceiling_light_switch' , 'switch.family_room_ceiling_light_switch', 'switch.office_lights_switch_2' ] %}
{%- if is_state('input_boolean.follow_me_lights', 'on') -%}
{%- for light in all_lights if (light not in light_remove) -%}
{{light}}{% if not loop.last %}{{", "}}{% endif %}
{%- endfor -%}
{%- else -%}
switch.null.switch
{%- endif -%}
- service: light.turn_off
data_template:
entity_id: >
{%- set light_remove = [ light_id ] %}
{%- set all_lights = ['light.living_room_ceiling_light_1_level', 'light.living_room_ceiling_light_2_level' ] %}
{%- if is_state('input_boolean.follow_me_lights', 'on') -%}
{%- for light in all_lights if (light not in light_remove) -%}
{{light}}{% if not loop.last %}{{", "}}{% endif %}
{%- endfor -%}
{%- else -%}
light.null.light
{%- endif -%}
In the above script: light_id is being passed in that this will be the light to turn ON… the all_lights variable is set with a list of hardcoded lights and switches I want to affect. (again, this list could be generated dynamically, but I only want to affect a few specific lights… Another complication here was that we must handle “switches” and “lights” separately in two separate loops… I could not figure out how to do it in one loop as homeassistant.turn_on service was not working on both types combined.
PROBLEM with ABOVE SCRIPT: As you see I am calling a non-existing: “light.null.light” entity_id in case “follow me light switch” is OFF. If I did not call something on the “else” part of statement , the YAML would fail. I do not know how to solve this issue at this time. If somebody can find a nice solution to this, please let me know.
Is there a way to have some sort of “/dev/null” type of call, to call a “null” switch to turn off, to have HA to just ignore it?
At this moment, if NO other lights are ON at the time, I will call to turn off the “light.null.light” just to make HA happy. so as a result, I have “ERROR” messages in the log file every time, there are NO lights to turn-off…
This ELSE also will be needed, if I wanted to check if the light is already OFF and only turn it OFF if it was ON.
If all the OTHER lights were already OFF, again we would face the same issue and needed to call some service in the “else” part of the “if” condition.
Finally, for every room that you want to be part of this we create an automation triggered by motion detection:
- alias: Familiy Room Lights ON
trigger:
platform: state
entity_id: sensor.family_room_motion
to: 'Burglar'
condition:
condition: and
conditions:
- condition: state
entity_id: sun.sun
state: 'below_horizon'
- condition: state
entity_id: input_boolean.motion_detection
state: 'on'
action:
service: script.follow_me_lights_on
data_template:
light_id: switch.family_room_ceiling_light_switch
In the above automation: we detect motion, check conditions: is sun sunset, do we have “motion detection” on?
If the answer is yes, we call our script “follow_me_lights_on” and we pass in the entity_id of the light we want to turn on.
And that is it folks! Enjoy the automation, comment on the ways to further improve it and let the lights follow you