[globals] Convert restoring globals to PollingComponent to reduce CPU usage (#13345)

This commit is contained in:
J. Nick Koston
2026-01-28 10:35:26 -10:00
committed by GitHub
parent 6f22509883
commit 6a3205f4db
3 changed files with 49 additions and 22 deletions
+33 -7
View File
@@ -9,30 +9,56 @@ from esphome.const import (
CONF_VALUE, CONF_VALUE,
) )
from esphome.core import CoroPriority, coroutine_with_priority from esphome.core import CoroPriority, coroutine_with_priority
from esphome.types import ConfigType
CODEOWNERS = ["@esphome/core"] CODEOWNERS = ["@esphome/core"]
globals_ns = cg.esphome_ns.namespace("globals") globals_ns = cg.esphome_ns.namespace("globals")
GlobalsComponent = globals_ns.class_("GlobalsComponent", cg.Component) 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 = globals_ns.class_(
"RestoringGlobalStringComponent", cg.Component "RestoringGlobalStringComponent", cg.PollingComponent
) )
GlobalVarSetAction = globals_ns.class_("GlobalVarSetAction", automation.Action) GlobalVarSetAction = globals_ns.class_("GlobalVarSetAction", automation.Action)
CONF_MAX_RESTORE_DATA_LENGTH = "max_restore_data_length" CONF_MAX_RESTORE_DATA_LENGTH = "max_restore_data_length"
# Base schema fields shared by both variants
MULTI_CONF = True _BASE_SCHEMA = {
CONFIG_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.declare_id(GlobalsComponent), cv.Required(CONF_ID): cv.declare_id(GlobalsComponent),
cv.Required(CONF_TYPE): cv.string_strict, cv.Required(CONF_TYPE): cv.string_strict,
cv.Optional(CONF_INITIAL_VALUE): cv.string_strict, cv.Optional(CONF_INITIAL_VALUE): cv.string_strict,
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
cv.Optional(CONF_MAX_RESTORE_DATA_LENGTH): cv.int_range(0, 254), cv.Optional(CONF_MAX_RESTORE_DATA_LENGTH): cv.int_range(0, 254),
}
# Non-restoring globals: regular Component (no polling needed)
_NON_RESTORING_SCHEMA = cv.Schema(
{
**_BASE_SCHEMA,
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
} }
).extend(cv.COMPONENT_SCHEMA) ).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 # Run with low priority so that namespaces are registered first
@coroutine_with_priority(CoroPriority.LATE) @coroutine_with_priority(CoroPriority.LATE)
+14 -14
View File
@@ -5,8 +5,7 @@
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
#include <cstring> #include <cstring>
namespace esphome { namespace esphome::globals {
namespace globals {
template<typename T> class GlobalsComponent : public Component { template<typename T> class GlobalsComponent : public Component {
public: public:
@@ -24,13 +23,14 @@ template<typename T> class GlobalsComponent : public Component {
T value_{}; T value_{};
}; };
template<typename T> class RestoringGlobalsComponent : public Component { template<typename T> class RestoringGlobalsComponent : public PollingComponent {
public: public:
using value_type = T; using value_type = T;
explicit RestoringGlobalsComponent() = default; explicit RestoringGlobalsComponent() : PollingComponent(1000) {}
explicit RestoringGlobalsComponent(T initial_value) : value_(initial_value) {} explicit RestoringGlobalsComponent(T initial_value) : PollingComponent(1000), value_(initial_value) {}
explicit RestoringGlobalsComponent( explicit RestoringGlobalsComponent(
std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value) { std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value)
: PollingComponent(1000) {
memcpy(this->value_, initial_value.data(), sizeof(T)); memcpy(this->value_, initial_value.data(), sizeof(T));
} }
@@ -44,7 +44,7 @@ template<typename T> class RestoringGlobalsComponent : public Component {
float get_setup_priority() const override { return setup_priority::HARDWARE; } 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_(); } void on_shutdown() override { store_value_(); }
@@ -66,13 +66,14 @@ template<typename T> class RestoringGlobalsComponent : public Component {
}; };
// Use with string or subclasses of strings // Use with string or subclasses of strings
template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public Component { template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public PollingComponent {
public: public:
using value_type = T; using value_type = T;
explicit RestoringGlobalStringComponent() = default; explicit RestoringGlobalStringComponent() : PollingComponent(1000) {}
explicit RestoringGlobalStringComponent(T initial_value) { this->value_ = initial_value; } explicit RestoringGlobalStringComponent(T initial_value) : PollingComponent(1000) { this->value_ = initial_value; }
explicit RestoringGlobalStringComponent( explicit RestoringGlobalStringComponent(
std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value) { std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value)
: PollingComponent(1000) {
memcpy(this->value_, initial_value.data(), sizeof(T)); memcpy(this->value_, initial_value.data(), sizeof(T));
} }
@@ -90,7 +91,7 @@ template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public C
float get_setup_priority() const override { return setup_priority::HARDWARE; } 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_(); } void on_shutdown() override { store_value_(); }
@@ -144,5 +145,4 @@ template<typename T> T &id(GlobalsComponent<T> *value) { return value->value();
template<typename T> T &id(RestoringGlobalsComponent<T> *value) { return value->value(); } template<typename T> T &id(RestoringGlobalsComponent<T> *value) { return value->value(); }
template<typename T, uint8_t SZ> T &id(RestoringGlobalStringComponent<T, SZ> *value) { return value->value(); } template<typename T, uint8_t SZ> T &id(RestoringGlobalStringComponent<T, SZ> *value) { return value->value(); }
} // namespace globals } // namespace esphome::globals
} // namespace esphome
+1
View File
@@ -10,6 +10,7 @@ globals:
type: int type: int
restore_value: true restore_value: true
initial_value: "0" initial_value: "0"
update_interval: 5s
- id: glob_float - id: glob_float
type: float type: float
restore_value: true restore_value: true