Hi !
I’m trying to write my first script in esp home and come to a point where I need help.
Here I call my script:
- platform: dallas
index: 0
name: "Dallas Temperature"
id: dallas_temperature
on_value:
- if:
condition:
lambda: |-
return id(External_Temp_Sensor_Lueftersteuerung).state == true;
then:
- script.execute:
id: update_pwm
#temp: id(dallas_temperature).state
temp: !lambda 'return id(dallas_temperature).state;'
This is my script:
script:
- id: update_pwm
mode: single
parameters:
#key: value
temp: float
then:
- if:
condition:
for:
time: 10s
condition:
- lambda: |-
return temp > id(max_temperature).state;
then:
- light.turn_on:
id: d4_light
effect: flashfast
- lambda: !lambda |-
id(Alarm).publish_state(true);
else:
- lambda: !lambda |-
id(Alarm).publish_state(false);
- light.turn_off: d4_light
- if:
condition:
- lambda: |-
return temp >= id(start_temp).state;
then:
- globals.set:
id: fan_started
value: "true"
I get this error message:
/config/esphome/wr-lufter-dallas-sensor.yaml: In lambda function:
/config/esphome/wr-lufter-dallas-sensor.yaml:322:14: error: 'temp' was not declared in this scope
322 | return temp > id(max_temperature).state;
Because I’m using the same code “return temp > id(some_sensor).state;” at two different places the issue should be in the condition “for”. But how to fix this ?
As additional note: the code was running before I moved it into the script.
The goal is to set an alarm if temperature is above a limit for 10s.
This seems to make issues in a script… how else I could achieve it ?
You could create a template binary sensor using this bit (and any other necessary checks).
id(dallas_temperature).state >id(max_temperature).state;
Add a delayed_on
filter of 10s.
Then add an on_press
action (move your actions there, or simply your script and call it from there)
Your logic and structure seems more complicated than it needs to be, unless I’m missing something.
Edit: Actually reading your script more carefully I can see it’s a bit more nuanced.
Nevertheless consider if you can and want to break it out into binary sensors. I find that easier to monitor and debug.
Masterzz
(Igors Micko)
April 11, 2024, 8:53am
4
Looks this is not solved bug in script parametyerts handling.
Similar staff reported as
opened 10:16AM - 17 Nov 22 UTC
### The problem
Script parameters are an awesome new feature!
I was expecting … to be able to do something like:
```yaml
script:
- id: my_script
parameters:
steps: int
then:
- while:
condition:
lambda: 'return steps > 0;'
then:
- ...do something...
- delay: 5ms
- lambda: 'steps--;'
```
But this creates a hard to spot infinite loop! Cause the nested lambda is translated to:
```c++
lambdaaction_16 = new LambdaAction<int>([=](int steps) -> void {
steps--;
});
```
so `steps` is a local variable of the lambda, and `steps--` has no effect!
This will likely create hard to spot bugs and frustration, it is very reasonable to expect to be able to modify paramerts. I see two solutions:
1. Ideally, pass `steps` by reference in the nested lambda, so that it can be modified (not sure if this creates issues elsewhere, though)
2. Accept that parameters are read-only, documentit, and declare `steps` as `const` so that the compiler does not allow you to modify it.
(Note that this wouldn't be an issue if the whole script body is pure c++ code, but in this example I need a "yaml while" to be able to use `delay`.)
### Which version of ESPHome has the issue?
2022.11.1
### What type of installation are you using?
Home Assistant Add-on
### Which version of Home Assistant has the issue?
2022.11
### What platform are you using?
ESP32-IDF
### Board
_No response_
### Component causing the issue
_No response_
### Example YAML snippet
_No response_
### Anything in the logs that might be useful for us?
_No response_
### Additional information
_No response_
Added Your case too in hope someone will fix it.
This is what I already had:
binary_sensor:
- platform: template
id: Alarm
name: $name Alarm
icon: mdi:fire
This were good ideas, thank you for the hint
I modified my script, so that the only thing I do inside the script now is to check the condition which should be fulfilled for the desired time. Any timing related stuff I moved to the binary_sensor outside the script with “on_press” and “on_release” options:
binary_sensor
- platform: template
id: Alarm
name: $name Alarm
icon: mdi:fire
filters:
delayed_on: 10s
on_press:
- light.turn_on:
id: d4_light
effect: flashfast
on_release:
- if:
condition:
- lambda: |-
return id(External_Temp_Sensor_Lueftersteuerung).state == true;
then:
- light.turn_on:
id: d4_light
effect: slow
else:
- light.turn_on:
id: d4_light
effect: fast
script:
- id: update_pwm
mode: single
parameters:
#key: value
temp: float
then:
# ALARM If over 'Max Temp' for 10 Seconds: Turn on 'binary_sensor: Alarm' & Flash the On-Board LED. Else, turn them off
- if:
condition:
- lambda: |-
return temp > id(max_temperature).state;
then:
- lambda: !lambda |-
id(Alarm).publish_state(true);
else:
- lambda: !lambda |-
id(Alarm).publish_state(false);
1 Like