diff --git a/esphome/components/globals/__init__.py b/esphome/components/globals/__init__.py index 633ccea66b..fc400c5dd1 100644 --- a/esphome/components/globals/__init__.py +++ b/esphome/components/globals/__init__.py @@ -9,30 +9,56 @@ from esphome.const import ( CONF_VALUE, ) from esphome.core import CoroPriority, coroutine_with_priority +from esphome.types import ConfigType CODEOWNERS = ["@esphome/core"] globals_ns = cg.esphome_ns.namespace("globals") GlobalsComponent = globals_ns.class_("GlobalsComponent", cg.Component) -RestoringGlobalsComponent = globals_ns.class_("RestoringGlobalsComponent", cg.Component) +RestoringGlobalsComponent = globals_ns.class_( + "RestoringGlobalsComponent", cg.PollingComponent +) RestoringGlobalStringComponent = globals_ns.class_( - "RestoringGlobalStringComponent", cg.Component + "RestoringGlobalStringComponent", cg.PollingComponent ) GlobalVarSetAction = globals_ns.class_("GlobalVarSetAction", automation.Action) CONF_MAX_RESTORE_DATA_LENGTH = "max_restore_data_length" +# Base schema fields shared by both variants +_BASE_SCHEMA = { + cv.Required(CONF_ID): cv.declare_id(GlobalsComponent), + cv.Required(CONF_TYPE): cv.string_strict, + cv.Optional(CONF_INITIAL_VALUE): cv.string_strict, + cv.Optional(CONF_MAX_RESTORE_DATA_LENGTH): cv.int_range(0, 254), +} -MULTI_CONF = True -CONFIG_SCHEMA = cv.Schema( +# Non-restoring globals: regular Component (no polling needed) +_NON_RESTORING_SCHEMA = cv.Schema( { - cv.Required(CONF_ID): cv.declare_id(GlobalsComponent), - cv.Required(CONF_TYPE): cv.string_strict, - cv.Optional(CONF_INITIAL_VALUE): cv.string_strict, + **_BASE_SCHEMA, cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean, - cv.Optional(CONF_MAX_RESTORE_DATA_LENGTH): cv.int_range(0, 254), } ).extend(cv.COMPONENT_SCHEMA) +# Restoring globals: PollingComponent with configurable update_interval +_RESTORING_SCHEMA = cv.Schema( + { + **_BASE_SCHEMA, + cv.Optional(CONF_RESTORE_VALUE, default=True): cv.boolean, + } +).extend(cv.polling_component_schema("1s")) + + +def _globals_schema(config: ConfigType) -> ConfigType: + """Select schema based on restore_value setting.""" + if config.get(CONF_RESTORE_VALUE, False): + return _RESTORING_SCHEMA(config) + return _NON_RESTORING_SCHEMA(config) + + +MULTI_CONF = True +CONFIG_SCHEMA = _globals_schema + # Run with low priority so that namespaces are registered first @coroutine_with_priority(CoroPriority.LATE) diff --git a/esphome/components/globals/globals_component.h b/esphome/components/globals/globals_component.h index 1d2a08937e..3db29bea35 100644 --- a/esphome/components/globals/globals_component.h +++ b/esphome/components/globals/globals_component.h @@ -5,8 +5,7 @@ #include "esphome/core/helpers.h" #include -namespace esphome { -namespace globals { +namespace esphome::globals { template class GlobalsComponent : public Component { public: @@ -24,13 +23,14 @@ template class GlobalsComponent : public Component { T value_{}; }; -template class RestoringGlobalsComponent : public Component { +template class RestoringGlobalsComponent : public PollingComponent { public: using value_type = T; - explicit RestoringGlobalsComponent() = default; - explicit RestoringGlobalsComponent(T initial_value) : value_(initial_value) {} + explicit RestoringGlobalsComponent() : PollingComponent(1000) {} + explicit RestoringGlobalsComponent(T initial_value) : PollingComponent(1000), value_(initial_value) {} explicit RestoringGlobalsComponent( - std::array::type, std::extent::value> initial_value) { + std::array::type, std::extent::value> initial_value) + : PollingComponent(1000) { memcpy(this->value_, initial_value.data(), sizeof(T)); } @@ -44,7 +44,7 @@ template class RestoringGlobalsComponent : public Component { float get_setup_priority() const override { return setup_priority::HARDWARE; } - void loop() override { store_value_(); } + void update() override { store_value_(); } void on_shutdown() override { store_value_(); } @@ -66,13 +66,14 @@ template class RestoringGlobalsComponent : public Component { }; // Use with string or subclasses of strings -template class RestoringGlobalStringComponent : public Component { +template class RestoringGlobalStringComponent : public PollingComponent { public: using value_type = T; - explicit RestoringGlobalStringComponent() = default; - explicit RestoringGlobalStringComponent(T initial_value) { this->value_ = initial_value; } + explicit RestoringGlobalStringComponent() : PollingComponent(1000) {} + explicit RestoringGlobalStringComponent(T initial_value) : PollingComponent(1000) { this->value_ = initial_value; } explicit RestoringGlobalStringComponent( - std::array::type, std::extent::value> initial_value) { + std::array::type, std::extent::value> initial_value) + : PollingComponent(1000) { memcpy(this->value_, initial_value.data(), sizeof(T)); } @@ -90,7 +91,7 @@ template class RestoringGlobalStringComponent : public C float get_setup_priority() const override { return setup_priority::HARDWARE; } - void loop() override { store_value_(); } + void update() override { store_value_(); } void on_shutdown() override { store_value_(); } @@ -144,5 +145,4 @@ template T &id(GlobalsComponent *value) { return value->value(); template T &id(RestoringGlobalsComponent *value) { return value->value(); } template T &id(RestoringGlobalStringComponent *value) { return value->value(); } -} // namespace globals -} // namespace esphome +} // namespace esphome::globals diff --git a/tests/components/globals/common.yaml b/tests/components/globals/common.yaml index 224a91a270..efa3cba076 100644 --- a/tests/components/globals/common.yaml +++ b/tests/components/globals/common.yaml @@ -10,6 +10,7 @@ globals: type: int restore_value: true initial_value: "0" + update_interval: 5s - id: glob_float type: float restore_value: true