Compare commits

..

1 Commits

Author SHA1 Message Date
J. Nick Koston
83c68e246d [lock] Extract set_state_ helper to reduce code duplication 2026-01-18 19:49:20 -10:00
4 changed files with 33 additions and 47 deletions

View File

@@ -6,7 +6,6 @@ from esphome.const import (
CONF_INITIAL_VALUE,
CONF_RESTORE_VALUE,
CONF_TYPE,
CONF_UPDATE_INTERVAL,
CONF_VALUE,
)
from esphome.core import CoroPriority, coroutine_with_priority
@@ -14,37 +13,25 @@ from esphome.core import CoroPriority, coroutine_with_priority
CODEOWNERS = ["@esphome/core"]
globals_ns = cg.esphome_ns.namespace("globals")
GlobalsComponent = globals_ns.class_("GlobalsComponent", cg.Component)
RestoringGlobalsComponent = globals_ns.class_(
"RestoringGlobalsComponent", cg.PollingComponent
)
RestoringGlobalsComponent = globals_ns.class_("RestoringGlobalsComponent", cg.Component)
RestoringGlobalStringComponent = globals_ns.class_(
"RestoringGlobalStringComponent", cg.PollingComponent
"RestoringGlobalStringComponent", cg.Component
)
GlobalVarSetAction = globals_ns.class_("GlobalVarSetAction", automation.Action)
CONF_MAX_RESTORE_DATA_LENGTH = "max_restore_data_length"
def validate_update_interval(config):
if CONF_UPDATE_INTERVAL in config and not config.get(CONF_RESTORE_VALUE, False):
raise cv.Invalid("update_interval requires restore_value to be true")
return config
MULTI_CONF = True
CONFIG_SCHEMA = cv.All(
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,
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
cv.Optional(CONF_MAX_RESTORE_DATA_LENGTH): cv.int_range(0, 254),
cv.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}
).extend(cv.COMPONENT_SCHEMA),
validate_update_interval,
)
CONFIG_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,
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)
# Run with low priority so that namespaces are registered first
@@ -78,8 +65,6 @@ async def to_code(config):
value = value.encode()
hash_ = int(hashlib.md5(value).hexdigest()[:8], 16)
cg.add(glob.set_name_hash(hash_))
if CONF_UPDATE_INTERVAL in config:
cg.add(glob.set_update_interval(config[CONF_UPDATE_INTERVAL]))
@automation.register_action(

View File

@@ -5,7 +5,8 @@
#include "esphome/core/helpers.h"
#include <cstring>
namespace esphome::globals {
namespace esphome {
namespace globals {
template<typename T> class GlobalsComponent : public Component {
public:
@@ -23,14 +24,13 @@ template<typename T> class GlobalsComponent : public Component {
T value_{};
};
template<typename T> class RestoringGlobalsComponent : public PollingComponent {
template<typename T> class RestoringGlobalsComponent : public Component {
public:
using value_type = T;
explicit RestoringGlobalsComponent() : PollingComponent(1000) {}
explicit RestoringGlobalsComponent(T initial_value) : PollingComponent(1000), value_(initial_value) {}
explicit RestoringGlobalsComponent() = default;
explicit RestoringGlobalsComponent(T initial_value) : value_(initial_value) {}
explicit RestoringGlobalsComponent(
std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value)
: PollingComponent(1000) {
std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value) {
memcpy(this->value_, initial_value.data(), sizeof(T));
}
@@ -44,7 +44,7 @@ template<typename T> class RestoringGlobalsComponent : public PollingComponent {
float get_setup_priority() const override { return setup_priority::HARDWARE; }
void update() override { store_value_(); }
void loop() override { store_value_(); }
void on_shutdown() override { store_value_(); }
@@ -66,14 +66,13 @@ template<typename T> class RestoringGlobalsComponent : public PollingComponent {
};
// Use with string or subclasses of strings
template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public PollingComponent {
template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public Component {
public:
using value_type = T;
explicit RestoringGlobalStringComponent() : PollingComponent(1000) {}
explicit RestoringGlobalStringComponent(T initial_value) : PollingComponent(1000) { this->value_ = initial_value; }
explicit RestoringGlobalStringComponent() = default;
explicit RestoringGlobalStringComponent(T initial_value) { this->value_ = initial_value; }
explicit RestoringGlobalStringComponent(
std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value)
: PollingComponent(1000) {
std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value) {
memcpy(this->value_, initial_value.data(), sizeof(T));
}
@@ -91,7 +90,7 @@ template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public P
float get_setup_priority() const override { return setup_priority::HARDWARE; }
void update() override { store_value_(); }
void loop() override { store_value_(); }
void on_shutdown() override { store_value_(); }
@@ -145,4 +144,5 @@ 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, uint8_t SZ> T &id(RestoringGlobalStringComponent<T, SZ> *value) { return value->value(); }
} // namespace esphome::globals
} // namespace globals
} // namespace esphome

View File

@@ -28,16 +28,14 @@ const LogString *lock_state_to_string(LockState state) {
Lock::Lock() : state(LOCK_STATE_NONE) {}
LockCall Lock::make_call() { return LockCall(this); }
void Lock::lock() {
void Lock::set_state_(LockState state) {
auto call = this->make_call();
call.set_state(LOCK_STATE_LOCKED);
this->control(call);
}
void Lock::unlock() {
auto call = this->make_call();
call.set_state(LOCK_STATE_UNLOCKED);
call.set_state(state);
this->control(call);
}
void Lock::lock() { this->set_state_(LOCK_STATE_LOCKED); }
void Lock::unlock() { this->set_state_(LOCK_STATE_UNLOCKED); }
void Lock::open() {
if (traits.get_supports_open()) {
ESP_LOGD(TAG, "'%s' Opening.", this->get_name().c_str());

View File

@@ -156,6 +156,9 @@ class Lock : public EntityBase {
protected:
friend LockCall;
/// Helper for lock/unlock convenience methods
void set_state_(LockState state);
/** Perform the open latch action with hardware. This method is optional to implement
* when creating a new lock.
*