Average temperature values

Hi
have a number of temperature sensors around the house and am trying a way to average the value.
I have written the below, it seems to work sometimes, but not others, I think this must be dues to the listen_state function as I assume this is best used for discrete state changes, not numbers.
What is the best way to run this so it will check for temp changes, without constant polling?

class AverageStateValue(hass.Hass):

    def initialize(self):
        # Subscribe to sensors
        for sensor in self.args["sensors"]:
           self.listen_state(self.change_detected, sensor)
        

    def change_detected(self, entity, attribute, old, new, kwargs): 
        sensor_value = []
        for sensor in self.args["sensors"]:
           theVal = self.get_state(sensor)
           if self.isNumber(theVal) and int(theVal) != 0: 
                  sensor_value.append(float(theVal))
                  
        self.log(sensor_value)
        averageValue = round(self.calcAverage(sensor_value),0)          
        self.set_state(self.args["averagesensor"], state = averageValue, attributes = {"friendly_name": self.args["averagefriendlyname"],"unit_of_measurement": self.args["averageunitmeasurement"], "icon": self.args["averageicon"]  })

    def calcAverage(self,num):
        if len(num) > 0:
            return sum(num)/len(num)
        else:
            return 0    

    def isNumber(self,str):
        if str is not None:
          if len(str) > 1:
             return str.isdigit() 
          else: 
           return False  
        return False

    averagetempupstairs:
          module: set_average_state
          class: AverageStateValue
          sensors:
            - sensor.temperature_158d00019cb5c2
            - sensor.temperature_158d00019cb85c
            - sensor.temperature_158d00019cb4f7
            - sensor.temperature_158d00019cb81a
            - sensor.temperature_158d00023792a5
            - sensor.temperature_158d00023792c8
          averagesensor: sensor.upstairs_temperature
          averagefriendlyname: "Upstairs Temperature"
          averageicon: "mdi:thermometer"
          averageunitmeasurement: "°C"

You can actually solve this without AD: HASS has a min/max sensor. Example config:

sensor:
  - platform: min_max
    name: "Average Indoor Temperature"
    type: "mean"
    round_digits: 1
    entity_ids:
      - sensor.temperature_living_room
      - sensor.temperature_kitchen
      - sensor.temperature_bedroom
4 Likes

like @bachya says
and if you want to do it in AD,

temp = float(self.get_state(sensor.temp))

instead of your isnumber fuction.
that will normally work with a tempsensor unless you have a tempsensor that returns the state unavailable

Thanks for the help. Didn’t know about the Min_max sensor. Tried that and it works great

Wish I would’ve known that little nugget. I knocked mine out with a template. This is so much cleaner. Now I have something to go change

Old way

- platform: template
  sensors:
    average_outside_temp:
      friendly_name: 'ST Avg Outside'
      unit_of_measurement: "F"
      value_template: >-
        {{ ((float(states.sensor.chicken_coop_temp.state) + float(states.sensor.east_side_sensor_temperature.state) + float(states.sensor.west_side_temp.state)) / 3) | round(2) }}