Calculate average of another sensor for non-zero values

Hi,

I’m not exactly sure how to do this, other than it might involve the use of templates, but I need to calculate the average over 30 days for a sensor shown here BUT I do not want the zero values to be included into the average

Is this possible?

My first thought would be to get the sum over the period (history stats, long- term statistics, Riemann integral or utility meter), get how long the sensor has been zero (a template binary sensor with history stats, perhaps) — then divide sum by (period - zero-time).

You could use a filter sensor to create a new entity excluding the zeroes. Then average that entity.

@michaelblight that is a actually a good suggestion, but then I realized that when the value is zero, it will make the state 0.01 (low bound), or am I incorrect about this…will it include 0.01 in the average when it zero?

# Example configuration.yaml entry
sensor:
  - platform: filter
    name: "HVAC non-zero velocity average"
    entity_id: sensor.hvac_velocity
    filters:
      - filter: range
           if new_state < lower_bound:
             lower_bound
           new_state
      - filter: lowpass
        low_bound: 0.01
        precision: 2

@Troon this sounds complex, but I think it will work, unless the filter method works as it would be easier. I’ll have try to set this up.

I’m starting to think that this multi-component way is the only way to do this, @Troon

  1. Use utility meter (via yaml) to create a meter that runs for 6 months using crontab
  2. Create a binary sensor that is on or off when velocity is more than zero
  3. Somehow, extract the time the binary sensor has been on
  4. Create a 4th sensor that does the math

6 months average = Sensor 1 /( sensor 3 time)

Wow, this is complicated…lol

Yeah good point, the range filter will substitute whatever you specify as the minimum.

I’ve done something similar in the past using a template sensor that copies the source entity, unless it is zero (or unavailable/unknown) in which case it copies its previous value. Something along the lines of (not tested):

{% if (states('sensor.source_entity') == '0') %}
  {{ states('sensor.new_entity') }}
{% else %}
  {{ states('sensor.source_entity') }}
{% endif %}

You may also run into issues with “purge_keep_days”, unless you want to set it to 30. An alternative might be to use the above and have it store long-term statistics (by setting state_class: measurement) and then use ApexCharts to show you the average over a month using:

statistics:
  type: mean
  period: month

This will display the average in a chart, but you won’t be able to use the value elsewhere. And assuming you don’t mind a month rather than 30 days.

thanks, this is actually interesting!

But there two things that prevent me from this route: as you say, the purge keep days could be an issue (set to 14 days) and I recently removed Aapexcharts from my HA instance (which is too bad, because its a great integration), but it was just slowing down my frontend. Without it, its much faster now when I use the built-in frontend addon like history graph.

I came up with something that could work, and basically I’m using the google sheets integration so it dumps the data to an Excel file, which also graphs the data and then I can see it there. Here’s the automation for that:

alias: HVAC Velocity Data
description: HVAC Velocity Data for filter state determination over time
trigger:
  - platform: state
    entity_id:
      - sensor.hvac_velocity
    id: HVAC on
    not_to:
      - unknown
      - unavailable
      - none
      - "0"
    not_from:
      - unknown
      - unavailable
      - none
      - "0"
condition: []
action:
  - service: google_sheets.append_sheet
    data:
      config_entry: [redacted]
      worksheet: HVAC
      data:
        HVAC Velocity (m/s): "{{ states('sensor.hvac_velocity') | float(0) }}"
mode: single

Interestingly, despite the not_from and not_to, it still logs 0 when it turns off. I don’t know why, however, it does not log 0, 0 ,0, 0… when its off, because is not changing so it only logs 1 zero.

not sure why it does, despite the conditions.