mirror of
https://github.com/randybb/esphome-configs.git
synced 2026-10-14 08:35:12 +02:00
Add status_led package: network, API, error and OTA status on a visible RGB light
Red blink without network, orange without an API client, purple on a component error, blue blink during OTA, green when things are back to normal, then the light returns to its previous state. echo uses it on the gateway LED ring; drop its status_led on GPIO23, which never worked because the ledc output owns that pin.
This commit is contained in:
1 parent
6845679bc0
commit
6a3002d9b7
2 files changed
+132
-9
No files matched your search
@@ -0,0 +1,126 @@
|
|||||||
|
---
|
||||||
|
# Status on a visible RGB light, which stays a normal light otherwise:
|
||||||
|
# network down red, slow blink
|
||||||
|
# no API client (HA) orange, slow blink
|
||||||
|
# component error purple, steady
|
||||||
|
# OTA blue, fast blink; green when done, 3 red blinks on error
|
||||||
|
# back to normal green for 1 s, then the light goes back to how it was
|
||||||
|
# packages:
|
||||||
|
# status_led: !include
|
||||||
|
# file: common/status_led.yaml
|
||||||
|
# vars:
|
||||||
|
# light_id: led_light
|
||||||
|
# Needs the ota id ota_esphome (common/ota_esp32.yaml).
|
||||||
|
defaults:
|
||||||
|
brightness: "0.3"
|
||||||
|
|
||||||
|
globals:
|
||||||
|
- id: status_led_active
|
||||||
|
type: bool
|
||||||
|
initial_value: "false"
|
||||||
|
- id: status_led_saved
|
||||||
|
type: light::LightColorValues
|
||||||
|
- id: status_led_last
|
||||||
|
type: uint32_t
|
||||||
|
initial_value: "0xFFFFFFFF"
|
||||||
|
|
||||||
|
script:
|
||||||
|
- id: status_led_show
|
||||||
|
parameters:
|
||||||
|
r: float
|
||||||
|
g: float
|
||||||
|
b: float
|
||||||
|
lit: bool
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
auto *l = id(${light_id});
|
||||||
|
uint32_t key = (lit << 24) | (uint32_t(r * 255) << 16) | (uint32_t(g * 255) << 8) | uint32_t(b * 255);
|
||||||
|
if (!id(status_led_active)) {
|
||||||
|
id(status_led_saved) = l->remote_values;
|
||||||
|
id(status_led_active) = true;
|
||||||
|
} else if (key == id(status_led_last)) {
|
||||||
|
return; // unchanged: don't flood Home Assistant with the same state
|
||||||
|
}
|
||||||
|
id(status_led_last) = key;
|
||||||
|
if (lit) {
|
||||||
|
l->turn_on().set_rgb(r, g, b).set_brightness(${brightness}).set_transition_length(0).set_effect("None").perform();
|
||||||
|
} else {
|
||||||
|
l->turn_off().set_transition_length(0).perform();
|
||||||
|
}
|
||||||
|
l->loop(); // write now: OTA blocks the main loop
|
||||||
|
- id: status_led_restore
|
||||||
|
parameters:
|
||||||
|
confirm: bool
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
if (id(status_led_active) && confirm) id(status_led_show)->execute(0.0f, 1.0f, 0.0f, true);
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: 'return id(status_led_active) && confirm;'
|
||||||
|
then:
|
||||||
|
- delay: 1s # green: back to normal
|
||||||
|
- lambda: |-
|
||||||
|
if (!id(status_led_active)) return;
|
||||||
|
id(status_led_active) = false;
|
||||||
|
id(status_led_last) = 0xFFFFFFFF;
|
||||||
|
id(${light_id})->make_call().from_light_color_values(id(status_led_saved)).set_transition_length(0).perform();
|
||||||
|
|
||||||
|
interval:
|
||||||
|
- interval: 500ms
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
static uint8_t tick = 0;
|
||||||
|
tick++;
|
||||||
|
bool slow = (tick / 2) % 2 == 0; // 1 s on, 1 s off
|
||||||
|
bool problem = !network::is_connected() || !api::global_api_server->is_connected() ||
|
||||||
|
(App.get_app_state() & STATUS_LED_ERROR);
|
||||||
|
if (problem) id(status_led_restore)->stop();
|
||||||
|
if (!network::is_connected()) {
|
||||||
|
id(status_led_show)->execute(1.0f, 0.0f, 0.0f, slow);
|
||||||
|
} else if (!api::global_api_server->is_connected()) {
|
||||||
|
id(status_led_show)->execute(1.0f, 0.4f, 0.0f, slow);
|
||||||
|
} else if (App.get_app_state() & STATUS_LED_ERROR) {
|
||||||
|
id(status_led_show)->execute(0.6f, 0.0f, 1.0f, true);
|
||||||
|
} else if (id(status_led_active) && !id(status_led_restore)->is_running()) {
|
||||||
|
id(status_led_restore)->execute(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ota:
|
||||||
|
- id: !extend ota_esphome
|
||||||
|
on_begin:
|
||||||
|
- script.execute:
|
||||||
|
id: status_led_show
|
||||||
|
r: 0.0
|
||||||
|
g: 0.0
|
||||||
|
b: 1.0
|
||||||
|
lit: true
|
||||||
|
on_progress:
|
||||||
|
- lambda: 'id(status_led_show)->execute(0.0f, 0.0f, 1.0f, (millis() / 250) % 2 == 0);'
|
||||||
|
on_end:
|
||||||
|
- script.execute:
|
||||||
|
id: status_led_show
|
||||||
|
r: 0.0
|
||||||
|
g: 1.0
|
||||||
|
b: 0.0
|
||||||
|
lit: true
|
||||||
|
on_error:
|
||||||
|
- repeat:
|
||||||
|
count: 3
|
||||||
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: status_led_show
|
||||||
|
r: 1.0
|
||||||
|
g: 0.0
|
||||||
|
b: 0.0
|
||||||
|
lit: true
|
||||||
|
- delay: 250ms
|
||||||
|
- script.execute:
|
||||||
|
id: status_led_show
|
||||||
|
r: 1.0
|
||||||
|
g: 0.0
|
||||||
|
b: 0.0
|
||||||
|
lit: false
|
||||||
|
- delay: 250ms
|
||||||
|
- script.execute:
|
||||||
|
id: status_led_restore
|
||||||
|
confirm: false
|
||||||
+6
-9
@@ -5,7 +5,7 @@
|
|||||||
# GPIO19 -> speaker_bus (i2s_audio i2s_bclk_pin)
|
# GPIO19 -> speaker_bus (i2s_audio i2s_bclk_pin)
|
||||||
# GPIO21 Gateway LED ring red -> led_red (output ledc)
|
# GPIO21 Gateway LED ring red -> led_red (output ledc)
|
||||||
# GPIO22 -> speaker_id (speaker i2s_audio i2s_dout_pin)
|
# GPIO22 -> speaker_id (speaker i2s_audio i2s_dout_pin)
|
||||||
# GPIO23 Gateway LED ring blue -> led_status (light status_led); led_blue (output ledc)
|
# GPIO23 Gateway LED ring blue -> led_blue (output ledc)
|
||||||
# GPIO25 Gateway LED ring green -> led_green (output ledc)
|
# GPIO25 Gateway LED ring green -> led_green (output ledc)
|
||||||
# GPIO26 Grove SDA -> i2c (i2c sda)
|
# GPIO26 Grove SDA -> i2c (i2c sda)
|
||||||
# GPIO27 ATOM onboard RGB LED (inside, not visible)
|
# GPIO27 ATOM onboard RGB LED (inside, not visible)
|
||||||
@@ -33,6 +33,10 @@ esp32:
|
|||||||
packages:
|
packages:
|
||||||
common: !include common/common.yaml
|
common: !include common/common.yaml
|
||||||
ipv6_only: !include common/ipv6_only.yaml
|
ipv6_only: !include common/ipv6_only.yaml
|
||||||
|
status_led: !include
|
||||||
|
file: common/status_led.yaml
|
||||||
|
vars:
|
||||||
|
light_id: led_light
|
||||||
|
|
||||||
external_components:
|
external_components:
|
||||||
# speaker media player: skip a failed playlist item (esphome#19862), drop once merged
|
# speaker media player: skip a failed playlist item (esphome#19862), drop once merged
|
||||||
@@ -90,11 +94,6 @@ light:
|
|||||||
red: led_red
|
red: led_red
|
||||||
green: led_green
|
green: led_green
|
||||||
blue: led_blue
|
blue: led_blue
|
||||||
- platform: status_led
|
|
||||||
id: led_status
|
|
||||||
pin:
|
|
||||||
number: 23
|
|
||||||
allow_other_uses: true
|
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- platform: ledc
|
- platform: ledc
|
||||||
@@ -105,9 +104,7 @@ output:
|
|||||||
pin: 25
|
pin: 25
|
||||||
- platform: ledc
|
- platform: ledc
|
||||||
id: led_blue
|
id: led_blue
|
||||||
pin:
|
pin: 23
|
||||||
number: 23
|
|
||||||
allow_other_uses: true
|
|
||||||
|
|
||||||
i2s_audio:
|
i2s_audio:
|
||||||
- id: speaker_bus
|
- id: speaker_bus
|
||||||
|
|||||||
Reference in new issue
Block a user