ESPhome: How to set up filters to take exactly 10 measurements and then average it?

Hello all. I have been struggling how to combine filters to take 10 measurements and return average.

The problem is that I use low power sensor and I do not want to take more than 10 measurements in order to save chip power. All methods I tried take measurements all time the esphome is awake and then can return average of last 10 (like moving average). I would like the sensor take exactly 10 measurements (0.1s apart), calculate average and then return exactly 1 result and go back to sleep. Is that actually possible?

1 Like

It should be possible using these components. Did you try the filter component of the sensors like this.

  filters:
    - sliding_window_moving_average:
        window_size: 10
        send_every: 10
        send_first_at: 10
    - throttle: 10s

Also you might have already put the update interval as 100ms and in deep sleep settings run as 12s

Thank you but this seems it is not working. Your script is simply taking measurements all time until deep sleep, so more than 10. The config is here:

sensor:
  platform: adc
  pin: 36
  name: Vcc Average
  update_interval: 100ms
  filters:
    - sliding_window_moving_average:

        window_size: 10
        send_every: 10
        send_first_at: 10
    - throttle: 10s

...

deep_sleep:
  id: deep_sleep_1
  run_duration: 3s #4s
  sleep_duration: 20s #15s # 3806s

and the log output is here:

INFO Starting log output from /dev/ttyUSB0 with baud rate 115200
[10:45:46][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:46][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:46][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:46][I][mqtt:202]: MQTT Connected!
[10:45:46][C][deep_sleep:013]: Setting up Deep Sleep...
[10:45:46][I][app:059]: setup() finished successfully!
[10:45:46][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:46][I][app:105]: ESPHome version 1.16.2 compiled on Apr 10 2021, 10:36:53
[10:45:46][C][wifi:443]: WiFi:
[10:45:46][C][wifi:303]:   SSID: 'IoT'
[10:45:46][C][wifi:304]:   IP Address: 10.0.0.254
[10:45:46][C][wifi:306]:   BSSID: EC:AD:E0:D2:FC:DB
[10:45:46][C][wifi:307]:   Hostname: 'average_test'
[10:45:46][C][wifi:311]:   Signal strength: -28 dB ▂▄▆█
[10:45:46][C][wifi:315]:   Channel: 3
[10:45:46][C][wifi:316]:   Subnet: 255.255.255.0
[10:45:46][C][wifi:317]:   Gateway: 10.0.0.138
[10:45:46][C][wifi:318]:   DNS1: 8.8.8.8
[10:45:47][C][wifi:319]:   DNS2: 8.8.4.4
[10:45:47][C][logger:185]: Logger:
[10:45:47][C][logger:186]:   Level: DEBUG
[10:45:47][C][logger:187]:   Log Baud Rate: 115200
[10:45:47][C][logger:188]:   Hardware UART: UART0
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][C][adc:026]: ADC Sensor 'Vcc Average'
[10:45:47][C][adc:026]:   Unit of Measurement: 'V'
[10:45:47][C][adc:026]:   Accuracy Decimals: 2
[10:45:47][C][adc:026]:   Icon: 'mdi:flash'
[10:45:47][C][adc:035]:   Pin: 36
[10:45:47][C][adc:038]:  Attenuation: 0db (max 1.1V)
[10:45:47][C][adc:051]:   Update Interval: 0.1s
[10:45:47][C][ota:029]: Over-The-Air Updates:
[10:45:47][C][ota:030]:   Address: 10.0.0.254:3232
[10:45:47][C][mqtt:051]: MQTT:
[10:45:47][C][mqtt:053]:   Server Address: 10.0.0.54:1883 (10.0.0.54)
[10:45:47][C][mqtt:054]:   Username: 'janb'
[10:45:47][C][mqtt:055]:   Client ID: 'average_test-10521c6d44e4'
[10:45:47][C][mqtt:057]:   Discovery prefix: 'homeassistant'
[10:45:47][C][mqtt:058]:   Discovery retain: YES
[10:45:47][C][mqtt:060]:   Topic Prefix: 'average_test'
[10:45:47][C][mqtt:062]:   Log Topic: 'average_test/debug'
[10:45:47][C][mqtt:065]:   Availability: 'mqtt_avg_test/status'
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][C][mqtt:551]: MQTT Message Trigger:
[10:45:47][C][mqtt:552]:   Topic: 'mqtt_avg_test/ota_mode'
[10:45:47][C][mqtt:553]:   QoS: 0
[10:45:47][C][mqtt:551]: MQTT Message Trigger:
[10:45:47][C][mqtt:552]:   Topic: 'mqtt_avg_test/sleep_mode'
[10:45:47][C][mqtt:553]:   QoS: 0
[10:45:47][C][mqtt.sensor:024]: MQTT Sensor 'Vcc Average':
[10:45:47][C][mqtt.sensor:028]:   State Topic: 'average_test/sensor/vcc_average/state'
[10:45:47][C][deep_sleep:020]: Setting up Deep Sleep...
[10:45:47][C][deep_sleep:023]:   Sleep Duration: 20000 ms
[10:45:47][C][deep_sleep:026]:   Run Duration: 3000 ms
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:47][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:48][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][D][adc:056]: 'Vcc Average': Got voltage=1.10V
[10:45:49][I][deep_sleep:067]: Beginning Deep Sleep

So it is reading all time. I would prefer to take just 10 readings and then send average.

I solved it with this:

globals:
  - id: bc2
    type: long int
    restore_value: yes
    initial_value: "0"
  - id: a_input
    restore_value: no
    type: float
    initial_value: "0.0"
  - id: i
    type: long int
    restore_value: no
    initial_value: "0"

...

  on_loop:
    lambda: |-
      id(i)++;
      if (id(i) <= 10) {
        id(vcc).update();
        float vcc_now = id(vcc).state;
        id(a_input) = id(a_input) + vcc_now/10;
        delay(100);
        }
      if (id(i) == 10) {
        id(vcc_average).update();
        }

....

sensor:
  - platform: adc
    pin: 36
    name: Vcc
    internal: true
    id: vcc
    update_interval: 10s

  - platform: template
    name: Vcc Average
    id: vcc_average
    update_interval: 10s
    lambda:
      if (id(i) > 1) {
        ESP_LOGD("main", "################################## Returns value");
        return id(a_input);
        }
      else {
        ESP_LOGD("main", "################################## Returns NAN");
        return NAN;
        }

working well.

1 Like