Create a new Entity from Values of Others

Hello -

As I continue to migrate my platform from Vera, I’ve stumbled across my latest issue.

I have two important temperature sensors in my HVAC system. I have a sensor before my AC coil and one after. In Vera, I created a device that displays the difference in these two sensors thereby giving me the delta (and performance) of my AC system.

Can someone explain how I can do a similar function in HA? I’m not afraid to RTFM, even. Just need to be pointed in the right direction.

Thanks!

The short answer is template integration. Create a template which leverages existing state and other information to define a brand new entity. So for your particular use case create a template entity like this:

template:
  - sensor:
      - name: Delta sensor
        state: "{{ states('sensor.one') | float(0) - states('sensor.two') | float(0) }}"

The slightly longer answer is you should take a look at the utility integrations. These integrations all take other state information and create new values out of it by running it through a formula or something like that. They are very useful for modifying the values that come from your devices.

1 Like

Thanks!

This is helpful. I was reading on templates as you answered. I used a slightly different form but basically doing the same thing (below).

Another related newb question: I see this sensor updates often (roughly every second or so). Should I throttle this somehow to save resources or do I not have to worry about it. If I need to throttle it (say: every 30 secs), how do I go about doing that?

- sensor:
  - name: "AC Performance"
    unit_of_measurement: "°F"
    state: >
      {% set beforecoil = states('sensor.hvac_return_temp_431') | float %}
      {% set aftercoil = states('sensor.hvac_discharge_temp_430') | float %}
      {{ (beforecoil - aftercoil) | round(1, default=0) }}

I wouldn’t worry about it. Just add state_class: measurement so it gets stored and managed as a statistic (see here for more info on that). It should be pretty efficient with DB space then.

If you’re thinking about runtime resources (like performance overhead of evaluating the template every 1 second) I wouldn’t really worry about it, that should be very lightweight. If you really want to because it updates way more then you care about and its simply too noisy then you can switch to a trigger template entity to take more control over how often it updates. Something like this would work:

template:
  - trigger:
      platform: time_pattern
      seconds: "/30"
    sensor:
      name: "AC Performance"
      unit_of_measurement: "°F"
      state_class: measurement
      availability: >-
        {{ states('sensor.hvac_return_temp_431') | float(-1000) > -1000 and
          states('sensor.hvac_discharge_temp_430') | float(-1000) > -1000 }} 
      state: >-
        {% set beforecoil = states('sensor.hvac_return_temp_431') | float %}
        {% set aftercoil = states('sensor.hvac_discharge_temp_430') | float %}
        {{ (beforecoil - aftercoil) | round(1, default=0) }}

This will only update the sensor every 30 seconds. It won’t actually check if the temperature sensors have updated in the past 30 seconds but from what you said that shouldn’t be an issue since they update every second. If that is an issue then you would have to put a last_updated check in and make the trigger a bit more complicated but it can be done.

Side note I noticed that you dropped the | float(0) from my template and just went with | float. Just an FYI a lot of times sensors will have a non-numeric state briefly around startup or in the case of a brief communication disconnect with the device. In those cases you’ll see errors if you are just using | float without a default specified. If you don’t want to default to 0 in those cases then I’d suggest an availability template like I did above to make your sensor go unavailable when its dependent sensors have a non-numeric state.

I also adjusted the default to acount for the fact that a fahrenheit sensor can legitimately have a negative value. But I figured -1000 is far outside the range of possibility and would only occur if you got a non-numeric state like unknown

3 Likes

Great feedback and advice!

I will make your suggested changes. Makes total sense!

This is kind of a silly use-case but it has caught my system performing inefficiently in the past. (low charge, cottonwood clogs, etc)

Thanks again.