Please help me fix the sensors in my configuration.yaml & teach my what i'm doing wrong!

I have tried creating custum sensors in my config.yaml and am utterly failing.

Currently I have three sensors defined, the first one works but the second and third don’t even show up as an entity. I suspect i’m doing something fundamentally (and probably a bunch of small things too) wrong with the structure of my .yaml but I am at my witts end.

Please help me and tell me what i’m doing wrong, so I can learn. I’m an absolute noob when it comes to coding, so please bear with me.
Thanks in advance!

Here is my file:

# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

template:

  - sensor:
    - name: "Technical & Garden | Power"
      unit_of_measurement: W
      icon: mdi:lightning-bolt
      state: >-
        {{ (states('sensor.shellyproem50_08f9e0e5c190_em0_power')|float -
        states('sensor.shellyproem50_08f9e0e5c190_em1_power')|float )|round(1) }}

  - sensor:
    - name: "Pellet heating status"
      state: >-
          {% if states('sensor.shellypro4pm_08f9e0e9ed64_switch_2_power') |float < 3) %}
            off
          {% elif states('sensor.shellypro4pm_08f9e0e9ed64_switch_2_power') |float < 10) %}
            'stand by'
          {% elif states('sensor.shellypro4pm_08f9e0e9ed64_switch_2_power') |float < 65) %}
            'cooling down'
          {% elif states('sensor.shellypro4pm_08f9e0e9ed64_switch_2_power') |float < 250) %}
            'heating'
          {% elif states('sensor.shellypro4pm_08f9e0e9ed64_switch_2_power') |float > 250) %}
            'ignition phase'
          {% else %}
            'unavailable'
          {% endif %}

  - sensor:
    - name: "Wind Direction TXT"
      state: >-
        {% set dir = int(states('sensor.gw2000a_wind_direction') | float  %}
        {% set navDir = [ 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N' ] %}
        {{ navDir[int(dir/22.5)] }}

You need to supply availability criteria and/or defaults for your int and float filter functions.
This is especially true for sensor entities with a unit_of_measurement since they expect a numeric value and will error out if the template does not render one.

# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

template:
  - sensor:
      - name: "Technical & Garden | Power"
        unit_of_measurement: W
        icon: mdi:lightning-bolt
        availability: >-
          {{ has_value('sensor.shellyproem50_08f9e0e5c190_em0_power') and
          has_value('sensor.shellyproem50_08f9e0e5c190_em1_power') }}
        state: >-
          {{ (states('sensor.shellyproem50_08f9e0e5c190_em0_power') | float(0) -
          states('sensor.shellyproem50_08f9e0e5c190_em1_power') | float(0) ) | round(1) }}

      - name: "Pellet heating status"
        availability: "{{ has_value('sensor.shellypro4pm_08f9e0e9ed64_switch_2_power') }}"
        state: >-
          {% set power = states('sensor.shellypro4pm_08f9e0e9ed64_switch_2_power') | float(0) %} 
          {% if  power < 3 %}
            off
          {% elif power < 10 %}
            stand by
          {% elif power < 65 %}
            cooling down
          {% elif power < 250 %}
            heating
          {% elif power > 250 %}
            ignition phase
          {% endif %}
      
      - name: "Wind Direction TXT"
        availability: "{{ has_value('sensor.gw2000a_wind_direction') }}"
        state: >-
          {% set dir = states('sensor.gw2000a_wind_direction') | int(0)  %}
          {% set navDir = [ 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N' ] %}
          {{ navDir[ (dir/22.5) | int(0) ] }}

Thank you so much! This looks a lot cleaner already!

So I only have to state “sensor” once and then each “name” creates a new sensor?

I now copy-pasted your yaml and it tells me all is fine, I save and reaload all yaml in dev tools. First sensor still works however the two thereafter still do not show up anywhere. So no improvement unfortunately…

There were a couple extraneous ) that I neglected to remove… I have fixed it above.

Also, try restarting HA instead of using the “Reload all YAML” option.

Wow. It just works. You are amazing. Thank you so much!
I will dissect all you changes to understan what I did wrong and learn.

You could clean it up a bit more by removing the defaults on the float and int filters, as you already check on their (numeric) state in the availability template. :slight_smile:

Thanks for you input. However I’m unfortunately too much of a noob to understand what it means… :see_no_evil:

So I tried to understand what you did and am now setting up another, similar sensor for an electric Boiler (for when the aforementioned pellet heating is not turned on in summer).

This is what I came up with. The sensor does show up in the UI, however it is “unavailable”. I suppose bringing in another sensor for the “off” state somehow messed things up, but no matter what I try, I’m too coding-retarded to make it work…

      - name: "Electric boiler status"
        unique_id: electric_boiler_status
        availability: >-
            {{ has_value('sensor.shellypro4pm_08f9e0e9ed64_switch_3_power') }} and
            has_value('switch.shellypro4pm_08f9e0e9ed64_switch_3') }}
        state: >-
          {% if is_state('switch.shellypro4pm_08f9e0e9ed64_switch_3', 'off') %}
            off
          {% set power = states('sensor.shellypro4pm_08f9e0e9ed64_switch_3_power') | float(0) %} 
          {% elif  power < 20 %}
            standby
          {% elif power > 20 %}
            heating
          {% endif %}

After staring at the code for an hour I finally noticed the additional }} in the availability test.

This gives me “off” when the shelly switch is off, but still “unavailable” when the boiler is turned on and in standby or heating.

      - name: "Electric boiler status"
        unique_id: electric_boiler_status
        availability: >-
            {{ has_value('sensor.shellypro4pm_08f9e0e9ed64_switch_3_power') and
            has_value('switch.shellypro4pm_08f9e0e9ed64_switch_3') }}
        state: >-
          {% if is_state('switch.shellypro4pm_08f9e0e9ed64_switch_3', 'off') %}
            off
          {% set power = states('sensor.shellypro4pm_08f9e0e9ed64_switch_3_power') | float(0) %} 
          {% elif  power < 20 %}
            standby
          {% elif power > 20 %}
            heating
          {% endif %}

You can’t “embed” that {% set power in the middle of the if block like that. Either set first:

{% set power = states('sensor.shellypro4pm_08f9e0e9ed64_switch_3_power') | float(0) %}
{% if is_state('switch.shellypro4pm_08f9e0e9ed64_switch_3', 'off') %}
  off
{% elif  power < 20 %}
  standby
{% elif power > 20 %}
  heating
{% endif %}

or use two nested blocks:

{% if is_state('switch.shellypro4pm_08f9e0e9ed64_switch_3', 'off') %}
  off
{% else %}
  {% set power = states('sensor.shellypro4pm_08f9e0e9ed64_switch_3_power') | float(0) %}
  {% if  power < 20 %}
    standby
  {% elif power > 20 %}
    heating
  {% endif %}
{% endif %}

However, I’d write it thus:

{{ 'off' if is_state('switch.shellypro4pm_08f9e0e9ed64_switch_3', 'off')
   else 'standby' if states('sensor.shellypro4pm_08f9e0e9ed64_switch_3_power')|int(0) < 20
   else 'heating' }}

which also behaves if the power is exactly 20.

Oh, I see. Thank you so much.
This is great eductional material.

…and of course your elegant code works perfectly!