Bitwise operation in a template Template

I’ve got an mqtt sensor…

  - platform: mqtt
    unique_id: sunny_mqtt_0019
    name: "Owl Intuition Heating State"
    state_topic: "tele/owl/heating"
    value_template: "{{value_json['Heating'].State}}"
    force_update: true

The state can be any number 0-7. Bit 1 means the Hall Thermostat is demanding heating.
I want to create a binary template sensor that does a bitwise AND with 1 to tell me that heating is or isn’t being demanded. I’ve looked at the template documentation but cannot work out the syntax.
I could also do it with something like in(1, 3, 5, 7) or even just a series of ifs, but feel a bitwise operation is the most elegant solution.
Can someone help me here?

There’s a bitwise_and filter. https://www.home-assistant.io/docs/configuration/templating/#numeric-functions-and-filters

You could also just check if the value is even or not with modulo 2, if bit 1 is set it’ll be an odd number.

{% set my_state = "2" %}
{{ my_state | int }} & 1 = {{ (my_state | int | bitwise_and(1))}} -> {{ (my_state | int | bitwise_and(1)) == 1 }}
{{ my_state | int }} % 2 = {{((my_state | int) % 2) }} -> {{ ((my_state | int) % 2) == 1 }} 

Renders:

2 & 1 = 0 -> False
2 % 2 = 0 -> False
{% set my_state = "5" %}
{{ my_state | int }} & 1 = {{ (my_state | int | bitwise_and(1))}} -> {{ (my_state | int | bitwise_and(1)) == 1 }}
{{ my_state | int }} % 2 = {{((my_state | int) % 2) }} -> {{ ((my_state | int) % 2) == 1 }} 

Renders:

5 & 1 = 1 -> True
5 % 2 = 1 -> True

I think your original proposal is pretty simple though. For such a small set of numbers to check, it won’t make much of a difference.

{{ (my_state | int) in [1, 3, 5, 7] }}
1 Like

Thanks, that got me going.

I’ve got the following working, you can see it uses the modulo 2 method.

binary_sensor:
  - platform: template
    sensors:
      hall_thermostat_demand:
        friendly_name: Hall Thermostat Demand
        value_template: '{% if states("sensor.owl_intuition_heating_state") | int % 2 == 1 %}  on {% else %} off {% endif %}'

It also works with the in(1,3,5,7) test and the bitwise_and(1). I struggled with the last one because I missed the second pipe! It also doesn’t need the ‘==1’ as, like other languages, a non-zero result means true. I’ve now discovered in Developer Tools, the Template Editor which makes crafting Templates so much quicker.
So, both these templates work too.

        value_template: '{% if states("sensor.owl_intuition_heating_state") | int in(1,3,5,7) %}  on {% else %} off {% endif %}'
        value_template: '{% if states("sensor.owl_intuition_heating_state") | int | bitwise_and(1) %}  on {% else %} off {% endif %}'

For a template binary_sensor, the state only needs to resolve to True or a positive number for it to be considered on (any other value is off). IMO, that’s simpler and cleaner then if/else logic.

Well that took a lot of wasted effort before I tried…

{{ states("sensor.owl_intuition_heating_state") | int | bitwise_and(1) }}

{{ ...}} not {%...%}

What a weird language this is. I should add that this is all new to me.