Sensor Filter based on state

I’d like to send a delta-t temperature reading but only when the air conditioner is running. Is there a filter condition that lets you only send sensor reading based on another sensor state? Ultimately, I’d like to only send delta-t (difference between intake and discharge temperature) when the blower is running. Extra points if I can delay the first reading for 2-min to allow the temperature to stabilize.

Seems doable.

I would approach this by using a Home Assistant Sensor so that ESPHome knows if “the air conditioner is running.”

Then I’d use on_value in order to filter the publishing of temperature data. I am assuming that the ESPhome device has two temps sensors? This wasn’t mentioned.

At which point you would want to include the condition of the airconditioner in an ESPHome automation which can be written in many ways. Of which the sample is pretty solid.

on_...:
  then:
    - if:
        condition:
          lambda: 'return id(airconditioner).state == 1;'
        then:
          lambda: 'return id(this_sensor).state;'

or perhaps

on_...:
  then:
    - if:
        condition:
          binary_sensor.is_on: airconditioner
        then:
          lambda: 'return id(this_sensor).state;'

A delayed_on filter would do it → Binary Sensor Component — ESPHome Albeit it might make sense to have HA be configured with this.

Thanks @crlogic. It’s not quite working as expected. I’m getting an error compiling, not sure where the mistake is.

/config/acwatcher.yaml: In lambda function:
/config/acwatcher.yaml:93:34: error: return-statement with a value, in function returning 'void' [-fpermissive]
   93 |               lambda: 'return (id(intake_temp).state - id(discharge_temp).state);'
      |               ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
*** [.pioenvs/acwatcher/src/main.cpp.o] Error 1

Here is the whole thing:

esphome:
  name: acwatcher

esp8266:
  board: d1_mini_pro

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "key="

ota:
  password: "password"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 10.1.12.239
    gateway: 10.1.12.1
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Acwatcher Fallback Hotspot"
    password: "password"

captive_portal:

globals:
   - id: hvac_on_threshold
     type: float
     restore_value: no
     initial_value: '2.00'

dallas:
  - pin: D4
  
# Individual sensors
sensor:
  - platform: dallas
    address: 0x51000005d3a58b28
    id: discharge_temp
    name: "Discharge Temperature"
    filters:
      - lambda: return x * (9.0/5.0) + 32.0;
    unit_of_measurement: "°F"
    
  - platform: dallas
    address: 0x0e000005d3516128
    id: intake_temp
    name: "Intake Temperature"
    # Green band
    filters:
      - lambda: return x * (9.0/5.0) + 32.0;
    unit_of_measurement: "°F"
    
  - platform: ct_clamp
    sensor: adc_sensor
    id: hvac_current
    name: "HVAC Current"
    update_interval: 1s
    filters:
      - calibrate_linear:
        - 0 -> 0
        - 0.052 -> 4.3
    
  - platform: adc
    pin: A0
    id: adc_sensor
    
  - platform: template
    name: "Delta T"
    id: temp_delta_t
    update_interval: 60s
    unit_of_measurement: "°F"
    lambda: |-
      return (id(intake_temp).state - id(discharge_temp).state);
      
  - platform: homeassistant
    name: "Delta T Filtered"
    entity_id: sensor.temp_delta_t_filtered
    unit_of_measurement: "°F"
    on_value:
      then:
        - if:
            condition:
              binary_sensor.is_on: hvac_stable_state
            then:
              lambda: 'return (id(intake_temp).state - id(discharge_temp).state);'
              
binary_sensor:
  - platform: template
    name: "HVAC State"
    id: hvac_state
    lambda: |-
      if (id(hvac_current).state > id(hvac_on_threshold)) {
        return true;
      } else {
        return false;
      }

  - platform: template
    name: "HVAC Stable State"
    id: hvac_stable_state
    filters:
      delayed_on: 
        minutes: 2
    lambda: |-
      if (id(hvac_current).state > id(hvac_on_threshold)) {
        return true;
      } else {
        return false;
      }

Looks like line 93 is reporting the state of temp_delta_t, have you tried lambda: return id(temp_delta_t).state;

Similar issues

/config/acwatcher.yaml: In lambda function:
/config/acwatcher.yaml:93:28: error: return-statement with a value, in function returning 'void' [-fpermissive]
   93 |               lambda: return id(temp_delta_t).state;
      |               ~~~~~~~~~~~~~^~~~~
*** [.pioenvs/acwatcher/src/main.cpp.o] Error 1
========================== [FAILED] Took 5.22 seconds ==========================

Tried with and without quoting the lambda statement.

I didn’t look closely enough, sorry.

  - platform: homeassistant
    name: "Delta T Filtered"
    entity_id: sensor.temp_delta_t_filtered
    unit_of_measurement: "°F"
    on_value:
      then:
        - if:
            condition:
              binary_sensor.is_on: hvac_stable_state
            then:
              lambda: return id(temp_delta_t).state;

Platform: Home Assistant only pulls values from HA and does not publish to HA. You want Template Sensor for that. But that also means that the template sensor doesn’t need the on_value lambda, you want to publish to it after a temp_delta_t update…

Was thinking more like this…

  - platform: template
    name: "Delta T"
    id: temp_delta_t
    update_interval: 60s
    unit_of_measurement: "°F"
    lambda: |-
      return (id(intake_temp).state - id(discharge_temp).state);
    on_value:
      then:
        - if:
            condition:
              binary_sensor.is_on: hvac_stable_state
            then:
              - sensor.template.publish:
                  id: temp_delta_t_filtered
                  state: !lambda 'return id(temp_delta_t).state;'

      
  - platform: template
    name: "Delta T Filtered"
    id: temp_delta_t_filtered
    unit_of_measurement: "°F"

Based on your excellent guidance, I’ve got this one working.

globals:
   - id: hvac_on_threshold
     type: float
     restore_value: no
     initial_value: '2.00'

dallas:
  - pin: D4
  
# Individual sensors
sensor:
  - platform: dallas
    address: 0x51000005d3a58b28
    id: discharge_temp
    name: "Discharge Temperature"
    filters:
      - lambda: return x * (9.0/5.0) + 32.0;
    unit_of_measurement: "°F"
    
  - platform: dallas
    address: 0x0e000005d3516128
    id: intake_temp
    name: "Intake Temperature"
    # Green band
    filters:
      - lambda: return x * (9.0/5.0) + 32.0;
    unit_of_measurement: "°F"
    
  - platform: ct_clamp
    sensor: adc_sensor
    id: hvac_current
    name: "HVAC Current"
    update_interval: 1s
    filters:
      - calibrate_linear:
        - 0 -> 0
        - 0.052 -> 4.3
    
  - platform: adc
    pin: A0
    id: adc_sensor
    
  - platform: template
    name: "Delta T"
    id: temp_delta_t
    update_interval: 60s
    unit_of_measurement: "°F"
    lambda: |-
      return (id(intake_temp).state - id(discharge_temp).state);
      
  - platform: template
    name: "Delta T Filtered"
    id: temp_delta_t_filtered
    unit_of_measurement: "°F"
    lambda: |-
      if (id(hvac_stable_state).state) {
          return id(temp_delta_t).state;
      } else {
        return{};
      }
    update_interval: 60s
    
              
binary_sensor:
  - platform: template
    name: "HVAC State"
    id: hvac_state
    lambda: |-
      if (id(hvac_current).state > id(hvac_on_threshold)) {
        return true;
      } else {
        return false;
      }

  - platform: template
    name: "HVAC Stable State"
    id: hvac_stable_state
    filters:
      delayed_on: 
        minutes: 2
    lambda: |-
      if (id(hvac_current).state > id(hvac_on_threshold)) {
        return true;
      } else {
        return false;
      }

Perfect. That works too :slight_smile:

The next challenge I always like to investigate is; replacing the fixed x minute delay with a dynamic means to determine “if the temperature is stable”.

You can do this with HA Trend sensors :stuck_out_tongue: