ashscott
(Ash)
August 24, 2021, 1:05pm
1
I have this…
- wait_until:
condition:
lambda: |-
return 'id(fish_food_hopper).state <= id(post_dose_weight).state';
… and it passes validation.
But on installing I get a compilation error:
Compiling /data/feeder/.pioenvs/feeder/src/main.cpp.o
/config/esphome/feeder.yaml:288:14: warning: character constant too long for its type
return 'id(fish_food_hopper).state <= id(post_dose_weight).state';
What is it trying to tell me?
tom_l
August 24, 2021, 1:53pm
2
Try it without the quotes:
- wait_until:
condition:
lambda: |-
return id(fish_food_hopper).state <= id(post_dose_weight).state;
Or use quotes around everything when it is on a single line:
- wait_until:
condition:
lambda: 'return id(fish_food_hopper).state <= id(post_dose_weight).state;'
ashscott
(Ash)
August 24, 2021, 2:46pm
3
Thanks, Tom.
Still the same with both of those options
Or, I should add, a myriad of other, probably longshot, syntax options.
I’m not sure where to go from here.
Does the lambda seem correct?
ashscott
(Ash)
August 24, 2021, 3:34pm
4
I’m getting the same result using while: then:.
Is it the types of fish_food_hopper
and post_dose_weight
that are causing the problem?
sensor:
- platform: hx711
name: "Fish food hopper"
id: fish_food_hopper
dout_pin: 27
clk_pin: 26
filters:
- calibrate_linear:
- 9800 -> 0
- 435000 -> 5.0
- sliding_window_moving_average:
window_size: 5
send_every: 5
update_interval: 2s
unit_of_measurement: gm
accuracy_decimals: 1
and:
globals:
- id: post_dose_weight
type: int
restore_value: yes
ashscott
(Ash)
August 24, 2021, 5:44pm
5
Some progress in that I now have a different error.
What is…
Condition must consist of key-value mapping! Got return id(pre_dose_weight).state <= id(post_dose_weight).state;.
condition: !lambda |-
return id(pre_dose_weight).state <= id(post_dose_weight).state; [source /config/esphome/feeder.yaml:287]
…trying to tell me?
I now have in my code:
- wait_until:
condition:
!lambda
'return id(pre_dose_weight).state <= id(post_dose_weight).state;'
tom_l
August 25, 2021, 12:42am
6
Don’t quote multi line lambdas. Only quote the whole line when it’s a single line lambda like my example above and just like jinja in Home Assistant.
Try asking on the ESPHome Discord, lots of expert helpers there: https://discord.gg/mdT9Kr9V
1 Like
paddy0174
(Patrick)
August 25, 2021, 12:54am
7
It would probably help, if you’d post your whole code. To see what’s wrong, it is at least necessary to post the parts around the error. Eg. if you forget a “;” at the end of statement, the error normally is set in the next line after…
1 Like
ashscott
(Ash)
August 25, 2021, 6:11am
8
Again, thank you both for the help. I appreciate it.
Here’s the whole thing. There’s some cruft and test code in there. I was at it until the early hours.
It was all looking good and working until I started to add the wait_until
:.
esphome:
name: feeder
platform: ESP32
board: esp32dev
platformio_options:
board_build.f_cpu: 80000000L
# Notes
# 5000g maximum tared weight
# 500g minimum weight
# 2 gms per second feed rate
on_boot:
then:
# read the RTC time once when the system boots
- ds1307.read_time:
- if:
condition:
sun.is_above_horizon:
then:
- binary_sensor.template.publish:
id: fish_feeder_sun_is_up
state: ON
else:
- binary_sensor.template.publish:
id: fish_feeder_sun_is_up
state: OFF
api:
i2c:
sda: 19
scl: 18
dallas:
- pin: GPIO23
update_interval: 60s
sun:
latitude: !secret latitude
longitude: !secret longitude
on_sunrise:
- then:
- binary_sensor.template.publish:
id: fish_feeder_sun_is_up
state: ON
on_sunset:
- then:
- binary_sensor.template.publish:
id: fish_feeder_sun_is_up
state: OFF
logger:
web_server:
port: 80
auth:
username: admin
password: !secret OTA_password
ota:
password: !secret OTA_password
wifi:
ssid: !secret dryderdale_wifi_SSID
password: !secret dryderdale_wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Feeder Fallback Hotspot"
password: !secret OTA_password
power_save_mode: none
captive_portal:
globals:
- id: feed_amount_timer_variable
type: int
restore_value: no
initial_value: '5'
- id: feeds_per_day_variable
type: int
restore_value: no
initial_value: '5'
- id: water_pre_dispense_time_variable
type: int
restore_value: yes
initial_value: '5'
- id: water_post_dispense_time_variable
type: int
restore_value: yes
initial_value: '5'
- id: current_hopper_weight
type: int
- id: pre_dose_weight
type: int
restore_value: yes
- id: post_dose_weight
type: int
restore_value: yes
time:
- platform: ds1307
# repeated synchronization is not necessary unless the external RTC
# is much more accurate than the internal clock
update_interval: never
- platform: homeassistant
# instead try to synchronize via network repeatedly ...
on_time_sync:
then:
# ... and update the RTC when the synchronization was successful
ds1307.write_time:
# on_time:
# # Every hour when sun is up
# - seconds: 0
# minutes: 0
# then:
# - if:
# condition:
# and:
# - sun.is_above_horizon:
# - binary_sensor.is_off: disable_fish_feed
# then:
# - script.execute: dispense_food
sensor:
- platform: hx711
name: "Fish food hopper"
id: fish_food_hopper
dout_pin: 27
clk_pin: 26
filters:
- calibrate_linear:
- 9800 -> 0
- 435000 -> 5.0
- sliding_window_moving_average:
window_size: 5
send_every: 5
update_interval: 2s
unit_of_measurement: gm
accuracy_decimals: 1
on_value:
then:
- globals.set:
id: current_hopper_weight
value: !lambda 'return x;'
- platform: homeassistant
name: "Fish feed amount"
entity_id: input_number.fish_feed_amount #defined in homeassistant
id: fish_feed_amount
on_value:
then:
- globals.set:
id: feed_amount_timer_variable
value: !lambda 'return x;'
- platform: homeassistant
name: "Feeds per day"
entity_id: input_number.feeds_per_day #defined in homeassistant
id: feeds_per_day
on_value:
then:
- globals.set:
id: feeds_per_day_variable
value: !lambda 'return x;'
- platform: homeassistant
name: "Water Pre Dispense Time"
entity_id: input_number.water_pre_dispense_time #defined in homeassistant
id: water_pre_dispense_time
on_value:
then:
- globals.set:
id: water_pre_dispense_time_variable
value: !lambda 'return x;'
- platform: homeassistant
name: "Water Post Dispense Time"
entity_id: input_number.water_post_dispense_time_HA #defined in homeassistant
id: water_post_dispense_time
on_value:
then:
- globals.set:
id: water_post_dispense_time_variable
value: !lambda 'return x;'
- platform: homeassistant
name: "Water temperature"
entity_id: sensor.pond_water_temperature #defined in homeassistant
id: water_temperature
- platform: dallas
address: 0x0301192A83D1AC28
name: "Feeder Water Temperature"
id: feeder_water_temperature
icon: mdi:temperature-celsius
text_sensor:
- platform: sun
name: Sun Next Sunrise
type: sunrise
- platform: sun
name: Sun Next Sunset
type: sunset
binary_sensor:
- platform: gpio
pin:
number: 17
mode: INPUT_PULLUP
name: "Manual Fish Feed"
id: manual_fish_feed
filters:
- invert:
on_press:
then:
- script.execute: dispense_food
# - switch.turn_on: fish_feed_motor
# on_release:
# then:
# script.execute: dispense_food
- platform: gpio
pin:
number: 16
mode: INPUT_PULLUP
name: "Disable Fish Feed"
id: disable_fish_feed
filters:
- invert:
- platform: template
name: "Fish feeder sun is up"
id: fish_feeder_sun_is_up
- platform: homeassistant
name: "Disable fish feeding"
entity_id: input_boolean.disable_fish_feeder #defined in homeassistant
id: disable_fish_feeding
- platform: homeassistant
name: "Manual feed"
entity_id: input_boolean.manually_feed_fish #defined in homeassistant
id: manual_fish_feeding
on_press:
then:
- script.execute: dispense_food
- delay: 1s
- homeassistant.service:
service: input_boolean.turn_off
data:
entity_id: input_boolean.manually_feed_fish
switch:
- platform: restart
name: "Restart fish feeder control"
id: restart_fish_feeder_control
- platform: gpio
pin: 21
name: "Fish Feed Motor"
id: fish_feed_motor
inverted: false
restore_mode: RESTORE_DEFAULT_OFF
script:
- id: dispense_food
then:
- if:
condition:
- binary_sensor.is_off: disable_fish_feeding
then:
- globals.set:
id: pre_dose_weight
value: current_hopper_weight
- globals.set:
id: post_dose_weight
value: !lambda return 'id(pre_dose_weight).state - id(fish_feed_amount).state;'
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.water_fill_valve
- delay: !lambda 'return id(water_pre_dispense_time_variable) * 1000;'
- switch.turn_on: fish_feed_motor
- wait_until:
condition:
lambda: |-
return id(current_hopper_weight).state <= id(post_dose_weight).state;
# - delay: !lambda 'return id(feed_amount_timer_variable) * 1000 /2;'
- switch.turn_off: fish_feed_motor
- delay: !lambda 'return id(water_post_dispense_time_variable) * 1000;'
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.water_fill_valve
1 Like
ashscott
(Ash)
August 25, 2021, 8:28am
9
Getting back to where I was originally, I have:
- wait_until:
condition:
lambda: 'return id(fish_food_hopper).state <= id(post_dose_weight).state;'
And this creates the following error:
/config/esphome/feeder.yaml: In lambda function:
/config/esphome/feeder.yaml:296:67: error: request for member 'state' in 'post_dose_weight->esphome::globals::GlobalsComponent<T>::value<int>()', which is of non-class type 'int'
lambda: 'return id(fish_food_hopper).state <= id(post_dose_weight).state;'
^
In file included from src/esphome/core/application.h:8:0,
from src/esphome/components/api/api_connection.h:4,
from src/esphome.h:2,
from src/main.cpp:3:
src/esphome/core/helpers.h: In instantiation of 'esphome::TemplatableValue<T, X>::TemplatableValue(F) [with F = esphome::globals::GlobalsComponent<int>*; typename std::enable_if<(! esphome::is_callable<F, X ...>::value), int>::type <anonymous> = 0; T = int; X = {}]':
src/esphome/components/globals/globals_component.h:60:3: required from 'void esphome::globals::GlobalVarSetAction<C, Ts>::set_value(V) [with V = esphome::globals::GlobalsComponent<int>*; C = esphome::globals::GlobalsComponent<int>; Ts = {}]'
/config/esphome/feeder.yaml:198:64: required from here
src/esphome/core/helpers.h:239:57: error: invalid conversion from 'esphome::globals::GlobalsComponent<int>*' to 'int' [-fpermissive]
TemplatableValue(F value) : type_(VALUE), value_(value) {}
It’s the “which is of non-class type 'int” and “invalid conversion” parts that has me think that this is not just a formatting issue.
Does the problem lie with my sensor and globals declarations maybe?
The fish_food_hopper
sensor has accuracy_decimals: 1
, which suggests it is of type float
, whereas the globals are of type int
. I have tried them as float with same result though. The sensor doesn’t support changing type .
EDIT:
Removing accuracy_decimals: 1
, according to the docs , causes the sensor to return int
.
With this, and globals set to int
, I now get this error:
invalid conversion from 'esphome::globals::GlobalsComponent<int>*' to 'int' [-fpermissive]
, which further suggests to me that it’s a mismatched type or similar. Just not sure how to fix it.
ashscott
(Ash)
August 25, 2021, 10:41am
10
Having painstakingly commented out each line of code, one by one, and compiled each time, I’ve narrowed it down to the commented out items in the script below.
I think I’m at the end of my current capabilities!
Any suggestions welcome.
script:
- id: dispense_food
then:
- if:
condition:
- binary_sensor.is_off: disable_fish_feeding
then:
# - globals.set:
# id: pre_dose_weight
# value: current_hopper_weight
# - globals.set:
# id: post_dose_weight
# value: !lambda 'return id(pre_dose_weight).state - id(fish_feed_amount).state;'
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.water_fill_valve
- delay: !lambda 'return id(water_pre_dispense_time_variable) * 1000;'
- switch.turn_on: fish_feed_motor
# - wait_until:
# condition:
# lambda: 'return id(fish_food_hopper).state <= 0;' # id(post_dose_weight).state;'
- delay: !lambda 'return id(feed_amount_timer_variable) * 500;'
- switch.turn_off: fish_feed_motor
- delay: !lambda 'return id(water_post_dispense_time_variable) * 1000;'
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.water_fill_valve
ashscott
(Ash)
August 25, 2021, 11:40am
11
Discord sorted it out!
the .state
is not required for the globals, just the sensor.
Thanks all for your help.
2 Likes