Displaying bit-based errors from a sensor (from decimal to binary + dictionary of errors)

Hi everyone,

I’m trying to create a template in Home Assistant that reads a numeric sensor (‘sensor.defro_bledy’), converts its value to binary, calculates which bits are set to ‘1’ (counting from the right), and then displays corresponding error messages from a dictionary.

For example, if the sensor value is ‘34’, the binary representation is ‘100010’. I expect the active bit positions to be ‘[2, 6]’, which should then map to the following errors:

  • Bit 2 → “Błąd wentylatora nawiewu”
  • Bit 6 → “Błąd czujnika temperatury wyrzut”

Here is what I have so far, this part correctly calculates the bit positions:

{% set val = states('sensor.defro_bledy') | int(0) %}
{% set binary = '{0:b}'.format(val) %}
{% set data = namespace(positions=[]) %}

{% for i in range(binary | length) %}
  {% if binary[-1 - i] == '1' %}
    {% set data.positions = data.positions + [i + 1] %}
  {% endif %}
{% endfor %}

Value: {{ val }}
Binary: {{ binary }}
Bit positions: {{ data.positions }}

I also have a dictionary of errors:

{% set errors = {
    1: "Błąd wentylatora wywiewu",
    2: "Błąd wentylatora nawiewu",
    3: "Błąd czujnika temperatury zewnętrznej",
    4: "Błąd czujnika temperatury wywiewu",
    5: "Błąd czujnika temperatury nawiewu",
    6: "Błąd czujnika temperatury wyrzut",
    7: "Błąd czujnika temperatury nawilżacza",
    10: "Błąd czujnika przepływu wywiewu",
    11: "Błąd czujnika przepływu nawiewu",
    12: "Błąd czujnika nawilżacza",
    13: "Błąd czujnika nagrzewnicy GWC",
    14: "Błąd czujnika temperatury nagrzewnicy nawilżacza",
    15: "Błąd wentylatora wywiewu przepływ",
    16: "Błąd wentylatora nawiewu przepływ"
} %}

I’ve tried combining these to show the active errors like this:

{% set active_errors = [] %}
{% for pos in data.positions %}
  {% set pos_str = pos | string %}
  {% if errors[pos_str] is defined %}
    {% set active_errors = active_errors + [errors[pos_str]] %}
  {% endif %}
{% endfor %}

Active errors: {{ active_errors }}

But I keep getting an empty list, even though I know some bits are set. I’ve tried using integer and string keys in the dictionary, ‘append()’ vs list concatenation, and different looping techniques, yet nothing seems to work.

My questions:

  1. What is the correct way to map bit positions to a dictionary of errors in Home Assistant templates?
  2. Is there a better approach to calculate and display active errors from a numeric sensor that represents flags?

Any guidance or working examples would be greatly appreciated.

Best regards,
Piotr

As you did in your first block of code, you need to use a namespace to update a list in a loop, and remove the string conversion:

{% set ns = namespace(active_errors=[]) %}
{% for pos in data.positions %}
  {% if errors[pos] is defined %}
    {% set ns.active_errors = ns.active_errors + [errors[pos]] %}
  {% endif %}
{% endfor %}

Active errors: {{ ns.active_errors }}

For safety, I think I’d prefer to make the dictionary keys into strings, then re-include your string conversion. Like this:

{% set errors = {
    "1": "Błąd wentylatora wywiewu",
    ^^^
1 Like

Thank you so much!

This code seems to work:

{% set val = states('sensor.defro_bledy') | int(0) %}
{% set binary = '{0:b}'.format(val) %}
{% set data = namespace(positions=[]) %}

{% for i in range(binary | length) %}
  {% if binary[-1 - i] == '1' %}
    {% set data.positions = data.positions + [i + 1] %}
  {% endif %}
{% endfor %}

{% set errors = {
    1: "Błąd wentylatora wywiewu",
    2: "Błąd wentylatora nawiewu",
    3: "Błąd czujnika temperatury zewnętrznej",
    4: "Błąd czujnika temperatury wywiewu",
    5: "Błąd czujnika temperatury nawiewu",
    6: "Błąd czujnika temperatury wyrzut",
    7: "Błąd czujnika temperatury nawilżacza",
    10: "Błąd czujnika przepływu wywiewu",
    11: "Błąd czujnika przepływu nawiewu",
    12: "Błąd czujnika nawilżacza",
    13: "Błąd czujnika nagrzewnicy GWC",
    14: "Błąd czujnika temperatury nagrzewnicy nawilżacza",
    15: "Błąd wentylatora wywiewu przepływ",
    16: "Błąd wentylatora nawiewu przepływ"
} %}

{% set ns = namespace(active_errors=[]) %}
{% for pos in data.positions %}
  {% if errors[pos] is defined %}
    {% set ns.active_errors = ns.active_errors + [errors[pos]] %}
  {% endif %}
{% endfor %}

Value: {{ val }}  
Binary: {{ binary }}  
Bit positions: {{ data.positions }}  
Active errors: {{ ns.active_errors }}

I tried with making the dictionary keys as strings but it didn’t work - nothing was returned for active errors. Like you mentioned:

{% set errors = {
    "1": "Błąd wentylatora wywiewu",
    ^^^

Maybe I wasn’t clear enough — if you do that, you need to put your pos_str variable back in too.

1 Like