Logical AND in a template

Hi
I’m writing this in case someone is looking for a way to create a template sensor where at least one set of multiple conditions need to be true in order to return an ON state (or whichever state is needed)

YAML is a new language for me and there are lots of examples of using variables or if…elif etc, but I couldn’t find anything using a logical AND or a logical OR in templates. Automation conditions, yes, but not in templating, but I got there in the end and hopefully this will find it’s way to someone that needs it.

I kinda fudged this together, so if there’s a better/alternative way then please share.

The example below is creating a sensor to detect when specific people/devices from home have WiFi enabled on their device and are connected to the home WiFi.
(The idea being that the result can underpin any away/home logic for alarms lights etc…)

Each of the mobile devices to be tracked have their companion app “Wifi Connection” and “WiFi State” sensors activated.

Example people:
Dave - Samsung S22
Brian - Pixel 6
Helen - IPhone 12

Sensor name: someone_is_on_wifi

# Mobile Device Home WIFI Detection
- platform: template
  sensors:
    someone_is_on_wifi:
      friendly_name: Someone trusted is connected to our WiFi
      icon_template: >-
        {% if is_state('binary_sensor.dave_s22_wifi_state','on') and is_state('sensor.dave_s22_wifi_state','MyHomeWIFIName') %}
        mdi:wifi
        {% elif is_state('binary_sensor.brian_pixel6_wifi_state','on') and is_state('sensor.brian_pixel6_wifi_connection','MyHomeWIFIName') %}
        mdi:wifi
        {% elif is_state('binary_sensor.helen_ip12_wifi_state','on') and is_state('sensor.helen_ip12_wifi_connection','MyHomeWIFIName') %}
        mdi:wifi
        {% else %}
        mdi:wifi-off
        {% endif %}
      value_template: >-
        {% if is_state('binary_sensor.dave_s22_wifi_state','on') and is_state('sensor.dave_s22_wifi_state','MyHomeWIFIName') %}
        on
        {% elif is_state('binary_sensor.brian_pixel6_wifi_state','on') and is_state('sensor.brian_pixel6_wifi_connection','MyHomeWIFIName') %}
        on
        {% elif is_state('binary_sensor.helen_ip12_wifi_state','on') and is_state('sensor.helen_ip12_wifi_connection','MyHomeWIFIName') %}
        on
        {% else %}
        off
        {% endif %}

This’ll be obvious to many, but like all knowledge, it’s easy when you already know the answer :wink:

2 Likes

FYI, it is in the documentation:

https://www.home-assistant.io/docs/configuration/templating/

If you trying to build presence detection, then device trackers/persons/zones are normally the way to go. Device trackers are normally used to follow the whereabouts of devices (e.g. through connecting to wifi). If you link device trackers to persons, you can use zones to see the number of people in that zone. Home is a zone that Home Assistant creates by default, but you can have more. You can also link more than one device tracker to a person to improve reliability, accuracy and speed.

It also seems like you are using a sensor to do the same kind of things that groups are meant for. If you create a group with the right entities, you can look at the state of the group to check a combination of entities. Groups can be used to see if at least one of the members is in a certain state, or if all of the members are in a certain state. It does require binary sensors per person though, or device trackers like above.

Maybe these features will get you where you want to be faster and better?

Thanks @tom_l
I think I came across that page in my searching, but it didn’t give any formatted examples using the logic in in a way I could relate to Home Assistant. Hopefully the simple example I posted will help someone Googling for a sample.

Thanks also @Edwin_D
That sounds interesting. Do you have an example you could share?

Put brackets around each statement you want to AND together as well as the whole “if”:

BROKEN:
{% if is_state('binary_sensor.dave_s22_wifi_state','on') and is_state('sensor.dave_s22_wifi_state','MyHomeWIFIName') %}

CORRECT:
{% if ( (is_state('binary_sensor.dave_s22_wifi_state','on')) and (is_state('sensor.dave_s22_wifi_state','MyHomeWIFIName')) ) %}    

I named a lot of things, so that is a tall order :slight_smile: But to be honest, pretty much no code is required. A device tracker is something you’d get by for instance installing an integration for your router. If there isn’t one you could use a ping sensor, that is the only thing that would require a tiny bit of code.

The settings page lists persons, where you can add persons and select the tracker that corresponds to the person. If you are ok with GPS tracking, just installing the companion app and logging in as a user creates both a device tracker and links it to you as a person. Zones are created using the edit button on the map. If you want to create a group, you can do so in settings - helpers. Create a group of persons to see if anyone is at home. From then on you have all you need to create automations in the GUI too. Creating automations in the GUI and looking at the code is a good way to start learning how to do it in code too.

A lot has changes in the last year, both with HA helpers and how I do templating :smiley:

I look at it now and immediately see the option for brackets that solaredge picked up on (doesn’t need doubles tho) as well as a logical OR that could have been used instead of 3 individual entries. I have a feeling I did it this way to keep it simple and to show the “elif”, but it’s too long ago to remember.

Still, I hope someone searching for some formatting for logical operands finds it and it helps get them on their way.