1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-20 08:46:01 +00:00

Merge upstream/dev into mid_loop branch

Resolved conflict in base_automation.h by combining:
- Upstream's const ref parameters (const Ts &...x)
- Our timestamp passing to check_internal_(now)
This commit is contained in:
J. Nick Koston
2025-11-04 19:28:08 -06:00
203 changed files with 1111 additions and 771 deletions

View File

@@ -105,7 +105,7 @@ template<typename... Ts> class AGS10NewI2cAddressAction : public Action<Ts...>,
public: public:
TEMPLATABLE_VALUE(uint8_t, new_address) TEMPLATABLE_VALUE(uint8_t, new_address)
void play(Ts... x) override { this->parent_->new_i2c_address(this->new_address_.value(x...)); } void play(const Ts &...x) override { this->parent_->new_i2c_address(this->new_address_.value(x...)); }
}; };
enum AGS10SetZeroPointActionMode { enum AGS10SetZeroPointActionMode {
@@ -122,7 +122,7 @@ template<typename... Ts> class AGS10SetZeroPointAction : public Action<Ts...>, p
TEMPLATABLE_VALUE(uint16_t, value) TEMPLATABLE_VALUE(uint16_t, value)
TEMPLATABLE_VALUE(AGS10SetZeroPointActionMode, mode) TEMPLATABLE_VALUE(AGS10SetZeroPointActionMode, mode)
void play(Ts... x) override { void play(const Ts &...x) override {
switch (this->mode_.value(x...)) { switch (this->mode_.value(x...)) {
case FACTORY_DEFAULT: case FACTORY_DEFAULT:
this->parent_->set_zero_point_with_factory_defaults(); this->parent_->set_zero_point_with_factory_defaults();

View File

@@ -13,7 +13,7 @@ template<typename... Ts> class SetAutoMuteAction : public Action<Ts...> {
TEMPLATABLE_VALUE(uint8_t, auto_mute_mode) TEMPLATABLE_VALUE(uint8_t, auto_mute_mode)
void play(Ts... x) override { this->aic3204_->set_auto_mute_mode(this->auto_mute_mode_.value(x...)); } void play(const Ts &...x) override { this->aic3204_->set_auto_mute_mode(this->auto_mute_mode_.value(x...)); }
protected: protected:
AIC3204 *aic3204_; AIC3204 *aic3204_;

View File

@@ -89,7 +89,7 @@ template<typename... Ts> class ArmAwayAction : public Action<Ts...> {
TEMPLATABLE_VALUE(std::string, code) TEMPLATABLE_VALUE(std::string, code)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->alarm_control_panel_->make_call(); auto call = this->alarm_control_panel_->make_call();
auto code = this->code_.optional_value(x...); auto code = this->code_.optional_value(x...);
if (code.has_value()) { if (code.has_value()) {
@@ -109,7 +109,7 @@ template<typename... Ts> class ArmHomeAction : public Action<Ts...> {
TEMPLATABLE_VALUE(std::string, code) TEMPLATABLE_VALUE(std::string, code)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->alarm_control_panel_->make_call(); auto call = this->alarm_control_panel_->make_call();
auto code = this->code_.optional_value(x...); auto code = this->code_.optional_value(x...);
if (code.has_value()) { if (code.has_value()) {
@@ -129,7 +129,7 @@ template<typename... Ts> class ArmNightAction : public Action<Ts...> {
TEMPLATABLE_VALUE(std::string, code) TEMPLATABLE_VALUE(std::string, code)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->alarm_control_panel_->make_call(); auto call = this->alarm_control_panel_->make_call();
auto code = this->code_.optional_value(x...); auto code = this->code_.optional_value(x...);
if (code.has_value()) { if (code.has_value()) {
@@ -149,7 +149,7 @@ template<typename... Ts> class DisarmAction : public Action<Ts...> {
TEMPLATABLE_VALUE(std::string, code) TEMPLATABLE_VALUE(std::string, code)
void play(Ts... x) override { this->alarm_control_panel_->disarm(this->code_.optional_value(x...)); } void play(const Ts &...x) override { this->alarm_control_panel_->disarm(this->code_.optional_value(x...)); }
protected: protected:
AlarmControlPanel *alarm_control_panel_; AlarmControlPanel *alarm_control_panel_;
@@ -159,7 +159,7 @@ template<typename... Ts> class PendingAction : public Action<Ts...> {
public: public:
explicit PendingAction(AlarmControlPanel *alarm_control_panel) : alarm_control_panel_(alarm_control_panel) {} explicit PendingAction(AlarmControlPanel *alarm_control_panel) : alarm_control_panel_(alarm_control_panel) {}
void play(Ts... x) override { this->alarm_control_panel_->make_call().pending().perform(); } void play(const Ts &...x) override { this->alarm_control_panel_->make_call().pending().perform(); }
protected: protected:
AlarmControlPanel *alarm_control_panel_; AlarmControlPanel *alarm_control_panel_;
@@ -169,7 +169,7 @@ template<typename... Ts> class TriggeredAction : public Action<Ts...> {
public: public:
explicit TriggeredAction(AlarmControlPanel *alarm_control_panel) : alarm_control_panel_(alarm_control_panel) {} explicit TriggeredAction(AlarmControlPanel *alarm_control_panel) : alarm_control_panel_(alarm_control_panel) {}
void play(Ts... x) override { this->alarm_control_panel_->make_call().triggered().perform(); } void play(const Ts &...x) override { this->alarm_control_panel_->make_call().triggered().perform(); }
protected: protected:
AlarmControlPanel *alarm_control_panel_; AlarmControlPanel *alarm_control_panel_;
@@ -178,7 +178,7 @@ template<typename... Ts> class TriggeredAction : public Action<Ts...> {
template<typename... Ts> class AlarmControlPanelCondition : public Condition<Ts...> { template<typename... Ts> class AlarmControlPanelCondition : public Condition<Ts...> {
public: public:
AlarmControlPanelCondition(AlarmControlPanel *parent) : parent_(parent) {} AlarmControlPanelCondition(AlarmControlPanel *parent) : parent_(parent) {}
bool check(Ts... x) override { bool check(const Ts &...x) override {
return this->parent_->is_state_armed(this->parent_->get_state()) || return this->parent_->is_state_armed(this->parent_->get_state()) ||
this->parent_->get_state() == ACP_STATE_PENDING || this->parent_->get_state() == ACP_STATE_TRIGGERED; this->parent_->get_state() == ACP_STATE_PENDING || this->parent_->get_state() == ACP_STATE_TRIGGERED;
} }

View File

@@ -39,7 +39,7 @@ class Animation : public image::Image {
template<typename... Ts> class AnimationNextFrameAction : public Action<Ts...> { template<typename... Ts> class AnimationNextFrameAction : public Action<Ts...> {
public: public:
AnimationNextFrameAction(Animation *parent) : parent_(parent) {} AnimationNextFrameAction(Animation *parent) : parent_(parent) {}
void play(Ts... x) override { this->parent_->next_frame(); } void play(const Ts &...x) override { this->parent_->next_frame(); }
protected: protected:
Animation *parent_; Animation *parent_;
@@ -48,7 +48,7 @@ template<typename... Ts> class AnimationNextFrameAction : public Action<Ts...> {
template<typename... Ts> class AnimationPrevFrameAction : public Action<Ts...> { template<typename... Ts> class AnimationPrevFrameAction : public Action<Ts...> {
public: public:
AnimationPrevFrameAction(Animation *parent) : parent_(parent) {} AnimationPrevFrameAction(Animation *parent) : parent_(parent) {}
void play(Ts... x) override { this->parent_->prev_frame(); } void play(const Ts &...x) override { this->parent_->prev_frame(); }
protected: protected:
Animation *parent_; Animation *parent_;
@@ -58,7 +58,7 @@ template<typename... Ts> class AnimationSetFrameAction : public Action<Ts...> {
public: public:
AnimationSetFrameAction(Animation *parent) : parent_(parent) {} AnimationSetFrameAction(Animation *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(uint16_t, frame) TEMPLATABLE_VALUE(uint16_t, frame)
void play(Ts... x) override { this->parent_->set_frame(this->frame_.value(x...)); } void play(const Ts &...x) override { this->parent_->set_frame(this->frame_.value(x...)); }
protected: protected:
Animation *parent_; Animation *parent_;

View File

@@ -410,8 +410,8 @@ uint16_t APIConnection::try_send_fan_state(EntityBase *entity, APIConnection *co
} }
if (traits.supports_direction()) if (traits.supports_direction())
msg.direction = static_cast<enums::FanDirection>(fan->direction); msg.direction = static_cast<enums::FanDirection>(fan->direction);
if (traits.supports_preset_modes()) if (traits.supports_preset_modes() && fan->has_preset_mode())
msg.set_preset_mode(StringRef(fan->preset_mode)); msg.set_preset_mode(StringRef(fan->get_preset_mode()));
return fill_and_encode_entity_state(fan, msg, FanStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); return fill_and_encode_entity_state(fan, msg, FanStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
} }
uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
@@ -877,7 +877,7 @@ uint16_t APIConnection::try_send_select_state(EntityBase *entity, APIConnection
bool is_single) { bool is_single) {
auto *select = static_cast<select::Select *>(entity); auto *select = static_cast<select::Select *>(entity);
SelectStateResponse resp; SelectStateResponse resp;
resp.set_state(StringRef(select->state)); resp.set_state(StringRef(select->current_option()));
resp.missing_state = !select->has_state(); resp.missing_state = !select->has_state();
return fill_and_encode_entity_state(select, resp, SelectStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); return fill_and_encode_entity_state(select, resp, SelectStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
} }

View File

@@ -224,7 +224,7 @@ void APIServer::dump_config() {
" Address: %s:%u\n" " Address: %s:%u\n"
" Listen backlog: %u\n" " Listen backlog: %u\n"
" Max connections: %u", " Max connections: %u",
network::get_use_address().c_str(), this->port_, this->listen_backlog_, this->max_connections_); network::get_use_address(), this->port_, this->listen_backlog_, this->max_connections_);
#ifdef USE_API_NOISE #ifdef USE_API_NOISE
ESP_LOGCONFIG(TAG, " Noise encryption: %s", YESNO(this->noise_ctx_->has_psk())); ESP_LOGCONFIG(TAG, " Noise encryption: %s", YESNO(this->noise_ctx_->has_psk()));
if (!this->noise_ctx_->has_psk()) { if (!this->noise_ctx_->has_psk()) {

View File

@@ -237,7 +237,7 @@ extern APIServer *global_api_server; // NOLINT(cppcoreguidelines-avoid-non-cons
template<typename... Ts> class APIConnectedCondition : public Condition<Ts...> { template<typename... Ts> class APIConnectedCondition : public Condition<Ts...> {
public: public:
bool check(Ts... x) override { return global_api_server->is_connected(); } bool check(const Ts &...x) override { return global_api_server->is_connected(); }
}; };
} // namespace esphome::api } // namespace esphome::api

View File

@@ -133,7 +133,7 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
Trigger<std::string, Ts...> *get_error_trigger() const { return this->error_trigger_; } Trigger<std::string, Ts...> *get_error_trigger() const { return this->error_trigger_; }
#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
void play(Ts... x) override { void play(const Ts &...x) override {
HomeassistantActionRequest resp; HomeassistantActionRequest resp;
std::string service_value = this->service_.value(x...); std::string service_value = this->service_.value(x...);
resp.set_service(StringRef(service_value)); resp.set_service(StringRef(service_value));

View File

@@ -10,7 +10,7 @@ namespace at581x {
template<typename... Ts> class AT581XResetAction : public Action<Ts...>, public Parented<AT581XComponent> { template<typename... Ts> class AT581XResetAction : public Action<Ts...>, public Parented<AT581XComponent> {
public: public:
void play(Ts... x) { this->parent_->reset_hardware_frontend(); } void play(const Ts &...x) { this->parent_->reset_hardware_frontend(); }
}; };
template<typename... Ts> class AT581XSettingsAction : public Action<Ts...>, public Parented<AT581XComponent> { template<typename... Ts> class AT581XSettingsAction : public Action<Ts...>, public Parented<AT581XComponent> {
@@ -25,7 +25,7 @@ template<typename... Ts> class AT581XSettingsAction : public Action<Ts...>, publ
TEMPLATABLE_VALUE(int, trigger_keep) TEMPLATABLE_VALUE(int, trigger_keep)
TEMPLATABLE_VALUE(int, stage_gain) TEMPLATABLE_VALUE(int, stage_gain)
void play(Ts... x) { void play(const Ts &...x) {
if (this->frequency_.has_value()) { if (this->frequency_.has_value()) {
int v = this->frequency_.value(x...); int v = this->frequency_.value(x...);
this->parent_->set_frequency(v); this->parent_->set_frequency(v);

View File

@@ -13,7 +13,7 @@ template<typename... Ts> class SetMicGainAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, mic_gain) TEMPLATABLE_VALUE(float, mic_gain)
void play(Ts... x) override { this->audio_adc_->set_mic_gain(this->mic_gain_.value(x...)); } void play(const Ts &...x) override { this->audio_adc_->set_mic_gain(this->mic_gain_.value(x...)); }
protected: protected:
AudioAdc *audio_adc_; AudioAdc *audio_adc_;

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class MuteOffAction : public Action<Ts...> {
public: public:
explicit MuteOffAction(AudioDac *audio_dac) : audio_dac_(audio_dac) {} explicit MuteOffAction(AudioDac *audio_dac) : audio_dac_(audio_dac) {}
void play(Ts... x) override { this->audio_dac_->set_mute_off(); } void play(const Ts &...x) override { this->audio_dac_->set_mute_off(); }
protected: protected:
AudioDac *audio_dac_; AudioDac *audio_dac_;
@@ -21,7 +21,7 @@ template<typename... Ts> class MuteOnAction : public Action<Ts...> {
public: public:
explicit MuteOnAction(AudioDac *audio_dac) : audio_dac_(audio_dac) {} explicit MuteOnAction(AudioDac *audio_dac) : audio_dac_(audio_dac) {}
void play(Ts... x) override { this->audio_dac_->set_mute_on(); } void play(const Ts &...x) override { this->audio_dac_->set_mute_on(); }
protected: protected:
AudioDac *audio_dac_; AudioDac *audio_dac_;
@@ -33,7 +33,7 @@ template<typename... Ts> class SetVolumeAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, volume) TEMPLATABLE_VALUE(float, volume)
void play(Ts... x) override { this->audio_dac_->set_volume(this->volume_.value(x...)); } void play(const Ts &...x) override { this->audio_dac_->set_volume(this->volume_.value(x...)); }
protected: protected:
AudioDac *audio_dac_; AudioDac *audio_dac_;

View File

@@ -141,7 +141,7 @@ class StateChangeTrigger : public Trigger<optional<bool>, optional<bool> > {
template<typename... Ts> class BinarySensorCondition : public Condition<Ts...> { template<typename... Ts> class BinarySensorCondition : public Condition<Ts...> {
public: public:
BinarySensorCondition(BinarySensor *parent, bool state) : parent_(parent), state_(state) {} BinarySensorCondition(BinarySensor *parent, bool state) : parent_(parent), state_(state) {}
bool check(Ts... x) override { return this->parent_->state == this->state_; } bool check(const Ts &...x) override { return this->parent_->state == this->state_; }
protected: protected:
BinarySensor *parent_; BinarySensor *parent_;
@@ -153,7 +153,7 @@ template<typename... Ts> class BinarySensorPublishAction : public Action<Ts...>
explicit BinarySensorPublishAction(BinarySensor *sensor) : sensor_(sensor) {} explicit BinarySensorPublishAction(BinarySensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(bool, state) TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override { void play(const Ts &...x) override {
auto val = this->state_.value(x...); auto val = this->state_.value(x...);
this->sensor_->publish_state(val); this->sensor_->publish_state(val);
} }
@@ -166,7 +166,7 @@ template<typename... Ts> class BinarySensorInvalidateAction : public Action<Ts..
public: public:
explicit BinarySensorInvalidateAction(BinarySensor *sensor) : sensor_(sensor) {} explicit BinarySensorInvalidateAction(BinarySensor *sensor) : sensor_(sensor) {}
void play(Ts... x) override { this->sensor_->invalidate_state(); } void play(const Ts &...x) override { this->sensor_->invalidate_state(); }
protected: protected:
BinarySensor *sensor_; BinarySensor *sensor_;

View File

@@ -89,7 +89,7 @@ class BL0906 : public PollingComponent, public uart::UARTDevice {
template<typename... Ts> class ResetEnergyAction : public Action<Ts...>, public Parented<BL0906> { template<typename... Ts> class ResetEnergyAction : public Action<Ts...>, public Parented<BL0906> {
public: public:
void play(Ts... x) override { this->parent_->enqueue_action_(&BL0906::reset_energy_); } void play(const Ts &...x) override { this->parent_->enqueue_action_(&BL0906::reset_energy_); }
}; };
} // namespace bl0906 } // namespace bl0906

View File

@@ -123,9 +123,9 @@ template<typename... Ts> class BLEClientWriteAction : public Action<Ts...>, publ
this->has_simple_value_ = true; this->has_simple_value_ = true;
} }
void play(Ts... x) override {} void play(const Ts &...x) override {}
void play_complex(Ts... x) override { void play_complex(const Ts &...x) override {
this->num_running_++; this->num_running_++;
this->var_ = std::make_tuple(x...); this->var_ = std::make_tuple(x...);
auto value = this->has_simple_value_ ? this->value_.simple : this->value_.template_func(x...); auto value = this->has_simple_value_ ? this->value_.simple : this->value_.template_func(x...);
@@ -229,7 +229,7 @@ template<typename... Ts> class BLEClientPasskeyReplyAction : public Action<Ts...
public: public:
BLEClientPasskeyReplyAction(BLEClient *ble_client) { parent_ = ble_client; } BLEClientPasskeyReplyAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override { void play(const Ts &...x) override {
uint32_t passkey; uint32_t passkey;
if (has_simple_value_) { if (has_simple_value_) {
passkey = this->value_.simple; passkey = this->value_.simple;
@@ -266,7 +266,7 @@ template<typename... Ts> class BLEClientNumericComparisonReplyAction : public Ac
public: public:
BLEClientNumericComparisonReplyAction(BLEClient *ble_client) { parent_ = ble_client; } BLEClientNumericComparisonReplyAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override { void play(const Ts &...x) override {
esp_bd_addr_t remote_bda; esp_bd_addr_t remote_bda;
memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t)); memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t));
if (has_simple_value_) { if (has_simple_value_) {
@@ -299,7 +299,7 @@ template<typename... Ts> class BLEClientRemoveBondAction : public Action<Ts...>
public: public:
BLEClientRemoveBondAction(BLEClient *ble_client) { parent_ = ble_client; } BLEClientRemoveBondAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override { void play(const Ts &...x) override {
esp_bd_addr_t remote_bda; esp_bd_addr_t remote_bda;
memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t)); memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t));
esp_ble_remove_bond_device(remote_bda); esp_ble_remove_bond_device(remote_bda);
@@ -334,9 +334,9 @@ template<typename... Ts> class BLEClientConnectAction : public Action<Ts...>, pu
} }
// not used since we override play_complex_ // not used since we override play_complex_
void play(Ts... x) override {} void play(const Ts &...x) override {}
void play_complex(Ts... x) override { void play_complex(const Ts &...x) override {
// it makes no sense to have multiple instances of this running at the same time. // it makes no sense to have multiple instances of this running at the same time.
// this would occur only if the same automation was re-triggered while still // this would occur only if the same automation was re-triggered while still
// running. So just cancel the second chain if this is detected. // running. So just cancel the second chain if this is detected.
@@ -379,9 +379,9 @@ template<typename... Ts> class BLEClientDisconnectAction : public Action<Ts...>,
} }
// not used since we override play_complex_ // not used since we override play_complex_
void play(Ts... x) override {} void play(const Ts &...x) override {}
void play_complex(Ts... x) override { void play_complex(const Ts &...x) override {
this->num_running_++; this->num_running_++;
if (this->node_state == espbt::ClientState::IDLE) { if (this->node_state == espbt::ClientState::IDLE) {
this->play_next_(x...); this->play_next_(x...);

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class PressAction : public Action<Ts...> {
public: public:
explicit PressAction(Button *button) : button_(button) {} explicit PressAction(Button *button) : button_(button) {}
void play(Ts... x) override { this->button_->press(); } void play(const Ts &...x) override { this->button_->press(); }
protected: protected:
Button *button_; Button *button_;

View File

@@ -129,7 +129,7 @@ template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public P
this->remote_transmission_request_ = remote_transmission_request; this->remote_transmission_request_ = remote_transmission_request;
} }
void play(Ts... x) override { void play(const Ts &...x) override {
auto can_id = this->can_id_.has_value() ? *this->can_id_ : this->parent_->can_id_; auto can_id = this->can_id_.has_value() ? *this->can_id_ : this->parent_->can_id_;
auto use_extended_id = auto use_extended_id =
this->use_extended_id_.has_value() ? *this->use_extended_id_ : this->parent_->use_extended_id_; this->use_extended_id_.has_value() ? *this->use_extended_id_ : this->parent_->use_extended_id_;

View File

@@ -22,7 +22,7 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
TEMPLATABLE_VALUE(std::string, custom_preset) TEMPLATABLE_VALUE(std::string, custom_preset)
TEMPLATABLE_VALUE(ClimateSwingMode, swing_mode) TEMPLATABLE_VALUE(ClimateSwingMode, swing_mode)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->climate_->make_call(); auto call = this->climate_->make_call();
call.set_mode(this->mode_.optional_value(x...)); call.set_mode(this->mode_.optional_value(x...));
call.set_target_temperature(this->target_temperature_.optional_value(x...)); call.set_target_temperature(this->target_temperature_.optional_value(x...));

View File

@@ -30,7 +30,7 @@ template<typename... Ts> class CM1106CalibrateZeroAction : public Action<Ts...>
public: public:
CM1106CalibrateZeroAction(CM1106Component *cm1106) : cm1106_(cm1106) {} CM1106CalibrateZeroAction(CM1106Component *cm1106) : cm1106_(cm1106) {}
void play(Ts... x) override { this->cm1106_->calibrate_zero(400); } void play(const Ts &...x) override { this->cm1106_->calibrate_zero(400); }
protected: protected:
CM1106Component *cm1106_; CM1106Component *cm1106_;

View File

@@ -8,6 +8,7 @@ BYTE_ORDER_BIG = "big_endian"
CONF_COLOR_DEPTH = "color_depth" CONF_COLOR_DEPTH = "color_depth"
CONF_DRAW_ROUNDING = "draw_rounding" CONF_DRAW_ROUNDING = "draw_rounding"
CONF_ENABLED = "enabled"
CONF_ON_RECEIVE = "on_receive" CONF_ON_RECEIVE = "on_receive"
CONF_ON_STATE_CHANGE = "on_state_change" CONF_ON_STATE_CHANGE = "on_state_change"
CONF_REQUEST_HEADERS = "request_headers" CONF_REQUEST_HEADERS = "request_headers"

View File

@@ -12,7 +12,7 @@ void CopyFan::setup() {
this->oscillating = source_->oscillating; this->oscillating = source_->oscillating;
this->speed = source_->speed; this->speed = source_->speed;
this->direction = source_->direction; this->direction = source_->direction;
this->preset_mode = source_->preset_mode; this->set_preset_mode_(source_->get_preset_mode());
this->publish_state(); this->publish_state();
}); });
@@ -20,7 +20,7 @@ void CopyFan::setup() {
this->oscillating = source_->oscillating; this->oscillating = source_->oscillating;
this->speed = source_->speed; this->speed = source_->speed;
this->direction = source_->direction; this->direction = source_->direction;
this->preset_mode = source_->preset_mode; this->set_preset_mode_(source_->get_preset_mode());
this->publish_state(); this->publish_state();
} }
@@ -49,7 +49,7 @@ void CopyFan::control(const fan::FanCall &call) {
call2.set_speed(*call.get_speed()); call2.set_speed(*call.get_speed());
if (call.get_direction().has_value()) if (call.get_direction().has_value())
call2.set_direction(*call.get_direction()); call2.set_direction(*call.get_direction());
if (!call.get_preset_mode().empty()) if (call.has_preset_mode())
call2.set_preset_mode(call.get_preset_mode()); call2.set_preset_mode(call.get_preset_mode());
call2.perform(); call2.perform();
} }

View File

@@ -7,19 +7,19 @@ namespace copy {
static const char *const TAG = "copy.select"; static const char *const TAG = "copy.select";
void CopySelect::setup() { void CopySelect::setup() {
source_->add_on_state_callback([this](const std::string &value, size_t index) { this->publish_state(value); }); source_->add_on_state_callback([this](const std::string &value, size_t index) { this->publish_state(index); });
traits.set_options(source_->traits.get_options()); traits.set_options(source_->traits.get_options());
if (source_->has_state()) if (source_->has_state())
this->publish_state(source_->state); this->publish_state(source_->active_index().value());
} }
void CopySelect::dump_config() { LOG_SELECT("", "Copy Select", this); } void CopySelect::dump_config() { LOG_SELECT("", "Copy Select", this); }
void CopySelect::control(const std::string &value) { void CopySelect::control(size_t index) {
auto call = source_->make_call(); auto call = source_->make_call();
call.set_option(value); call.set_index(index);
call.perform(); call.perform();
} }

View File

@@ -13,7 +13,7 @@ class CopySelect : public select::Select, public Component {
void dump_config() override; void dump_config() override;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
select::Select *source_; select::Select *source_;
}; };

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class OpenAction : public Action<Ts...> {
public: public:
explicit OpenAction(Cover *cover) : cover_(cover) {} explicit OpenAction(Cover *cover) : cover_(cover) {}
void play(Ts... x) override { this->cover_->make_call().set_command_open().perform(); } void play(const Ts &...x) override { this->cover_->make_call().set_command_open().perform(); }
protected: protected:
Cover *cover_; Cover *cover_;
@@ -21,7 +21,7 @@ template<typename... Ts> class CloseAction : public Action<Ts...> {
public: public:
explicit CloseAction(Cover *cover) : cover_(cover) {} explicit CloseAction(Cover *cover) : cover_(cover) {}
void play(Ts... x) override { this->cover_->make_call().set_command_close().perform(); } void play(const Ts &...x) override { this->cover_->make_call().set_command_close().perform(); }
protected: protected:
Cover *cover_; Cover *cover_;
@@ -31,7 +31,7 @@ template<typename... Ts> class StopAction : public Action<Ts...> {
public: public:
explicit StopAction(Cover *cover) : cover_(cover) {} explicit StopAction(Cover *cover) : cover_(cover) {}
void play(Ts... x) override { this->cover_->make_call().set_command_stop().perform(); } void play(const Ts &...x) override { this->cover_->make_call().set_command_stop().perform(); }
protected: protected:
Cover *cover_; Cover *cover_;
@@ -41,7 +41,7 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
public: public:
explicit ToggleAction(Cover *cover) : cover_(cover) {} explicit ToggleAction(Cover *cover) : cover_(cover) {}
void play(Ts... x) override { this->cover_->make_call().set_command_toggle().perform(); } void play(const Ts &...x) override { this->cover_->make_call().set_command_toggle().perform(); }
protected: protected:
Cover *cover_; Cover *cover_;
@@ -55,7 +55,7 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, position) TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt) TEMPLATABLE_VALUE(float, tilt)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->cover_->make_call(); auto call = this->cover_->make_call();
if (this->stop_.has_value()) if (this->stop_.has_value())
call.set_stop(this->stop_.value(x...)); call.set_stop(this->stop_.value(x...));
@@ -77,7 +77,7 @@ template<typename... Ts> class CoverPublishAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, tilt) TEMPLATABLE_VALUE(float, tilt)
TEMPLATABLE_VALUE(CoverOperation, current_operation) TEMPLATABLE_VALUE(CoverOperation, current_operation)
void play(Ts... x) override { void play(const Ts &...x) override {
if (this->position_.has_value()) if (this->position_.has_value())
this->cover_->position = this->position_.value(x...); this->cover_->position = this->position_.value(x...);
if (this->tilt_.has_value()) if (this->tilt_.has_value())
@@ -94,7 +94,7 @@ template<typename... Ts> class CoverPublishAction : public Action<Ts...> {
template<typename... Ts> class CoverIsOpenCondition : public Condition<Ts...> { template<typename... Ts> class CoverIsOpenCondition : public Condition<Ts...> {
public: public:
CoverIsOpenCondition(Cover *cover) : cover_(cover) {} CoverIsOpenCondition(Cover *cover) : cover_(cover) {}
bool check(Ts... x) override { return this->cover_->is_fully_open(); } bool check(const Ts &...x) override { return this->cover_->is_fully_open(); }
protected: protected:
Cover *cover_; Cover *cover_;
@@ -103,7 +103,7 @@ template<typename... Ts> class CoverIsOpenCondition : public Condition<Ts...> {
template<typename... Ts> class CoverIsClosedCondition : public Condition<Ts...> { template<typename... Ts> class CoverIsClosedCondition : public Condition<Ts...> {
public: public:
CoverIsClosedCondition(Cover *cover) : cover_(cover) {} CoverIsClosedCondition(Cover *cover) : cover_(cover) {}
bool check(Ts... x) override { return this->cover_->is_fully_closed(); } bool check(const Ts &...x) override { return this->cover_->is_fully_closed(); }
protected: protected:
Cover *cover_; Cover *cover_;

View File

@@ -114,7 +114,7 @@ template<typename... Ts> class CS5460ARestartAction : public Action<Ts...> {
public: public:
CS5460ARestartAction(CS5460AComponent *cs5460a) : cs5460a_(cs5460a) {} CS5460ARestartAction(CS5460AComponent *cs5460a) : cs5460a_(cs5460a) {}
void play(Ts... x) override { cs5460a_->restart(); } void play(const Ts &...x) override { cs5460a_->restart(); }
protected: protected:
CS5460AComponent *cs5460a_; CS5460AComponent *cs5460a_;

View File

@@ -101,7 +101,7 @@ template<typename... Ts> class DateSetAction : public Action<Ts...>, public Pare
public: public:
TEMPLATABLE_VALUE(ESPTime, date) TEMPLATABLE_VALUE(ESPTime, date)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->parent_->make_call(); auto call = this->parent_->make_call();
if (this->date_.has_value()) { if (this->date_.has_value()) {

View File

@@ -124,7 +124,7 @@ template<typename... Ts> class DateTimeSetAction : public Action<Ts...>, public
public: public:
TEMPLATABLE_VALUE(ESPTime, datetime) TEMPLATABLE_VALUE(ESPTime, datetime)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->parent_->make_call(); auto call = this->parent_->make_call();
if (this->datetime_.has_value()) { if (this->datetime_.has_value()) {

View File

@@ -103,7 +103,7 @@ template<typename... Ts> class TimeSetAction : public Action<Ts...>, public Pare
public: public:
TEMPLATABLE_VALUE(ESPTime, time) TEMPLATABLE_VALUE(ESPTime, time)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->parent_->make_call(); auto call = this->parent_->make_call();
if (this->time_.has_value()) { if (this->time_.has_value()) {

View File

@@ -148,7 +148,7 @@ template<typename... Ts> class EnterDeepSleepAction : public Action<Ts...> {
void set_time(time::RealTimeClock *time) { this->time_ = time; } void set_time(time::RealTimeClock *time) { this->time_ = time; }
#endif #endif
void play(Ts... x) override { void play(const Ts &...x) override {
if (this->sleep_duration_.has_value()) { if (this->sleep_duration_.has_value()) {
this->deep_sleep_->set_sleep_duration(this->sleep_duration_.value(x...)); this->deep_sleep_->set_sleep_duration(this->sleep_duration_.value(x...));
} }
@@ -207,12 +207,12 @@ template<typename... Ts> class EnterDeepSleepAction : public Action<Ts...> {
template<typename... Ts> class PreventDeepSleepAction : public Action<Ts...>, public Parented<DeepSleepComponent> { template<typename... Ts> class PreventDeepSleepAction : public Action<Ts...>, public Parented<DeepSleepComponent> {
public: public:
void play(Ts... x) override { this->parent_->prevent_deep_sleep(); } void play(const Ts &...x) override { this->parent_->prevent_deep_sleep(); }
}; };
template<typename... Ts> class AllowDeepSleepAction : public Action<Ts...>, public Parented<DeepSleepComponent> { template<typename... Ts> class AllowDeepSleepAction : public Action<Ts...>, public Parented<DeepSleepComponent> {
public: public:
void play(Ts... x) override { this->parent_->allow_deep_sleep(); } void play(const Ts &...x) override { this->parent_->allow_deep_sleep(); }
}; };
} // namespace deep_sleep } // namespace deep_sleep

View File

@@ -77,7 +77,7 @@ class DFPlayer : public uart::UARTDevice, public Component {
class ACTION_CLASS : /* NOLINT */ \ class ACTION_CLASS : /* NOLINT */ \
public Action<Ts...>, \ public Action<Ts...>, \
public Parented<DFPlayer> { \ public Parented<DFPlayer> { \
void play(Ts... x) override { this->parent_->ACTION_METHOD(); } \ void play(const Ts &...x) override { this->parent_->ACTION_METHOD(); } \
}; };
DFPLAYER_SIMPLE_ACTION(NextAction, next) DFPLAYER_SIMPLE_ACTION(NextAction, next)
@@ -87,7 +87,7 @@ template<typename... Ts> class PlayMp3Action : public Action<Ts...>, public Pare
public: public:
TEMPLATABLE_VALUE(uint16_t, file) TEMPLATABLE_VALUE(uint16_t, file)
void play(Ts... x) override { void play(const Ts &...x) override {
auto file = this->file_.value(x...); auto file = this->file_.value(x...);
this->parent_->play_mp3(file); this->parent_->play_mp3(file);
} }
@@ -98,7 +98,7 @@ template<typename... Ts> class PlayFileAction : public Action<Ts...>, public Par
TEMPLATABLE_VALUE(uint16_t, file) TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(bool, loop) TEMPLATABLE_VALUE(bool, loop)
void play(Ts... x) override { void play(const Ts &...x) override {
auto file = this->file_.value(x...); auto file = this->file_.value(x...);
auto loop = this->loop_.value(x...); auto loop = this->loop_.value(x...);
if (loop) { if (loop) {
@@ -115,7 +115,7 @@ template<typename... Ts> class PlayFolderAction : public Action<Ts...>, public P
TEMPLATABLE_VALUE(uint16_t, file) TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(bool, loop) TEMPLATABLE_VALUE(bool, loop)
void play(Ts... x) override { void play(const Ts &...x) override {
auto folder = this->folder_.value(x...); auto folder = this->folder_.value(x...);
auto file = this->file_.value(x...); auto file = this->file_.value(x...);
auto loop = this->loop_.value(x...); auto loop = this->loop_.value(x...);
@@ -131,7 +131,7 @@ template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Pa
public: public:
TEMPLATABLE_VALUE(Device, device) TEMPLATABLE_VALUE(Device, device)
void play(Ts... x) override { void play(const Ts &...x) override {
auto device = this->device_.value(x...); auto device = this->device_.value(x...);
this->parent_->set_device(device); this->parent_->set_device(device);
} }
@@ -141,7 +141,7 @@ template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Pa
public: public:
TEMPLATABLE_VALUE(uint8_t, volume) TEMPLATABLE_VALUE(uint8_t, volume)
void play(Ts... x) override { void play(const Ts &...x) override {
auto volume = this->volume_.value(x...); auto volume = this->volume_.value(x...);
this->parent_->set_volume(volume); this->parent_->set_volume(volume);
} }
@@ -151,7 +151,7 @@ template<typename... Ts> class SetEqAction : public Action<Ts...>, public Parent
public: public:
TEMPLATABLE_VALUE(EqPreset, eq) TEMPLATABLE_VALUE(EqPreset, eq)
void play(Ts... x) override { void play(const Ts &...x) override {
auto eq = this->eq_.value(x...); auto eq = this->eq_.value(x...);
this->parent_->set_eq(eq); this->parent_->set_eq(eq);
} }
@@ -168,7 +168,7 @@ DFPLAYER_SIMPLE_ACTION(VolumeDownAction, volume_down)
template<typename... Ts> class DFPlayerIsPlayingCondition : public Condition<Ts...>, public Parented<DFPlayer> { template<typename... Ts> class DFPlayerIsPlayingCondition : public Condition<Ts...>, public Parented<DFPlayer> {
public: public:
bool check(Ts... x) override { return this->parent_->is_playing(); } bool check(const Ts &...x) override { return this->parent_->is_playing(); }
}; };
class DFPlayerFinishedPlaybackTrigger : public Trigger<> { class DFPlayerFinishedPlaybackTrigger : public Trigger<> {

View File

@@ -11,7 +11,7 @@ namespace dfrobot_sen0395 {
template<typename... Ts> template<typename... Ts>
class DfrobotSen0395ResetAction : public Action<Ts...>, public Parented<DfrobotSen0395Component> { class DfrobotSen0395ResetAction : public Action<Ts...>, public Parented<DfrobotSen0395Component> {
public: public:
void play(Ts... x) { this->parent_->enqueue(make_unique<ResetSystemCommand>()); } void play(const Ts &...x) { this->parent_->enqueue(make_unique<ResetSystemCommand>()); }
}; };
template<typename... Ts> template<typename... Ts>
@@ -33,7 +33,7 @@ class DfrobotSen0395SettingsAction : public Action<Ts...>, public Parented<Dfrob
TEMPLATABLE_VALUE(float, det_min4) TEMPLATABLE_VALUE(float, det_min4)
TEMPLATABLE_VALUE(float, det_max4) TEMPLATABLE_VALUE(float, det_max4)
void play(Ts... x) { void play(const Ts &...x) {
this->parent_->enqueue(make_unique<PowerCommand>(0)); this->parent_->enqueue(make_unique<PowerCommand>(0));
if (this->factory_reset_.has_value() && this->factory_reset_.value(x...) == true) { if (this->factory_reset_.has_value() && this->factory_reset_.value(x...) == true) {
this->parent_->enqueue(make_unique<FactoryResetCommand>()); this->parent_->enqueue(make_unique<FactoryResetCommand>());

View File

@@ -176,7 +176,117 @@ class Display;
class DisplayPage; class DisplayPage;
class DisplayOnPageChangeTrigger; class DisplayOnPageChangeTrigger;
using display_writer_t = std::function<void(Display &)>; /** Optimized display writer that uses function pointers for stateless lambdas.
*
* Similar to TemplatableValue but specialized for display writer callbacks.
* Saves ~8 bytes per stateless lambda on 32-bit platforms (16 bytes std::function → ~8 bytes discriminator+pointer).
*
* Supports both:
* - Stateless lambdas (from YAML) → function pointer (4 bytes)
* - Stateful lambdas/std::function (from C++ code) → std::function* (heap allocated)
*
* @tparam T The display type (e.g., Display, Nextion, GPIOLCDDisplay)
*/
template<typename T> class DisplayWriter {
public:
DisplayWriter() : type_(NONE) {}
// For stateless lambdas (convertible to function pointer): use function pointer (4 bytes)
template<typename F>
DisplayWriter(F f) requires std::invocable<F, T &> && std::convertible_to<F, void (*)(T &)>
: type_(STATELESS_LAMBDA) {
this->stateless_f_ = f; // Implicit conversion to function pointer
}
// For stateful lambdas and std::function (not convertible to function pointer): use std::function* (heap allocated)
// This handles backwards compatibility with external components
template<typename F>
DisplayWriter(F f) requires std::invocable<F, T &> &&(!std::convertible_to<F, void (*)(T &)>) : type_(LAMBDA) {
this->f_ = new std::function<void(T &)>(std::move(f));
}
// Copy constructor
DisplayWriter(const DisplayWriter &other) : type_(other.type_) {
if (type_ == LAMBDA) {
this->f_ = new std::function<void(T &)>(*other.f_);
} else if (type_ == STATELESS_LAMBDA) {
this->stateless_f_ = other.stateless_f_;
}
}
// Move constructor
DisplayWriter(DisplayWriter &&other) noexcept : type_(other.type_) {
if (type_ == LAMBDA) {
this->f_ = other.f_;
other.f_ = nullptr;
} else if (type_ == STATELESS_LAMBDA) {
this->stateless_f_ = other.stateless_f_;
}
other.type_ = NONE;
}
// Assignment operators
DisplayWriter &operator=(const DisplayWriter &other) {
if (this != &other) {
this->~DisplayWriter();
new (this) DisplayWriter(other);
}
return *this;
}
DisplayWriter &operator=(DisplayWriter &&other) noexcept {
if (this != &other) {
this->~DisplayWriter();
new (this) DisplayWriter(std::move(other));
}
return *this;
}
~DisplayWriter() {
if (type_ == LAMBDA) {
delete this->f_;
}
// STATELESS_LAMBDA/NONE: no cleanup needed (function pointer or empty)
}
bool has_value() const { return this->type_ != NONE; }
void call(T &display) const {
switch (this->type_) {
case STATELESS_LAMBDA:
this->stateless_f_(display); // Direct function pointer call
break;
case LAMBDA:
(*this->f_)(display); // std::function call
break;
case NONE:
default:
break;
}
}
// Operator() for convenience
void operator()(T &display) const { this->call(display); }
// Operator* for backwards compatibility with (*writer_)(*this) pattern
DisplayWriter &operator*() { return *this; }
const DisplayWriter &operator*() const { return *this; }
protected:
enum : uint8_t {
NONE,
LAMBDA,
STATELESS_LAMBDA,
} type_;
union {
std::function<void(T &)> *f_;
void (*stateless_f_)(T &);
};
};
// Type alias for Display writer - uses optimized DisplayWriter instead of std::function
using display_writer_t = DisplayWriter<Display>;
#define LOG_DISPLAY(prefix, type, obj) \ #define LOG_DISPLAY(prefix, type, obj) \
if ((obj) != nullptr) { \ if ((obj) != nullptr) { \
@@ -678,7 +788,7 @@ class Display : public PollingComponent {
void sort_triangle_points_by_y_(int *x1, int *y1, int *x2, int *y2, int *x3, int *y3); void sort_triangle_points_by_y_(int *x1, int *y1, int *x2, int *y2, int *x3, int *y3);
DisplayRotation rotation_{DISPLAY_ROTATION_0_DEGREES}; DisplayRotation rotation_{DISPLAY_ROTATION_0_DEGREES};
optional<display_writer_t> writer_{}; display_writer_t writer_{};
DisplayPage *page_{nullptr}; DisplayPage *page_{nullptr};
DisplayPage *previous_page_{nullptr}; DisplayPage *previous_page_{nullptr};
std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_; std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
@@ -709,7 +819,7 @@ template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
public: public:
TEMPLATABLE_VALUE(DisplayPage *, page) TEMPLATABLE_VALUE(DisplayPage *, page)
void play(Ts... x) override { void play(const Ts &...x) override {
auto *page = this->page_.value(x...); auto *page = this->page_.value(x...);
if (page != nullptr) { if (page != nullptr) {
page->show(); page->show();
@@ -721,7 +831,7 @@ template<typename... Ts> class DisplayPageShowNextAction : public Action<Ts...>
public: public:
DisplayPageShowNextAction(Display *buffer) : buffer_(buffer) {} DisplayPageShowNextAction(Display *buffer) : buffer_(buffer) {}
void play(Ts... x) override { this->buffer_->show_next_page(); } void play(const Ts &...x) override { this->buffer_->show_next_page(); }
Display *buffer_; Display *buffer_;
}; };
@@ -730,7 +840,7 @@ template<typename... Ts> class DisplayPageShowPrevAction : public Action<Ts...>
public: public:
DisplayPageShowPrevAction(Display *buffer) : buffer_(buffer) {} DisplayPageShowPrevAction(Display *buffer) : buffer_(buffer) {}
void play(Ts... x) override { this->buffer_->show_prev_page(); } void play(const Ts &...x) override { this->buffer_->show_prev_page(); }
Display *buffer_; Display *buffer_;
}; };
@@ -740,7 +850,7 @@ template<typename... Ts> class DisplayIsDisplayingPageCondition : public Conditi
DisplayIsDisplayingPageCondition(Display *parent) : parent_(parent) {} DisplayIsDisplayingPageCondition(Display *parent) : parent_(parent) {}
void set_page(DisplayPage *page) { this->page_ = page; } void set_page(DisplayPage *page) { this->page_ = page; }
bool check(Ts... x) override { return this->parent_->get_active_page() == this->page_; } bool check(const Ts &...x) override { return this->parent_->get_active_page() == this->page_; }
protected: protected:
Display *parent_; Display *parent_;

View File

@@ -10,7 +10,7 @@ template<typename... Ts> class UpAction : public Action<Ts...> {
public: public:
explicit UpAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit UpAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->up(); } void play(const Ts &...x) override { this->menu_->up(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -20,7 +20,7 @@ template<typename... Ts> class DownAction : public Action<Ts...> {
public: public:
explicit DownAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit DownAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->down(); } void play(const Ts &...x) override { this->menu_->down(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -30,7 +30,7 @@ template<typename... Ts> class LeftAction : public Action<Ts...> {
public: public:
explicit LeftAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit LeftAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->left(); } void play(const Ts &...x) override { this->menu_->left(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -40,7 +40,7 @@ template<typename... Ts> class RightAction : public Action<Ts...> {
public: public:
explicit RightAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit RightAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->right(); } void play(const Ts &...x) override { this->menu_->right(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -50,7 +50,7 @@ template<typename... Ts> class EnterAction : public Action<Ts...> {
public: public:
explicit EnterAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit EnterAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->enter(); } void play(const Ts &...x) override { this->menu_->enter(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -60,7 +60,7 @@ template<typename... Ts> class ShowAction : public Action<Ts...> {
public: public:
explicit ShowAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit ShowAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->show(); } void play(const Ts &...x) override { this->menu_->show(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -70,7 +70,7 @@ template<typename... Ts> class HideAction : public Action<Ts...> {
public: public:
explicit HideAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit HideAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->hide(); } void play(const Ts &...x) override { this->menu_->hide(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -80,7 +80,7 @@ template<typename... Ts> class ShowMainAction : public Action<Ts...> {
public: public:
explicit ShowMainAction(DisplayMenuComponent *menu) : menu_(menu) {} explicit ShowMainAction(DisplayMenuComponent *menu) : menu_(menu) {}
void play(Ts... x) override { this->menu_->show_main(); } void play(const Ts &...x) override { this->menu_->show_main(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;
@@ -88,7 +88,7 @@ template<typename... Ts> class ShowMainAction : public Action<Ts...> {
template<typename... Ts> class IsActiveCondition : public Condition<Ts...> { template<typename... Ts> class IsActiveCondition : public Condition<Ts...> {
public: public:
explicit IsActiveCondition(DisplayMenuComponent *menu) : menu_(menu) {} explicit IsActiveCondition(DisplayMenuComponent *menu) : menu_(menu) {}
bool check(Ts... x) override { return this->menu_->is_active(); } bool check(const Ts &...x) override { return this->menu_->is_active(); }
protected: protected:
DisplayMenuComponent *menu_; DisplayMenuComponent *menu_;

View File

@@ -42,7 +42,7 @@ std::string MenuItemSelect::get_value_text() const {
result = this->value_getter_.value()(this); result = this->value_getter_.value()(this);
} else { } else {
if (this->select_var_ != nullptr) { if (this->select_var_ != nullptr) {
result = this->select_var_->state; result = this->select_var_->current_option();
} }
} }

View File

@@ -59,12 +59,12 @@ class DS1307Component : public time::RealTimeClock, public i2c::I2CDevice {
template<typename... Ts> class WriteAction : public Action<Ts...>, public Parented<DS1307Component> { template<typename... Ts> class WriteAction : public Action<Ts...>, public Parented<DS1307Component> {
public: public:
void play(Ts... x) override { this->parent_->write_time(); } void play(const Ts &...x) override { this->parent_->write_time(); }
}; };
template<typename... Ts> class ReadAction : public Action<Ts...>, public Parented<DS1307Component> { template<typename... Ts> class ReadAction : public Action<Ts...>, public Parented<DS1307Component> {
public: public:
void play(Ts... x) override { this->parent_->read_time(); } void play(const Ts &...x) override { this->parent_->read_time(); }
}; };
} // namespace ds1307 } // namespace ds1307
} // namespace esphome } // namespace esphome

View File

@@ -51,15 +51,15 @@ class DutyTimeSensor : public sensor::Sensor, public PollingComponent {
template<typename... Ts> class BaseAction : public Action<Ts...>, public Parented<DutyTimeSensor> {}; template<typename... Ts> class BaseAction : public Action<Ts...>, public Parented<DutyTimeSensor> {};
template<typename... Ts> class StartAction : public BaseAction<Ts...> { template<typename... Ts> class StartAction : public BaseAction<Ts...> {
void play(Ts... x) override { this->parent_->start(); } void play(const Ts &...x) override { this->parent_->start(); }
}; };
template<typename... Ts> class StopAction : public BaseAction<Ts...> { template<typename... Ts> class StopAction : public BaseAction<Ts...> {
void play(Ts... x) override { this->parent_->stop(); } void play(const Ts &...x) override { this->parent_->stop(); }
}; };
template<typename... Ts> class ResetAction : public BaseAction<Ts...> { template<typename... Ts> class ResetAction : public BaseAction<Ts...> {
void play(Ts... x) override { this->parent_->reset(); } void play(const Ts &...x) override { this->parent_->reset(); }
}; };
template<typename... Ts> class RunningCondition : public Condition<Ts...>, public Parented<DutyTimeSensor> { template<typename... Ts> class RunningCondition : public Condition<Ts...>, public Parented<DutyTimeSensor> {
@@ -67,7 +67,7 @@ template<typename... Ts> class RunningCondition : public Condition<Ts...>, publi
explicit RunningCondition(DutyTimeSensor *parent, bool state) : Parented(parent), state_(state) {} explicit RunningCondition(DutyTimeSensor *parent, bool state) : Parented(parent), state_(state) {}
protected: protected:
bool check(Ts... x) override { return this->parent_->is_running() == this->state_; } bool check(const Ts &...x) override { return this->parent_->is_running() == this->state_; }
bool state_; bool state_;
}; };

View File

@@ -214,17 +214,17 @@ extern ESP32BLE *global_ble;
template<typename... Ts> class BLEEnabledCondition : public Condition<Ts...> { template<typename... Ts> class BLEEnabledCondition : public Condition<Ts...> {
public: public:
bool check(Ts... x) override { return global_ble->is_active(); } bool check(const Ts &...x) override { return global_ble->is_active(); }
}; };
template<typename... Ts> class BLEEnableAction : public Action<Ts...> { template<typename... Ts> class BLEEnableAction : public Action<Ts...> {
public: public:
void play(Ts... x) override { global_ble->enable(); } void play(const Ts &...x) override { global_ble->enable(); }
}; };
template<typename... Ts> class BLEDisableAction : public Action<Ts...> { template<typename... Ts> class BLEDisableAction : public Action<Ts...> {
public: public:
void play(Ts... x) override { global_ble->disable(); } void play(const Ts &...x) override { global_ble->disable(); }
}; };
} // namespace esphome::esp32_ble } // namespace esphome::esp32_ble

View File

@@ -71,7 +71,7 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
BLECharacteristicSetValueAction(BLECharacteristic *characteristic) : parent_(characteristic) {} BLECharacteristicSetValueAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer) TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer)
void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); } void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); }
void play(Ts... x) override { void play(const Ts &...x) override {
// If the listener is already set, do nothing // If the listener is already set, do nothing
if (BLECharacteristicSetValueActionManager::get_instance()->has_listener(this->parent_)) if (BLECharacteristicSetValueActionManager::get_instance()->has_listener(this->parent_))
return; return;
@@ -96,7 +96,7 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts...> { template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts...> {
public: public:
BLECharacteristicNotifyAction(BLECharacteristic *characteristic) : parent_(characteristic) {} BLECharacteristicNotifyAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
void play(Ts... x) override { void play(const Ts &...x) override {
#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION #ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
// Call the pre-notify event // Call the pre-notify event
BLECharacteristicSetValueActionManager::get_instance()->emit_pre_notify(this->parent_); BLECharacteristicSetValueActionManager::get_instance()->emit_pre_notify(this->parent_);
@@ -116,7 +116,7 @@ template<typename... Ts> class BLEDescriptorSetValueAction : public Action<Ts...
BLEDescriptorSetValueAction(BLEDescriptor *descriptor) : parent_(descriptor) {} BLEDescriptorSetValueAction(BLEDescriptor *descriptor) : parent_(descriptor) {}
TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer) TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer)
void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); } void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); }
void play(Ts... x) override { this->parent_->set_value(this->buffer_.value(x...)); } void play(const Ts &...x) override { this->parent_->set_value(this->buffer_.value(x...)); }
protected: protected:
BLEDescriptor *parent_; BLEDescriptor *parent_;

View File

@@ -96,7 +96,7 @@ template<typename... Ts> class ESP32BLEStartScanAction : public Action<Ts...> {
public: public:
ESP32BLEStartScanAction(ESP32BLETracker *parent) : parent_(parent) {} ESP32BLEStartScanAction(ESP32BLETracker *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(bool, continuous) TEMPLATABLE_VALUE(bool, continuous)
void play(Ts... x) override { void play(const Ts &...x) override {
this->parent_->set_scan_continuous(this->continuous_.value(x...)); this->parent_->set_scan_continuous(this->continuous_.value(x...));
this->parent_->start_scan(); this->parent_->start_scan();
} }
@@ -107,7 +107,7 @@ template<typename... Ts> class ESP32BLEStartScanAction : public Action<Ts...> {
template<typename... Ts> class ESP32BLEStopScanAction : public Action<Ts...>, public Parented<ESP32BLETracker> { template<typename... Ts> class ESP32BLEStopScanAction : public Action<Ts...>, public Parented<ESP32BLETracker> {
public: public:
void play(Ts... x) override { this->parent_->stop_scan(); } void play(const Ts &...x) override { this->parent_->stop_scan(); }
}; };
} // namespace esphome::esp32_ble_tracker } // namespace esphome::esp32_ble_tracker

View File

@@ -40,7 +40,7 @@ template<typename... Ts> class SetFrequencyAction : public Action<Ts...> {
SetFrequencyAction(ESP8266PWM *parent) : parent_(parent) {} SetFrequencyAction(ESP8266PWM *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(float, frequency); TEMPLATABLE_VALUE(float, frequency);
void play(Ts... x) { void play(const Ts &...x) {
float freq = this->frequency_.value(x...); float freq = this->frequency_.value(x...);
this->parent_->update_frequency(freq); this->parent_->update_frequency(freq);
} }

View File

@@ -34,7 +34,7 @@ template<typename... Ts> class AdjustAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, voltage) TEMPLATABLE_VALUE(float, voltage)
void play(Ts... x) override { this->ldo_->adjust_voltage(this->voltage_.value(x...)); } void play(const Ts &...x) override { this->ldo_->adjust_voltage(this->voltage_.value(x...)); }
protected: protected:
EspLdo *ldo_; EspLdo *ldo_;

View File

@@ -94,7 +94,7 @@ void ESPHomeOTAComponent::dump_config() {
"Over-The-Air updates:\n" "Over-The-Air updates:\n"
" Address: %s:%u\n" " Address: %s:%u\n"
" Version: %d", " Version: %d",
network::get_use_address().c_str(), this->port_, USE_OTA_VERSION); network::get_use_address(), this->port_, USE_OTA_VERSION);
#ifdef USE_OTA_PASSWORD #ifdef USE_OTA_PASSWORD
if (!this->password_.empty()) { if (!this->password_.empty()) {
ESP_LOGCONFIG(TAG, " Password configured"); ESP_LOGCONFIG(TAG, " Password configured");

View File

@@ -36,7 +36,7 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
void set_wait_for_sent(bool wait_for_sent) { this->flags_.wait_for_sent = wait_for_sent; } void set_wait_for_sent(bool wait_for_sent) { this->flags_.wait_for_sent = wait_for_sent; }
void set_continue_on_error(bool continue_on_error) { this->flags_.continue_on_error = continue_on_error; } void set_continue_on_error(bool continue_on_error) { this->flags_.continue_on_error = continue_on_error; }
void play_complex(Ts... x) override { void play_complex(const Ts &...x) override {
this->num_running_++; this->num_running_++;
send_callback_t send_callback = [this, x...](esp_err_t status) { send_callback_t send_callback = [this, x...](esp_err_t status) {
if (status == ESP_OK) { if (status == ESP_OK) {
@@ -67,7 +67,7 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
} }
} }
void play(Ts... x) override { /* ignore - see play_complex */ void play(const Ts &...x) override { /* ignore - see play_complex */
} }
void stop() override { void stop() override {
@@ -90,7 +90,7 @@ template<typename... Ts> class AddPeerAction : public Action<Ts...>, public Pare
TEMPLATABLE_VALUE(peer_address_t, address); TEMPLATABLE_VALUE(peer_address_t, address);
public: public:
void play(Ts... x) override { void play(const Ts &...x) override {
peer_address_t address = this->address_.value(x...); peer_address_t address = this->address_.value(x...);
this->parent_->add_peer(address.data()); this->parent_->add_peer(address.data());
} }
@@ -100,7 +100,7 @@ template<typename... Ts> class DeletePeerAction : public Action<Ts...>, public P
TEMPLATABLE_VALUE(peer_address_t, address); TEMPLATABLE_VALUE(peer_address_t, address);
public: public:
void play(Ts... x) override { void play(const Ts &...x) override {
peer_address_t address = this->address_.value(x...); peer_address_t address = this->address_.value(x...);
this->parent_->del_peer(address.data()); this->parent_->del_peer(address.data());
} }
@@ -109,7 +109,7 @@ template<typename... Ts> class DeletePeerAction : public Action<Ts...>, public P
template<typename... Ts> class SetChannelAction : public Action<Ts...>, public Parented<ESPNowComponent> { template<typename... Ts> class SetChannelAction : public Action<Ts...>, public Parented<ESPNowComponent> {
public: public:
TEMPLATABLE_VALUE(uint8_t, channel) TEMPLATABLE_VALUE(uint8_t, channel)
void play(Ts... x) override { void play(const Ts &...x) override {
if (this->parent_->is_wifi_enabled()) { if (this->parent_->is_wifi_enabled()) {
return; return;
} }

View File

@@ -691,9 +691,9 @@ void EthernetComponent::set_manual_ip(const ManualIP &manual_ip) { this->manual_
// set_use_address() is guaranteed to be called during component setup by Python code generation, // set_use_address() is guaranteed to be called during component setup by Python code generation,
// so use_address_ will always be valid when get_use_address() is called - no fallback needed. // so use_address_ will always be valid when get_use_address() is called - no fallback needed.
const std::string &EthernetComponent::get_use_address() const { return this->use_address_; } const char *EthernetComponent::get_use_address() const { return this->use_address_; }
void EthernetComponent::set_use_address(const std::string &use_address) { this->use_address_ = use_address; } void EthernetComponent::set_use_address(const char *use_address) { this->use_address_ = use_address; }
void EthernetComponent::get_eth_mac_address_raw(uint8_t *mac) { void EthernetComponent::get_eth_mac_address_raw(uint8_t *mac) {
esp_err_t err; esp_err_t err;

View File

@@ -88,8 +88,8 @@ class EthernetComponent : public Component {
network::IPAddresses get_ip_addresses(); network::IPAddresses get_ip_addresses();
network::IPAddress get_dns_address(uint8_t num); network::IPAddress get_dns_address(uint8_t num);
const std::string &get_use_address() const; const char *get_use_address() const;
void set_use_address(const std::string &use_address); void set_use_address(const char *use_address);
void get_eth_mac_address_raw(uint8_t *mac); void get_eth_mac_address_raw(uint8_t *mac);
std::string get_eth_mac_address_pretty(); std::string get_eth_mac_address_pretty();
eth_duplex_t get_duplex_mode(); eth_duplex_t get_duplex_mode();
@@ -114,7 +114,6 @@ class EthernetComponent : public Component {
/// @brief Set arbitratry PHY registers from config. /// @brief Set arbitratry PHY registers from config.
void write_phy_register_(esp_eth_mac_t *mac, PHYRegister register_data); void write_phy_register_(esp_eth_mac_t *mac, PHYRegister register_data);
std::string use_address_;
#ifdef USE_ETHERNET_SPI #ifdef USE_ETHERNET_SPI
uint8_t clk_pin_; uint8_t clk_pin_;
uint8_t miso_pin_; uint8_t miso_pin_;
@@ -158,6 +157,11 @@ class EthernetComponent : public Component {
esp_eth_handle_t eth_handle_; esp_eth_handle_t eth_handle_;
esp_eth_phy_t *phy_{nullptr}; esp_eth_phy_t *phy_{nullptr};
optional<std::array<uint8_t, 6>> fixed_mac_; optional<std::array<uint8_t, 6>> fixed_mac_;
private:
// Stores a pointer to a string literal (static storage duration).
// ONLY set from Python-generated code with string literals - never dynamic strings.
const char *use_address_{""};
}; };
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class TriggerEventAction : public Action<Ts...>, public
public: public:
TEMPLATABLE_VALUE(std::string, event_type) TEMPLATABLE_VALUE(std::string, event_type)
void play(Ts... x) override { this->parent_->trigger(this->event_type_.value(x...)); } void play(const Ts &...x) override { this->parent_->trigger(this->event_type_.value(x...)); }
}; };
class EventTrigger : public Trigger<std::string> { class EventTrigger : public Trigger<std::string> {

View File

@@ -17,35 +17,35 @@ class LedTrigger : public Trigger<bool> {
class CustomTrigger : public Trigger<std::string> { class CustomTrigger : public Trigger<std::string> {
public: public:
explicit CustomTrigger(EZOSensor *ezo) { explicit CustomTrigger(EZOSensor *ezo) {
ezo->add_custom_callback([this](std::string value) { this->trigger(std::move(value)); }); ezo->add_custom_callback([this](const std::string &value) { this->trigger(value); });
} }
}; };
class TTrigger : public Trigger<std::string> { class TTrigger : public Trigger<std::string> {
public: public:
explicit TTrigger(EZOSensor *ezo) { explicit TTrigger(EZOSensor *ezo) {
ezo->add_t_callback([this](std::string value) { this->trigger(std::move(value)); }); ezo->add_t_callback([this](const std::string &value) { this->trigger(value); });
} }
}; };
class CalibrationTrigger : public Trigger<std::string> { class CalibrationTrigger : public Trigger<std::string> {
public: public:
explicit CalibrationTrigger(EZOSensor *ezo) { explicit CalibrationTrigger(EZOSensor *ezo) {
ezo->add_calibration_callback([this](std::string value) { this->trigger(std::move(value)); }); ezo->add_calibration_callback([this](const std::string &value) { this->trigger(value); });
} }
}; };
class SlopeTrigger : public Trigger<std::string> { class SlopeTrigger : public Trigger<std::string> {
public: public:
explicit SlopeTrigger(EZOSensor *ezo) { explicit SlopeTrigger(EZOSensor *ezo) {
ezo->add_slope_callback([this](std::string value) { this->trigger(std::move(value)); }); ezo->add_slope_callback([this](const std::string &value) { this->trigger(value); });
} }
}; };
class DeviceInformationTrigger : public Trigger<std::string> { class DeviceInformationTrigger : public Trigger<std::string> {
public: public:
explicit DeviceInformationTrigger(EZOSensor *ezo) { explicit DeviceInformationTrigger(EZOSensor *ezo) {
ezo->add_device_infomation_callback([this](std::string value) { this->trigger(std::move(value)); }); ezo->add_device_infomation_callback([this](const std::string &value) { this->trigger(value); });
} }
}; };

View File

@@ -119,7 +119,7 @@ template<typename... Ts> class EzoPMPFindAction : public Action<Ts...> {
public: public:
EzoPMPFindAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPFindAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->find(); } void play(const Ts &...x) override { this->ezopmp_->find(); }
protected: protected:
EzoPMP *ezopmp_; EzoPMP *ezopmp_;
@@ -129,7 +129,7 @@ template<typename... Ts> class EzoPMPDoseContinuouslyAction : public Action<Ts..
public: public:
EzoPMPDoseContinuouslyAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPDoseContinuouslyAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->dose_continuously(); } void play(const Ts &...x) override { this->ezopmp_->dose_continuously(); }
protected: protected:
EzoPMP *ezopmp_; EzoPMP *ezopmp_;
@@ -139,7 +139,7 @@ template<typename... Ts> class EzoPMPDoseVolumeAction : public Action<Ts...> {
public: public:
EzoPMPDoseVolumeAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPDoseVolumeAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->dose_volume(this->volume_.value(x...)); } void play(const Ts &...x) override { this->ezopmp_->dose_volume(this->volume_.value(x...)); }
TEMPLATABLE_VALUE(double, volume) TEMPLATABLE_VALUE(double, volume)
protected: protected:
@@ -150,7 +150,7 @@ template<typename... Ts> class EzoPMPDoseVolumeOverTimeAction : public Action<Ts
public: public:
EzoPMPDoseVolumeOverTimeAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPDoseVolumeOverTimeAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { void play(const Ts &...x) override {
this->ezopmp_->dose_volume_over_time(this->volume_.value(x...), this->duration_.value(x...)); this->ezopmp_->dose_volume_over_time(this->volume_.value(x...), this->duration_.value(x...));
} }
TEMPLATABLE_VALUE(double, volume) TEMPLATABLE_VALUE(double, volume)
@@ -164,7 +164,7 @@ template<typename... Ts> class EzoPMPDoseWithConstantFlowRateAction : public Act
public: public:
EzoPMPDoseWithConstantFlowRateAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPDoseWithConstantFlowRateAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { void play(const Ts &...x) override {
this->ezopmp_->dose_with_constant_flow_rate(this->volume_.value(x...), this->duration_.value(x...)); this->ezopmp_->dose_with_constant_flow_rate(this->volume_.value(x...), this->duration_.value(x...));
} }
TEMPLATABLE_VALUE(double, volume) TEMPLATABLE_VALUE(double, volume)
@@ -178,7 +178,7 @@ template<typename... Ts> class EzoPMPSetCalibrationVolumeAction : public Action<
public: public:
EzoPMPSetCalibrationVolumeAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPSetCalibrationVolumeAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->set_calibration_volume(this->volume_.value(x...)); } void play(const Ts &...x) override { this->ezopmp_->set_calibration_volume(this->volume_.value(x...)); }
TEMPLATABLE_VALUE(double, volume) TEMPLATABLE_VALUE(double, volume)
protected: protected:
@@ -189,7 +189,7 @@ template<typename... Ts> class EzoPMPClearTotalVolumeDispensedAction : public Ac
public: public:
EzoPMPClearTotalVolumeDispensedAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPClearTotalVolumeDispensedAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->clear_total_volume_dosed(); } void play(const Ts &...x) override { this->ezopmp_->clear_total_volume_dosed(); }
protected: protected:
EzoPMP *ezopmp_; EzoPMP *ezopmp_;
@@ -199,7 +199,7 @@ template<typename... Ts> class EzoPMPClearCalibrationAction : public Action<Ts..
public: public:
EzoPMPClearCalibrationAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPClearCalibrationAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->clear_calibration(); } void play(const Ts &...x) override { this->ezopmp_->clear_calibration(); }
protected: protected:
EzoPMP *ezopmp_; EzoPMP *ezopmp_;
@@ -209,7 +209,7 @@ template<typename... Ts> class EzoPMPPauseDosingAction : public Action<Ts...> {
public: public:
EzoPMPPauseDosingAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPPauseDosingAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->pause_dosing(); } void play(const Ts &...x) override { this->ezopmp_->pause_dosing(); }
protected: protected:
EzoPMP *ezopmp_; EzoPMP *ezopmp_;
@@ -219,7 +219,7 @@ template<typename... Ts> class EzoPMPStopDosingAction : public Action<Ts...> {
public: public:
EzoPMPStopDosingAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPStopDosingAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->stop_dosing(); } void play(const Ts &...x) override { this->ezopmp_->stop_dosing(); }
protected: protected:
EzoPMP *ezopmp_; EzoPMP *ezopmp_;
@@ -229,7 +229,7 @@ template<typename... Ts> class EzoPMPChangeI2CAddressAction : public Action<Ts..
public: public:
EzoPMPChangeI2CAddressAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPChangeI2CAddressAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->change_i2c_address(this->address_.value(x...)); } void play(const Ts &...x) override { this->ezopmp_->change_i2c_address(this->address_.value(x...)); }
TEMPLATABLE_VALUE(int, address) TEMPLATABLE_VALUE(int, address)
protected: protected:
@@ -240,7 +240,7 @@ template<typename... Ts> class EzoPMPArbitraryCommandAction : public Action<Ts..
public: public:
EzoPMPArbitraryCommandAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {} EzoPMPArbitraryCommandAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->exec_arbitrary_command(this->command_.value(x...)); } void play(const Ts &...x) override { this->ezopmp_->exec_arbitrary_command(this->command_.value(x...)); }
TEMPLATABLE_VALUE(std::string, command) TEMPLATABLE_VALUE(std::string, command)
protected: protected:

View File

@@ -15,7 +15,7 @@ template<typename... Ts> class TurnOnAction : public Action<Ts...> {
TEMPLATABLE_VALUE(int, speed) TEMPLATABLE_VALUE(int, speed)
TEMPLATABLE_VALUE(FanDirection, direction) TEMPLATABLE_VALUE(FanDirection, direction)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->state_->turn_on(); auto call = this->state_->turn_on();
if (this->oscillating_.has_value()) { if (this->oscillating_.has_value()) {
call.set_oscillating(this->oscillating_.value(x...)); call.set_oscillating(this->oscillating_.value(x...));
@@ -36,7 +36,7 @@ template<typename... Ts> class TurnOffAction : public Action<Ts...> {
public: public:
explicit TurnOffAction(Fan *state) : state_(state) {} explicit TurnOffAction(Fan *state) : state_(state) {}
void play(Ts... x) override { this->state_->turn_off().perform(); } void play(const Ts &...x) override { this->state_->turn_off().perform(); }
Fan *state_; Fan *state_;
}; };
@@ -45,7 +45,7 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
public: public:
explicit ToggleAction(Fan *state) : state_(state) {} explicit ToggleAction(Fan *state) : state_(state) {}
void play(Ts... x) override { this->state_->toggle().perform(); } void play(const Ts &...x) override { this->state_->toggle().perform(); }
Fan *state_; Fan *state_;
}; };
@@ -56,7 +56,7 @@ template<typename... Ts> class CycleSpeedAction : public Action<Ts...> {
TEMPLATABLE_VALUE(bool, no_off_cycle) TEMPLATABLE_VALUE(bool, no_off_cycle)
void play(Ts... x) override { void play(const Ts &...x) override {
// check to see if fan supports speeds and is on // check to see if fan supports speeds and is on
if (this->state_->get_traits().supported_speed_count()) { if (this->state_->get_traits().supported_speed_count()) {
if (this->state_->state) { if (this->state_->state) {
@@ -97,7 +97,7 @@ template<typename... Ts> class CycleSpeedAction : public Action<Ts...> {
template<typename... Ts> class FanIsOnCondition : public Condition<Ts...> { template<typename... Ts> class FanIsOnCondition : public Condition<Ts...> {
public: public:
explicit FanIsOnCondition(Fan *state) : state_(state) {} explicit FanIsOnCondition(Fan *state) : state_(state) {}
bool check(Ts... x) override { return this->state_->state; } bool check(const Ts &...x) override { return this->state_->state; }
protected: protected:
Fan *state_; Fan *state_;
@@ -105,7 +105,7 @@ template<typename... Ts> class FanIsOnCondition : public Condition<Ts...> {
template<typename... Ts> class FanIsOffCondition : public Condition<Ts...> { template<typename... Ts> class FanIsOffCondition : public Condition<Ts...> {
public: public:
explicit FanIsOffCondition(Fan *state) : state_(state) {} explicit FanIsOffCondition(Fan *state) : state_(state) {}
bool check(Ts... x) override { return !this->state_->state; } bool check(const Ts &...x) override { return !this->state_->state; }
protected: protected:
Fan *state_; Fan *state_;
@@ -212,18 +212,19 @@ class FanPresetSetTrigger : public Trigger<std::string> {
public: public:
FanPresetSetTrigger(Fan *state) { FanPresetSetTrigger(Fan *state) {
state->add_on_state_callback([this, state]() { state->add_on_state_callback([this, state]() {
auto preset_mode = state->preset_mode; const auto *preset_mode = state->get_preset_mode();
auto should_trigger = preset_mode != this->last_preset_mode_; auto should_trigger = preset_mode != this->last_preset_mode_;
this->last_preset_mode_ = preset_mode; this->last_preset_mode_ = preset_mode;
if (should_trigger) { if (should_trigger) {
this->trigger(preset_mode); // Trigger with empty string when nullptr to maintain backward compatibility
this->trigger(preset_mode != nullptr ? preset_mode : "");
} }
}); });
this->last_preset_mode_ = state->preset_mode; this->last_preset_mode_ = state->get_preset_mode();
} }
protected: protected:
std::string last_preset_mode_; const char *last_preset_mode_{nullptr};
}; };
} // namespace fan } // namespace fan

View File

@@ -17,6 +17,27 @@ const LogString *fan_direction_to_string(FanDirection direction) {
} }
} }
FanCall &FanCall::set_preset_mode(const std::string &preset_mode) { return this->set_preset_mode(preset_mode.c_str()); }
FanCall &FanCall::set_preset_mode(const char *preset_mode) {
if (preset_mode == nullptr || strlen(preset_mode) == 0) {
this->preset_mode_ = nullptr;
return *this;
}
// Find and validate pointer from traits immediately
auto traits = this->parent_.get_traits();
const char *validated_mode = traits.find_preset_mode(preset_mode);
if (validated_mode != nullptr) {
this->preset_mode_ = validated_mode; // Store pointer from traits
} else {
// Preset mode not found in traits - log warning and don't set
ESP_LOGW(TAG, "%s: Preset mode '%s' not supported", this->parent_.get_name().c_str(), preset_mode);
this->preset_mode_ = nullptr;
}
return *this;
}
void FanCall::perform() { void FanCall::perform() {
ESP_LOGD(TAG, "'%s' - Setting:", this->parent_.get_name().c_str()); ESP_LOGD(TAG, "'%s' - Setting:", this->parent_.get_name().c_str());
this->validate_(); this->validate_();
@@ -32,8 +53,8 @@ void FanCall::perform() {
if (this->direction_.has_value()) { if (this->direction_.has_value()) {
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(*this->direction_))); ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(*this->direction_)));
} }
if (!this->preset_mode_.empty()) { if (this->has_preset_mode()) {
ESP_LOGD(TAG, " Preset Mode: %s", this->preset_mode_.c_str()); ESP_LOGD(TAG, " Preset Mode: %s", this->preset_mode_);
} }
this->parent_.control(*this); this->parent_.control(*this);
} }
@@ -46,30 +67,15 @@ void FanCall::validate_() {
// https://developers.home-assistant.io/docs/core/entity/fan/#preset-modes // https://developers.home-assistant.io/docs/core/entity/fan/#preset-modes
// "Manually setting a speed must disable any set preset mode" // "Manually setting a speed must disable any set preset mode"
this->preset_mode_.clear(); this->preset_mode_ = nullptr;
}
if (!this->preset_mode_.empty()) {
const auto &preset_modes = traits.supported_preset_modes();
bool found = false;
for (const auto &mode : preset_modes) {
if (strcmp(mode, this->preset_mode_.c_str()) == 0) {
found = true;
break;
}
}
if (!found) {
ESP_LOGW(TAG, "%s: Preset mode '%s' not supported", this->parent_.get_name().c_str(), this->preset_mode_.c_str());
this->preset_mode_.clear();
}
} }
// when turning on... // when turning on...
if (!this->parent_.state && this->binary_state_.has_value() && if (!this->parent_.state && this->binary_state_.has_value() &&
*this->binary_state_ *this->binary_state_
// ..,and no preset mode will be active... // ..,and no preset mode will be active...
&& this->preset_mode_.empty() && && !this->has_preset_mode() &&
this->parent_.preset_mode.empty() this->parent_.get_preset_mode() == nullptr
// ...and neither current nor new speed is available... // ...and neither current nor new speed is available...
&& traits.supports_speed() && this->parent_.speed == 0 && !this->speed_.has_value()) { && traits.supports_speed() && this->parent_.speed == 0 && !this->speed_.has_value()) {
// ...set speed to 100% // ...set speed to 100%
@@ -117,12 +123,13 @@ void FanRestoreState::apply(Fan &fan) {
auto traits = fan.get_traits(); auto traits = fan.get_traits();
if (traits.supports_preset_modes()) { if (traits.supports_preset_modes()) {
// Use stored preset index to get preset name // Use stored preset index to get preset name from traits
const auto &preset_modes = traits.supported_preset_modes(); const auto &preset_modes = traits.supported_preset_modes();
if (this->preset_mode < preset_modes.size()) { if (this->preset_mode < preset_modes.size()) {
fan.preset_mode = preset_modes[this->preset_mode]; fan.set_preset_mode_(preset_modes[this->preset_mode]);
} }
} }
fan.publish_state(); fan.publish_state();
} }
@@ -131,6 +138,29 @@ FanCall Fan::turn_off() { return this->make_call().set_state(false); }
FanCall Fan::toggle() { return this->make_call().set_state(!this->state); } FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }
FanCall Fan::make_call() { return FanCall(*this); } FanCall Fan::make_call() { return FanCall(*this); }
const char *Fan::find_preset_mode_(const char *preset_mode) { return this->get_traits().find_preset_mode(preset_mode); }
bool Fan::set_preset_mode_(const char *preset_mode) {
if (preset_mode == nullptr) {
// Treat nullptr as clearing the preset mode
if (this->preset_mode_ == nullptr) {
return false; // No change
}
this->clear_preset_mode_();
return true;
}
const char *validated = this->find_preset_mode_(preset_mode);
if (validated == nullptr || this->preset_mode_ == validated) {
return false; // Preset mode not supported or no change
}
this->preset_mode_ = validated;
return true;
}
bool Fan::set_preset_mode_(const std::string &preset_mode) { return this->set_preset_mode_(preset_mode.c_str()); }
void Fan::clear_preset_mode_() { this->preset_mode_ = nullptr; }
void Fan::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); } void Fan::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
void Fan::publish_state() { void Fan::publish_state() {
auto traits = this->get_traits(); auto traits = this->get_traits();
@@ -146,8 +176,9 @@ void Fan::publish_state() {
if (traits.supports_direction()) { if (traits.supports_direction()) {
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction))); ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction)));
} }
if (traits.supports_preset_modes() && !this->preset_mode.empty()) { const char *preset = this->get_preset_mode();
ESP_LOGD(TAG, " Preset Mode: %s", this->preset_mode.c_str()); if (preset != nullptr) {
ESP_LOGD(TAG, " Preset Mode: %s", preset);
} }
this->state_callback_.call(); this->state_callback_.call();
this->save_state_(); this->save_state_();
@@ -199,16 +230,15 @@ void Fan::save_state_() {
state.speed = this->speed; state.speed = this->speed;
state.direction = this->direction; state.direction = this->direction;
if (traits.supports_preset_modes() && !this->preset_mode.empty()) { const char *preset = this->get_preset_mode();
if (preset != nullptr) {
const auto &preset_modes = traits.supported_preset_modes(); const auto &preset_modes = traits.supported_preset_modes();
// Store index of current preset mode // Find index of current preset mode (pointer comparison is safe since preset is from traits)
size_t i = 0; for (size_t i = 0; i < preset_modes.size(); i++) {
for (const auto &mode : preset_modes) { if (preset_modes[i] == preset) {
if (strcmp(mode, this->preset_mode.c_str()) == 0) {
state.preset_mode = i; state.preset_mode = i;
break; break;
} }
i++;
} }
} }

View File

@@ -70,11 +70,10 @@ class FanCall {
return *this; return *this;
} }
optional<FanDirection> get_direction() const { return this->direction_; } optional<FanDirection> get_direction() const { return this->direction_; }
FanCall &set_preset_mode(const std::string &preset_mode) { FanCall &set_preset_mode(const std::string &preset_mode);
this->preset_mode_ = preset_mode; FanCall &set_preset_mode(const char *preset_mode);
return *this; const char *get_preset_mode() const { return this->preset_mode_; }
} bool has_preset_mode() const { return this->preset_mode_ != nullptr; }
std::string get_preset_mode() const { return this->preset_mode_; }
void perform(); void perform();
@@ -86,7 +85,7 @@ class FanCall {
optional<bool> oscillating_; optional<bool> oscillating_;
optional<int> speed_; optional<int> speed_;
optional<FanDirection> direction_{}; optional<FanDirection> direction_{};
std::string preset_mode_{}; const char *preset_mode_{nullptr}; // Pointer to string in traits (after validation)
}; };
struct FanRestoreState { struct FanRestoreState {
@@ -112,8 +111,6 @@ class Fan : public EntityBase {
int speed{0}; int speed{0};
/// The current direction of the fan /// The current direction of the fan
FanDirection direction{FanDirection::FORWARD}; FanDirection direction{FanDirection::FORWARD};
// The current preset mode of the fan
std::string preset_mode{};
FanCall turn_on(); FanCall turn_on();
FanCall turn_off(); FanCall turn_off();
@@ -130,8 +127,15 @@ class Fan : public EntityBase {
/// Set the restore mode of this fan. /// Set the restore mode of this fan.
void set_restore_mode(FanRestoreMode restore_mode) { this->restore_mode_ = restore_mode; } void set_restore_mode(FanRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
/// Get the current preset mode (returns pointer to string stored in traits, or nullptr if not set)
const char *get_preset_mode() const { return this->preset_mode_; }
/// Check if a preset mode is currently active
bool has_preset_mode() const { return this->preset_mode_ != nullptr; }
protected: protected:
friend FanCall; friend FanCall;
friend struct FanRestoreState;
virtual void control(const FanCall &call) = 0; virtual void control(const FanCall &call) = 0;
@@ -140,9 +144,21 @@ class Fan : public EntityBase {
void dump_traits_(const char *tag, const char *prefix); void dump_traits_(const char *tag, const char *prefix);
/// Set the preset mode (finds and stores pointer from traits). Returns true if changed.
bool set_preset_mode_(const char *preset_mode);
/// Set the preset mode (finds and stores pointer from traits). Returns true if changed.
bool set_preset_mode_(const std::string &preset_mode);
/// Clear the preset mode
void clear_preset_mode_();
/// Find and return the matching preset mode pointer from traits, or nullptr if not found.
const char *find_preset_mode_(const char *preset_mode);
CallbackManager<void()> state_callback_{}; CallbackManager<void()> state_callback_{};
ESPPreferenceObject rtc_; ESPPreferenceObject rtc_;
FanRestoreMode restore_mode_; FanRestoreMode restore_mode_;
private:
const char *preset_mode_{nullptr};
}; };
} // namespace fan } // namespace fan

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <cstring>
#include <vector> #include <vector>
#include <initializer_list> #include <initializer_list>
@@ -44,6 +45,17 @@ class FanTraits {
/// Return if preset modes are supported /// Return if preset modes are supported
bool supports_preset_modes() const { return !this->preset_modes_.empty(); } bool supports_preset_modes() const { return !this->preset_modes_.empty(); }
/// Find and return the matching preset mode pointer from supported modes, or nullptr if not found.
const char *find_preset_mode(const char *preset_mode) const {
if (preset_mode == nullptr)
return nullptr;
for (const char *mode : this->preset_modes_) {
if (strcmp(mode, preset_mode) == 0) {
return mode; // Return pointer from traits
}
}
return nullptr;
}
protected: protected:
bool oscillation_{false}; bool oscillation_{false};

View File

@@ -273,7 +273,7 @@ template<typename... Ts> class EnrollmentAction : public Action<Ts...>, public P
TEMPLATABLE_VALUE(uint16_t, finger_id) TEMPLATABLE_VALUE(uint16_t, finger_id)
TEMPLATABLE_VALUE(uint8_t, num_scans) TEMPLATABLE_VALUE(uint8_t, num_scans)
void play(Ts... x) override { void play(const Ts &...x) override {
auto finger_id = this->finger_id_.value(x...); auto finger_id = this->finger_id_.value(x...);
auto num_scans = this->num_scans_.value(x...); auto num_scans = this->num_scans_.value(x...);
if (num_scans) { if (num_scans) {
@@ -287,14 +287,14 @@ template<typename... Ts> class EnrollmentAction : public Action<Ts...>, public P
template<typename... Ts> template<typename... Ts>
class CancelEnrollmentAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> { class CancelEnrollmentAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> {
public: public:
void play(Ts... x) override { this->parent_->finish_enrollment(1); } void play(const Ts &...x) override { this->parent_->finish_enrollment(1); }
}; };
template<typename... Ts> class DeleteAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> { template<typename... Ts> class DeleteAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> {
public: public:
TEMPLATABLE_VALUE(uint16_t, finger_id) TEMPLATABLE_VALUE(uint16_t, finger_id)
void play(Ts... x) override { void play(const Ts &...x) override {
auto finger_id = this->finger_id_.value(x...); auto finger_id = this->finger_id_.value(x...);
this->parent_->delete_fingerprint(finger_id); this->parent_->delete_fingerprint(finger_id);
} }
@@ -302,14 +302,14 @@ template<typename... Ts> class DeleteAction : public Action<Ts...>, public Paren
template<typename... Ts> class DeleteAllAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> { template<typename... Ts> class DeleteAllAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> {
public: public:
void play(Ts... x) override { this->parent_->delete_all_fingerprints(); } void play(const Ts &...x) override { this->parent_->delete_all_fingerprints(); }
}; };
template<typename... Ts> class LEDControlAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> { template<typename... Ts> class LEDControlAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> {
public: public:
TEMPLATABLE_VALUE(bool, state) TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override { void play(const Ts &...x) override {
auto state = this->state_.value(x...); auto state = this->state_.value(x...);
this->parent_->led_control(state); this->parent_->led_control(state);
} }
@@ -322,7 +322,7 @@ template<typename... Ts> class AuraLEDControlAction : public Action<Ts...>, publ
TEMPLATABLE_VALUE(uint8_t, color) TEMPLATABLE_VALUE(uint8_t, color)
TEMPLATABLE_VALUE(uint8_t, count) TEMPLATABLE_VALUE(uint8_t, count)
void play(Ts... x) override { void play(const Ts &...x) override {
auto state = this->state_.value(x...); auto state = this->state_.value(x...);
auto speed = this->speed_.value(x...); auto speed = this->speed_.value(x...);
auto color = this->color_.value(x...); auto color = this->color_.value(x...);

View File

@@ -134,7 +134,7 @@ template<class C, typename... Ts> class GlobalVarSetAction : public Action<Ts...
TEMPLATABLE_VALUE(T, value); TEMPLATABLE_VALUE(T, value);
void play(Ts... x) override { this->parent_->value() = this->value_.value(x...); } void play(const Ts &...x) override { this->parent_->value() = this->value_.value(x...); }
protected: protected:
C *parent_; C *parent_;

View File

@@ -168,7 +168,7 @@ class GROVETB6612FNGMotorRunAction : public Action<Ts...>, public Parented<Grove
TEMPLATABLE_VALUE(uint8_t, channel) TEMPLATABLE_VALUE(uint8_t, channel)
TEMPLATABLE_VALUE(uint16_t, speed) TEMPLATABLE_VALUE(uint16_t, speed)
void play(Ts... x) override { void play(const Ts &...x) override {
auto channel = this->channel_.value(x...); auto channel = this->channel_.value(x...);
auto speed = this->speed_.value(x...); auto speed = this->speed_.value(x...);
this->parent_->dc_motor_run(channel, speed); this->parent_->dc_motor_run(channel, speed);
@@ -180,7 +180,7 @@ class GROVETB6612FNGMotorBrakeAction : public Action<Ts...>, public Parented<Gro
public: public:
TEMPLATABLE_VALUE(uint8_t, channel) TEMPLATABLE_VALUE(uint8_t, channel)
void play(Ts... x) override { this->parent_->dc_motor_brake(this->channel_.value(x...)); } void play(const Ts &...x) override { this->parent_->dc_motor_brake(this->channel_.value(x...)); }
}; };
template<typename... Ts> template<typename... Ts>
@@ -188,19 +188,19 @@ class GROVETB6612FNGMotorStopAction : public Action<Ts...>, public Parented<Grov
public: public:
TEMPLATABLE_VALUE(uint8_t, channel) TEMPLATABLE_VALUE(uint8_t, channel)
void play(Ts... x) override { this->parent_->dc_motor_stop(this->channel_.value(x...)); } void play(const Ts &...x) override { this->parent_->dc_motor_stop(this->channel_.value(x...)); }
}; };
template<typename... Ts> template<typename... Ts>
class GROVETB6612FNGMotorStandbyAction : public Action<Ts...>, public Parented<GroveMotorDriveTB6612FNG> { class GROVETB6612FNGMotorStandbyAction : public Action<Ts...>, public Parented<GroveMotorDriveTB6612FNG> {
public: public:
void play(Ts... x) override { this->parent_->standby(); } void play(const Ts &...x) override { this->parent_->standby(); }
}; };
template<typename... Ts> template<typename... Ts>
class GROVETB6612FNGMotorNoStandbyAction : public Action<Ts...>, public Parented<GroveMotorDriveTB6612FNG> { class GROVETB6612FNGMotorNoStandbyAction : public Action<Ts...>, public Parented<GroveMotorDriveTB6612FNG> {
public: public:
void play(Ts... x) override { this->parent_->not_standby(); } void play(const Ts &...x) override { this->parent_->not_standby(); }
}; };
template<typename... Ts> template<typename... Ts>
@@ -208,7 +208,7 @@ class GROVETB6612FNGMotorChangeAddressAction : public Action<Ts...>, public Pare
public: public:
TEMPLATABLE_VALUE(uint8_t, address) TEMPLATABLE_VALUE(uint8_t, address)
void play(Ts... x) override { this->parent_->set_i2c_addr(this->address_.value(x...)); } void play(const Ts &...x) override { this->parent_->set_i2c_addr(this->address_.value(x...)); }
}; };
} // namespace grove_tb6612fng } // namespace grove_tb6612fng

View File

@@ -10,7 +10,7 @@ namespace haier {
template<typename... Ts> class DisplayOnAction : public Action<Ts...> { template<typename... Ts> class DisplayOnAction : public Action<Ts...> {
public: public:
DisplayOnAction(HaierClimateBase *parent) : parent_(parent) {} DisplayOnAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->set_display_state(true); } void play(const Ts &...x) { this->parent_->set_display_state(true); }
protected: protected:
HaierClimateBase *parent_; HaierClimateBase *parent_;
@@ -19,7 +19,7 @@ template<typename... Ts> class DisplayOnAction : public Action<Ts...> {
template<typename... Ts> class DisplayOffAction : public Action<Ts...> { template<typename... Ts> class DisplayOffAction : public Action<Ts...> {
public: public:
DisplayOffAction(HaierClimateBase *parent) : parent_(parent) {} DisplayOffAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->set_display_state(false); } void play(const Ts &...x) { this->parent_->set_display_state(false); }
protected: protected:
HaierClimateBase *parent_; HaierClimateBase *parent_;
@@ -28,7 +28,7 @@ template<typename... Ts> class DisplayOffAction : public Action<Ts...> {
template<typename... Ts> class BeeperOnAction : public Action<Ts...> { template<typename... Ts> class BeeperOnAction : public Action<Ts...> {
public: public:
BeeperOnAction(HonClimate *parent) : parent_(parent) {} BeeperOnAction(HonClimate *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->set_beeper_state(true); } void play(const Ts &...x) { this->parent_->set_beeper_state(true); }
protected: protected:
HonClimate *parent_; HonClimate *parent_;
@@ -37,7 +37,7 @@ template<typename... Ts> class BeeperOnAction : public Action<Ts...> {
template<typename... Ts> class BeeperOffAction : public Action<Ts...> { template<typename... Ts> class BeeperOffAction : public Action<Ts...> {
public: public:
BeeperOffAction(HonClimate *parent) : parent_(parent) {} BeeperOffAction(HonClimate *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->set_beeper_state(false); } void play(const Ts &...x) { this->parent_->set_beeper_state(false); }
protected: protected:
HonClimate *parent_; HonClimate *parent_;
@@ -47,7 +47,7 @@ template<typename... Ts> class VerticalAirflowAction : public Action<Ts...> {
public: public:
VerticalAirflowAction(HonClimate *parent) : parent_(parent) {} VerticalAirflowAction(HonClimate *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(hon_protocol::VerticalSwingMode, direction) TEMPLATABLE_VALUE(hon_protocol::VerticalSwingMode, direction)
void play(Ts... x) { this->parent_->set_vertical_airflow(this->direction_.value(x...)); } void play(const Ts &...x) { this->parent_->set_vertical_airflow(this->direction_.value(x...)); }
protected: protected:
HonClimate *parent_; HonClimate *parent_;
@@ -57,7 +57,7 @@ template<typename... Ts> class HorizontalAirflowAction : public Action<Ts...> {
public: public:
HorizontalAirflowAction(HonClimate *parent) : parent_(parent) {} HorizontalAirflowAction(HonClimate *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(hon_protocol::HorizontalSwingMode, direction) TEMPLATABLE_VALUE(hon_protocol::HorizontalSwingMode, direction)
void play(Ts... x) { this->parent_->set_horizontal_airflow(this->direction_.value(x...)); } void play(const Ts &...x) { this->parent_->set_horizontal_airflow(this->direction_.value(x...)); }
protected: protected:
HonClimate *parent_; HonClimate *parent_;
@@ -66,7 +66,7 @@ template<typename... Ts> class HorizontalAirflowAction : public Action<Ts...> {
template<typename... Ts> class HealthOnAction : public Action<Ts...> { template<typename... Ts> class HealthOnAction : public Action<Ts...> {
public: public:
HealthOnAction(HaierClimateBase *parent) : parent_(parent) {} HealthOnAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->set_health_mode(true); } void play(const Ts &...x) { this->parent_->set_health_mode(true); }
protected: protected:
HaierClimateBase *parent_; HaierClimateBase *parent_;
@@ -75,7 +75,7 @@ template<typename... Ts> class HealthOnAction : public Action<Ts...> {
template<typename... Ts> class HealthOffAction : public Action<Ts...> { template<typename... Ts> class HealthOffAction : public Action<Ts...> {
public: public:
HealthOffAction(HaierClimateBase *parent) : parent_(parent) {} HealthOffAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->set_health_mode(false); } void play(const Ts &...x) { this->parent_->set_health_mode(false); }
protected: protected:
HaierClimateBase *parent_; HaierClimateBase *parent_;
@@ -84,7 +84,7 @@ template<typename... Ts> class HealthOffAction : public Action<Ts...> {
template<typename... Ts> class StartSelfCleaningAction : public Action<Ts...> { template<typename... Ts> class StartSelfCleaningAction : public Action<Ts...> {
public: public:
StartSelfCleaningAction(HonClimate *parent) : parent_(parent) {} StartSelfCleaningAction(HonClimate *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->start_self_cleaning(); } void play(const Ts &...x) { this->parent_->start_self_cleaning(); }
protected: protected:
HonClimate *parent_; HonClimate *parent_;
@@ -93,7 +93,7 @@ template<typename... Ts> class StartSelfCleaningAction : public Action<Ts...> {
template<typename... Ts> class StartSteriCleaningAction : public Action<Ts...> { template<typename... Ts> class StartSteriCleaningAction : public Action<Ts...> {
public: public:
StartSteriCleaningAction(HonClimate *parent) : parent_(parent) {} StartSteriCleaningAction(HonClimate *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->start_steri_cleaning(); } void play(const Ts &...x) { this->parent_->start_steri_cleaning(); }
protected: protected:
HonClimate *parent_; HonClimate *parent_;
@@ -102,7 +102,7 @@ template<typename... Ts> class StartSteriCleaningAction : public Action<Ts...> {
template<typename... Ts> class PowerOnAction : public Action<Ts...> { template<typename... Ts> class PowerOnAction : public Action<Ts...> {
public: public:
PowerOnAction(HaierClimateBase *parent) : parent_(parent) {} PowerOnAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->send_power_on_command(); } void play(const Ts &...x) { this->parent_->send_power_on_command(); }
protected: protected:
HaierClimateBase *parent_; HaierClimateBase *parent_;
@@ -111,7 +111,7 @@ template<typename... Ts> class PowerOnAction : public Action<Ts...> {
template<typename... Ts> class PowerOffAction : public Action<Ts...> { template<typename... Ts> class PowerOffAction : public Action<Ts...> {
public: public:
PowerOffAction(HaierClimateBase *parent) : parent_(parent) {} PowerOffAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->send_power_off_command(); } void play(const Ts &...x) { this->parent_->send_power_off_command(); }
protected: protected:
HaierClimateBase *parent_; HaierClimateBase *parent_;
@@ -120,7 +120,7 @@ template<typename... Ts> class PowerOffAction : public Action<Ts...> {
template<typename... Ts> class PowerToggleAction : public Action<Ts...> { template<typename... Ts> class PowerToggleAction : public Action<Ts...> {
public: public:
PowerToggleAction(HaierClimateBase *parent) : parent_(parent) {} PowerToggleAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->toggle_power(); } void play(const Ts &...x) { this->parent_->toggle_power(); }
protected: protected:
HaierClimateBase *parent_; HaierClimateBase *parent_;

View File

@@ -57,7 +57,7 @@ void HBridgeFan::control(const fan::FanCall &call) {
this->oscillating = *call.get_oscillating(); this->oscillating = *call.get_oscillating();
if (call.get_direction().has_value()) if (call.get_direction().has_value())
this->direction = *call.get_direction(); this->direction = *call.get_direction();
this->preset_mode = call.get_preset_mode(); this->set_preset_mode_(call.get_preset_mode());
this->write_state_(); this->write_state_();
this->publish_state(); this->publish_state();

View File

@@ -49,7 +49,7 @@ template<typename... Ts> class BrakeAction : public Action<Ts...> {
public: public:
explicit BrakeAction(HBridgeFan *parent) : parent_(parent) {} explicit BrakeAction(HBridgeFan *parent) : parent_(parent) {}
void play(Ts... x) override { this->parent_->brake(); } void play(const Ts &...x) override { this->parent_->brake(); }
HBridgeFan *parent_; HBridgeFan *parent_;
}; };

View File

@@ -113,8 +113,8 @@ class HttpContainer : public Parented<HttpRequestComponent> {
class HttpRequestResponseTrigger : public Trigger<std::shared_ptr<HttpContainer>, std::string &> { class HttpRequestResponseTrigger : public Trigger<std::shared_ptr<HttpContainer>, std::string &> {
public: public:
void process(std::shared_ptr<HttpContainer> container, std::string &response_body) { void process(const std::shared_ptr<HttpContainer> &container, std::string &response_body) {
this->trigger(std::move(container), response_body); this->trigger(container, response_body);
} }
}; };
@@ -210,7 +210,7 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
this->max_response_buffer_size_ = max_response_buffer_size; this->max_response_buffer_size_ = max_response_buffer_size;
} }
void play(Ts... x) override { void play(const Ts &...x) override {
std::string body; std::string body;
if (this->body_.has_value()) { if (this->body_.has_value()) {
body = this->body_.value(x...); body = this->body_.value(x...);

View File

@@ -15,7 +15,7 @@ template<typename... Ts> class OtaHttpRequestComponentFlashAction : public Actio
TEMPLATABLE_VALUE(std::string, url) TEMPLATABLE_VALUE(std::string, url)
TEMPLATABLE_VALUE(std::string, username) TEMPLATABLE_VALUE(std::string, username)
void play(Ts... x) override { void play(const Ts &...x) override {
if (this->md5_url_.has_value()) { if (this->md5_url_.has_value()) {
this->parent_->set_md5_url(this->md5_url_.value(x...)); this->parent_->set_md5_url(this->md5_url_.value(x...));
} }

View File

@@ -41,7 +41,7 @@ template<typename... Ts> class SetHeaterLevelAction : public Action<Ts...>, publ
public: public:
TEMPLATABLE_VALUE(uint8_t, level) TEMPLATABLE_VALUE(uint8_t, level)
void play(Ts... x) override { void play(const Ts &...x) override {
auto level = this->level_.value(x...); auto level = this->level_.value(x...);
this->parent_->set_heater_level(level); this->parent_->set_heater_level(level);
@@ -52,7 +52,7 @@ template<typename... Ts> class SetHeaterAction : public Action<Ts...>, public Pa
public: public:
TEMPLATABLE_VALUE(bool, status) TEMPLATABLE_VALUE(bool, status)
void play(Ts... x) override { void play(const Ts &...x) override {
auto status = this->status_.value(x...); auto status = this->status_.value(x...);
this->parent_->set_heater(status); this->parent_->set_heater(status);

View File

@@ -75,7 +75,7 @@ template<typename... Ts> class ResetAction : public Action<Ts...> {
public: public:
explicit ResetAction(IntegrationSensor *parent) : parent_(parent) {} explicit ResetAction(IntegrationSensor *parent) : parent_(parent) {}
void play(Ts... x) override { this->parent_->reset(); } void play(const Ts &...x) override { this->parent_->reset(); }
protected: protected:
IntegrationSensor *parent_; IntegrationSensor *parent_;

View File

@@ -52,11 +52,11 @@ class KeyCollector : public Component {
}; };
template<typename... Ts> class EnableAction : public Action<Ts...>, public Parented<KeyCollector> { template<typename... Ts> class EnableAction : public Action<Ts...>, public Parented<KeyCollector> {
void play(Ts... x) override { this->parent_->set_enabled(true); } void play(const Ts &...x) override { this->parent_->set_enabled(true); }
}; };
template<typename... Ts> class DisableAction : public Action<Ts...>, public Parented<KeyCollector> { template<typename... Ts> class DisableAction : public Action<Ts...>, public Parented<KeyCollector> {
void play(Ts... x) override { this->parent_->set_enabled(false); } void play(const Ts &...x) override { this->parent_->set_enabled(false); }
}; };
} // namespace key_collector } // namespace key_collector

View File

@@ -2,13 +2,18 @@
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include "esphome/components/lcd_base/lcd_display.h" #include "esphome/components/lcd_base/lcd_display.h"
#include "esphome/components/display/display.h"
namespace esphome { namespace esphome {
namespace lcd_gpio { namespace lcd_gpio {
class GPIOLCDDisplay;
using gpio_lcd_writer_t = display::DisplayWriter<GPIOLCDDisplay>;
class GPIOLCDDisplay : public lcd_base::LCDDisplay { class GPIOLCDDisplay : public lcd_base::LCDDisplay {
public: public:
void set_writer(std::function<void(GPIOLCDDisplay &)> &&writer) { this->writer_ = std::move(writer); } void set_writer(gpio_lcd_writer_t &&writer) { this->writer_ = std::move(writer); }
void setup() override; void setup() override;
void set_data_pins(GPIOPin *d0, GPIOPin *d1, GPIOPin *d2, GPIOPin *d3) { void set_data_pins(GPIOPin *d0, GPIOPin *d1, GPIOPin *d2, GPIOPin *d3) {
this->data_pins_[0] = d0; this->data_pins_[0] = d0;
@@ -43,7 +48,7 @@ class GPIOLCDDisplay : public lcd_base::LCDDisplay {
GPIOPin *rw_pin_{nullptr}; GPIOPin *rw_pin_{nullptr};
GPIOPin *enable_pin_{nullptr}; GPIOPin *enable_pin_{nullptr};
GPIOPin *data_pins_[8]{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; GPIOPin *data_pins_[8]{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
std::function<void(GPIOLCDDisplay &)> writer_; gpio_lcd_writer_t writer_;
}; };
} // namespace lcd_gpio } // namespace lcd_gpio

View File

@@ -3,13 +3,18 @@
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/components/lcd_base/lcd_display.h" #include "esphome/components/lcd_base/lcd_display.h"
#include "esphome/components/i2c/i2c.h" #include "esphome/components/i2c/i2c.h"
#include "esphome/components/display/display.h"
namespace esphome { namespace esphome {
namespace lcd_pcf8574 { namespace lcd_pcf8574 {
class PCF8574LCDDisplay;
using pcf8574_lcd_writer_t = display::DisplayWriter<PCF8574LCDDisplay>;
class PCF8574LCDDisplay : public lcd_base::LCDDisplay, public i2c::I2CDevice { class PCF8574LCDDisplay : public lcd_base::LCDDisplay, public i2c::I2CDevice {
public: public:
void set_writer(std::function<void(PCF8574LCDDisplay &)> &&writer) { this->writer_ = std::move(writer); } void set_writer(pcf8574_lcd_writer_t &&writer) { this->writer_ = std::move(writer); }
void setup() override; void setup() override;
void dump_config() override; void dump_config() override;
void backlight(); void backlight();
@@ -24,7 +29,7 @@ class PCF8574LCDDisplay : public lcd_base::LCDDisplay, public i2c::I2CDevice {
// Stores the current state of the backlight. // Stores the current state of the backlight.
uint8_t backlight_value_; uint8_t backlight_value_;
std::function<void(PCF8574LCDDisplay &)> writer_; pcf8574_lcd_writer_t writer_;
}; };
} // namespace lcd_pcf8574 } // namespace lcd_pcf8574

View File

@@ -12,7 +12,7 @@ template<typename... Ts> class BluetoothPasswordSetAction : public Action<Ts...>
explicit BluetoothPasswordSetAction(LD2410Component *ld2410_comp) : ld2410_comp_(ld2410_comp) {} explicit BluetoothPasswordSetAction(LD2410Component *ld2410_comp) : ld2410_comp_(ld2410_comp) {}
TEMPLATABLE_VALUE(std::string, password) TEMPLATABLE_VALUE(std::string, password)
void play(Ts... x) override { this->ld2410_comp_->set_bluetooth_password(this->password_.value(x...)); } void play(const Ts &...x) override { this->ld2410_comp_->set_bluetooth_password(this->password_.value(x...)); }
protected: protected:
LD2410Component *ld2410_comp_; LD2410Component *ld2410_comp_;

View File

@@ -121,9 +121,9 @@ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = {
}; };
// Helper functions for lookups // Helper functions for lookups
template<size_t N> uint8_t find_uint8(const StringToUint8 (&arr)[N], const std::string &str) { template<size_t N> uint8_t find_uint8(const StringToUint8 (&arr)[N], const char *str) {
for (const auto &entry : arr) { for (const auto &entry : arr) {
if (str == entry.str) if (strcmp(str, entry.str) == 0)
return entry.value; return entry.value;
} }
return 0xFF; // Not found return 0xFF; // Not found
@@ -441,7 +441,7 @@ bool LD2410Component::handle_ack_data_() {
ESP_LOGV(TAG, "Baud rate change"); ESP_LOGV(TAG, "Baud rate change");
#ifdef USE_SELECT #ifdef USE_SELECT
if (this->baud_rate_select_ != nullptr) { if (this->baud_rate_select_ != nullptr) {
ESP_LOGE(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->state.c_str()); ESP_LOGE(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->current_option());
} }
#endif #endif
break; break;
@@ -626,14 +626,14 @@ void LD2410Component::set_bluetooth(bool enable) {
this->set_timeout(200, [this]() { this->restart_and_read_all_info(); }); this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
} }
void LD2410Component::set_distance_resolution(const std::string &state) { void LD2410Component::set_distance_resolution(const char *state) {
this->set_config_mode_(true); this->set_config_mode_(true);
const uint8_t cmd_value[2] = {find_uint8(DISTANCE_RESOLUTIONS_BY_STR, state), 0x00}; const uint8_t cmd_value[2] = {find_uint8(DISTANCE_RESOLUTIONS_BY_STR, state), 0x00};
this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, sizeof(cmd_value)); this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, sizeof(cmd_value));
this->set_timeout(200, [this]() { this->restart_and_read_all_info(); }); this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
} }
void LD2410Component::set_baud_rate(const std::string &state) { void LD2410Component::set_baud_rate(const char *state) {
this->set_config_mode_(true); this->set_config_mode_(true);
const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00}; const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00};
this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value)); this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value));
@@ -759,10 +759,10 @@ void LD2410Component::set_light_out_control() {
#endif #endif
#ifdef USE_SELECT #ifdef USE_SELECT
if (this->light_function_select_ != nullptr && this->light_function_select_->has_state()) { if (this->light_function_select_ != nullptr && this->light_function_select_->has_state()) {
this->light_function_ = find_uint8(LIGHT_FUNCTIONS_BY_STR, this->light_function_select_->state); this->light_function_ = find_uint8(LIGHT_FUNCTIONS_BY_STR, this->light_function_select_->current_option());
} }
if (this->out_pin_level_select_ != nullptr && this->out_pin_level_select_->has_state()) { if (this->out_pin_level_select_ != nullptr && this->out_pin_level_select_->has_state()) {
this->out_pin_level_ = find_uint8(OUT_PIN_LEVELS_BY_STR, this->out_pin_level_select_->state); this->out_pin_level_ = find_uint8(OUT_PIN_LEVELS_BY_STR, this->out_pin_level_select_->current_option());
} }
#endif #endif
this->set_config_mode_(true); this->set_config_mode_(true);

View File

@@ -98,8 +98,8 @@ class LD2410Component : public Component, public uart::UARTDevice {
void read_all_info(); void read_all_info();
void restart_and_read_all_info(); void restart_and_read_all_info();
void set_bluetooth(bool enable); void set_bluetooth(bool enable);
void set_distance_resolution(const std::string &state); void set_distance_resolution(const char *state);
void set_baud_rate(const std::string &state); void set_baud_rate(const char *state);
void factory_reset(); void factory_reset();
protected: protected:

View File

@@ -3,9 +3,9 @@
namespace esphome { namespace esphome {
namespace ld2410 { namespace ld2410 {
void BaudRateSelect::control(const std::string &value) { void BaudRateSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_baud_rate(state); this->parent_->set_baud_rate(this->option_at(index));
} }
} // namespace ld2410 } // namespace ld2410

View File

@@ -11,7 +11,7 @@ class BaudRateSelect : public select::Select, public Parented<LD2410Component> {
BaudRateSelect() = default; BaudRateSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2410 } // namespace ld2410

View File

@@ -3,9 +3,9 @@
namespace esphome { namespace esphome {
namespace ld2410 { namespace ld2410 {
void DistanceResolutionSelect::control(const std::string &value) { void DistanceResolutionSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_distance_resolution(state); this->parent_->set_distance_resolution(this->option_at(index));
} }
} // namespace ld2410 } // namespace ld2410

View File

@@ -11,7 +11,7 @@ class DistanceResolutionSelect : public select::Select, public Parented<LD2410Co
DistanceResolutionSelect() = default; DistanceResolutionSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2410 } // namespace ld2410

View File

@@ -3,8 +3,8 @@
namespace esphome { namespace esphome {
namespace ld2410 { namespace ld2410 {
void LightOutControlSelect::control(const std::string &value) { void LightOutControlSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_light_out_control(); this->parent_->set_light_out_control();
} }

View File

@@ -11,7 +11,7 @@ class LightOutControlSelect : public select::Select, public Parented<LD2410Compo
LightOutControlSelect() = default; LightOutControlSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2410 } // namespace ld2410

View File

@@ -132,9 +132,9 @@ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = {
}; };
// Helper functions for lookups // Helper functions for lookups
template<size_t N> uint8_t find_uint8(const StringToUint8 (&arr)[N], const std::string &str) { template<size_t N> uint8_t find_uint8(const StringToUint8 (&arr)[N], const char *str) {
for (const auto &entry : arr) { for (const auto &entry : arr) {
if (str == entry.str) { if (strcmp(str, entry.str) == 0) {
return entry.value; return entry.value;
} }
} }
@@ -485,7 +485,7 @@ bool LD2412Component::handle_ack_data_() {
ESP_LOGV(TAG, "Baud rate change"); ESP_LOGV(TAG, "Baud rate change");
#ifdef USE_SELECT #ifdef USE_SELECT
if (this->baud_rate_select_ != nullptr) { if (this->baud_rate_select_ != nullptr) {
ESP_LOGW(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->state.c_str()); ESP_LOGW(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->current_option());
} }
#endif #endif
break; break;
@@ -699,14 +699,14 @@ void LD2412Component::set_bluetooth(bool enable) {
this->set_timeout(200, [this]() { this->restart_and_read_all_info(); }); this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
} }
void LD2412Component::set_distance_resolution(const std::string &state) { void LD2412Component::set_distance_resolution(const char *state) {
this->set_config_mode_(true); this->set_config_mode_(true);
const uint8_t cmd_value[6] = {find_uint8(DISTANCE_RESOLUTIONS_BY_STR, state), 0x00, 0x00, 0x00, 0x00, 0x00}; const uint8_t cmd_value[6] = {find_uint8(DISTANCE_RESOLUTIONS_BY_STR, state), 0x00, 0x00, 0x00, 0x00, 0x00};
this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, sizeof(cmd_value)); this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, sizeof(cmd_value));
this->set_timeout(200, [this]() { this->restart_and_read_all_info(); }); this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
} }
void LD2412Component::set_baud_rate(const std::string &state) { void LD2412Component::set_baud_rate(const char *state) {
this->set_config_mode_(true); this->set_config_mode_(true);
const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00}; const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00};
this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value)); this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value));
@@ -783,7 +783,7 @@ void LD2412Component::set_basic_config() {
1, TOTAL_GATES, DEFAULT_PRESENCE_TIMEOUT, 0, 1, TOTAL_GATES, DEFAULT_PRESENCE_TIMEOUT, 0,
#endif #endif
#ifdef USE_SELECT #ifdef USE_SELECT
find_uint8(OUT_PIN_LEVELS_BY_STR, this->out_pin_level_select_->state), find_uint8(OUT_PIN_LEVELS_BY_STR, this->out_pin_level_select_->current_option()),
#else #else
0x01, // Default value if not using select 0x01, // Default value if not using select
#endif #endif
@@ -837,7 +837,7 @@ void LD2412Component::set_light_out_control() {
#endif #endif
#ifdef USE_SELECT #ifdef USE_SELECT
if (this->light_function_select_ != nullptr && this->light_function_select_->has_state()) { if (this->light_function_select_ != nullptr && this->light_function_select_->has_state()) {
this->light_function_ = find_uint8(LIGHT_FUNCTIONS_BY_STR, this->light_function_select_->state); this->light_function_ = find_uint8(LIGHT_FUNCTIONS_BY_STR, this->light_function_select_->current_option());
} }
#endif #endif
uint8_t value[2] = {this->light_function_, this->light_threshold_}; uint8_t value[2] = {this->light_function_, this->light_threshold_};

View File

@@ -99,8 +99,8 @@ class LD2412Component : public Component, public uart::UARTDevice {
void read_all_info(); void read_all_info();
void restart_and_read_all_info(); void restart_and_read_all_info();
void set_bluetooth(bool enable); void set_bluetooth(bool enable);
void set_distance_resolution(const std::string &state); void set_distance_resolution(const char *state);
void set_baud_rate(const std::string &state); void set_baud_rate(const char *state);
void factory_reset(); void factory_reset();
void start_dynamic_background_correction(); void start_dynamic_background_correction();

View File

@@ -3,9 +3,9 @@
namespace esphome { namespace esphome {
namespace ld2412 { namespace ld2412 {
void BaudRateSelect::control(const std::string &value) { void BaudRateSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_baud_rate(state); this->parent_->set_baud_rate(this->option_at(index));
} }
} // namespace ld2412 } // namespace ld2412

View File

@@ -11,7 +11,7 @@ class BaudRateSelect : public select::Select, public Parented<LD2412Component> {
BaudRateSelect() = default; BaudRateSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2412 } // namespace ld2412

View File

@@ -3,9 +3,9 @@
namespace esphome { namespace esphome {
namespace ld2412 { namespace ld2412 {
void DistanceResolutionSelect::control(const std::string &value) { void DistanceResolutionSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_distance_resolution(state); this->parent_->set_distance_resolution(this->option_at(index));
} }
} // namespace ld2412 } // namespace ld2412

View File

@@ -11,7 +11,7 @@ class DistanceResolutionSelect : public select::Select, public Parented<LD2412Co
DistanceResolutionSelect() = default; DistanceResolutionSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2412 } // namespace ld2412

View File

@@ -3,8 +3,8 @@
namespace esphome { namespace esphome {
namespace ld2412 { namespace ld2412 {
void LightOutControlSelect::control(const std::string &value) { void LightOutControlSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_light_out_control(); this->parent_->set_light_out_control();
} }

View File

@@ -11,7 +11,7 @@ class LightOutControlSelect : public select::Select, public Parented<LD2412Compo
LightOutControlSelect() = default; LightOutControlSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2412 } // namespace ld2412

View File

@@ -131,8 +131,8 @@ static const uint8_t CMD_FRAME_STATUS = 7;
static const uint8_t CMD_ERROR_WORD = 8; static const uint8_t CMD_ERROR_WORD = 8;
static const uint8_t ENERGY_SENSOR_START = 9; static const uint8_t ENERGY_SENSOR_START = 9;
static const uint8_t CALIBRATE_REPORT_INTERVAL = 4; static const uint8_t CALIBRATE_REPORT_INTERVAL = 4;
static const std::string OP_NORMAL_MODE_STRING = "Normal"; static const char *const OP_NORMAL_MODE_STRING = "Normal";
static const std::string OP_SIMPLE_MODE_STRING = "Simple"; static const char *const OP_SIMPLE_MODE_STRING = "Simple";
// Memory-efficient lookup tables // Memory-efficient lookup tables
struct StringToUint8 { struct StringToUint8 {
@@ -379,7 +379,7 @@ void LD2420Component::report_gate_data() {
ESP_LOGI(TAG, "Total samples: %d", this->total_sample_number_counter); ESP_LOGI(TAG, "Total samples: %d", this->total_sample_number_counter);
} }
void LD2420Component::set_operating_mode(const std::string &state) { void LD2420Component::set_operating_mode(const char *state) {
// If unsupported firmware ignore mode select // If unsupported firmware ignore mode select
if (ld2420::get_firmware_int(firmware_ver_) >= CALIBRATE_VERSION_MIN) { if (ld2420::get_firmware_int(firmware_ver_) >= CALIBRATE_VERSION_MIN) {
this->current_operating_mode = find_uint8(OP_MODE_BY_STR, state); this->current_operating_mode = find_uint8(OP_MODE_BY_STR, state);

View File

@@ -107,7 +107,7 @@ class LD2420Component : public Component, public uart::UARTDevice {
int send_cmd_from_array(CmdFrameT cmd_frame); int send_cmd_from_array(CmdFrameT cmd_frame);
void report_gate_data(); void report_gate_data();
void handle_cmd_error(uint8_t error); void handle_cmd_error(uint8_t error);
void set_operating_mode(const std::string &state); void set_operating_mode(const char *state);
void auto_calibrate_sensitivity(); void auto_calibrate_sensitivity();
void update_radar_data(uint16_t const *gate_energy, uint8_t sample_number); void update_radar_data(uint16_t const *gate_energy, uint8_t sample_number);
uint8_t set_config_mode(bool enable); uint8_t set_config_mode(bool enable);

View File

@@ -7,9 +7,9 @@ namespace ld2420 {
static const char *const TAG = "ld2420.select"; static const char *const TAG = "ld2420.select";
void LD2420Select::control(const std::string &value) { void LD2420Select::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_operating_mode(value); this->parent_->set_operating_mode(this->option_at(index));
} }
} // namespace ld2420 } // namespace ld2420

View File

@@ -11,7 +11,7 @@ class LD2420Select : public Component, public select::Select, public Parented<LD
LD2420Select() = default; LD2420Select() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2420 } // namespace ld2420

View File

@@ -380,7 +380,7 @@ void LD2450Component::read_all_info() {
this->set_config_mode_(false); this->set_config_mode_(false);
#ifdef USE_SELECT #ifdef USE_SELECT
const auto baud_rate = std::to_string(this->parent_->get_baud_rate()); const auto baud_rate = std::to_string(this->parent_->get_baud_rate());
if (this->baud_rate_select_ != nullptr && this->baud_rate_select_->state != baud_rate) { if (this->baud_rate_select_ != nullptr && strcmp(this->baud_rate_select_->current_option(), baud_rate.c_str()) != 0) {
this->baud_rate_select_->publish_state(baud_rate); this->baud_rate_select_->publish_state(baud_rate);
} }
this->publish_zone_type(); this->publish_zone_type();
@@ -635,7 +635,7 @@ bool LD2450Component::handle_ack_data_() {
ESP_LOGV(TAG, "Baud rate change"); ESP_LOGV(TAG, "Baud rate change");
#ifdef USE_SELECT #ifdef USE_SELECT
if (this->baud_rate_select_ != nullptr) { if (this->baud_rate_select_ != nullptr) {
ESP_LOGE(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->state.c_str()); ESP_LOGE(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->current_option());
} }
#endif #endif
break; break;
@@ -716,7 +716,7 @@ bool LD2450Component::handle_ack_data_() {
this->publish_zone_type(); this->publish_zone_type();
#ifdef USE_SELECT #ifdef USE_SELECT
if (this->zone_type_select_ != nullptr) { if (this->zone_type_select_ != nullptr) {
ESP_LOGV(TAG, "Change zone type to: %s", this->zone_type_select_->state.c_str()); ESP_LOGV(TAG, "Change zone type to: %s", this->zone_type_select_->current_option());
} }
#endif #endif
if (this->buffer_data_[10] == 0x00) { if (this->buffer_data_[10] == 0x00) {
@@ -790,7 +790,7 @@ void LD2450Component::set_bluetooth(bool enable) {
} }
// Set Baud rate // Set Baud rate
void LD2450Component::set_baud_rate(const std::string &state) { void LD2450Component::set_baud_rate(const char *state) {
this->set_config_mode_(true); this->set_config_mode_(true);
const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00}; const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00};
this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value)); this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value));
@@ -798,8 +798,8 @@ void LD2450Component::set_baud_rate(const std::string &state) {
} }
// Set Zone Type - one of: Disabled, Detection, Filter // Set Zone Type - one of: Disabled, Detection, Filter
void LD2450Component::set_zone_type(const std::string &state) { void LD2450Component::set_zone_type(const char *state) {
ESP_LOGV(TAG, "Set zone type: %s", state.c_str()); ESP_LOGV(TAG, "Set zone type: %s", state);
uint8_t zone_type = find_uint8(ZONE_TYPE_BY_STR, state); uint8_t zone_type = find_uint8(ZONE_TYPE_BY_STR, state);
this->zone_type_ = zone_type; this->zone_type_ = zone_type;
this->send_set_zone_command_(); this->send_set_zone_command_();

View File

@@ -115,8 +115,8 @@ class LD2450Component : public Component, public uart::UARTDevice {
void restart_and_read_all_info(); void restart_and_read_all_info();
void set_bluetooth(bool enable); void set_bluetooth(bool enable);
void set_multi_target(bool enable); void set_multi_target(bool enable);
void set_baud_rate(const std::string &state); void set_baud_rate(const char *state);
void set_zone_type(const std::string &state); void set_zone_type(const char *state);
void publish_zone_type(); void publish_zone_type();
void factory_reset(); void factory_reset();
#ifdef USE_TEXT_SENSOR #ifdef USE_TEXT_SENSOR

View File

@@ -3,9 +3,9 @@
namespace esphome { namespace esphome {
namespace ld2450 { namespace ld2450 {
void BaudRateSelect::control(const std::string &value) { void BaudRateSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_baud_rate(state); this->parent_->set_baud_rate(this->option_at(index));
} }
} // namespace ld2450 } // namespace ld2450

View File

@@ -11,7 +11,7 @@ class BaudRateSelect : public select::Select, public Parented<LD2450Component> {
BaudRateSelect() = default; BaudRateSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2450 } // namespace ld2450

View File

@@ -3,9 +3,9 @@
namespace esphome { namespace esphome {
namespace ld2450 { namespace ld2450 {
void ZoneTypeSelect::control(const std::string &value) { void ZoneTypeSelect::control(size_t index) {
this->publish_state(value); this->publish_state(index);
this->parent_->set_zone_type(state); this->parent_->set_zone_type(this->option_at(index));
} }
} // namespace ld2450 } // namespace ld2450

View File

@@ -11,7 +11,7 @@ class ZoneTypeSelect : public select::Select, public Parented<LD2450Component> {
ZoneTypeSelect() = default; ZoneTypeSelect() = default;
protected: protected:
void control(const std::string &value) override; void control(size_t index) override;
}; };
} // namespace ld2450 } // namespace ld2450

View File

@@ -47,7 +47,7 @@ template<typename... Ts> class SetFrequencyAction : public Action<Ts...> {
SetFrequencyAction(LEDCOutput *parent) : parent_(parent) {} SetFrequencyAction(LEDCOutput *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(float, frequency); TEMPLATABLE_VALUE(float, frequency);
void play(Ts... x) { void play(const Ts &...x) {
float freq = this->frequency_.value(x...); float freq = this->frequency_.value(x...);
this->parent_->update_frequency(freq); this->parent_->update_frequency(freq);
} }

View File

@@ -40,7 +40,7 @@ template<typename... Ts> class SetFrequencyAction : public Action<Ts...> {
SetFrequencyAction(LibreTinyPWM *parent) : parent_(parent) {} SetFrequencyAction(LibreTinyPWM *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(float, frequency); TEMPLATABLE_VALUE(float, frequency);
void play(Ts... x) { void play(const Ts &...x) {
float freq = this->frequency_.value(x...); float freq = this->frequency_.value(x...);
this->parent_->update_frequency(freq); this->parent_->update_frequency(freq);
} }

View File

@@ -15,7 +15,7 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
TEMPLATABLE_VALUE(uint32_t, transition_length) TEMPLATABLE_VALUE(uint32_t, transition_length)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->state_->toggle(); auto call = this->state_->toggle();
call.set_transition_length(this->transition_length_.optional_value(x...)); call.set_transition_length(this->transition_length_.optional_value(x...));
call.perform(); call.perform();
@@ -44,7 +44,7 @@ template<typename... Ts> class LightControlAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, warm_white) TEMPLATABLE_VALUE(float, warm_white)
TEMPLATABLE_VALUE(std::string, effect) TEMPLATABLE_VALUE(std::string, effect)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->parent_->make_call(); auto call = this->parent_->make_call();
call.set_color_mode(this->color_mode_.optional_value(x...)); call.set_color_mode(this->color_mode_.optional_value(x...));
call.set_state(this->state_.optional_value(x...)); call.set_state(this->state_.optional_value(x...));
@@ -74,7 +74,7 @@ template<typename... Ts> class DimRelativeAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, relative_brightness) TEMPLATABLE_VALUE(float, relative_brightness)
TEMPLATABLE_VALUE(uint32_t, transition_length) TEMPLATABLE_VALUE(uint32_t, transition_length)
void play(Ts... x) override { void play(const Ts &...x) override {
auto call = this->parent_->make_call(); auto call = this->parent_->make_call();
float rel = this->relative_brightness_.value(x...); float rel = this->relative_brightness_.value(x...);
float cur; float cur;
@@ -107,7 +107,7 @@ template<typename... Ts> class DimRelativeAction : public Action<Ts...> {
template<typename... Ts> class LightIsOnCondition : public Condition<Ts...> { template<typename... Ts> class LightIsOnCondition : public Condition<Ts...> {
public: public:
explicit LightIsOnCondition(LightState *state) : state_(state) {} explicit LightIsOnCondition(LightState *state) : state_(state) {}
bool check(Ts... x) override { return this->state_->current_values.is_on(); } bool check(const Ts &...x) override { return this->state_->current_values.is_on(); }
protected: protected:
LightState *state_; LightState *state_;
@@ -115,7 +115,7 @@ template<typename... Ts> class LightIsOnCondition : public Condition<Ts...> {
template<typename... Ts> class LightIsOffCondition : public Condition<Ts...> { template<typename... Ts> class LightIsOffCondition : public Condition<Ts...> {
public: public:
explicit LightIsOffCondition(LightState *state) : state_(state) {} explicit LightIsOffCondition(LightState *state) : state_(state) {}
bool check(Ts... x) override { return !this->state_->current_values.is_on(); } bool check(const Ts &...x) override { return !this->state_->current_values.is_on(); }
protected: protected:
LightState *state_; LightState *state_;
@@ -179,7 +179,7 @@ template<typename... Ts> class AddressableSet : public Action<Ts...> {
TEMPLATABLE_VALUE(float, blue) TEMPLATABLE_VALUE(float, blue)
TEMPLATABLE_VALUE(float, white) TEMPLATABLE_VALUE(float, white)
void play(Ts... x) override { void play(const Ts &...x) override {
auto *out = (AddressableLight *) this->parent_->get_output(); auto *out = (AddressableLight *) this->parent_->get_output();
int32_t range_from = interpret_index(this->range_from_.value_or(x..., 0), out->size()); int32_t range_from = interpret_index(this->range_from_.value_or(x..., 0), out->size());
if (range_from < 0 || range_from >= out->size()) if (range_from < 0 || range_from >= out->size())

View File

@@ -51,7 +51,7 @@ template<typename... Ts> class SendRawAction : public Action<Ts...> {
void set_pulse_length(const int &data) { pulse_length_ = data; } void set_pulse_length(const int &data) { pulse_length_ = data; }
void set_data(const std::vector<uint8_t> &data) { code_ = data; } void set_data(const std::vector<uint8_t> &data) { code_ = data; }
void play(Ts... x) { void play(const Ts &...x) {
int repeats = this->repeat_.value(x...); int repeats = this->repeat_.value(x...);
int inverted = this->inverted_.value(x...); int inverted = this->inverted_.value(x...);
int pulse_length = this->pulse_length_.value(x...); int pulse_length = this->pulse_length_.value(x...);

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class LockAction : public Action<Ts...> {
public: public:
explicit LockAction(Lock *a_lock) : lock_(a_lock) {} explicit LockAction(Lock *a_lock) : lock_(a_lock) {}
void play(Ts... x) override { this->lock_->lock(); } void play(const Ts &...x) override { this->lock_->lock(); }
protected: protected:
Lock *lock_; Lock *lock_;
@@ -21,7 +21,7 @@ template<typename... Ts> class UnlockAction : public Action<Ts...> {
public: public:
explicit UnlockAction(Lock *a_lock) : lock_(a_lock) {} explicit UnlockAction(Lock *a_lock) : lock_(a_lock) {}
void play(Ts... x) override { this->lock_->unlock(); } void play(const Ts &...x) override { this->lock_->unlock(); }
protected: protected:
Lock *lock_; Lock *lock_;
@@ -31,7 +31,7 @@ template<typename... Ts> class OpenAction : public Action<Ts...> {
public: public:
explicit OpenAction(Lock *a_lock) : lock_(a_lock) {} explicit OpenAction(Lock *a_lock) : lock_(a_lock) {}
void play(Ts... x) override { this->lock_->open(); } void play(const Ts &...x) override { this->lock_->open(); }
protected: protected:
Lock *lock_; Lock *lock_;
@@ -40,7 +40,7 @@ template<typename... Ts> class OpenAction : public Action<Ts...> {
template<typename... Ts> class LockCondition : public Condition<Ts...> { template<typename... Ts> class LockCondition : public Condition<Ts...> {
public: public:
LockCondition(Lock *parent, bool state) : parent_(parent), state_(state) {} LockCondition(Lock *parent, bool state) : parent_(parent), state_(state) {}
bool check(Ts... x) override { bool check(const Ts &...x) override {
auto check_state = this->state_ ? LockState::LOCK_STATE_LOCKED : LockState::LOCK_STATE_UNLOCKED; auto check_state = this->state_ ? LockState::LOCK_STATE_LOCKED : LockState::LOCK_STATE_UNLOCKED;
return this->parent_->state == check_state; return this->parent_->state == check_state;
} }

View File

@@ -3,10 +3,10 @@
namespace esphome::logger { namespace esphome::logger {
void LoggerLevelSelect::publish_state(int level) { void LoggerLevelSelect::publish_state(int level) {
const auto &option = this->at(level_to_index(level)); auto index = level_to_index(level);
if (!option) if (!this->has_index(index))
return; return;
Select::publish_state(option.value()); Select::publish_state(index);
} }
void LoggerLevelSelect::setup() { void LoggerLevelSelect::setup() {
@@ -14,11 +14,6 @@ void LoggerLevelSelect::setup() {
this->publish_state(this->parent_->get_log_level()); this->publish_state(this->parent_->get_log_level());
} }
void LoggerLevelSelect::control(const std::string &value) { void LoggerLevelSelect::control(size_t index) { this->parent_->set_log_level(index_to_level(index)); }
const auto index = this->index_of(value);
if (!index)
return;
this->parent_->set_log_level(index_to_level(index.value()));
}
} // namespace esphome::logger } // namespace esphome::logger

View File

@@ -9,7 +9,7 @@ class LoggerLevelSelect : public Component, public select::Select, public Parent
public: public:
void publish_state(int level); void publish_state(int level);
void setup() override; void setup() override;
void control(const std::string &value) override; void control(size_t index) override;
protected: protected:
// Convert log level to option index (skip CONFIG at level 4) // Convert log level to option index (skip CONFIG at level 4)

View File

@@ -1,4 +1,5 @@
import re import re
import textwrap
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_HEIGHT, CONF_TYPE, CONF_WIDTH from esphome.const import CONF_HEIGHT, CONF_TYPE, CONF_WIDTH
@@ -122,7 +123,7 @@ class FlexLayout(Layout):
def get_layout_schemas(self, config: dict) -> tuple: def get_layout_schemas(self, config: dict) -> tuple:
layout = config.get(CONF_LAYOUT) layout = config.get(CONF_LAYOUT)
if not isinstance(layout, dict) or layout.get(CONF_TYPE) != TYPE_FLEX: if not isinstance(layout, dict) or layout.get(CONF_TYPE).lower() != TYPE_FLEX:
return None, {} return None, {}
child_schema = FLEX_OBJ_SCHEMA child_schema = FLEX_OBJ_SCHEMA
if grow := layout.get(CONF_FLEX_GROW): if grow := layout.get(CONF_FLEX_GROW):
@@ -161,6 +162,8 @@ class DirectionalLayout(FlexLayout):
return self.direction return self.direction
def get_layout_schemas(self, config: dict) -> tuple: def get_layout_schemas(self, config: dict) -> tuple:
if not isinstance(config.get(CONF_LAYOUT), str):
return None, {}
if config.get(CONF_LAYOUT, "").lower() != self.direction: if config.get(CONF_LAYOUT, "").lower() != self.direction:
return None, {} return None, {}
return cv.one_of(self.direction, lower=True), flex_hv_schema(self.direction) return cv.one_of(self.direction, lower=True), flex_hv_schema(self.direction)
@@ -206,7 +209,7 @@ class GridLayout(Layout):
# Not a valid grid layout string # Not a valid grid layout string
return None, {} return None, {}
if not isinstance(layout, dict) or layout.get(CONF_TYPE) != TYPE_GRID: if not isinstance(layout, dict) or layout.get(CONF_TYPE).lower() != TYPE_GRID:
return None, {} return None, {}
return ( return (
{ {
@@ -259,7 +262,7 @@ class GridLayout(Layout):
) )
# should be guaranteed to be a dict at this point # should be guaranteed to be a dict at this point
assert isinstance(layout, dict) assert isinstance(layout, dict)
assert layout.get(CONF_TYPE) == TYPE_GRID assert layout.get(CONF_TYPE).lower() == TYPE_GRID
rows = len(layout[CONF_GRID_ROWS]) rows = len(layout[CONF_GRID_ROWS])
columns = len(layout[CONF_GRID_COLUMNS]) columns = len(layout[CONF_GRID_COLUMNS])
used_cells = [[None] * columns for _ in range(rows)] used_cells = [[None] * columns for _ in range(rows)]
@@ -335,6 +338,17 @@ def append_layout_schema(schema, config: dict):
if CONF_LAYOUT not in config: if CONF_LAYOUT not in config:
# If no layout is specified, return the schema as is # If no layout is specified, return the schema as is
return schema.extend({cv.Optional(CONF_WIDGETS): any_widget_schema()}) return schema.extend({cv.Optional(CONF_WIDGETS): any_widget_schema()})
layout = config[CONF_LAYOUT]
# Sanity check the layout to avoid redundant checks in each type
if not isinstance(layout, str) and not isinstance(layout, dict):
raise cv.Invalid(
"The 'layout' option must be a string or a dictionary", [CONF_LAYOUT]
)
if isinstance(layout, dict) and not isinstance(layout.get(CONF_TYPE), str):
raise cv.Invalid(
"Invalid layout type; must be a string ('flex' or 'grid')",
[CONF_LAYOUT, CONF_TYPE],
)
for layout_class in LAYOUT_CLASSES: for layout_class in LAYOUT_CLASSES:
layout_schema, child_schema = layout_class.get_layout_schemas(config) layout_schema, child_schema = layout_class.get_layout_schemas(config)
@@ -348,10 +362,17 @@ def append_layout_schema(schema, config: dict):
layout_schema.add_extra(layout_class.validate) layout_schema.add_extra(layout_class.validate)
return layout_schema.extend(schema) return layout_schema.extend(schema)
# If no layout class matched, return a default schema if isinstance(layout, dict):
return cv.Schema( raise cv.Invalid(
{ "Invalid layout type; must be 'flex' or 'grid'", [CONF_LAYOUT, CONF_TYPE]
cv.Optional(CONF_LAYOUT): cv.one_of(*LAYOUT_CHOICES, lower=True), )
cv.Optional(CONF_WIDGETS): any_widget_schema(), raise cv.Invalid(
} textwrap.dedent(
"""
Invalid 'layout' value
layout choices are 'horizontal', 'vertical', '<rows>x<cols>',
or a dictionary with a 'type' key
"""
),
[CONF_LAYOUT],
) )

View File

@@ -129,7 +129,7 @@ template<typename... Ts> class ObjUpdateAction : public Action<Ts...> {
public: public:
explicit ObjUpdateAction(std::function<void(Ts...)> &&lamb) : lamb_(std::move(lamb)) {} explicit ObjUpdateAction(std::function<void(Ts...)> &&lamb) : lamb_(std::move(lamb)) {}
void play(Ts... x) override { this->lamb_(x...); } void play(const Ts &...x) override { this->lamb_(x...); }
protected: protected:
std::function<void(Ts...)> lamb_; std::function<void(Ts...)> lamb_;
@@ -263,7 +263,7 @@ class IdleTrigger : public Trigger<> {
template<typename... Ts> class LvglAction : public Action<Ts...>, public Parented<LvglComponent> { template<typename... Ts> class LvglAction : public Action<Ts...>, public Parented<LvglComponent> {
public: public:
explicit LvglAction(std::function<void(LvglComponent *)> &&lamb) : action_(std::move(lamb)) {} explicit LvglAction(std::function<void(LvglComponent *)> &&lamb) : action_(std::move(lamb)) {}
void play(Ts... x) override { this->action_(this->parent_); } void play(const Ts &...x) override { this->action_(this->parent_); }
protected: protected:
std::function<void(LvglComponent *)> action_{}; std::function<void(LvglComponent *)> action_{};
@@ -272,7 +272,7 @@ template<typename... Ts> class LvglAction : public Action<Ts...>, public Parente
template<typename Tc, typename... Ts> class LvglCondition : public Condition<Ts...>, public Parented<Tc> { template<typename Tc, typename... Ts> class LvglCondition : public Condition<Ts...>, public Parented<Tc> {
public: public:
LvglCondition(std::function<bool(Tc *)> &&condition_lambda) : condition_lambda_(std::move(condition_lambda)) {} LvglCondition(std::function<bool(Tc *)> &&condition_lambda) : condition_lambda_(std::move(condition_lambda)) {}
bool check(Ts... x) override { return this->condition_lambda_(this->parent_); } bool check(const Ts &...x) override { return this->condition_lambda_(this->parent_); }
protected: protected:
std::function<bool(Tc *)> condition_lambda_{}; std::function<bool(Tc *)> condition_lambda_{};

Some files were not shown because too many files have changed in this diff Show More