如题。
配置如下,问每秒刷新的 text_sensor 是否会被 on_loop 中的 delay:3s 阻塞?
# Apply to ESPHOME 1.14.3
# 测试开发板:Goouuu MiniS1
# board: ESP8266-S1 由于 PIO 不支持这个板子,山寨板子只有2M Flash故此选择 esp8285
substitutions:
devicename: 'wifi_hotport'
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
api_password: !secret api_password
ota_password: !secret ota_password
status_light_time: "4s"
hotport_ssid: !secret hotport_ssid
hotport_password: !secret hotport_password
esphome:
name: $devicename
platform: ESP8266
board: esp8285
on_boot:
# --------------------------------------------
#这个板子默认亮起 led 灯,所以启动时候要灭掉。
- light.turn_off: red_light
- light.turn_off: green_light
- light.turn_off: blue_light
# ----------------------------------------------
# 循环检查 wifi 状态,修改指示灯。
on_loop:
then:
- light.turn_on: red_light
- delay: 3s
- light.turn_off: red_light
wifi:
# 设置ID 可以在 lambda 下用 id($id_name) 调用,继承 WiFiComponent 类。
id: wifi_state
ssid: $wifi_ssid
password: $wifi_password
# 启动 AP 模式,当
ap:
ssid: $hotport_ssid
password: $hotport_password
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
password: $api_password
reboot_timeout: 0s
text_sensor:
- platform: template
name: "TEST"
lambda: |-
return {"Hello World"};
update_interval: 1s
ota:
password: $ota_password
light:
- platform: binary
name: "red_light"
id: "red_light"
output: RED_LED_GPIO12
- platform: binary
name: "blue_light"
id: "blue_light"
output: BLUE_LED_GPIO14
- platform: binary
name: "green_light"
id: "green_light"
output: GREEN_LED_GPIO13
output:
- platform: gpio
id: RED_LED_GPIO12
pin: GPIO12
inverted: true
- platform: gpio
id: BLUE_LED_GPIO14
pin: GPIO14
inverted: true
- platform: gpio
id: GREEN_LED_GPIO13
pin: GPIO13
inverted: true
经过测试
on_loop:
then:
- light.turn_on: red_light
- delay: 3s
- light.turn_off: red_light
这样写是错误的。
这三个动作都是 同时进行。on 和 off 还有delay 分别是三个不同的任务。
并不是没有办法,从 esphome 翻译过来的 C++ 文件看,这样写是不对的,这样他生成了三个自动化实例,然后多任务(只是猜测)执行他们。
delayaction = new DelayAction<>();
App.register_component(delayaction);
delayaction->set_delay(4000);
light_lightcontrolaction_5 = new light::LightControlAction<>(red_light);
light_lightcontrolaction_5->set_state(false);
automation_2->add_actions({light_lightcontrolaction_4, delayaction, light_lightcontrolaction_5});
但是 换一个做法。
on_loop:
then:
lambda: |-
// 如果 WIFI 连接上了
if (id(wifi_state).is_connected())
{
//ESP_LOGD("WIFI","WIFI connected Code:%d",int(id(wifi_state).is_connected()));
// 蓝灯未亮起
if (!id(blue_light).remote_values.get_state())
{
auto blue_light_on = id(blue_light).turn_on();
blue_light_on.perform();
}
}
// 如果 WiFi 未连接
else
{
//ESP_LOGD("WIFI","WIFI not connect Code:%d",int(id(wifi_state).is_connected()));
auto blue_light_off = id(blue_light).turn_off();
auto red_light_on = id(red_light).turn_on();
red_light_on.perform();
delay(3000);
auto red_light_off = id(red_light).turn_off();
red_light_off.perform();
}
直接在 on_loop 中写 lambda 的话,使用 delay(3000)
就会阻塞主程序。
所以 on_loop 里面不能使用 lambda 来写 delay。
实现 WIFI 指示灯的功能如下:
# Apply to ESPHOME 1.14.3
# 测试开发板:Goouuu MiniS1
# board: ESP8266-S1 由于 PIO 不支持这个板子,山寨板子只有2M Flash故此选择 esp8285
substitutions:
devicename: 'wifi_hotport'
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
api_password: !secret api_password
ota_password: !secret ota_password
status_light_time: "4s"
hotport_ssid: !secret hotport_ssid
hotport_password: !secret hotport_password
esphome:
name: $devicename
platform: ESP8266
board: esp8285
on_boot:
# --------------------------------------------
#这个板子默认亮起 led 灯,所以启动时候要灭掉。
- light.turn_off: red_light
- light.turn_off: green_light
- light.turn_off: blue_light
# ----------------------------------------------
# 循环检查 wifi 状态,修改指示灯。
on_loop:
then:
# 如果 wifi 未连接,关闭蓝灯,执行 script:red_binary(红灯闪烁)
# 这里 script 是异步处理的,script 里面加延迟并不会阻塞主程序
# 也不能使用以下方式
# ----错误示范-----
# on_loop:
# then:
# - light.turn_on: red_light
# - delay: 3s
# - light.turn_off: red_light
# -----------------
# 上方的做法只是三个任务分开执行,关闭红灯和亮起红灯在主程序时间线上是同步执行的.
- if:
condition:
not:
- wifi.connected:
then:
if:
condition:
not:
- script.is_running: red_binary
then:
- script.execute: red_binary
# 如果 wifi 连接正常,并蓝灯还没亮起,那么亮起蓝灯。
- if:
condition:
and:
- light.is_off: blue_light
- wifi.connected:
then:
- light.turn_on: blue_light
wifi:
# 设置ID 可以在 lambda 下用 id($id_name) 调用,继承 WiFiComponent 类。
id: wifi_state
ssid: $wifi_ssid
password: $wifi_password
# 启动 AP 模式,当
ap:
ssid: $hotport_ssid
password: $hotport_password
captive_portal:
# AP 模式下必须启用
web_server:
port: 80
# Enable logging
logger:
# Enable Home Assistant API
api:
password: $api_password
reboot_timeout: 0s
text_sensor:
- platform: template
name: "TEST"
lambda: |-
return {"Hello World"};
update_interval: 2s
ota:
password: $ota_password
light:
- platform: binary
name: "red_light"
id: "red_light"
output: RED_LED_GPIO12
- platform: binary
name: "blue_light"
id: "blue_light"
output: BLUE_LED_GPIO14
- platform: binary
name: "green_light"
id: "green_light"
output: GREEN_LED_GPIO13
output:
- platform: gpio
id: RED_LED_GPIO12
pin: GPIO12
inverted: true
- platform: gpio
id: BLUE_LED_GPIO14
pin: GPIO14
inverted: true
- platform: gpio
id: GREEN_LED_GPIO13
pin: GPIO13
inverted: true
script:
- id: red_binary
then:
# 如果蓝灯亮起就熄灭它
- if:
condition:
light.is_on: blue_light
then:
light.turn_off: blue_light
- light.turn_on: red_light
- delay: 1000ms
- light.turn_off: red_light
- delay: 1000ms