My project is hooked to my furnace to keep track of what is running. My furnace fan, stages, reversing valve, and aux heat are all fed into a Wemos D1 through an optocoupler on each pin. I know the GPIO’s work.
My GPIO binary sensors read On and Off in HA, so far so good. However my template binary sensors that use a simple if statement always show as “Unavailable” in my dashboard. If I convert them into Text sensors they work just fine so I’m not sure what gives. There has to be a typo or something in them but for the life of me I can’t figure out where. Thoughts?
binary_sensor:
- platform: gpio
name: "Furnace Fan"
id: furnace_fan
pin:
number: GPIO1
inverted: true
mode:
input: true
- platform: gpio
name: "Thermostat Stage 1"
id: furnace_stage1
internal: true
pin:
number: GPIO3
inverted: true
mode:
input: true
- platform: gpio
name: "Thermostat Stage 2"
id: furnace_stage2
internal: true
pin:
number: GPIO12
inverted: true
mode:
input: true
- platform: gpio
name: "Thermostat Reversing Valve"
id: furnace_reversing_valve
internal: true
pin:
number: GPIO13
inverted: true
mode:
input: true
- platform: gpio
name: "Thermostat Aux Heat"
id: furnace_gas_heat
#internal: true
pin:
number: GPIO14
inverted: true
mode:
input: true
- platform: template
name: "Cool Stage 1"
id: cool_stage_1
publish_initial_state: true
lambda: |-
if ((id(furnace_reversing_valve).state == false) && (id(furnace_stage1).state == true)) {
return true;
} else {
return false;
}
- platform: template
name: "Cool Stage 2"
id: cool_stage_2
publish_initial_state: true
lambda: |-
if ((id(furnace_reversing_valve).state == false) && (id(furnace_stage2).state == true)) {
return true;
} else {
return false;
}
- platform: template
name: "Heat Stage 1"
id: heat_stage_1
publish_initial_state: true
lambda: |-
if ((id(furnace_reversing_valve).state == true) && (id(furnace_stage1).state == true)) {
return true;
} else {
return false;
}
- platform: template
name: "Heat Stage 2"
id: heat_stage_2
publish_initial_state: true
lambda: |-
if ((id(furnace_reversing_valve).state == true) && (id(furnace_stage2).state == true)) {
return true;
} else {
return false;
}
tom_l
July 7, 2024, 9:47pm
2
Try this:
binary_sensor:
- platform: gpio
name: "Furnace Fan"
id: furnace_fan
pin:
number: GPIO1
inverted: true
mode:
input: true
- platform: gpio
name: "Thermostat Stage 1"
id: furnace_stage1
internal: true
pin:
number: GPIO3
inverted: true
mode:
input: true
on_state:
- then:
- component.update:
- cool_stage_1
- cool_stage_2
- heat_stage_1
- heat_stage_2
- platform: gpio
name: "Thermostat Stage 2"
id: furnace_stage2
internal: true
pin:
number: GPIO12
inverted: true
mode:
input: true
on_state:
- then:
- component.update:
- cool_stage_1
- cool_stage_2
- heat_stage_1
- heat_stage_2
- platform: gpio
name: "Thermostat Reversing Valve"
id: furnace_reversing_valve
internal: true
pin:
number: GPIO13
inverted: true
mode:
input: true
on_state:
- then:
- component.update:
- cool_stage_1
- cool_stage_2
- heat_stage_1
- heat_stage_2
- platform: gpio
name: "Thermostat Aux Heat"
id: furnace_gas_heat
#internal: true
pin:
number: GPIO14
inverted: true
mode:
input: true
- platform: template
name: "Cool Stage 1"
id: cool_stage_1
publish_initial_state: true
lambda: |-
return !id(furnace_reversing_valve).state && id(furnace_stage1).state;
- platform: template
name: "Cool Stage 2"
id: cool_stage_2
publish_initial_state: true
lambda: |-
return !id(furnace_reversing_valve).state && id(furnace_stage2).state;
- platform: template
name: "Heat Stage 1"
id: heat_stage_1
publish_initial_state: true
lambda: |-
return id(furnace_reversing_valve).state && id(furnace_stage1).state;
- platform: template
name: "Heat Stage 2"
id: heat_stage_2
publish_initial_state: true
lambda: |-
return furnace_reversing_valve).state && id(furnace_stage2).state;
Thank you for the help, the lambda logic is a lot cleaner!
Unfortunately, the component.update does not seem to be able to take a list. The error thrown on the on_state component.update of multiple id’s is “string value cannot be dictionary or list.”
tom_l
July 8, 2024, 12:45am
4
Ugh. Really?
You’ll have to do this then:
- then:
- component.update: cool_stage_1
- component.update: cool_stage_2
- component.update: heat_stage_1
- component.update: heat_stage_2
Well… Now I get this error on those lines:
ID ‘cool_stage_1’ of type template_::TemplateBinarySensor doesn’t inherit from PollingComponent. Please double check your ID is pointing to the correct value.
tom_l
July 8, 2024, 1:38am
6
The last template is malformed:
Should be:
- platform: template
name: "Heat Stage 2"
id: heat_stage_2
publish_initial_state: true
lambda: |-
return id(furnace_reversing_valve).state && id(furnace_stage2).state;
Gotcha. I caught that one when trying to compile one of my other attempts.
A little progress was made. When I make the template sensors just plain sensors, the code compiles and the values received are 0 and 1. Aside from not being binary, things work.
However, when I make them binary sensors, the component.update action of on_state throws this error:
tom_l
July 8, 2024, 3:53am
8
Ok apparently that is not needed:
https://esphome.io/components/binary_sensor/template
Delete all the
on_state:
- then:
- component.update: ...
OK, so after copying the ESPhome YAML to a text file, deleting it from HA, removing all entities, rebooting HA, and pasting the ESPhome YAML back in, everything works. Thanks Tom!
Here’s the working code for future reference if anyone runs into this issue:
esphome:
name: furnace-monitor
friendly_name: Furnace Monitor
esp8266:
board: d1_mini
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: ""
ota:
- platform: esphome
password: ""
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Furnace-Monitor Fallback Hotspot"
password: "
captive_portal:
binary_sensor:
- platform: gpio #Fan GPIO
name: "Furnace Fan"
id: furnace_fan
pin:
number: GPIO3
inverted: true
mode:
input: true
- platform: gpio #Stage 1 GPIO
name: "Thermostat Stage 1"
id: furnace_stage1
#internal: true
publish_initial_state: true
pin:
number: GPIO1
inverted: true
mode:
input: true
- platform: gpio #Stage 2 GPIO
name: "Thermostat Stage 2"
id: furnace_stage2
#internal: true
publish_initial_state: true
pin:
number: GPIO12
inverted: true
mode:
input: true
- platform: gpio #Reversing Valve GPIO
name: "Thermostat Reversing Valve"
id: furnace_reversing_valve
#internal: true
pin:
number: GPIO13
inverted: true
mode:
input: true
- platform: gpio #Aux Heat GPIO
name: "Thermostat Aux Heat"
id: furnace_gas_heat
#internal: true
pin:
number: GPIO14
inverted: true
mode:
input: true
- platform: template #Cooling Stage 1 Template Sensor
name: "Cool Stage 1"
id: cool_stage_1
lambda: |-
return !id(furnace_reversing_valve).state && id(furnace_stage1).state;
- platform: template #Cooling Stage 2 Template Sensor
name: "Cool Stage 2"
id: cool_stage_2
lambda: |-
return !id(furnace_reversing_valve).state && id(furnace_stage2).state;
- platform: template #Heating Stage 1 Template Sensor
name: "Heat Stage 1"
id: heat_stage_1
lambda: |-
return id(furnace_reversing_valve).state && id(furnace_stage1).state;
- platform: template #Heating Stage 2 Template Sensor
name: "Heat Stage 2"
id: heat_stage_2
lambda: |-
return id(furnace_reversing_valve).state && id(furnace_stage2).state;