It compiles ok for me, with or without. It’s the missing brackets and extra semi colon that would have made it fail.
I got the Lambda to compile fine (after a full hour of debugging syntax) and display on the LCD the text wind direction, converted inside ESPhome.
Values come from the internal wind direction sensor (which in turn comes from HA via WU). North required two ‘if’ conditions to handle wrapping past 0 degrees.
Just did four cardinal points for a test, now need to expand the else if’s to a full sixteen…
Any suggestions to streamline it welcome.
text_sensor:
- platform: template
id: internal_winddir_conversion
lambda: |-
if ((id(wupws_wind_dir).state >= 0) and (id(wupws_wind_dir).state <= 11)) {
return {"North"};}
else if ((id(wupws_wind_dir).state >= 12) and (id(wupws_wind_dir).state <= 33)) {
return {"N-N-E"};}
else if ((id(wupws_wind_dir).state >= 34) and (id(wupws_wind_dir).state <= 56)) {
return {"N-E"};}
else if ((id(wupws_wind_dir).state >= 57) and (id(wupws_wind_dir).state <= 78)) {
return {"E-N-E"};}
else if ((id(wupws_wind_dir).state >= 79) and (id(wupws_wind_dir).state <= 101)) {
return {"East"};}
else if ((id(wupws_wind_dir).state >= 102) and (id(wupws_wind_dir).state <= 123)) {
return {"E-S-E"};}
else if ((id(wupws_wind_dir).state >= 124) and (id(wupws_wind_dir).state <= 146)) {
return {"S-E"};}
else if ((id(wupws_wind_dir).state >= 147) and (id(wupws_wind_dir).state <= 168)) {
return {"S-S-E"};}
else if ((id(wupws_wind_dir).state >= 169) and (id(wupws_wind_dir).state <= 191)) {
return {"South"};}
else if ((id(wupws_wind_dir).state >= 192) and (id(wupws_wind_dir).state <= 213)) {
return {"S-S-W"};}
else if ((id(wupws_wind_dir).state >= 214) and (id(wupws_wind_dir).state <= 236)) {
return {"S-W"};}
else if ((id(wupws_wind_dir).state >= 237) and (id(wupws_wind_dir).state <= 258)) {
return {"W-S-W"};}
else if ((id(wupws_wind_dir).state >= 259) and (id(wupws_wind_dir).state <= 281)) {
return {"West"};}
else if ((id(wupws_wind_dir).state >= 282) and (id(wupws_wind_dir).state <= 303)) {
return {"W-N-W"};}
else if ((id(wupws_wind_dir).state >= 304) and (id(wupws_wind_dir).state <= 326)) {
return {"N-W"};}
else if ((id(wupws_wind_dir).state >= 327) and (id(wupws_wind_dir).state <= 348)) {
return {"N-N-W"};}
else if ((id(wupws_wind_dir).state >= 349) and (id(wupws_wind_dir).state <= 359)) {
return {"North"};}
else {
return {"invalid"};}
update_interval: 30s
The particular internal sensor (of many)
- platform: homeassistant
id: wupws_wind_dir
name: "Wind direction via WU-WH2900"
entity_id: sensor.wupws_winddir
internal: true
The LCD display code (just that line).
it.printf(0, 0, "Wind: %s", id(internal_winddir_conversion).state.c_str());
Glad its working, why are there some with and some without else
?
Yep that was an error, caused by my cut & pasting. Fixed it, still works fine…
You could replace both North if
with:
if ((id(wupws_wind_dir).state >= 0) and (id(wupws_wind_dir).state <= 11)) or
((id(wupws_wind_dir).state >= 349) and (id(wupws_wind_dir).state <= 359)) {
return {"North"};}
I also look at ESPHome devices as compartmentalized, meaning that if I need to translate the values from a connected device into human consumable values then I do so on the ESPHome device.
I want the device to look more like what it is supporting than have to glue things together on the Home Assistant side.
It’s also very hard for me get out of the habit of moving processing to the edge. So many years of performance optimizing large scaled services.
Cheers
hi,
i am trying to have two conditions for a sensor value below 1 . First program to check first condition and take action and then check other condition and take action. Irrespective of first condition result and action program must check the second condition and take action.
I am getting this error while compiling.
my code below.
sensor:
- platform: adc
pin: A0
name: "intercom_adc_value"
# unit_of_measurement: 'v'
update_interval: 100ms
filters:
- multiply: 3.3
on_value_range:
- above: 3
then:
- switch.turn_off: intercom_local_alerts
- switch.turn_off: intercom_remote_alerts
- below: 1.0
then:
if:
condition:
- switch.is_on: intercom_local_alerts_enable_disable
then:
- switch.turn_on: intercom_local_alerts
if:
condition:
- switch.is_on: intercom_remote_alerts_enable_disable
then:
- switch.turn_on: intercom_remote_alerts
hi Usman, I just saw your post, did you manage to get it running in the time between then and now.
I am by no means a programmer or esphome wizard but i did manage to get a temperature sensor to do different actions on different values. Maybe it will help you or somebody else along. btw i did use substitutions for most values and id’s so i can quickly multiply and only have to change names in the top bit of the yaml.
# Temperature sensor, met temperatuur activatie?
- platform: dallas
address: $dallas_id_1
name: "$temp_id"
accuracy_decimals: 1
id: $temp_id
on_value:
then:
- if:
condition:
and:
- lambda: return id($temp_id).state < $cold_temp;
- binary_sensor.is_on: esphome_fans_on_off
then:
- fan.turn_on:
id: $fan_id
speed: 15
- if:
condition:
and:
- lambda: return id($temp_id).state > $cold_temp;
- lambda: return id($temp_id).state < $low_temp;
- binary_sensor.is_on: esphome_fans_on_off
then:
- fan.turn_off:
id: $fan_id
- if:
condition:
and:
- lambda: return id($temp_id).state > $low_temp;
- lambda: return id($temp_id).state < $medium_temp;
- binary_sensor.is_on: esphome_fans_on_off
then:
- fan.turn_on:
id: $fan_id
speed: 44
- if:
condition:
and:
- lambda: return id($temp_id).state < $high_temp;
- lambda: return id($temp_id).state > $medium_temp;
- binary_sensor.is_on: esphome_fans_on_off
then:
- fan.turn_on:
id: $fan_id
speed: 50
- if:
condition:
and:
- lambda: return id($temp_id).state > $high_temp;
- binary_sensor.is_on: esphome_fans_on_off
then:
- fan.turn_on:
id: $fan_id
speed: 80
Back to the original question, is it possible to write nested if statements in YAML?
My use case is a service to water plants, where I want also to check if the pump is actually working:
services:
- service: water_plants
then:
if:
condition:
and:
- binary_sensor.is_off: esp32_garden_sensor_empty # tank empty sensor
- sensor.in_range:
id: ep32_garden_daily_flow # flow sensor (integration)
below: 4.0
then:
- switch.turn_on: esp32_garden_relay1 # pump supply
- delay: 10s
if:
condition:
- sensor.in_range:
id: ep32_garden_flow_rate # instant flow sensor
below: 0.2
then:
- switch.turn_off: esp32_garden_relay1
- homeassistant.service:
service: notify.mobile_app
data:
message: 'The pump is not pumping!'
- delay: 300s # time to water plants
- switch.turn_off: esp32_garden_relay1 # stop watering
This would be straightforward in C/C++ or any other languages, but I’m trying to stick to YAML as the whole house is automated with esphome & YAML.
I know I could do that with lambdas, but I would prefer to keep everything in YAML.
It looks like I just had to fix lists and indentations, this is working:
services:
- service: water_plants
then:
if:
condition:
and:
- binary_sensor.is_off: esp32_garden_sensor_empty # tank empty sensor
- sensor.in_range:
id: ep32_garden_daily_flow # flow sensor (integration)
below: 4.0
then:
- switch.turn_on: esp32_garden_relay1 # pump supply
- delay: 10s
- if:
condition:
- sensor.in_range:
id: ep32_garden_flow_rate # instant flow sensor
below: 0.2
then:
- switch.turn_off: esp32_garden_relay1
- homeassistant.service:
service: notify.mobile_app
data:
message: 'The pump is not pumping!'
- delay: 300s # time to water plants
- switch.turn_off: esp32_garden_relay1 # stop watering
Someone has opened an issue about this: Switch Case Algorithm · Issue #824 · esphome/feature-requests · GitHub
Maybe you all want to join and therefore show the developers that this feature is a interesting one?