From f659af0f6a302e2c4f2e7d1650c0d34a61a95112 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Mon, 20 Nov 2023 19:22:10 +0100 Subject: [PATCH 01/29] Add has_network() to tell of there is a network component setup --- esphome/components/network/util.cpp | 17 +++++++++++++++++ esphome/components/network/util.h | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/esphome/components/network/util.cpp b/esphome/components/network/util.cpp index 109c2947ce..af72658154 100644 --- a/esphome/components/network/util.cpp +++ b/esphome/components/network/util.cpp @@ -12,6 +12,23 @@ namespace esphome { namespace network { +bool has_network() { +#ifdef USE_ETHERNET + if (ethernet::global_eth_component != nullptr) + return true; +#endif + +#ifdef USE_WIFI + if (wifi::global_wifi_component != nullptr) + return true; +#endif + +#ifdef USE_HOST + return true; // Assume its connected +#endif + return false; +} + bool is_connected() { #ifdef USE_ETHERNET if (ethernet::global_eth_component != nullptr && ethernet::global_eth_component->is_connected()) diff --git a/esphome/components/network/util.h b/esphome/components/network/util.h index 0322f19215..d9d62f008c 100644 --- a/esphome/components/network/util.h +++ b/esphome/components/network/util.h @@ -5,7 +5,8 @@ namespace esphome { namespace network { - +/// Return whether has network components enabled (through wifi, eth, ...) +bool has_network(); /// Return whether the node is connected to the network (through wifi, eth, ...) bool is_connected(); /// Return whether the network is disabled (only wifi for now) From a9e3a8ae8c853df5d78673591dfacb123bc8a53f Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Mon, 20 Nov 2023 19:23:23 +0100 Subject: [PATCH 02/29] add is_ap_enabled() to the wifi component --- esphome/components/wifi/wifi_component.cpp | 2 ++ esphome/components/wifi/wifi_component.h | 1 + 2 files changed, 3 insertions(+) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index c1d5138f7b..a3b626815c 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -193,6 +193,8 @@ void WiFiComponent::loop() { WiFiComponent::WiFiComponent() { global_wifi_component = this; } bool WiFiComponent::has_ap() const { return this->has_ap_; } +bool WiFiComponent::is_ap_enabled() const { return this->ap_setup_; } + bool WiFiComponent::has_sta() const { return !this->sta_.empty(); } void WiFiComponent::set_fast_connect(bool fast_connect) { this->fast_connect_ = fast_connect; } #ifdef USE_WIFI_11KV_SUPPORT diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 3ee69bb5de..412c5eebb7 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -244,6 +244,7 @@ class WiFiComponent : public Component { bool has_sta() const; bool has_ap() const; + bool is_ap_enabled() const; #ifdef USE_WIFI_11KV_SUPPORT void set_btm(bool btm); From d8b42afdf2ec974a78d1885a7197081f0001ccc4 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Mon, 20 Nov 2023 19:25:50 +0100 Subject: [PATCH 03/29] first commit of the status_indicator comp. --- .../components/status_indicator/__init__.py | 121 ++++++++++++++ .../status_indicator/status_indicator.cpp | 153 ++++++++++++++++++ .../status_indicator/status_indicator.h | 89 ++++++++++ 3 files changed, 363 insertions(+) create mode 100644 esphome/components/status_indicator/__init__.py create mode 100644 esphome/components/status_indicator/status_indicator.cpp create mode 100644 esphome/components/status_indicator/status_indicator.h diff --git a/esphome/components/status_indicator/__init__.py b/esphome/components/status_indicator/__init__.py new file mode 100644 index 0000000000..047d1f593d --- /dev/null +++ b/esphome/components/status_indicator/__init__.py @@ -0,0 +1,121 @@ +import esphome.config_validation as cv +import esphome.codegen as cg +import esphome.automation as auto +from esphome.const import ( + CONF_ID, + CONF_PRIORITY, + CONF_GROUP, + CONF_TRIGGER_ID, +) + +from esphome.core import coroutine_with_priority + +CODEOWNERS = ["@nielsnl68"] + +status_led_ns = cg.esphome_ns.namespace("status_indicator") +StatusLED = status_led_ns.class_("StatusIndicator", cg.Component) +StatusTrigger = status_led_ns.class_("StatusTrigger", auto.Trigger.template()) +StatusAction = status_led_ns.class_("StatusAction", auto.Trigger.template()) +CONF_TRIGGER_LIST = { + "on_app_error": True, + "on_clear_app_error": True, + "on_app_warning": True, + "on_clear_app_warning": True, + "on_network_connected": True, + "on_network_disconnected": True, + "on_wifi_ap_enabled": True, + "on_wifi_ap_disabled": True, + "on_api_connected": True, + "on_api_disconnected": True, + "on_mqtt_connected": True, + "on_mgtt_disconnected": True, + "on_custom_status": False, +} + + +def trigger_setup(Single): + return auto.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StatusTrigger), + cv.Optional(CONF_GROUP, default=""): cv.string, + cv.Optional(CONF_PRIORITY, default=0): cv.int_range(0, 10), + }, + single=Single, + ) + + +def add_default_triggers(): + result = {} + + for trigger, single in CONF_TRIGGER_LIST.items(): + result[cv.Optional(trigger)] = trigger_setup(single) + return cv.Schema(result) + + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(CONF_ID): cv.declare_id(StatusLED), + } + ) + .extend(cv.COMPONENT_SCHEMA) + .extend(add_default_triggers()) +) + + +async def add_trigger(var, conf, key): + trigger = cg.new_Pvariable( + conf[CONF_TRIGGER_ID], + var, + conf[CONF_GROUP], + conf[CONF_PRIORITY], + ) + await auto.build_automation(trigger, [], conf) + cg.add(var.set_trigger(key, trigger)) + + +@coroutine_with_priority(80.0) +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + for trigger_name, single in CONF_TRIGGER_LIST.items(): + conf = config.get(trigger_name, None) + if conf is None: + continue + if single: + await add_trigger(var, conf, trigger_name) + else: + for conf in config.get(trigger_name, []): + await add_trigger(var, conf, conf[CONF_TRIGGER_ID].id) + + +@auto.register_action( + "status.push", + StatusAction, + cv.Schema( + { + cv.Required(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), + } + ), +) +async def status_action_push_to_code(config, action_id, template_arg, args): + paren = await cg.get_variable(config[CONF_TRIGGER_ID]) + var = cg.new_Pvariable(action_id, template_arg, paren) + cg.add(var.set_state(True)) + return var + + +@auto.register_action( + "status.pop", + StatusAction, + cv.Schema( + { + cv.Required(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), + } + ), +) +async def status_action_pop_to_code(config, action_id, template_arg, args): + paren = await cg.get_variable(config[CONF_TRIGGER_ID]) + var = cg.new_Pvariable(action_id, template_arg, paren) + cg.add(var.set_state(False)) + return var diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp new file mode 100644 index 0000000000..c2577dac24 --- /dev/null +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -0,0 +1,153 @@ +#include "status_indicator.h" +#include "esphome/core/log.h" +#include "esphome/core/application.h" + +#include "esphome/components/network/util.h" + +#ifdef USE_WIFI +#include "esphome/components/wifi/wifi_component.h" +#endif + +#ifdef USE_MQTT +#include "esphome/components/mqtt/mqtt_client.h" +#endif +#ifdef USE_API +#include "esphome/components/api/api_server.h" +#endif + +namespace esphome { +namespace status_indicator { + +static const char *const TAG = "status_indicator"; + +void StatusIndicator::dump_config() { ESP_LOGCONFIG(TAG, "Status Indicator:"); } +void StatusIndicator::loop() { + std::string status{""}; + if ((App.get_app_state() & STATUS_LED_ERROR) != 0u) { + status = "on_app_error"; + this->status_.on_error = 1; + } else if (this->status_.on_error == 1) { + status = "on_clear_app_error"; + this->status_.on_error = 0; + } else if ((App.get_app_state() & STATUS_LED_WARNING) != 0u) { + status = "on_app_warning"; + this->status_.on_warning = 1; + } else if (this->status_.on_warning == 1) { + status = "on_clear_app_warning"; + this->status_.on_warning = 0; + } + if (this->current_trigger_ != nullptr) { + if (this->current_trigger_->is_action_running()) { + if (status == "") { + return; + } + this->current_trigger_->stop_action(); + } + } + if (network::has_network()) { +#ifdef USE_WIFI + if (status == "" && wifi::global_wifi_component->is_ap_enabled()) { + status = "on_wifi_ap_enabled"; + this->status_.on_wifi_ap = 1; + } else if (this->status_.on_wifi_ap == 1) { + status = "on_wifi_ap_disabled"; + this->status_.on_wifi_ap = 0; + } +#endif + + if (status == "" && not network::is_connected()) { + status = "on_network_disconnected"; + this->status_.on_network = 1; + } else if (this->status_.on_network == 1) { + status = "on_network_connected"; + this->status_.on_network = 0; + } + +#ifdef USE_API + if (status == "" && api::global_api_server != nullptr && not api::global_api_server->is_connected()) { + status = "on_api_disconnected"; + this->status_.on_api = 1; + } else if (this->status_.on_error == 1) { + status = "on_api_connected"; + this->status_.on_api = 0; + } +#endif +#ifdef USE_MQTT + if (status == "" && mqtt::global_mqtt_client != nullptr && not mqtt::global_mqtt_client->is_connected()) { + status = "on_mqtt_disconnected"; + this->status_.on_mqtt = 1; + } else if (this->status_.on_mqtt == 1) { + status = "on_mqtt_connected"; + this->status_.on_mqtt = 0; + } +#endif + } + if (this->current_status_ != status) { + if (status != "") { + this->current_trigger_ = get_trigger(status); + if (this->current_trigger_ != nullptr) { + this->current_trigger_->trigger(); + } + } else { + this->current_trigger_ = nullptr; + if (!this->custom_triggers_.empty()) { + this->custom_triggers_[0]->trigger(); + } + } + this->current_status_ = status; + } +} + +float StatusIndicator::get_setup_priority() const { return setup_priority::HARDWARE; } +float StatusIndicator::get_loop_priority() const { return 50.0f; } + +StatusTrigger *StatusIndicator::get_trigger(std::string key) { + auto search = this->triggers_.find(key); + if (search != this->triggers_.end()) + return search->second; + else { + return nullptr; + } +} + +void StatusIndicator::set_trigger(std::string key, StatusTrigger *trigger) { this->triggers_[key] = trigger; } + +void StatusIndicator::push_trigger(StatusTrigger *trigger) { + this->pop_trigger(trigger, true); + uint32_t x = 0; + while (this->custom_triggers_.size() > x) { + if (trigger->get_priority() <= this->custom_triggers_[x]->get_priority()) { + this->custom_triggers_.insert(this->custom_triggers_.begin() + x, trigger); + break; + } else { + x++; + } + } +} + +void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { + uint32_t x = 0; + while (this->custom_triggers_.size() > x) { + if (trigger == this->custom_triggers_[x]) { + this->custom_triggers_.erase(this->custom_triggers_.begin() + x); + } else if (incl_group && trigger->get_group() != "" && trigger->get_group() == this->custom_triggers_[x]->get_group()) { + this->custom_triggers_.erase(this->custom_triggers_.begin() + x); + } else { + x++; + } + } +} + +void StatusIndicator::pop_trigger(std::string group) { + uint32_t x = 0; + while (this->custom_triggers_.size() > x) { + if ( group == this->custom_triggers_[x]->get_group()) { + this->custom_triggers_.erase(this->custom_triggers_.begin() + x); + } else { + x++; + } + } +} + +} // namespace status_indicator +} // namespace esphome diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h new file mode 100644 index 0000000000..402c01041d --- /dev/null +++ b/esphome/components/status_indicator/status_indicator.h @@ -0,0 +1,89 @@ +#pragma once + +#include +#include +#include "esphome/core/component.h" +#include "esphome/core/hal.h" +#include "esphome/components/light/automation.h" + +namespace esphome { +namespace status_indicator { +class StatusTrigger; +union StatusFlags { + struct { + int on_error : 1; + int on_warning : 1; + int on_network : 1; + int on_api : 1; + int on_mqtt : 1; + int on_wifi_ap : 1; + }; + int setter = 0; +}; + +class StatusIndicator : public Component { + public: + void dump_config() override; + void loop() override; + + float get_setup_priority() const override; + float get_loop_priority() const override; + + StatusTrigger *get_trigger(std::string key); + void set_trigger(std::string key, StatusTrigger *trigger); + void push_trigger(StatusTrigger *trigger); + void pop_trigger(StatusTrigger *trigger, bool incl_group = false); + void pop_trigger(std::string group); + + protected: + std::string current_status_{""}; + StatusTrigger *current_trigger_{nullptr}; + StatusFlags status_; + std::map triggers_{}; + std::vector custom_triggers_{}; +}; + +class StatusTrigger : public Trigger<> { + public: + explicit StatusTrigger(StatusIndicator *parent, std::string group, uint32_t priority) + : parent_(parent), group_(group), priority_(priority) {} + std::string get_group() { return this->group_; } + uint32 get_priority() { return this->priority_; } + void push_me() { parent_->push_trigger(this); } + void pop_me() { parent_->pop_trigger(this, false); } + + protected: + StatusIndicator *parent_; + std::string group_; /// Minimum length of click. 0 means no minimum. + uint32_t priority_; /// Maximum length of click. 0 means no maximum. +}; + +template class StatusCondition : public Condition { + public: + StatusCondition(StatusIndicator *parent, bool state) : parent_(parent), state_(state) {} + bool check(Ts... x) override { return (this->parent_->status_.setter == 0) == this->state_; } + + protected: + StatusIndicator *parent_; + bool state_; +}; + +template class StatusAction : public Action { + public: + explicit StatusAction(StatusTrigger *trigger) : trigger_(trigger) {} + TEMPLATABLE_VALUE(bool, state) + + void play(Ts... x) override { + if (this->state_) { + + } else { + + } + } + + protected: + StatusTrigger *trigger_; +}; + +} // namespace status_indicator +} // namespace esphome From 9ac02ea20c293be897333e4adc56bafa9a573ff2 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 15:25:19 +0100 Subject: [PATCH 04/29] add test script --- esphome/components/network/util.cpp | 17 --- esphome/components/network/util.h | 3 +- .../components/status_indicator/__init__.py | 20 ++-- .../status_indicator/_test/.gitignore | 5 + .../status_indicator/_test/test.yaml | 107 ++++++++++++++++++ .../status_indicator/status_indicator.cpp | 78 ++++++++++--- .../status_indicator/status_indicator.h | 4 +- 7 files changed, 188 insertions(+), 46 deletions(-) create mode 100644 esphome/components/status_indicator/_test/.gitignore create mode 100644 esphome/components/status_indicator/_test/test.yaml diff --git a/esphome/components/network/util.cpp b/esphome/components/network/util.cpp index af72658154..109c2947ce 100644 --- a/esphome/components/network/util.cpp +++ b/esphome/components/network/util.cpp @@ -12,23 +12,6 @@ namespace esphome { namespace network { -bool has_network() { -#ifdef USE_ETHERNET - if (ethernet::global_eth_component != nullptr) - return true; -#endif - -#ifdef USE_WIFI - if (wifi::global_wifi_component != nullptr) - return true; -#endif - -#ifdef USE_HOST - return true; // Assume its connected -#endif - return false; -} - bool is_connected() { #ifdef USE_ETHERNET if (ethernet::global_eth_component != nullptr && ethernet::global_eth_component->is_connected()) diff --git a/esphome/components/network/util.h b/esphome/components/network/util.h index d9d62f008c..0322f19215 100644 --- a/esphome/components/network/util.h +++ b/esphome/components/network/util.h @@ -5,8 +5,7 @@ namespace esphome { namespace network { -/// Return whether has network components enabled (through wifi, eth, ...) -bool has_network(); + /// Return whether the node is connected to the network (through wifi, eth, ...) bool is_connected(); /// Return whether the network is disabled (only wifi for now) diff --git a/esphome/components/status_indicator/__init__.py b/esphome/components/status_indicator/__init__.py index 047d1f593d..ff84ddb9f1 100644 --- a/esphome/components/status_indicator/__init__.py +++ b/esphome/components/status_indicator/__init__.py @@ -31,6 +31,7 @@ CONF_TRIGGER_LIST = { "on_mgtt_disconnected": True, "on_custom_status": False, } +CONF_ON_TURN_OFF = "on_turn_off" def trigger_setup(Single): @@ -56,6 +57,7 @@ CONFIG_SCHEMA = ( cv.Schema( { cv.GenerateID(CONF_ID): cv.declare_id(StatusLED), + cv.Required(CONF_ON_TURN_OFF): trigger_setup(True), } ) .extend(cv.COMPONENT_SCHEMA) @@ -71,22 +73,24 @@ async def add_trigger(var, conf, key): conf[CONF_PRIORITY], ) await auto.build_automation(trigger, [], conf) - cg.add(var.set_trigger(key, trigger)) + if key is not None: + cg.add(var.set_trigger(key, trigger)) @coroutine_with_priority(80.0) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) + await add_trigger(var, config.get(CONF_ON_TURN_OFF), CONF_ON_TURN_OFF) + for trigger_name, single in CONF_TRIGGER_LIST.items(): conf = config.get(trigger_name, None) - if conf is None: - continue - if single: - await add_trigger(var, conf, trigger_name) - else: - for conf in config.get(trigger_name, []): - await add_trigger(var, conf, conf[CONF_TRIGGER_ID].id) + if conf is not None: + if single: + await add_trigger(var, conf, trigger_name) + else: + for conf in config.get(trigger_name, []): + await add_trigger(var, conf, None) @auto.register_action( diff --git a/esphome/components/status_indicator/_test/.gitignore b/esphome/components/status_indicator/_test/.gitignore new file mode 100644 index 0000000000..d8b4157aef --- /dev/null +++ b/esphome/components/status_indicator/_test/.gitignore @@ -0,0 +1,5 @@ +# Gitignore settings for ESPHome +# This is an example and may include too much for your use-case. +# You can modify this file to suit your needs. +/.esphome/ +/secrets.yaml diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml new file mode 100644 index 0000000000..aa2152f729 --- /dev/null +++ b/esphome/components/status_indicator/_test/test.yaml @@ -0,0 +1,107 @@ +--- +esphome: + name: m5stack-atom-echo + +esp32: + board: m5stack-atom + + +light: + - platform: esp32_rmt_led_strip + id: led + name: None + disabled_by_default: true + entity_category: config + pin: GPIO27 + default_transition_length: 0s + chipset: SK6812 + num_leds: 1 + rgb_order: grb + rmt_channel: 0 + effects: + - pulse: + name: "Slow Pulse" + transition_length: 250ms + update_interval: 250ms + min_brightness: 50% + max_brightness: 100% + - pulse: + name: "Fast Pulse" + transition_length: 100ms + update_interval: 100ms + min_brightness: 50% + max_brightness: 100% + + +binary_sensor: + - platform: gpio + pin: + number: GPIO39 + inverted: true + name: Button + disabled_by_default: true + entity_category: diagnostic + id: button + on_press: + - status.push: + trigger_id: custom_status + on_release: + - status.pop: + trigger_id: custom_status + on_click: + - min_length: 50ms + max_length: 350ms + then: + - status.push: + trigger_id: custom_status + - min_length: 500ms + max_length: 1000ms + then: + - status.pop: + trigger_id: custom_status + + +status_indicator: + on_clear_all: #Manditory + - light.turn_off: + id: led + + on_app_error: + then: + - light.turn_on: + id: led + red: 100% + green: 0% + blue: 0% + brightness: 100% + effect: Fast Pulse + + on_app_warning: + then: + - light.turn_on: + id: led + red: 100% + green: 0% + blue: 0% + brightness: 100% + effect: None + + on_custom_status: + - trigger_id: custom_status + then: + - light.turn_on: + id: led + red: 0% + green: 100% + blue: 0% + brightness: 100% + effect: None + - trigger_id: custom_status2 + then: + - light.turn_on: + id: led + red: 0% + green: 100% + blue: 50% + brightness: 100% + effect: None diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index c2577dac24..5c93daf384 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -2,12 +2,9 @@ #include "esphome/core/log.h" #include "esphome/core/application.h" -#include "esphome/components/network/util.h" - #ifdef USE_WIFI #include "esphome/components/wifi/wifi_component.h" #endif - #ifdef USE_MQTT #include "esphome/components/mqtt/mqtt_client.h" #endif @@ -18,6 +15,40 @@ namespace esphome { namespace status_indicator { +bool has_network() { +#ifdef USE_ETHERNET + if (ethernet::global_eth_component != nullptr) + return true; +#endif + +#ifdef USE_WIFI + if (wifi::global_wifi_component != nullptr) + return true; +#endif + +#ifdef USE_HOST + return true; // Assume its connected +#endif + return false; +} + +bool is_connected() { +#ifdef USE_ETHERNET + if (ethernet::global_eth_component != nullptr && ethernet::global_eth_component->is_connected()) + return true; +#endif + +#ifdef USE_WIFI + if (wifi::global_wifi_component != nullptr) + return wifi::global_wifi_component->is_connected(); +#endif + +#ifdef USE_HOST + return true; // Assume its connected +#endif + return false; +} + static const char *const TAG = "status_indicator"; void StatusIndicator::dump_config() { ESP_LOGCONFIG(TAG, "Status Indicator:"); } @@ -44,7 +75,7 @@ void StatusIndicator::loop() { this->current_trigger_->stop_action(); } } - if (network::has_network()) { + if (has_network()) { #ifdef USE_WIFI if (status == "" && wifi::global_wifi_component->is_ap_enabled()) { status = "on_wifi_ap_enabled"; @@ -55,7 +86,7 @@ void StatusIndicator::loop() { } #endif - if (status == "" && not network::is_connected()) { + if (status == "" && not is_connected()) { status = "on_network_disconnected"; this->status_.on_network = 1; } else if (this->status_.on_network == 1) { @@ -83,17 +114,19 @@ void StatusIndicator::loop() { #endif } if (this->current_status_ != status) { + StatusTrigger *oldtrigger = this->current_trigger_; if (status != "") { this->current_trigger_ = get_trigger(status); if (this->current_trigger_ != nullptr) { - this->current_trigger_->trigger(); + this->current_trigger_ = get_trigger("on_turn_off"); } + } else if (!this->custom_triggers_.empty()) { + this->current_trigger_ = this->custom_triggers_[0]; } else { - this->current_trigger_ = nullptr; - if (!this->custom_triggers_.empty()) { - this->custom_triggers_[0]->trigger(); - } + this->current_trigger_ = get_trigger("on_turn_off"); } + if (oldtrigger != this->current_trigger_) + this->current_trigger_->trigger(); this->current_status_ = status; } } @@ -115,12 +148,18 @@ void StatusIndicator::set_trigger(std::string key, StatusTrigger *trigger) { thi void StatusIndicator::push_trigger(StatusTrigger *trigger) { this->pop_trigger(trigger, true); uint32_t x = 0; - while (this->custom_triggers_.size() > x) { - if (trigger->get_priority() <= this->custom_triggers_[x]->get_priority()) { - this->custom_triggers_.insert(this->custom_triggers_.begin() + x, trigger); - break; - } else { - x++; + if (this->custom_triggers_.empty()) { + this->custom_triggers_.push_back(trigger); + this->current_status_ = "update me"; + } else { + while (this->custom_triggers_.size() > x) { + if (trigger->get_priority() <= this->custom_triggers_[x]->get_priority()) { + this->custom_triggers_.insert(this->custom_triggers_.begin() + x, trigger); + this->current_status_ = "update me"; + break; + } else { + x++; + } } } } @@ -130,8 +169,11 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { while (this->custom_triggers_.size() > x) { if (trigger == this->custom_triggers_[x]) { this->custom_triggers_.erase(this->custom_triggers_.begin() + x); - } else if (incl_group && trigger->get_group() != "" && trigger->get_group() == this->custom_triggers_[x]->get_group()) { + this->current_status_ = "update me"; + } else if (incl_group && trigger->get_group() != "" && + trigger->get_group() == this->custom_triggers_[x]->get_group()) { this->custom_triggers_.erase(this->custom_triggers_.begin() + x); + this->current_status_ = "update me"; } else { x++; } @@ -143,10 +185,12 @@ void StatusIndicator::pop_trigger(std::string group) { while (this->custom_triggers_.size() > x) { if ( group == this->custom_triggers_[x]->get_group()) { this->custom_triggers_.erase(this->custom_triggers_.begin() + x); + this->current_status_ = "update me"; } else { x++; } } + } } // namespace status_indicator diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index 402c01041d..358c968dd0 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -48,7 +48,7 @@ class StatusTrigger : public Trigger<> { explicit StatusTrigger(StatusIndicator *parent, std::string group, uint32_t priority) : parent_(parent), group_(group), priority_(priority) {} std::string get_group() { return this->group_; } - uint32 get_priority() { return this->priority_; } + uint32_t get_priority() { return this->priority_; } void push_me() { parent_->push_trigger(this); } void pop_me() { parent_->pop_trigger(this, false); } @@ -74,7 +74,7 @@ template class StatusAction : public Action { TEMPLATABLE_VALUE(bool, state) void play(Ts... x) override { - if (this->state_) { + if (false) { } else { From f05def1339b8dffcea7be3d6f1aac5aa8728f746 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 15:28:13 +0100 Subject: [PATCH 05/29] update test script --- esphome/components/status_indicator/_test/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml index aa2152f729..5335558e9b 100644 --- a/esphome/components/status_indicator/_test/test.yaml +++ b/esphome/components/status_indicator/_test/test.yaml @@ -53,12 +53,12 @@ binary_sensor: max_length: 350ms then: - status.push: - trigger_id: custom_status + trigger_id: custom_status2 - min_length: 500ms max_length: 1000ms then: - status.pop: - trigger_id: custom_status + trigger_id: custom_status2 status_indicator: From ccfaa219fbbc208e7276f810537c7d90718bfdf1 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 15:34:35 +0100 Subject: [PATCH 06/29] update codeowners --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index dd1586d039..f1d713606a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -304,6 +304,7 @@ esphome/components/ssd1351_spi/* @kbx81 esphome/components/st7735/* @SenexCrenshaw esphome/components/st7789v/* @kbx81 esphome/components/st7920/* @marsjan155 +esphome/components/status_indicator/* @nielsnl68 esphome/components/substitutions/* @esphome/core esphome/components/sun/* @OttoWinter esphome/components/switch/* @esphome/core From 8dd4415065d9a81bd898bfc03bb370206103b670 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 15:43:58 +0100 Subject: [PATCH 07/29] update suggested fixes --- esphome/components/status_indicator/__init__.py | 2 +- esphome/components/status_indicator/status_indicator.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/esphome/components/status_indicator/__init__.py b/esphome/components/status_indicator/__init__.py index ff84ddb9f1..19048f5a77 100644 --- a/esphome/components/status_indicator/__init__.py +++ b/esphome/components/status_indicator/__init__.py @@ -6,6 +6,7 @@ from esphome.const import ( CONF_PRIORITY, CONF_GROUP, CONF_TRIGGER_ID, + CONF_ON_TURN_OFF, ) from esphome.core import coroutine_with_priority @@ -31,7 +32,6 @@ CONF_TRIGGER_LIST = { "on_mgtt_disconnected": True, "on_custom_status": False, } -CONF_ON_TURN_OFF = "on_turn_off" def trigger_setup(Single): diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index 358c968dd0..8a4fe48270 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -75,14 +75,12 @@ template class StatusAction : public Action { void play(Ts... x) override { if (false) { - } else { - } } protected: - StatusTrigger *trigger_; + StatusTrigger *trigger_; }; } // namespace status_indicator From 661c9de61082b5ea6ae0ac16140f5e0bb9558486 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 15:47:33 +0100 Subject: [PATCH 08/29] update suggested fixes part2 --- esphome/components/status_indicator/status_indicator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 5c93daf384..c63cd79e11 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -183,14 +183,13 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { void StatusIndicator::pop_trigger(std::string group) { uint32_t x = 0; while (this->custom_triggers_.size() > x) { - if ( group == this->custom_triggers_[x]->get_group()) { + if (group == this->custom_triggers_[x]->get_group()) { this->custom_triggers_.erase(this->custom_triggers_.begin() + x); this->current_status_ = "update me"; } else { x++; } } - } } // namespace status_indicator From ce9e00a45330916f59da5430f3f894957ee00c76 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 18:47:49 +0100 Subject: [PATCH 09/29] implement push/pop action --- .../components/status_indicator/__init__.py | 34 +++++++++++++------ .../status_indicator/_test/test.yaml | 14 ++++---- .../status_indicator/status_indicator.h | 25 +++++++++----- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/esphome/components/status_indicator/__init__.py b/esphome/components/status_indicator/__init__.py index 19048f5a77..583f9af903 100644 --- a/esphome/components/status_indicator/__init__.py +++ b/esphome/components/status_indicator/__init__.py @@ -14,7 +14,7 @@ from esphome.core import coroutine_with_priority CODEOWNERS = ["@nielsnl68"] status_led_ns = cg.esphome_ns.namespace("status_indicator") -StatusLED = status_led_ns.class_("StatusIndicator", cg.Component) +StatusIndicator = status_led_ns.class_("StatusIndicator", cg.Component) StatusTrigger = status_led_ns.class_("StatusTrigger", auto.Trigger.template()) StatusAction = status_led_ns.class_("StatusAction", auto.Trigger.template()) CONF_TRIGGER_LIST = { @@ -32,6 +32,7 @@ CONF_TRIGGER_LIST = { "on_mgtt_disconnected": True, "on_custom_status": False, } +CONF_WHICH = "which" def trigger_setup(Single): @@ -56,7 +57,7 @@ def add_default_triggers(): CONFIG_SCHEMA = ( cv.Schema( { - cv.GenerateID(CONF_ID): cv.declare_id(StatusLED), + cv.GenerateID(CONF_ID): cv.declare_id(StatusIndicator), cv.Required(CONF_ON_TURN_OFF): trigger_setup(True), } ) @@ -96,30 +97,43 @@ async def to_code(config): @auto.register_action( "status.push", StatusAction, - cv.Schema( + cv.maybe_simple_value( { + cv.GenerateID(CONF_ID): cv.use_id(StatusIndicator), cv.Required(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), - } + }, + key=CONF_TRIGGER_ID, ), ) async def status_action_push_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_TRIGGER_ID]) + paren = await cg.get_variable(config[CONF_ID]) var = cg.new_Pvariable(action_id, template_arg, paren) cg.add(var.set_state(True)) + cg.add(var.set_trigger(config[CONF_TRIGGER_ID])) return var @auto.register_action( "status.pop", StatusAction, - cv.Schema( - { - cv.Required(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), - } + cv.All( + cv.maybe_simple_value( + { + cv.GenerateID(CONF_ID): cv.use_id(StatusIndicator), + cv.Optional(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), + cv.Optional(CONF_WHICH): cv.string, + }, + key=CONF_TRIGGER_ID, + ), ), ) async def status_action_pop_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_TRIGGER_ID]) + paren = await cg.get_variable(config[CONF_ID]) var = cg.new_Pvariable(action_id, template_arg, paren) cg.add(var.set_state(False)) + if CONF_TRIGGER_ID in config: + cg.add(var.set_group(config[CONF_TRIGGER_ID])) + else: + cg.add(var.set_trigger(config[CONF_WHICH])) + return var diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml index 5335558e9b..8d31140f91 100644 --- a/esphome/components/status_indicator/_test/test.yaml +++ b/esphome/components/status_indicator/_test/test.yaml @@ -43,26 +43,23 @@ binary_sensor: entity_category: diagnostic id: button on_press: - - status.push: - trigger_id: custom_status + - status.push: custom_status on_release: - - status.pop: - trigger_id: custom_status + - status.pop: custom_status on_click: - min_length: 50ms max_length: 350ms then: - - status.push: - trigger_id: custom_status2 + - status.push: custom_status2 - min_length: 500ms max_length: 1000ms then: - status.pop: - trigger_id: custom_status2 + which: "lailydfasdf" status_indicator: - on_clear_all: #Manditory + on_turn_off: #Manditory - light.turn_off: id: led @@ -97,6 +94,7 @@ status_indicator: brightness: 100% effect: None - trigger_id: custom_status2 + group: laily then: - light.turn_on: id: led diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index 8a4fe48270..3e2fbfe352 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -46,11 +46,9 @@ class StatusIndicator : public Component { class StatusTrigger : public Trigger<> { public: explicit StatusTrigger(StatusIndicator *parent, std::string group, uint32_t priority) - : parent_(parent), group_(group), priority_(priority) {} + : parent_(parent), group_(std::move(std::move(group))), priority_(priority) {} std::string get_group() { return this->group_; } uint32_t get_priority() { return this->priority_; } - void push_me() { parent_->push_trigger(this); } - void pop_me() { parent_->pop_trigger(this, false); } protected: StatusIndicator *parent_; @@ -70,17 +68,28 @@ template class StatusCondition : public Condition { template class StatusAction : public Action { public: - explicit StatusAction(StatusTrigger *trigger) : trigger_(trigger) {} - TEMPLATABLE_VALUE(bool, state) + explicit StatusAction(StatusIndicator *indicator) : indicator_(indicator) {} + void set_state(bool state) { this->state_ = state; } + void set_tigger(StatusTrigger *trigger) { this->trigger_ = trigger; } + void set_group(std::string group) {this->group_ = std::move(std::move(group)); } void play(Ts... x) override { - if (false) { - } else { + if (this->state_) { + if (this->trigger_ != nullptr) { + indicator_->push_trigger(this->trigger_); + } + } else if (this->group_ !="") { + indicator_->pop_trigger(group); + } else if (this->trigger_ != nullptr) { + indicator_->pop_trigger(this->trigger_, false); } } protected: - StatusTrigger *trigger_; + StatusIndicator *indicator_; + StatusTrigger *trigger_{nullptr}; + std::string group{""}; + bool State_{false}; }; } // namespace status_indicator From 0a8822d9f59fd5ba76fd8329d0c8d539fb57188a Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 20:13:34 +0100 Subject: [PATCH 10/29] implemented the push/pop action properly --- .../components/status_indicator/__init__.py | 60 +++++++++++++------ .../status_indicator/_test/test.yaml | 17 ++---- .../status_indicator/status_indicator.h | 15 +++-- 3 files changed, 55 insertions(+), 37 deletions(-) diff --git a/esphome/components/status_indicator/__init__.py b/esphome/components/status_indicator/__init__.py index 583f9af903..d5869db8d4 100644 --- a/esphome/components/status_indicator/__init__.py +++ b/esphome/components/status_indicator/__init__.py @@ -7,6 +7,11 @@ from esphome.const import ( CONF_GROUP, CONF_TRIGGER_ID, CONF_ON_TURN_OFF, + CONF_VALUE, +) +from esphome.schema_extractors import ( + SCHEMA_EXTRACT, + schema_extractor, ) from esphome.core import coroutine_with_priority @@ -16,7 +21,7 @@ CODEOWNERS = ["@nielsnl68"] status_led_ns = cg.esphome_ns.namespace("status_indicator") StatusIndicator = status_led_ns.class_("StatusIndicator", cg.Component) StatusTrigger = status_led_ns.class_("StatusTrigger", auto.Trigger.template()) -StatusAction = status_led_ns.class_("StatusAction", auto.Trigger.template()) +StatusAction = status_led_ns.class_("StatusAction", auto.Action) CONF_TRIGGER_LIST = { "on_app_error": True, "on_clear_app_error": True, @@ -94,10 +99,26 @@ async def to_code(config): await add_trigger(var, conf, None) +def maybe_simple_valuex(*validators, **kwargs): + key = kwargs.pop("key", CONF_VALUE) + validator = cv.All(*validators) + + @schema_extractor("maybe") + def validate(value): + if value == SCHEMA_EXTRACT: + return (validator, key) + + if isinstance(value, dict): + return validator(value) + return validator({key: value}) + + return validate + + @auto.register_action( "status.push", StatusAction, - cv.maybe_simple_value( + maybe_simple_valuex( { cv.GenerateID(CONF_ID): cv.use_id(StatusIndicator), cv.Required(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), @@ -106,34 +127,37 @@ async def to_code(config): ), ) async def status_action_push_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_ID]) - var = cg.new_Pvariable(action_id, template_arg, paren) + var = cg.new_Pvariable(action_id, template_arg) + + await cg.register_parented(var, config[CONF_ID]) + cg.add(var.set_state(True)) - cg.add(var.set_trigger(config[CONF_TRIGGER_ID])) + trigger = await cg.get_variable(config[CONF_TRIGGER_ID]) + cg.add(var.set_trigger(trigger)) return var @auto.register_action( "status.pop", StatusAction, - cv.All( - cv.maybe_simple_value( - { - cv.GenerateID(CONF_ID): cv.use_id(StatusIndicator), - cv.Optional(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), - cv.Optional(CONF_WHICH): cv.string, - }, - key=CONF_TRIGGER_ID, - ), + maybe_simple_valuex( + { + cv.GenerateID(CONF_ID): cv.use_id(StatusIndicator), + cv.Optional(CONF_GROUP): cv.string, + cv.Optional(CONF_TRIGGER_ID): cv.use_id(StatusTrigger), + }, + cv.has_exactly_one_key(CONF_GROUP, CONF_TRIGGER_ID), + key=CONF_TRIGGER_ID, ), ) async def status_action_pop_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_ID]) - var = cg.new_Pvariable(action_id, template_arg, paren) + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) cg.add(var.set_state(False)) if CONF_TRIGGER_ID in config: - cg.add(var.set_group(config[CONF_TRIGGER_ID])) + trigger = await cg.get_variable(config[CONF_TRIGGER_ID]) + cg.add(var.set_trigger(trigger)) else: - cg.add(var.set_trigger(config[CONF_WHICH])) + cg.add(var.set_group(config[CONF_GROUP])) return var diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml index 8d31140f91..fdc6e819e4 100644 --- a/esphome/components/status_indicator/_test/test.yaml +++ b/esphome/components/status_indicator/_test/test.yaml @@ -44,18 +44,13 @@ binary_sensor: id: button on_press: - status.push: custom_status + - status.push: custom_status2 on_release: + - status.pop: + group: "custom" + - delay: 5s - status.pop: custom_status - on_click: - - min_length: 50ms - max_length: 350ms - then: - - status.push: custom_status2 - - min_length: 500ms - max_length: 1000ms - then: - - status.pop: - which: "lailydfasdf" + status_indicator: @@ -94,7 +89,7 @@ status_indicator: brightness: 100% effect: None - trigger_id: custom_status2 - group: laily + group: custom then: - light.turn_on: id: led diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index 3e2fbfe352..fe02f70023 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -66,30 +66,29 @@ template class StatusCondition : public Condition { bool state_; }; -template class StatusAction : public Action { +template class StatusAction : public Action, public Parented { public: - explicit StatusAction(StatusIndicator *indicator) : indicator_(indicator) {} void set_state(bool state) { this->state_ = state; } - void set_tigger(StatusTrigger *trigger) { this->trigger_ = trigger; } + void set_trigger(StatusTrigger *trigger) { this->trigger_ = trigger; } void set_group(std::string group) {this->group_ = std::move(std::move(group)); } void play(Ts... x) override { if (this->state_) { if (this->trigger_ != nullptr) { - indicator_->push_trigger(this->trigger_); + this->parent_->push_trigger(this->trigger_); } } else if (this->group_ !="") { - indicator_->pop_trigger(group); + this->parent_->pop_trigger(this->group_); } else if (this->trigger_ != nullptr) { - indicator_->pop_trigger(this->trigger_, false); + this->parent_->pop_trigger(this->trigger_, false); } } protected: StatusIndicator *indicator_; StatusTrigger *trigger_{nullptr}; - std::string group{""}; - bool State_{false}; + std::string group_{""}; + bool state_{false}; }; } // namespace status_indicator From 5d779d17c7237ffb073b694b8cadd8331450d4b5 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 20:19:29 +0100 Subject: [PATCH 11/29] update suggested fixes part3 --- esphome/components/status_indicator/status_indicator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index fe02f70023..9b9e072f8f 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -70,14 +70,14 @@ template class StatusAction : public Action, public Paren public: void set_state(bool state) { this->state_ = state; } void set_trigger(StatusTrigger *trigger) { this->trigger_ = trigger; } - void set_group(std::string group) {this->group_ = std::move(std::move(group)); } + void set_group(std::string group) { this->group_ = std::move(std::move(group)); } void play(Ts... x) override { if (this->state_) { if (this->trigger_ != nullptr) { this->parent_->push_trigger(this->trigger_); } - } else if (this->group_ !="") { + } else if (this->group_ != "") { this->parent_->pop_trigger(this->group_); } else if (this->trigger_ != nullptr) { this->parent_->pop_trigger(this->trigger_, false); From 03d2f8a5c33d167371ff1c82a1cb59ee8f5b7f5b Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 21:15:38 +0100 Subject: [PATCH 12/29] update suggested fixes part4 --- .../status_indicator/status_indicator.cpp | 24 +++++++++---------- .../status_indicator/status_indicator.h | 8 +++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index c63cd79e11..a66f60d6af 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -69,7 +69,7 @@ void StatusIndicator::loop() { } if (this->current_trigger_ != nullptr) { if (this->current_trigger_->is_action_running()) { - if (status == "") { + if (status.empty()) { return; } this->current_trigger_->stop_action(); @@ -77,7 +77,7 @@ void StatusIndicator::loop() { } if (has_network()) { #ifdef USE_WIFI - if (status == "" && wifi::global_wifi_component->is_ap_enabled()) { + if (status.empty() && wifi::global_wifi_component->is_ap_enabled()) { status = "on_wifi_ap_enabled"; this->status_.on_wifi_ap = 1; } else if (this->status_.on_wifi_ap == 1) { @@ -86,7 +86,7 @@ void StatusIndicator::loop() { } #endif - if (status == "" && not is_connected()) { + if (status.empty() && not is_connected()) { status = "on_network_disconnected"; this->status_.on_network = 1; } else if (this->status_.on_network == 1) { @@ -95,7 +95,7 @@ void StatusIndicator::loop() { } #ifdef USE_API - if (status == "" && api::global_api_server != nullptr && not api::global_api_server->is_connected()) { + if (status.empty() && api::global_api_server != nullptr && not api::global_api_server->is_connected()) { status = "on_api_disconnected"; this->status_.on_api = 1; } else if (this->status_.on_error == 1) { @@ -104,7 +104,7 @@ void StatusIndicator::loop() { } #endif #ifdef USE_MQTT - if (status == "" && mqtt::global_mqtt_client != nullptr && not mqtt::global_mqtt_client->is_connected()) { + if (status.empty() && mqtt::global_mqtt_client != nullptr && not mqtt::global_mqtt_client->is_connected()) { status = "on_mqtt_disconnected"; this->status_.on_mqtt = 1; } else if (this->status_.on_mqtt == 1) { @@ -115,7 +115,7 @@ void StatusIndicator::loop() { } if (this->current_status_ != status) { StatusTrigger *oldtrigger = this->current_trigger_; - if (status != "") { + if (!status.empty()) { this->current_trigger_ = get_trigger(status); if (this->current_trigger_ != nullptr) { this->current_trigger_ = get_trigger("on_turn_off"); @@ -134,16 +134,16 @@ void StatusIndicator::loop() { float StatusIndicator::get_setup_priority() const { return setup_priority::HARDWARE; } float StatusIndicator::get_loop_priority() const { return 50.0f; } -StatusTrigger *StatusIndicator::get_trigger(std::string key) { +StatusTrigger *StatusIndicator::get_trigger(const std::string& key) { auto search = this->triggers_.find(key); - if (search != this->triggers_.end()) + if (search != this->triggers_.end()) { return search->second; - else { + } else { return nullptr; } } -void StatusIndicator::set_trigger(std::string key, StatusTrigger *trigger) { this->triggers_[key] = trigger; } +void StatusIndicator::set_trigger(const std::string& key, StatusTrigger *trigger) { this->triggers_[key] = trigger; } void StatusIndicator::push_trigger(StatusTrigger *trigger) { this->pop_trigger(trigger, true); @@ -170,7 +170,7 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { if (trigger == this->custom_triggers_[x]) { this->custom_triggers_.erase(this->custom_triggers_.begin() + x); this->current_status_ = "update me"; - } else if (incl_group && trigger->get_group() != "" && + } else if (incl_group && !trigger->get_group().empty() && trigger->get_group() == this->custom_triggers_[x]->get_group()) { this->custom_triggers_.erase(this->custom_triggers_.begin() + x); this->current_status_ = "update me"; @@ -180,7 +180,7 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { } } -void StatusIndicator::pop_trigger(std::string group) { +void StatusIndicator::pop_trigger(const std::string& group) { uint32_t x = 0; while (this->custom_triggers_.size() > x) { if (group == this->custom_triggers_[x]->get_group()) { diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index 9b9e072f8f..86fc23fa0a 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -29,11 +29,11 @@ class StatusIndicator : public Component { float get_setup_priority() const override; float get_loop_priority() const override; - StatusTrigger *get_trigger(std::string key); - void set_trigger(std::string key, StatusTrigger *trigger); + StatusTrigger *get_trigger(const std::string &key); + void set_trigger(const std::string &key, StatusTrigger *trigger); void push_trigger(StatusTrigger *trigger); void pop_trigger(StatusTrigger *trigger, bool incl_group = false); - void pop_trigger(std::string group); + void pop_trigger(const std::string &group); protected: std::string current_status_{""}; @@ -70,7 +70,7 @@ template class StatusAction : public Action, public Paren public: void set_state(bool state) { this->state_ = state; } void set_trigger(StatusTrigger *trigger) { this->trigger_ = trigger; } - void set_group(std::string group) { this->group_ = std::move(std::move(group)); } + void set_group(const std::string &group) { this->group_ = std::move(std::move(group)); } void play(Ts... x) override { if (this->state_) { From 4524483f0d21e8d804bd1146dc74facde262ea5c Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 21:32:11 +0100 Subject: [PATCH 13/29] update suggested fixes part5 --- esphome/components/status_indicator/status_indicator.cpp | 6 +++--- esphome/components/status_indicator/status_indicator.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index a66f60d6af..32c2bb298d 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -134,7 +134,7 @@ void StatusIndicator::loop() { float StatusIndicator::get_setup_priority() const { return setup_priority::HARDWARE; } float StatusIndicator::get_loop_priority() const { return 50.0f; } -StatusTrigger *StatusIndicator::get_trigger(const std::string& key) { +StatusTrigger *StatusIndicator::get_trigger(const std::string &key) { auto search = this->triggers_.find(key); if (search != this->triggers_.end()) { return search->second; @@ -143,7 +143,7 @@ StatusTrigger *StatusIndicator::get_trigger(const std::string& key) { } } -void StatusIndicator::set_trigger(const std::string& key, StatusTrigger *trigger) { this->triggers_[key] = trigger; } +void StatusIndicator::set_trigger(const std::string &key, StatusTrigger *trigger) { this->triggers_[key] = trigger; } void StatusIndicator::push_trigger(StatusTrigger *trigger) { this->pop_trigger(trigger, true); @@ -180,7 +180,7 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { } } -void StatusIndicator::pop_trigger(const std::string& group) { +void StatusIndicator::pop_trigger(const std::string & group) { uint32_t x = 0; while (this->custom_triggers_.size() > x) { if (group == this->custom_triggers_[x]->get_group()) { diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index 86fc23fa0a..863115aa71 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -46,7 +46,7 @@ class StatusIndicator : public Component { class StatusTrigger : public Trigger<> { public: explicit StatusTrigger(StatusIndicator *parent, std::string group, uint32_t priority) - : parent_(parent), group_(std::move(std::move(group))), priority_(priority) {} + : parent_(parent), group_(std::move(group)), priority_(priority) {} std::string get_group() { return this->group_; } uint32_t get_priority() { return this->priority_; } @@ -70,7 +70,7 @@ template class StatusAction : public Action, public Paren public: void set_state(bool state) { this->state_ = state; } void set_trigger(StatusTrigger *trigger) { this->trigger_ = trigger; } - void set_group(const std::string &group) { this->group_ = std::move(std::move(group)); } + void set_group(const std::string &group) { this->group_ = std::move(group); } void play(Ts... x) override { if (this->state_) { From 698d4f42edd83ca990673d88f2262e8df207bf25 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 21:51:47 +0100 Subject: [PATCH 14/29] update suggested fixes part6 --- esphome/components/status_indicator/status_indicator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 32c2bb298d..4cba846798 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -180,7 +180,7 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { } } -void StatusIndicator::pop_trigger(const std::string & group) { +void StatusIndicator::pop_trigger(const std::string &group) { uint32_t x = 0; while (this->custom_triggers_.size() > x) { if (group == this->custom_triggers_[x]->get_group()) { From 81e2db496bf1b4d6748665279dc9e70613919bcd Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 22:19:30 +0100 Subject: [PATCH 15/29] update suggested fixes part7 --- esphome/components/status_indicator/status_indicator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index 863115aa71..b75d20cd8b 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -70,7 +70,7 @@ template class StatusAction : public Action, public Paren public: void set_state(bool state) { this->state_ = state; } void set_trigger(StatusTrigger *trigger) { this->trigger_ = trigger; } - void set_group(const std::string &group) { this->group_ = std::move(group); } + void set_group(const std::string &group) { this->group_ = group; } void play(Ts... x) override { if (this->state_) { From ae2e86b82695725ccfc7a2d515efc3e0b261c862 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 22:53:36 +0100 Subject: [PATCH 16/29] update suggested fixes part8 --- esphome/components/status_indicator/status_indicator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 4cba846798..7406ac3c5d 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -2,6 +2,9 @@ #include "esphome/core/log.h" #include "esphome/core/application.h" +#ifdef USE_ETHERNET +#include "esphome/components/ethernet/ethernet_component.h" +#endif #ifdef USE_WIFI #include "esphome/components/wifi/wifi_component.h" #endif From 99ef329d3680701594b966fcf28c79ff929773a0 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 21 Nov 2023 23:42:14 +0100 Subject: [PATCH 17/29] update suggested fixes part9 --- esphome/components/status_indicator/status_indicator.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 7406ac3c5d..40f7bb4671 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -170,11 +170,9 @@ void StatusIndicator::push_trigger(StatusTrigger *trigger) { void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { uint32_t x = 0; while (this->custom_triggers_.size() > x) { - if (trigger == this->custom_triggers_[x]) { - this->custom_triggers_.erase(this->custom_triggers_.begin() + x); - this->current_status_ = "update me"; - } else if (incl_group && !trigger->get_group().empty() && - trigger->get_group() == this->custom_triggers_[x]->get_group()) { + if ((incl_group && !trigger->get_group().empty() && + trigger->get_group() == this->custom_triggers_[x]->get_group()) || + (trigger == this->custom_triggers_[x])) { this->custom_triggers_.erase(this->custom_triggers_.begin() + x); this->current_status_ = "update me"; } else { From d8ad98f3484114513cdeea131e79bd8f9eab86b3 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 22 Nov 2023 03:17:06 +0100 Subject: [PATCH 18/29] fixing some bugs --- .../components/status_indicator/__init__.py | 1 + .../status_indicator/_test/test.yaml | 28 ++++++-- .../status_indicator/status_indicator.cpp | 68 +++++++++++-------- .../status_indicator/status_indicator.h | 9 ++- 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/esphome/components/status_indicator/__init__.py b/esphome/components/status_indicator/__init__.py index d5869db8d4..884f3c6fe5 100644 --- a/esphome/components/status_indicator/__init__.py +++ b/esphome/components/status_indicator/__init__.py @@ -77,6 +77,7 @@ async def add_trigger(var, conf, key): var, conf[CONF_GROUP], conf[CONF_PRIORITY], + conf[CONF_TRIGGER_ID].id, ) await auto.build_automation(trigger, [], conf) if key is not None: diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml index fdc6e819e4..562085631d 100644 --- a/esphome/components/status_indicator/_test/test.yaml +++ b/esphome/components/status_indicator/_test/test.yaml @@ -5,6 +5,8 @@ esphome: esp32: board: m5stack-atom +logger: + level: DEBUG light: - platform: esp32_rmt_led_strip @@ -43,15 +45,14 @@ binary_sensor: entity_category: diagnostic id: button on_press: - - status.push: custom_status - status.push: custom_status2 + - status.push: custom_status3 + - status.push: custom_status1 on_release: - status.pop: group: "custom" - delay: 5s - - status.pop: custom_status - - + - status.pop: custom_status1 status_indicator: on_turn_off: #Manditory @@ -79,7 +80,8 @@ status_indicator: effect: None on_custom_status: - - trigger_id: custom_status + - trigger_id: custom_status1 + priority: 1 then: - light.turn_on: id: led @@ -90,11 +92,23 @@ status_indicator: effect: None - trigger_id: custom_status2 group: custom + priority: 3 then: - light.turn_on: id: led - red: 0% + red: 50% + green: 0% + blue: 100% + brightness: 100% + effect: None + - trigger_id: custom_status3 + group: custom1 + priority: 1 + then: + - light.turn_on: + id: led + red: 100% green: 100% blue: 50% brightness: 100% - effect: None + effect: Fast pulse diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 40f7bb4671..ae4f578374 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -123,13 +123,15 @@ void StatusIndicator::loop() { if (this->current_trigger_ != nullptr) { this->current_trigger_ = get_trigger("on_turn_off"); } - } else if (!this->custom_triggers_.empty()) { - this->current_trigger_ = this->custom_triggers_[0]; + } else if (!this->stack_.empty()) { + this->current_trigger_ = this->stack_.back(); } else { this->current_trigger_ = get_trigger("on_turn_off"); } - if (oldtrigger != this->current_trigger_) + if (oldtrigger != this->current_trigger_) { + ESP_LOGD(TAG, "Current trigger: %s", this->current_trigger_->get_info().c_str()); this->current_trigger_->trigger(); + } this->current_status_ = status; } } @@ -150,47 +152,59 @@ void StatusIndicator::set_trigger(const std::string &key, StatusTrigger *trigger void StatusIndicator::push_trigger(StatusTrigger *trigger) { this->pop_trigger(trigger, true); - uint32_t x = 0; - if (this->custom_triggers_.empty()) { - this->custom_triggers_.push_back(trigger); - this->current_status_ = "update me"; - } else { - while (this->custom_triggers_.size() > x) { - if (trigger->get_priority() <= this->custom_triggers_[x]->get_priority()) { - this->custom_triggers_.insert(this->custom_triggers_.begin() + x, trigger); + ESP_LOGD(TAG, "Push ID: %s", trigger->get_info().c_str()); + + for (auto i = this->stack_.begin(); i != this->stack_.end(); ++i) { + StatusTrigger *st = *i; + if (trigger->get_priority() < st->get_priority()) { + this->stack_.insert(i, trigger); this->current_status_ = "update me"; - break; - } else { - x++; + log_triggers_(); + return; } } - } + this->stack_.push_back(trigger); + this->current_status_ = "update me"; + log_triggers_(); } void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { - uint32_t x = 0; - while (this->custom_triggers_.size() > x) { - if ((incl_group && !trigger->get_group().empty() && - trigger->get_group() == this->custom_triggers_[x]->get_group()) || - (trigger == this->custom_triggers_[x])) { - this->custom_triggers_.erase(this->custom_triggers_.begin() + x); + incl_group = incl_group && !trigger->get_group().empty(); + ESP_LOGD(TAG, "Pop by ID: %s || %s", trigger->get_info().c_str(), YESNO(incl_group)); + std::string group = trigger->get_group(); + for (auto i = this->stack_.begin(); i != this->stack_.end();) { + StatusTrigger *st = *i; + if ((incl_group && group == st->get_group()) || (trigger == st)) { + this->stack_.erase(i); this->current_status_ = "update me"; } else { - x++; + ++i; } } + log_triggers_(); } void StatusIndicator::pop_trigger(const std::string &group) { - uint32_t x = 0; - while (this->custom_triggers_.size() > x) { - if (group == this->custom_triggers_[x]->get_group()) { - this->custom_triggers_.erase(this->custom_triggers_.begin() + x); + ESP_LOGD(TAG, "Pop by group: %s", group.c_str()); + + for (auto i = this->stack_.begin(); i != this->stack_.end();) { + StatusTrigger *st = *i; + if (group == st->get_group()) { + this->stack_.erase(i); this->current_status_ = "update me"; } else { - x++; + ++i; } } + log_triggers_(); +} + +void StatusIndicator::log_triggers_() { + for (auto i = this->stack_.begin(); i != this->stack_.end(); ++i) { + StatusTrigger *st = *i; + ESP_LOGD(TAG, "%s", st->get_info().c_str()); + } + ESP_LOGD(TAG, "----------------------------- %d ----", this->stack_.size()); } } // namespace status_indicator diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index b75d20cd8b..e7e56feac4 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -36,22 +36,25 @@ class StatusIndicator : public Component { void pop_trigger(const std::string &group); protected: + void log_triggers_(); std::string current_status_{""}; StatusTrigger *current_trigger_{nullptr}; StatusFlags status_; std::map triggers_{}; - std::vector custom_triggers_{}; + std::vector stack_{}; }; class StatusTrigger : public Trigger<> { public: - explicit StatusTrigger(StatusIndicator *parent, std::string group, uint32_t priority) - : parent_(parent), group_(std::move(group)), priority_(priority) {} + explicit StatusTrigger(StatusIndicator *parent, std::string group, uint32_t priority, std::string name) + : parent_(parent), group_(std::move(group)), priority_(priority), name_(std::move(name)) {} std::string get_group() { return this->group_; } uint32_t get_priority() { return this->priority_; } + std::string get_info() { return this->name_ + " \t| " + this->group_ + " \t| " + std::to_string(this->priority_); } protected: StatusIndicator *parent_; + std::string name_; /// Minimum length of click. 0 means no minimum. std::string group_; /// Minimum length of click. 0 means no minimum. uint32_t priority_; /// Maximum length of click. 0 means no maximum. }; From 6641318834bed3a7a14f180f7359ea846844ebca Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 22 Nov 2023 03:32:05 +0100 Subject: [PATCH 19/29] update suggested fixes part10 --- .../status_indicator/_test/test.yaml | 3 --- .../status_indicator/status_indicator.cpp | 22 +++++++++---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml index 562085631d..b16838f4e9 100644 --- a/esphome/components/status_indicator/_test/test.yaml +++ b/esphome/components/status_indicator/_test/test.yaml @@ -11,9 +11,6 @@ logger: light: - platform: esp32_rmt_led_strip id: led - name: None - disabled_by_default: true - entity_category: config pin: GPIO27 default_transition_length: 0s chipset: SK6812 diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index ae4f578374..23a6e5f415 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -154,18 +154,18 @@ void StatusIndicator::push_trigger(StatusTrigger *trigger) { this->pop_trigger(trigger, true); ESP_LOGD(TAG, "Push ID: %s", trigger->get_info().c_str()); - for (auto i = this->stack_.begin(); i != this->stack_.end(); ++i) { - StatusTrigger *st = *i; - if (trigger->get_priority() < st->get_priority()) { - this->stack_.insert(i, trigger); - this->current_status_ = "update me"; - log_triggers_(); - return; - } + for (auto i = this->stack_.begin(); i != this->stack_.end(); ++i) { + StatusTrigger *st = *i; + if (trigger->get_priority() < st->get_priority()) { + this->stack_.insert(i, trigger); + this->current_status_ = "update me"; + log_triggers_(); + return; } - this->stack_.push_back(trigger); - this->current_status_ = "update me"; - log_triggers_(); + } + this->stack_.push_back(trigger); + this->current_status_ = "update me"; + log_triggers_(); } void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { From 69ef6219fe85c42949f3064e48d151155e49bfc7 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 22 Nov 2023 10:19:21 +0100 Subject: [PATCH 20/29] some new fixings and change reporting --- .../status_indicator/_test/test.yaml | 37 ++++++++++++++++++- .../status_indicator/status_indicator.cpp | 25 ++++++++----- .../status_indicator/status_indicator.h | 4 +- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml index b16838f4e9..41ca59c60d 100644 --- a/esphome/components/status_indicator/_test/test.yaml +++ b/esphome/components/status_indicator/_test/test.yaml @@ -31,6 +31,9 @@ light: min_brightness: 50% max_brightness: 100% +wifi: + ssid: LumenIOT24 + password: Lum3nS0fT binary_sensor: - platform: gpio @@ -64,7 +67,7 @@ status_indicator: green: 0% blue: 0% brightness: 100% - effect: Fast Pulse + effect: None on_app_warning: then: @@ -74,8 +77,38 @@ status_indicator: green: 0% blue: 0% brightness: 100% + effect: Slow Pulse + + on_wifi_ap_enabled: + then: + - light.turn_on: + id: led + red: 100% + green: 100% + blue: 50% + brightness: 100% effect: None + on_network_disconnected: + then: + - light.turn_on: + id: led + red: 100% + green: 0% + blue: 0% + brightness: 100% + effect: Fast Pulse + + on_api_disconnected: + then: + - light.turn_on: + id: led + red: 100% + green: 100% + blue: 0% + brightness: 100% + effect: Fast Pulse + on_custom_status: - trigger_id: custom_status1 priority: 1 @@ -109,3 +142,5 @@ status_indicator: blue: 50% brightness: 100% effect: Fast pulse + - delay: 10s + - status.pop: custom_status3 diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 23a6e5f415..8bec9dadb6 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -54,7 +54,12 @@ bool is_connected() { static const char *const TAG = "status_indicator"; -void StatusIndicator::dump_config() { ESP_LOGCONFIG(TAG, "Status Indicator:"); } +void StatusIndicator::dump_config() { + ESP_LOGCONFIG(TAG, "Status Indicator supports:"); + for (auto i = this->triggers_.begin(); i != this->triggers_.end(); i++) { + ESP_LOGCONFIG(TAG, " * %s: %s", i->first.c_str(), i->second->get_info().c_str()); + } +} void StatusIndicator::loop() { std::string status{""}; if ((App.get_app_state() & STATUS_LED_ERROR) != 0u) { @@ -118,18 +123,18 @@ void StatusIndicator::loop() { } if (this->current_status_ != status) { StatusTrigger *oldtrigger = this->current_trigger_; - if (!status.empty()) { + + if (!status.empty() && this->triggers_.count(status)==1) { this->current_trigger_ = get_trigger(status); - if (this->current_trigger_ != nullptr) { - this->current_trigger_ = get_trigger("on_turn_off"); - } } else if (!this->stack_.empty()) { this->current_trigger_ = this->stack_.back(); + status = "on_custom_status"; } else { this->current_trigger_ = get_trigger("on_turn_off"); + status = "on_turn_off"; } if (oldtrigger != this->current_trigger_) { - ESP_LOGD(TAG, "Current trigger: %s", this->current_trigger_->get_info().c_str()); + ESP_LOGI(TAG, "<>> Current trigger:%s->%s", status.c_str(), this->current_trigger_->get_name().c_str()); this->current_trigger_->trigger(); } this->current_status_ = status; @@ -159,13 +164,13 @@ void StatusIndicator::push_trigger(StatusTrigger *trigger) { if (trigger->get_priority() < st->get_priority()) { this->stack_.insert(i, trigger); this->current_status_ = "update me"; - log_triggers_(); + // log_triggers_(); return; } } this->stack_.push_back(trigger); this->current_status_ = "update me"; - log_triggers_(); +// log_triggers_(); } void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { @@ -181,7 +186,7 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { ++i; } } - log_triggers_(); +// log_triggers_(); } void StatusIndicator::pop_trigger(const std::string &group) { @@ -196,7 +201,7 @@ void StatusIndicator::pop_trigger(const std::string &group) { ++i; } } - log_triggers_(); + //log_triggers_(); } void StatusIndicator::log_triggers_() { diff --git a/esphome/components/status_indicator/status_indicator.h b/esphome/components/status_indicator/status_indicator.h index e7e56feac4..6f2fb84a68 100644 --- a/esphome/components/status_indicator/status_indicator.h +++ b/esphome/components/status_indicator/status_indicator.h @@ -9,6 +9,7 @@ namespace esphome { namespace status_indicator { class StatusTrigger; + union StatusFlags { struct { int on_error : 1; @@ -47,9 +48,10 @@ class StatusIndicator : public Component { class StatusTrigger : public Trigger<> { public: explicit StatusTrigger(StatusIndicator *parent, std::string group, uint32_t priority, std::string name) - : parent_(parent), group_(std::move(group)), priority_(priority), name_(std::move(name)) {} + : parent_(parent), name_(std::move(name)), group_(std::move(group)), priority_(priority) {} std::string get_group() { return this->group_; } uint32_t get_priority() { return this->priority_; } + std::string get_name() { return this->name_; } std::string get_info() { return this->name_ + " \t| " + this->group_ + " \t| " + std::to_string(this->priority_); } protected: From 869bf8061945635e13c92586794204d93942835d Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 22 Nov 2023 10:35:58 +0100 Subject: [PATCH 21/29] clang --- .../components/status_indicator/status_indicator.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 8bec9dadb6..c87454d36b 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -124,7 +124,7 @@ void StatusIndicator::loop() { if (this->current_status_ != status) { StatusTrigger *oldtrigger = this->current_trigger_; - if (!status.empty() && this->triggers_.count(status)==1) { + if (!status.empty() && this->triggers_.count(status) == 1) { this->current_trigger_ = get_trigger(status); } else if (!this->stack_.empty()) { this->current_trigger_ = this->stack_.back(); @@ -164,13 +164,13 @@ void StatusIndicator::push_trigger(StatusTrigger *trigger) { if (trigger->get_priority() < st->get_priority()) { this->stack_.insert(i, trigger); this->current_status_ = "update me"; - // log_triggers_(); + // log_triggers_(); return; } } this->stack_.push_back(trigger); this->current_status_ = "update me"; -// log_triggers_(); + // log_triggers_(); } void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { @@ -186,7 +186,7 @@ void StatusIndicator::pop_trigger(StatusTrigger *trigger, bool incl_group) { ++i; } } -// log_triggers_(); + // log_triggers_(); } void StatusIndicator::pop_trigger(const std::string &group) { @@ -201,7 +201,7 @@ void StatusIndicator::pop_trigger(const std::string &group) { ++i; } } - //log_triggers_(); + // log_triggers_(); } void StatusIndicator::log_triggers_() { From cc2b0a1b52b71593f35faf08a032db8cbc771d3b Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 22 Nov 2023 10:56:51 +0100 Subject: [PATCH 22/29] while this be the last clang fix? --- esphome/components/status_indicator/status_indicator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index c87454d36b..927e8e135a 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -205,8 +205,7 @@ void StatusIndicator::pop_trigger(const std::string &group) { } void StatusIndicator::log_triggers_() { - for (auto i = this->stack_.begin(); i != this->stack_.end(); ++i) { - StatusTrigger *st = *i; + for (auto st : this->stack_) { ESP_LOGD(TAG, "%s", st->get_info().c_str()); } ESP_LOGD(TAG, "----------------------------- %d ----", this->stack_.size()); From 83318839822288175af627ec028db43fe941bb98 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 22 Nov 2023 11:43:54 +0100 Subject: [PATCH 23/29] sadly not. --- esphome/components/status_indicator/status_indicator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 927e8e135a..352445fd30 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -205,7 +205,7 @@ void StatusIndicator::pop_trigger(const std::string &group) { } void StatusIndicator::log_triggers_() { - for (auto st : this->stack_) { + for (auto *st : this->stack_) { ESP_LOGD(TAG, "%s", st->get_info().c_str()); } ESP_LOGD(TAG, "----------------------------- %d ----", this->stack_.size()); From 38fe067876b5afc8665482f2dc66779ab4694996 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 22 Nov 2023 16:19:46 +0100 Subject: [PATCH 24/29] not sure --- esphome/components/status_indicator/status_indicator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 352445fd30..dd8e7e90a3 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -134,7 +134,7 @@ void StatusIndicator::loop() { status = "on_turn_off"; } if (oldtrigger != this->current_trigger_) { - ESP_LOGI(TAG, "<>> Current trigger:%s->%s", status.c_str(), this->current_trigger_->get_name().c_str()); + ESP_LOGI(TAG, "<>> %s->%s", status.c_str(), this->current_trigger_->get_name().c_str()); this->current_trigger_->trigger(); } this->current_status_ = status; From fa4b9daf59a095efdc7f26e93f114616a1daed7c Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Mon, 25 Dec 2023 06:40:20 +0100 Subject: [PATCH 25/29] move code around --- .../status_indicator/status_indicator.cpp | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index dd8e7e90a3..a1691e7072 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -68,21 +68,8 @@ void StatusIndicator::loop() { } else if (this->status_.on_error == 1) { status = "on_clear_app_error"; this->status_.on_error = 0; - } else if ((App.get_app_state() & STATUS_LED_WARNING) != 0u) { - status = "on_app_warning"; - this->status_.on_warning = 1; - } else if (this->status_.on_warning == 1) { - status = "on_clear_app_warning"; - this->status_.on_warning = 0; - } - if (this->current_trigger_ != nullptr) { - if (this->current_trigger_->is_action_running()) { - if (status.empty()) { - return; - } - this->current_trigger_->stop_action(); - } } + if (has_network()) { #ifdef USE_WIFI if (status.empty() && wifi::global_wifi_component->is_ap_enabled()) { @@ -121,7 +108,18 @@ void StatusIndicator::loop() { } #endif } + if (status.empty() && (App.get_app_state() & STATUS_LED_WARNING) != 0u) { + status = "on_app_warning"; + this->status_.on_warning = 1; + } else if (this->status_.on_warning == 1) { + status = "on_clear_app_warning"; + this->status_.on_warning = 0; + } + if (this->current_status_ != status) { + if (this->current_trigger_ != nullptr and this->current_trigger_->is_action_running() and !status.empty()) { + this->current_trigger_->stop_action(); + } StatusTrigger *oldtrigger = this->current_trigger_; if (!status.empty() && this->triggers_.count(status) == 1) { From 38548cf503fefbf80899590dd7ef14ee56bfd469 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 5 Mar 2024 14:54:22 +0100 Subject: [PATCH 26/29] fix warnings --- esphome/components/status_indicator/status_indicator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index a1691e7072..c19707bde9 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -93,7 +93,7 @@ void StatusIndicator::loop() { if (status.empty() && api::global_api_server != nullptr && not api::global_api_server->is_connected()) { status = "on_api_disconnected"; this->status_.on_api = 1; - } else if (this->status_.on_error == 1) { + } else if (this->status_.on_error) { status = "on_api_connected"; this->status_.on_api = 0; } @@ -102,7 +102,7 @@ void StatusIndicator::loop() { if (status.empty() && mqtt::global_mqtt_client != nullptr && not mqtt::global_mqtt_client->is_connected()) { status = "on_mqtt_disconnected"; this->status_.on_mqtt = 1; - } else if (this->status_.on_mqtt == 1) { + } else if (this->status_.on_mqtt) { status = "on_mqtt_connected"; this->status_.on_mqtt = 0; } @@ -111,7 +111,7 @@ void StatusIndicator::loop() { if (status.empty() && (App.get_app_state() & STATUS_LED_WARNING) != 0u) { status = "on_app_warning"; this->status_.on_warning = 1; - } else if (this->status_.on_warning == 1) { + } else if (this->status_.on_warning) { status = "on_clear_app_warning"; this->status_.on_warning = 0; } From f74b4396369d7045b0d01473d33b0f82d3c2f3bc Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 5 Mar 2024 15:00:54 +0100 Subject: [PATCH 27/29] fix warnings --- esphome/components/status_indicator/status_indicator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index c19707bde9..495ff5f1a8 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -65,7 +65,7 @@ void StatusIndicator::loop() { if ((App.get_app_state() & STATUS_LED_ERROR) != 0u) { status = "on_app_error"; this->status_.on_error = 1; - } else if (this->status_.on_error == 1) { + } else if (this->status_.on_error) { status = "on_clear_app_error"; this->status_.on_error = 0; } @@ -75,7 +75,7 @@ void StatusIndicator::loop() { if (status.empty() && wifi::global_wifi_component->is_ap_enabled()) { status = "on_wifi_ap_enabled"; this->status_.on_wifi_ap = 1; - } else if (this->status_.on_wifi_ap == 1) { + } else if (this->status_.on_wifi_ap) { status = "on_wifi_ap_disabled"; this->status_.on_wifi_ap = 0; } @@ -84,7 +84,7 @@ void StatusIndicator::loop() { if (status.empty() && not is_connected()) { status = "on_network_disconnected"; this->status_.on_network = 1; - } else if (this->status_.on_network == 1) { + } else if (this->status_.on_network) { status = "on_network_connected"; this->status_.on_network = 0; } From 75fcbc097df851134794110afc5195110dfcf829 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Tue, 5 Mar 2024 15:01:40 +0100 Subject: [PATCH 28/29] fix warnings --- esphome/components/status_indicator/status_indicator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/status_indicator/status_indicator.cpp b/esphome/components/status_indicator/status_indicator.cpp index 495ff5f1a8..9ff57aa308 100644 --- a/esphome/components/status_indicator/status_indicator.cpp +++ b/esphome/components/status_indicator/status_indicator.cpp @@ -93,7 +93,7 @@ void StatusIndicator::loop() { if (status.empty() && api::global_api_server != nullptr && not api::global_api_server->is_connected()) { status = "on_api_disconnected"; this->status_.on_api = 1; - } else if (this->status_.on_error) { + } else if (this->status_.on_api) { status = "on_api_connected"; this->status_.on_api = 0; } From 630fb117584e6f675a72e7e84b4a209967a9b1b8 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Wed, 6 Mar 2024 00:48:09 +0100 Subject: [PATCH 29/29] YAML code formating --- .../status_indicator/_test/test.yaml | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/esphome/components/status_indicator/_test/test.yaml b/esphome/components/status_indicator/_test/test.yaml index 41ca59c60d..73ee01c26d 100644 --- a/esphome/components/status_indicator/_test/test.yaml +++ b/esphome/components/status_indicator/_test/test.yaml @@ -55,59 +55,59 @@ binary_sensor: - status.pop: custom_status1 status_indicator: - on_turn_off: #Manditory + on_turn_off: # Manditory - light.turn_off: id: led on_app_error: then: - - light.turn_on: - id: led - red: 100% - green: 0% - blue: 0% - brightness: 100% - effect: None + - light.turn_on: + id: led + red: 100% + green: 0% + blue: 0% + brightness: 100% + effect: None on_app_warning: then: - - light.turn_on: - id: led - red: 100% - green: 0% - blue: 0% - brightness: 100% - effect: Slow Pulse + - light.turn_on: + id: led + red: 100% + green: 0% + blue: 0% + brightness: 100% + effect: Slow Pulse on_wifi_ap_enabled: then: - - light.turn_on: - id: led - red: 100% - green: 100% - blue: 50% - brightness: 100% - effect: None + - light.turn_on: + id: led + red: 100% + green: 100% + blue: 50% + brightness: 100% + effect: None on_network_disconnected: then: - - light.turn_on: - id: led - red: 100% - green: 0% - blue: 0% - brightness: 100% - effect: Fast Pulse + - light.turn_on: + id: led + red: 100% + green: 0% + blue: 0% + brightness: 100% + effect: Fast Pulse on_api_disconnected: then: - - light.turn_on: - id: led - red: 100% - green: 100% - blue: 0% - brightness: 100% - effect: Fast Pulse + - light.turn_on: + id: led + red: 100% + green: 100% + blue: 0% + brightness: 100% + effect: Fast Pulse on_custom_status: - trigger_id: custom_status1