Trigger based on charging / location status of multiple iphones

Hi there!

I’m looking for help with an automation.

Some background. We’re a family of 3, all with iPhones that we tend to put on charge when we go to bed, and take off charge when we get up. I’d like to trigger a ‘go to bed’ routine when the last phone that is at home (eg if I’m away on business then my phone on/off charge status is not relevant / ignored) is put on charge, and a ‘get up’ routine when the last phone that is at home is taken off charge.

I’ve already set up all our phones to trigger ‘update sensors’ via the HA app on the iphone so HA knows when phones are taken off / put on charge, now I need to set up an automation trigger that would cater for the logic of ‘last phone on charge’ / ‘last phone off charge’.

Does anyone have an elegant solution to this? Ideally it would cater for other phones (eg visitors that come to stay or house sit), so I’m thinking that setting up a helper or two is likely to be part of the solution.

Thanks in advance for any helpful suggestions! :pray:

I spend the evening tinkering and here is the solution i came up with for your problem.

{%- set device_names = states.device_tracker
    | selectattr('state', 'eq', 'home')
    | selectattr('attributes.latitude', 'defined')
    | map(attribute='entity_id') 
    | map('replace', 'device_tracker.', '') 
    | list %}
    
{%- set all_ac = namespace(value=True) %}

{%- for device in device_names %}
  {%- set charger_type = states.sensor 
      | selectattr('entity_id', 'equalto', 'sensor.' + device + '_charger_type')
      | map(attribute='state') 
      | first %}
      
  {%- if charger_type != 'ac' %}
    {%- set all_ac.value = False %}
  {% endif %}
  
{%- endfor %}

{{ all_ac.value }}

Explanation

  • device_names initialization:

    • Retrieves the entity IDs of all devices in the “home” state.
    • With defined latitude attributes to select only mobile devices (devices with GPS) in my case.
  • all_ac initialization:

    • all_ac is defined as a namespace variable with an initial value of True.
    • The scope of a variable defined within a for-loop is limited to the for-loop. A variable defined outside a for-loop can be modified within a for-loop but that value isn’t preserved outside of the for-loop. To get the variable’s scope to cover inside and outside the for-loop, use namespace .
  • Loop through devices:

    • Iterates over each device in device_names.
    • Retrieves the charger type for each device using states.sensor.
    • Checks if the charger type is not ‘ac’.
    • If the charger type is not ‘ac’, updates all_ac.value to False.
  • Output:

    • Outputs all_ac.value, which will be True if all devices have charger type ‘ac’, otherwise False.

Example Output

  • If the devices have charger type statuses as indicated:

    • device1: ‘usb’
    • device2: ‘ac’
    all_ac.value: false
    
  • If the devices have charger type statuses as indicated:

    • device1: ‘ac’
    • device2: ‘ac’
    all_ac.value: true
    

This template ensures that the sensor accurately reflects the charger type status for each device and correctly updates the all_ac status based on the presence of ‘ac’ charger types for all devices. Adjust the template as needed to match your specific device and sensor naming conventions.

zone.home has the count of devices in your home zone. you already said you have sensors for when each phone is charging. so you can trigger on when the count of charging sensors==zone.home and when the count of charging sensors=0.

you should also constrain to reasonable night times and such to not trigger if everyone happens to charge in the middle of the day.

sounds like you are pretty config capable and was just looking for some direction, but if you need yaml coding help, holler

  1. I am not the TS but just someone who had the same goal, I took your advise to ensure that there need to be at least more devices then 0, to account for the all_ac to allways report true if no devices are in the network.
  2. I added a time constraint in the automation to only activate after 21:30.
{%- set device_names = states.device_tracker
    | selectattr('state', 'eq', 'home')
    | selectattr('attributes.latitude', 'defined')
    | map(attribute='entity_id') 
    | map('replace', 'device_tracker.', '') 
    | list %}
    
{%- set all_ac = namespace(value = true) %}

{%- if device_names | length > 0 %}
  {%- for device in device_names %}
    {%- set charger_type = states.sensor 
        | selectattr('entity_id', 'equalto', 'sensor.' + device + '_charger_type')
        | map(attribute='state') 
        | first %}
        
    {%- if charger_type != 'ac' %}
      {%- set all_ac.value = false %}
    {%- endif %}
  {%- endfor %}
{%- else %}
  {%- set all_ac.value = false %}
{%- endif %}

{{ all_ac.value }}