1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-05 09:31:54 +00:00

Compare commits

...

13 Commits

Author SHA1 Message Date
J. Nick Koston
32975c9d8b [select][lvgl] Fix FixedVector size() returning 0 when using operator[] after init() (#11721) 2025-11-05 01:49:27 +00:00
J. Nick Koston
1446e7174a [core] Reduce action framework argument copies by 83% (#11704)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-11-05 01:23:24 +00:00
Gnuspice
64f8963566 [const] Move CONF_ENABLED to const.py (#11719) 2025-11-05 12:46:06 +13:00
J. Nick Koston
6f7e54c3f3 [select] Refactor to index-based operations for immediate and future RAM savings (#11623) 2025-11-05 11:33:01 +13:00
J. Nick Koston
c7ae424613 [display] Optimize display writers with function pointers for stateless lambdas (#11629) 2025-11-05 11:14:54 +13:00
Clyde Stubbs
c5e5609e92 [lvgl] Fix case sensitivity in flex layout (#11717) 2025-11-05 09:00:12 +11:00
J. Nick Koston
885508775f [fan] Remove duplicate preset mode storage to save RAM (#11632) 2025-11-05 10:55:37 +13:00
J. Nick Koston
531b27582a [network] Store use_address in RODATA to save RAM (#11707) 2025-11-05 10:52:10 +13:00
J. Nick Koston
aed7505f53 [automations] Reduce memory usage in if/while/repeat actions (32-36 bytes per instance) (#11650)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2025-11-05 10:48:20 +13:00
Javier Peletier
191a88c2dc [gt911] Fix gt911 touchscreen with reset pin not initializing when loglevel is set to NONE (#11715) 2025-11-04 13:38:59 -05:00
SeByDocKy
968df6cb3f [gp8403] Add gp8413 (15 bits) DAC model (#7726)
Co-authored-by: Djordje Mandic <6750655+DjordjeMandic@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-11-04 12:16:11 -05:00
Cameron Steel
71fa88c9d4 [max7219digit] support flip_x when rotate_chip is 90° or 270° (#6109)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-04 16:32:23 +00:00
Chaser Huang
84f7cacef9 [sgp30] Fix reading from preexisting stored baseline even with store_baseline:false (#7922)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
2025-11-04 15:41:30 +00:00
217 changed files with 1203 additions and 806 deletions

View File

@@ -181,7 +181,7 @@ esphome/components/gdk101/* @Szewcson
esphome/components/gl_r01_i2c/* @pkejval
esphome/components/globals/* @esphome/core
esphome/components/gp2y1010au0f/* @zry98
esphome/components/gp8403/* @jesserockz
esphome/components/gp8403/* @jesserockz @sebydocky
esphome/components/gpio/* @esphome/core
esphome/components/gpio/one_wire/* @ssieb
esphome/components/gps/* @coogle @ximex

View File

@@ -105,7 +105,7 @@ template<typename... Ts> class AGS10NewI2cAddressAction : public Action<Ts...>,
public:
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 {
@@ -122,7 +122,7 @@ template<typename... Ts> class AGS10SetZeroPointAction : public Action<Ts...>, p
TEMPLATABLE_VALUE(uint16_t, value)
TEMPLATABLE_VALUE(AGS10SetZeroPointActionMode, mode)
void play(Ts... x) override {
void play(const Ts &...x) override {
switch (this->mode_.value(x...)) {
case FACTORY_DEFAULT:
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)
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:
AIC3204 *aic3204_;

View File

@@ -89,7 +89,7 @@ template<typename... Ts> class ArmAwayAction : public Action<Ts...> {
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 code = this->code_.optional_value(x...);
if (code.has_value()) {
@@ -109,7 +109,7 @@ template<typename... Ts> class ArmHomeAction : public Action<Ts...> {
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 code = this->code_.optional_value(x...);
if (code.has_value()) {
@@ -129,7 +129,7 @@ template<typename... Ts> class ArmNightAction : public Action<Ts...> {
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 code = this->code_.optional_value(x...);
if (code.has_value()) {
@@ -149,7 +149,7 @@ template<typename... Ts> class DisarmAction : public Action<Ts...> {
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:
AlarmControlPanel *alarm_control_panel_;
@@ -159,7 +159,7 @@ template<typename... Ts> class PendingAction : public Action<Ts...> {
public:
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:
AlarmControlPanel *alarm_control_panel_;
@@ -169,7 +169,7 @@ template<typename... Ts> class TriggeredAction : public Action<Ts...> {
public:
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:
AlarmControlPanel *alarm_control_panel_;
@@ -178,7 +178,7 @@ template<typename... Ts> class TriggeredAction : public Action<Ts...> {
template<typename... Ts> class AlarmControlPanelCondition : public Condition<Ts...> {
public:
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()) ||
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...> {
public:
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:
Animation *parent_;
@@ -48,7 +48,7 @@ template<typename... Ts> class AnimationNextFrameAction : public Action<Ts...> {
template<typename... Ts> class AnimationPrevFrameAction : public Action<Ts...> {
public:
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:
Animation *parent_;
@@ -58,7 +58,7 @@ template<typename... Ts> class AnimationSetFrameAction : public Action<Ts...> {
public:
AnimationSetFrameAction(Animation *parent) : parent_(parent) {}
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:
Animation *parent_;

View File

@@ -410,8 +410,8 @@ uint16_t APIConnection::try_send_fan_state(EntityBase *entity, APIConnection *co
}
if (traits.supports_direction())
msg.direction = static_cast<enums::FanDirection>(fan->direction);
if (traits.supports_preset_modes())
msg.set_preset_mode(StringRef(fan->preset_mode));
if (traits.supports_preset_modes() && fan->has_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);
}
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) {
auto *select = static_cast<select::Select *>(entity);
SelectStateResponse resp;
resp.set_state(StringRef(select->state));
resp.set_state(StringRef(select->current_option()));
resp.missing_state = !select->has_state();
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"
" Listen backlog: %u\n"
" 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
ESP_LOGCONFIG(TAG, " Noise encryption: %s", YESNO(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...> {
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

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_; }
#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
void play(Ts... x) override {
void play(const Ts &...x) override {
HomeassistantActionRequest resp;
std::string service_value = this->service_.value(x...);
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> {
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> {
@@ -25,7 +25,7 @@ template<typename... Ts> class AT581XSettingsAction : public Action<Ts...>, publ
TEMPLATABLE_VALUE(int, trigger_keep)
TEMPLATABLE_VALUE(int, stage_gain)
void play(Ts... x) {
void play(const Ts &...x) {
if (this->frequency_.has_value()) {
int v = this->frequency_.value(x...);
this->parent_->set_frequency(v);

View File

@@ -13,7 +13,7 @@ template<typename... Ts> class SetMicGainAction : public Action<Ts...> {
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:
AudioAdc *audio_adc_;

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class MuteOffAction : public Action<Ts...> {
public:
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:
AudioDac *audio_dac_;
@@ -21,7 +21,7 @@ template<typename... Ts> class MuteOnAction : public Action<Ts...> {
public:
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:
AudioDac *audio_dac_;
@@ -33,7 +33,7 @@ template<typename... Ts> class SetVolumeAction : public Action<Ts...> {
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:
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...> {
public:
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:
BinarySensor *parent_;
@@ -153,7 +153,7 @@ template<typename... Ts> class BinarySensorPublishAction : public Action<Ts...>
explicit BinarySensorPublishAction(BinarySensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto val = this->state_.value(x...);
this->sensor_->publish_state(val);
}
@@ -166,7 +166,7 @@ template<typename... Ts> class BinarySensorInvalidateAction : public Action<Ts..
public:
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:
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> {
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

View File

@@ -123,9 +123,9 @@ template<typename... Ts> class BLEClientWriteAction : public Action<Ts...>, publ
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->var_ = std::make_tuple(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:
BLEClientPasskeyReplyAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override {
void play(const Ts &...x) override {
uint32_t passkey;
if (has_simple_value_) {
passkey = this->value_.simple;
@@ -266,7 +266,7 @@ template<typename... Ts> class BLEClientNumericComparisonReplyAction : public Ac
public:
BLEClientNumericComparisonReplyAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override {
void play(const Ts &...x) override {
esp_bd_addr_t remote_bda;
memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t));
if (has_simple_value_) {
@@ -299,7 +299,7 @@ template<typename... Ts> class BLEClientRemoveBondAction : public Action<Ts...>
public:
BLEClientRemoveBondAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override {
void play(const Ts &...x) override {
esp_bd_addr_t remote_bda;
memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t));
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_
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.
// this would occur only if the same automation was re-triggered while still
// 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_
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_++;
if (this->node_state == espbt::ClientState::IDLE) {
this->play_next_(x...);

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class PressAction : public Action<Ts...> {
public:
explicit PressAction(Button *button) : button_(button) {}
void play(Ts... x) override { this->button_->press(); }
void play(const Ts &...x) override { this->button_->press(); }
protected:
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;
}
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 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(ClimateSwingMode, swing_mode)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto call = this->climate_->make_call();
call.set_mode(this->mode_.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:
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:
CM1106Component *cm1106_;

View File

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

View File

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

View File

@@ -7,19 +7,19 @@ namespace copy {
static const char *const TAG = "copy.select";
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());
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::control(const std::string &value) {
void CopySelect::control(size_t index) {
auto call = source_->make_call();
call.set_option(value);
call.set_index(index);
call.perform();
}

View File

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

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class OpenAction : public Action<Ts...> {
public:
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:
Cover *cover_;
@@ -21,7 +21,7 @@ template<typename... Ts> class CloseAction : public Action<Ts...> {
public:
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:
Cover *cover_;
@@ -31,7 +31,7 @@ template<typename... Ts> class StopAction : public Action<Ts...> {
public:
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:
Cover *cover_;
@@ -41,7 +41,7 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
public:
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:
Cover *cover_;
@@ -55,7 +55,7 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto call = this->cover_->make_call();
if (this->stop_.has_value())
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(CoverOperation, current_operation)
void play(Ts... x) override {
void play(const Ts &...x) override {
if (this->position_.has_value())
this->cover_->position = this->position_.value(x...);
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...> {
public:
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:
Cover *cover_;
@@ -103,7 +103,7 @@ template<typename... Ts> class CoverIsOpenCondition : public Condition<Ts...> {
template<typename... Ts> class CoverIsClosedCondition : public Condition<Ts...> {
public:
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:
Cover *cover_;

View File

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

View File

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

View File

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

View File

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

View File

@@ -77,7 +77,7 @@ class DFPlayer : public uart::UARTDevice, public Component {
class ACTION_CLASS : /* NOLINT */ \
public Action<Ts...>, \
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)
@@ -87,7 +87,7 @@ template<typename... Ts> class PlayMp3Action : public Action<Ts...>, public Pare
public:
TEMPLATABLE_VALUE(uint16_t, file)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto file = this->file_.value(x...);
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(bool, loop)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto file = this->file_.value(x...);
auto loop = this->loop_.value(x...);
if (loop) {
@@ -115,7 +115,7 @@ template<typename... Ts> class PlayFolderAction : public Action<Ts...>, public P
TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(bool, loop)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto folder = this->folder_.value(x...);
auto file = this->file_.value(x...);
auto loop = this->loop_.value(x...);
@@ -131,7 +131,7 @@ template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Pa
public:
TEMPLATABLE_VALUE(Device, device)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto device = this->device_.value(x...);
this->parent_->set_device(device);
}
@@ -141,7 +141,7 @@ template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Pa
public:
TEMPLATABLE_VALUE(uint8_t, volume)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto volume = this->volume_.value(x...);
this->parent_->set_volume(volume);
}
@@ -151,7 +151,7 @@ template<typename... Ts> class SetEqAction : public Action<Ts...>, public Parent
public:
TEMPLATABLE_VALUE(EqPreset, eq)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto eq = this->eq_.value(x...);
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> {
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<> {

View File

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

View File

@@ -176,7 +176,117 @@ class Display;
class DisplayPage;
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) \
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);
DisplayRotation rotation_{DISPLAY_ROTATION_0_DEGREES};
optional<display_writer_t> writer_{};
display_writer_t writer_{};
DisplayPage *page_{nullptr};
DisplayPage *previous_page_{nullptr};
std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
@@ -709,7 +819,7 @@ template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
public:
TEMPLATABLE_VALUE(DisplayPage *, page)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto *page = this->page_.value(x...);
if (page != nullptr) {
page->show();
@@ -721,7 +831,7 @@ template<typename... Ts> class DisplayPageShowNextAction : public Action<Ts...>
public:
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_;
};
@@ -730,7 +840,7 @@ template<typename... Ts> class DisplayPageShowPrevAction : public Action<Ts...>
public:
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_;
};
@@ -740,7 +850,7 @@ template<typename... Ts> class DisplayIsDisplayingPageCondition : public Conditi
DisplayIsDisplayingPageCondition(Display *parent) : parent_(parent) {}
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:
Display *parent_;

View File

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

View File

@@ -42,7 +42,7 @@ std::string MenuItemSelect::get_value_text() const {
result = this->value_getter_.value()(this);
} else {
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> {
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> {
public:
void play(Ts... x) override { this->parent_->read_time(); }
void play(const Ts &...x) override { this->parent_->read_time(); }
};
} // namespace ds1307
} // 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 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...> {
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...> {
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> {
@@ -67,7 +67,7 @@ template<typename... Ts> class RunningCondition : public Condition<Ts...>, publi
explicit RunningCondition(DutyTimeSensor *parent, bool state) : Parented(parent), state_(state) {}
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_;
};

View File

@@ -214,17 +214,17 @@ extern ESP32BLE *global_ble;
template<typename... Ts> class BLEEnabledCondition : public Condition<Ts...> {
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...> {
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...> {
public:
void play(Ts... x) override { global_ble->disable(); }
void play(const Ts &...x) override { global_ble->disable(); }
};
} // namespace esphome::esp32_ble

View File

@@ -71,7 +71,7 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
BLECharacteristicSetValueAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer)
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 (BLECharacteristicSetValueActionManager::get_instance()->has_listener(this->parent_))
return;
@@ -96,7 +96,7 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts...> {
public:
BLECharacteristicNotifyAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
void play(Ts... x) override {
void play(const Ts &...x) override {
#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
// Call the pre-notify event
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) {}
TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer)
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:
BLEDescriptor *parent_;

View File

@@ -96,7 +96,7 @@ template<typename... Ts> class ESP32BLEStartScanAction : public Action<Ts...> {
public:
ESP32BLEStartScanAction(ESP32BLETracker *parent) : parent_(parent) {}
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_->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> {
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

View File

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

View File

@@ -34,7 +34,7 @@ template<typename... Ts> class AdjustAction : public Action<Ts...> {
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:
EspLdo *ldo_;

View File

@@ -94,7 +94,7 @@ void ESPHomeOTAComponent::dump_config() {
"Over-The-Air updates:\n"
" Address: %s:%u\n"
" 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
if (!this->password_.empty()) {
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_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_++;
send_callback_t send_callback = [this, x...](esp_err_t status) {
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 {
@@ -90,7 +90,7 @@ template<typename... Ts> class AddPeerAction : public Action<Ts...>, public Pare
TEMPLATABLE_VALUE(peer_address_t, address);
public:
void play(Ts... x) override {
void play(const Ts &...x) override {
peer_address_t address = this->address_.value(x...);
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);
public:
void play(Ts... x) override {
void play(const Ts &...x) override {
peer_address_t address = this->address_.value(x...);
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> {
public:
TEMPLATABLE_VALUE(uint8_t, channel)
void play(Ts... x) override {
void play(const Ts &...x) override {
if (this->parent_->is_wifi_enabled()) {
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,
// 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) {
esp_err_t err;

View File

@@ -88,8 +88,8 @@ class EthernetComponent : public Component {
network::IPAddresses get_ip_addresses();
network::IPAddress get_dns_address(uint8_t num);
const std::string &get_use_address() const;
void set_use_address(const std::string &use_address);
const char *get_use_address() const;
void set_use_address(const char *use_address);
void get_eth_mac_address_raw(uint8_t *mac);
std::string get_eth_mac_address_pretty();
eth_duplex_t get_duplex_mode();
@@ -114,7 +114,6 @@ class EthernetComponent : public Component {
/// @brief Set arbitratry PHY registers from config.
void write_phy_register_(esp_eth_mac_t *mac, PHYRegister register_data);
std::string use_address_;
#ifdef USE_ETHERNET_SPI
uint8_t clk_pin_;
uint8_t miso_pin_;
@@ -158,6 +157,11 @@ class EthernetComponent : public Component {
esp_eth_handle_t eth_handle_;
esp_eth_phy_t *phy_{nullptr};
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)

View File

@@ -11,7 +11,7 @@ template<typename... Ts> class TriggerEventAction : public Action<Ts...>, public
public:
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> {

View File

@@ -17,35 +17,35 @@ class LedTrigger : public Trigger<bool> {
class CustomTrigger : public Trigger<std::string> {
public:
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> {
public:
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> {
public:
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> {
public:
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> {
public:
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:
EzoPMPFindAction(EzoPMP *ezopmp) : ezopmp_(ezopmp) {}
void play(Ts... x) override { this->ezopmp_->find(); }
void play(const Ts &...x) override { this->ezopmp_->find(); }
protected:
EzoPMP *ezopmp_;
@@ -129,7 +129,7 @@ template<typename... Ts> class EzoPMPDoseContinuouslyAction : public Action<Ts..
public:
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:
EzoPMP *ezopmp_;
@@ -139,7 +139,7 @@ template<typename... Ts> class EzoPMPDoseVolumeAction : public Action<Ts...> {
public:
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)
protected:
@@ -150,7 +150,7 @@ template<typename... Ts> class EzoPMPDoseVolumeOverTimeAction : public Action<Ts
public:
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...));
}
TEMPLATABLE_VALUE(double, volume)
@@ -164,7 +164,7 @@ template<typename... Ts> class EzoPMPDoseWithConstantFlowRateAction : public Act
public:
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...));
}
TEMPLATABLE_VALUE(double, volume)
@@ -178,7 +178,7 @@ template<typename... Ts> class EzoPMPSetCalibrationVolumeAction : public Action<
public:
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)
protected:
@@ -189,7 +189,7 @@ template<typename... Ts> class EzoPMPClearTotalVolumeDispensedAction : public Ac
public:
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:
EzoPMP *ezopmp_;
@@ -199,7 +199,7 @@ template<typename... Ts> class EzoPMPClearCalibrationAction : public Action<Ts..
public:
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:
EzoPMP *ezopmp_;
@@ -209,7 +209,7 @@ template<typename... Ts> class EzoPMPPauseDosingAction : public Action<Ts...> {
public:
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:
EzoPMP *ezopmp_;
@@ -219,7 +219,7 @@ template<typename... Ts> class EzoPMPStopDosingAction : public Action<Ts...> {
public:
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:
EzoPMP *ezopmp_;
@@ -229,7 +229,7 @@ template<typename... Ts> class EzoPMPChangeI2CAddressAction : public Action<Ts..
public:
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)
protected:
@@ -240,7 +240,7 @@ template<typename... Ts> class EzoPMPArbitraryCommandAction : public Action<Ts..
public:
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)
protected:

View File

@@ -15,7 +15,7 @@ template<typename... Ts> class TurnOnAction : public Action<Ts...> {
TEMPLATABLE_VALUE(int, speed)
TEMPLATABLE_VALUE(FanDirection, direction)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto call = this->state_->turn_on();
if (this->oscillating_.has_value()) {
call.set_oscillating(this->oscillating_.value(x...));
@@ -36,7 +36,7 @@ template<typename... Ts> class TurnOffAction : public Action<Ts...> {
public:
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_;
};
@@ -45,7 +45,7 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
public:
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_;
};
@@ -56,7 +56,7 @@ template<typename... Ts> class CycleSpeedAction : public Action<Ts...> {
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
if (this->state_->get_traits().supported_speed_count()) {
if (this->state_->state) {
@@ -97,7 +97,7 @@ template<typename... Ts> class CycleSpeedAction : public Action<Ts...> {
template<typename... Ts> class FanIsOnCondition : public Condition<Ts...> {
public:
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:
Fan *state_;
@@ -105,7 +105,7 @@ template<typename... Ts> class FanIsOnCondition : public Condition<Ts...> {
template<typename... Ts> class FanIsOffCondition : public Condition<Ts...> {
public:
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:
Fan *state_;
@@ -212,18 +212,19 @@ class FanPresetSetTrigger : public Trigger<std::string> {
public:
FanPresetSetTrigger(Fan *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_;
this->last_preset_mode_ = preset_mode;
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:
std::string last_preset_mode_;
const char *last_preset_mode_{nullptr};
};
} // 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() {
ESP_LOGD(TAG, "'%s' - Setting:", this->parent_.get_name().c_str());
this->validate_();
@@ -32,8 +53,8 @@ void FanCall::perform() {
if (this->direction_.has_value()) {
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(*this->direction_)));
}
if (!this->preset_mode_.empty()) {
ESP_LOGD(TAG, " Preset Mode: %s", this->preset_mode_.c_str());
if (this->has_preset_mode()) {
ESP_LOGD(TAG, " Preset Mode: %s", this->preset_mode_);
}
this->parent_.control(*this);
}
@@ -46,30 +67,15 @@ void FanCall::validate_() {
// https://developers.home-assistant.io/docs/core/entity/fan/#preset-modes
// "Manually setting a speed must disable any set preset mode"
this->preset_mode_.clear();
}
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();
}
this->preset_mode_ = nullptr;
}
// when turning on...
if (!this->parent_.state && this->binary_state_.has_value() &&
*this->binary_state_
// ..,and no preset mode will be active...
&& this->preset_mode_.empty() &&
this->parent_.preset_mode.empty()
&& !this->has_preset_mode() &&
this->parent_.get_preset_mode() == nullptr
// ...and neither current nor new speed is available...
&& traits.supports_speed() && this->parent_.speed == 0 && !this->speed_.has_value()) {
// ...set speed to 100%
@@ -117,12 +123,13 @@ void FanRestoreState::apply(Fan &fan) {
auto traits = fan.get_traits();
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();
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();
}
@@ -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::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::publish_state() {
auto traits = this->get_traits();
@@ -146,8 +176,9 @@ void Fan::publish_state() {
if (traits.supports_direction()) {
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction)));
}
if (traits.supports_preset_modes() && !this->preset_mode.empty()) {
ESP_LOGD(TAG, " Preset Mode: %s", this->preset_mode.c_str());
const char *preset = this->get_preset_mode();
if (preset != nullptr) {
ESP_LOGD(TAG, " Preset Mode: %s", preset);
}
this->state_callback_.call();
this->save_state_();
@@ -199,16 +230,15 @@ void Fan::save_state_() {
state.speed = this->speed;
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();
// Store index of current preset mode
size_t i = 0;
for (const auto &mode : preset_modes) {
if (strcmp(mode, this->preset_mode.c_str()) == 0) {
// Find index of current preset mode (pointer comparison is safe since preset is from traits)
for (size_t i = 0; i < preset_modes.size(); i++) {
if (preset_modes[i] == preset) {
state.preset_mode = i;
break;
}
i++;
}
}

View File

@@ -70,11 +70,10 @@ class FanCall {
return *this;
}
optional<FanDirection> get_direction() const { return this->direction_; }
FanCall &set_preset_mode(const std::string &preset_mode) {
this->preset_mode_ = preset_mode;
return *this;
}
std::string get_preset_mode() const { return this->preset_mode_; }
FanCall &set_preset_mode(const std::string &preset_mode);
FanCall &set_preset_mode(const char *preset_mode);
const char *get_preset_mode() const { return this->preset_mode_; }
bool has_preset_mode() const { return this->preset_mode_ != nullptr; }
void perform();
@@ -86,7 +85,7 @@ class FanCall {
optional<bool> oscillating_;
optional<int> speed_;
optional<FanDirection> direction_{};
std::string preset_mode_{};
const char *preset_mode_{nullptr}; // Pointer to string in traits (after validation)
};
struct FanRestoreState {
@@ -112,8 +111,6 @@ class Fan : public EntityBase {
int speed{0};
/// The current direction of the fan
FanDirection direction{FanDirection::FORWARD};
// The current preset mode of the fan
std::string preset_mode{};
FanCall turn_on();
FanCall turn_off();
@@ -130,8 +127,15 @@ class Fan : public EntityBase {
/// Set the restore mode of this fan.
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:
friend FanCall;
friend struct FanRestoreState;
virtual void control(const FanCall &call) = 0;
@@ -140,9 +144,21 @@ class Fan : public EntityBase {
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_{};
ESPPreferenceObject rtc_;
FanRestoreMode restore_mode_;
private:
const char *preset_mode_{nullptr};
};
} // namespace fan

View File

@@ -1,5 +1,6 @@
#pragma once
#include <cstring>
#include <vector>
#include <initializer_list>
@@ -44,6 +45,17 @@ class FanTraits {
/// Return if preset modes are supported
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:
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(uint8_t, num_scans)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto finger_id = this->finger_id_.value(x...);
auto num_scans = this->num_scans_.value(x...);
if (num_scans) {
@@ -287,14 +287,14 @@ template<typename... Ts> class EnrollmentAction : public Action<Ts...>, public P
template<typename... Ts>
class CancelEnrollmentAction : public Action<Ts...>, public Parented<FingerprintGrowComponent> {
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> {
public:
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...);
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> {
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> {
public:
TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto state = this->state_.value(x...);
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, count)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto state = this->state_.value(x...);
auto speed = this->speed_.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);
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:
C *parent_;

View File

@@ -1,19 +1,25 @@
import esphome.codegen as cg
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_VOLTAGE
from esphome.const import CONF_ID, CONF_MODEL, CONF_VOLTAGE
CODEOWNERS = ["@jesserockz"]
CODEOWNERS = ["@jesserockz", "@sebydocky"]
DEPENDENCIES = ["i2c"]
MULTI_CONF = True
gp8403_ns = cg.esphome_ns.namespace("gp8403")
GP8403 = gp8403_ns.class_("GP8403", cg.Component, i2c.I2CDevice)
GP8403Component = gp8403_ns.class_("GP8403Component", cg.Component, i2c.I2CDevice)
GP8403Voltage = gp8403_ns.enum("GP8403Voltage")
GP8403Model = gp8403_ns.enum("GP8403Model")
CONF_GP8403_ID = "gp8403_id"
MODELS = {
"GP8403": GP8403Model.GP8403,
"GP8413": GP8403Model.GP8413,
}
VOLTAGES = {
"5V": GP8403Voltage.GP8403_VOLTAGE_5V,
"10V": GP8403Voltage.GP8403_VOLTAGE_10V,
@@ -22,7 +28,8 @@ VOLTAGES = {
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(GP8403),
cv.GenerateID(): cv.declare_id(GP8403Component),
cv.Optional(CONF_MODEL, default="GP8403"): cv.enum(MODELS, upper=True),
cv.Required(CONF_VOLTAGE): cv.enum(VOLTAGES, upper=True),
}
)
@@ -35,5 +42,5 @@ async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
cg.add(var.set_model(config[CONF_MODEL]))
cg.add(var.set_voltage(config[CONF_VOLTAGE]))

View File

@@ -8,16 +8,48 @@ namespace gp8403 {
static const char *const TAG = "gp8403";
static const uint8_t RANGE_REGISTER = 0x01;
static const uint8_t OUTPUT_REGISTER = 0x02;
void GP8403::setup() { this->write_register(RANGE_REGISTER, (uint8_t *) (&this->voltage_), 1); }
const LogString *model_to_string(GP8403Model model) {
switch (model) {
case GP8403Model::GP8403:
return LOG_STR("GP8403");
case GP8403Model::GP8413:
return LOG_STR("GP8413");
}
return LOG_STR("Unknown");
};
void GP8403::dump_config() {
void GP8403Component::setup() { this->write_register(RANGE_REGISTER, (uint8_t *) (&this->voltage_), 1); }
void GP8403Component::dump_config() {
ESP_LOGCONFIG(TAG,
"GP8403:\n"
" Voltage: %dV",
this->voltage_ == GP8403_VOLTAGE_5V ? 5 : 10);
" Voltage: %dV\n"
" Model: %s",
this->voltage_ == GP8403_VOLTAGE_5V ? 5 : 10, LOG_STR_ARG(model_to_string(this->model_)));
LOG_I2C_DEVICE(this);
}
void GP8403Component::write_state(float state, uint8_t channel) {
uint16_t val = 0;
switch (this->model_) {
case GP8403Model::GP8403:
val = ((uint16_t) (4095 * state)) << 4;
break;
case GP8403Model::GP8413:
val = ((uint16_t) (32767 * state)) << 1;
break;
default:
ESP_LOGE(TAG, "Unknown model %s", LOG_STR_ARG(model_to_string(this->model_)));
return;
}
ESP_LOGV(TAG, "Calculated DAC value: %" PRIu16, val);
i2c::ErrorCode err = this->write_register(OUTPUT_REGISTER + (2 * channel), (uint8_t *) &val, 2);
if (err != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Error writing to %s, code %d", LOG_STR_ARG(model_to_string(this->model_)), err);
}
}
} // namespace gp8403
} // namespace esphome

View File

@@ -11,15 +11,24 @@ enum GP8403Voltage {
GP8403_VOLTAGE_10V = 0x11,
};
class GP8403 : public Component, public i2c::I2CDevice {
enum GP8403Model {
GP8403,
GP8413,
};
class GP8403Component : public Component, public i2c::I2CDevice {
public:
void setup() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA; }
void set_model(GP8403Model model) { this->model_ = model; }
void set_voltage(gp8403::GP8403Voltage voltage) { this->voltage_ = voltage; }
void write_state(float state, uint8_t channel);
protected:
GP8403Voltage voltage_;
GP8403Model model_{GP8403Model::GP8403};
};
} // namespace gp8403

View File

@@ -3,7 +3,7 @@ from esphome.components import i2c, output
import esphome.config_validation as cv
from esphome.const import CONF_CHANNEL, CONF_ID
from .. import CONF_GP8403_ID, GP8403, gp8403_ns
from .. import CONF_GP8403_ID, GP8403Component, gp8403_ns
DEPENDENCIES = ["gp8403"]
@@ -14,7 +14,7 @@ GP8403Output = gp8403_ns.class_(
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(GP8403Output),
cv.GenerateID(CONF_GP8403_ID): cv.use_id(GP8403),
cv.GenerateID(CONF_GP8403_ID): cv.use_id(GP8403Component),
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=1),
}
).extend(cv.COMPONENT_SCHEMA)

View File

@@ -7,8 +7,6 @@ namespace gp8403 {
static const char *const TAG = "gp8403.output";
static const uint8_t OUTPUT_REGISTER = 0x02;
void GP8403Output::dump_config() {
ESP_LOGCONFIG(TAG,
"GP8403 Output:\n"
@@ -16,13 +14,7 @@ void GP8403Output::dump_config() {
this->channel_);
}
void GP8403Output::write_state(float state) {
uint16_t value = ((uint16_t) (state * 4095)) << 4;
i2c::ErrorCode err = this->parent_->write_register(OUTPUT_REGISTER + (2 * this->channel_), (uint8_t *) &value, 2);
if (err != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Error writing to GP8403, code %d", err);
}
}
void GP8403Output::write_state(float state) { this->parent_->write_state(state, this->channel_); }
} // namespace gp8403
} // namespace esphome

View File

@@ -8,13 +8,11 @@
namespace esphome {
namespace gp8403 {
class GP8403Output : public Component, public output::FloatOutput, public Parented<GP8403> {
class GP8403Output : public Component, public output::FloatOutput, public Parented<GP8403Component> {
public:
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA - 1; }
void set_channel(uint8_t channel) { this->channel_ = channel; }
void write_state(float state) override;
protected:

View File

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

View File

@@ -34,8 +34,8 @@ void GT911Touchscreen::setup() {
this->interrupt_pin_->digital_write(false);
}
delay(2);
this->reset_pin_->digital_write(true); // wait 50ms after reset
this->set_timeout(50, [this] { this->setup_internal_(); });
this->reset_pin_->digital_write(true); // wait at least T3+T4 ms as per the datasheet
this->set_timeout(5 + 50 + 1, [this] { this->setup_internal_(); });
return;
}
this->setup_internal_();

View File

@@ -10,7 +10,7 @@ namespace haier {
template<typename... Ts> class DisplayOnAction : public Action<Ts...> {
public:
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:
HaierClimateBase *parent_;
@@ -19,7 +19,7 @@ template<typename... Ts> class DisplayOnAction : public Action<Ts...> {
template<typename... Ts> class DisplayOffAction : public Action<Ts...> {
public:
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:
HaierClimateBase *parent_;
@@ -28,7 +28,7 @@ template<typename... Ts> class DisplayOffAction : public Action<Ts...> {
template<typename... Ts> class BeeperOnAction : public Action<Ts...> {
public:
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:
HonClimate *parent_;
@@ -37,7 +37,7 @@ template<typename... Ts> class BeeperOnAction : public Action<Ts...> {
template<typename... Ts> class BeeperOffAction : public Action<Ts...> {
public:
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:
HonClimate *parent_;
@@ -47,7 +47,7 @@ template<typename... Ts> class VerticalAirflowAction : public Action<Ts...> {
public:
VerticalAirflowAction(HonClimate *parent) : parent_(parent) {}
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:
HonClimate *parent_;
@@ -57,7 +57,7 @@ template<typename... Ts> class HorizontalAirflowAction : public Action<Ts...> {
public:
HorizontalAirflowAction(HonClimate *parent) : parent_(parent) {}
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:
HonClimate *parent_;
@@ -66,7 +66,7 @@ template<typename... Ts> class HorizontalAirflowAction : public Action<Ts...> {
template<typename... Ts> class HealthOnAction : public Action<Ts...> {
public:
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:
HaierClimateBase *parent_;
@@ -75,7 +75,7 @@ template<typename... Ts> class HealthOnAction : public Action<Ts...> {
template<typename... Ts> class HealthOffAction : public Action<Ts...> {
public:
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:
HaierClimateBase *parent_;
@@ -84,7 +84,7 @@ template<typename... Ts> class HealthOffAction : public Action<Ts...> {
template<typename... Ts> class StartSelfCleaningAction : public Action<Ts...> {
public:
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:
HonClimate *parent_;
@@ -93,7 +93,7 @@ template<typename... Ts> class StartSelfCleaningAction : public Action<Ts...> {
template<typename... Ts> class StartSteriCleaningAction : public Action<Ts...> {
public:
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:
HonClimate *parent_;
@@ -102,7 +102,7 @@ template<typename... Ts> class StartSteriCleaningAction : public Action<Ts...> {
template<typename... Ts> class PowerOnAction : public Action<Ts...> {
public:
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:
HaierClimateBase *parent_;
@@ -111,7 +111,7 @@ template<typename... Ts> class PowerOnAction : public Action<Ts...> {
template<typename... Ts> class PowerOffAction : public Action<Ts...> {
public:
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:
HaierClimateBase *parent_;
@@ -120,7 +120,7 @@ template<typename... Ts> class PowerOffAction : public Action<Ts...> {
template<typename... Ts> class PowerToggleAction : public Action<Ts...> {
public:
PowerToggleAction(HaierClimateBase *parent) : parent_(parent) {}
void play(Ts... x) { this->parent_->toggle_power(); }
void play(const Ts &...x) { this->parent_->toggle_power(); }
protected:
HaierClimateBase *parent_;

View File

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

View File

@@ -49,7 +49,7 @@ template<typename... Ts> class BrakeAction : public Action<Ts...> {
public:
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_;
};

View File

@@ -113,8 +113,8 @@ class HttpContainer : public Parented<HttpRequestComponent> {
class HttpRequestResponseTrigger : public Trigger<std::shared_ptr<HttpContainer>, std::string &> {
public:
void process(std::shared_ptr<HttpContainer> container, std::string &response_body) {
this->trigger(std::move(container), response_body);
void process(const std::shared_ptr<HttpContainer> &container, std::string &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;
}
void play(Ts... x) override {
void play(const Ts &...x) override {
std::string body;
if (this->body_.has_value()) {
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, username)
void play(Ts... x) override {
void play(const Ts &...x) override {
if (this->md5_url_.has_value()) {
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:
TEMPLATABLE_VALUE(uint8_t, level)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto level = this->level_.value(x...);
this->parent_->set_heater_level(level);
@@ -52,7 +52,7 @@ template<typename... Ts> class SetHeaterAction : public Action<Ts...>, public Pa
public:
TEMPLATABLE_VALUE(bool, status)
void play(Ts... x) override {
void play(const Ts &...x) override {
auto status = this->status_.value(x...);
this->parent_->set_heater(status);

View File

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

View File

@@ -52,11 +52,11 @@ class KeyCollector : public Component {
};
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> {
void play(Ts... x) override { this->parent_->set_enabled(false); }
void play(const Ts &...x) override { this->parent_->set_enabled(false); }
};
} // namespace key_collector

View File

@@ -2,13 +2,18 @@
#include "esphome/core/hal.h"
#include "esphome/components/lcd_base/lcd_display.h"
#include "esphome/components/display/display.h"
namespace esphome {
namespace lcd_gpio {
class GPIOLCDDisplay;
using gpio_lcd_writer_t = display::DisplayWriter<GPIOLCDDisplay>;
class GPIOLCDDisplay : public lcd_base::LCDDisplay {
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 set_data_pins(GPIOPin *d0, GPIOPin *d1, GPIOPin *d2, GPIOPin *d3) {
this->data_pins_[0] = d0;
@@ -43,7 +48,7 @@ class GPIOLCDDisplay : public lcd_base::LCDDisplay {
GPIOPin *rw_pin_{nullptr};
GPIOPin *enable_pin_{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

View File

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

View File

@@ -121,9 +121,9 @@ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = {
};
// 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) {
if (str == entry.str)
if (strcmp(str, entry.str) == 0)
return entry.value;
}
return 0xFF; // Not found
@@ -441,7 +441,7 @@ bool LD2410Component::handle_ack_data_() {
ESP_LOGV(TAG, "Baud rate change");
#ifdef USE_SELECT
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
break;
@@ -626,14 +626,14 @@ void LD2410Component::set_bluetooth(bool enable) {
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);
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->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);
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));
@@ -759,10 +759,10 @@ void LD2410Component::set_light_out_control() {
#endif
#ifdef USE_SELECT
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()) {
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
this->set_config_mode_(true);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -132,9 +132,9 @@ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = {
};
// 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) {
if (str == entry.str) {
if (strcmp(str, entry.str) == 0) {
return entry.value;
}
}
@@ -485,7 +485,7 @@ bool LD2412Component::handle_ack_data_() {
ESP_LOGV(TAG, "Baud rate change");
#ifdef USE_SELECT
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
break;
@@ -699,14 +699,14 @@ void LD2412Component::set_bluetooth(bool enable) {
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);
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->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);
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));
@@ -783,7 +783,7 @@ void LD2412Component::set_basic_config() {
1, TOTAL_GATES, DEFAULT_PRESENCE_TIMEOUT, 0,
#endif
#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
0x01, // Default value if not using select
#endif
@@ -837,7 +837,7 @@ void LD2412Component::set_light_out_control() {
#endif
#ifdef USE_SELECT
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
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 restart_and_read_all_info();
void set_bluetooth(bool enable);
void set_distance_resolution(const std::string &state);
void set_baud_rate(const std::string &state);
void set_distance_resolution(const char *state);
void set_baud_rate(const char *state);
void factory_reset();
void start_dynamic_background_correction();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ class LightOutControlSelect : public select::Select, public Parented<LD2412Compo
LightOutControlSelect() = default;
protected:
void control(const std::string &value) override;
void control(size_t index) override;
};
} // 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 ENERGY_SENSOR_START = 9;
static const uint8_t CALIBRATE_REPORT_INTERVAL = 4;
static const std::string OP_NORMAL_MODE_STRING = "Normal";
static const std::string OP_SIMPLE_MODE_STRING = "Simple";
static const char *const OP_NORMAL_MODE_STRING = "Normal";
static const char *const OP_SIMPLE_MODE_STRING = "Simple";
// Memory-efficient lookup tables
struct StringToUint8 {
@@ -379,7 +379,7 @@ void LD2420Component::report_gate_data() {
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 (ld2420::get_firmware_int(firmware_ver_) >= CALIBRATE_VERSION_MIN) {
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);
void report_gate_data();
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 update_radar_data(uint16_t const *gate_energy, uint8_t sample_number);
uint8_t set_config_mode(bool enable);

View File

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

View File

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

View File

@@ -380,7 +380,7 @@ void LD2450Component::read_all_info() {
this->set_config_mode_(false);
#ifdef USE_SELECT
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->publish_zone_type();
@@ -635,7 +635,7 @@ bool LD2450Component::handle_ack_data_() {
ESP_LOGV(TAG, "Baud rate change");
#ifdef USE_SELECT
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
break;
@@ -716,7 +716,7 @@ bool LD2450Component::handle_ack_data_() {
this->publish_zone_type();
#ifdef USE_SELECT
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
if (this->buffer_data_[10] == 0x00) {
@@ -790,7 +790,7 @@ void LD2450Component::set_bluetooth(bool enable) {
}
// 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);
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));
@@ -798,8 +798,8 @@ void LD2450Component::set_baud_rate(const std::string &state) {
}
// Set Zone Type - one of: Disabled, Detection, Filter
void LD2450Component::set_zone_type(const std::string &state) {
ESP_LOGV(TAG, "Set zone type: %s", state.c_str());
void LD2450Component::set_zone_type(const char *state) {
ESP_LOGV(TAG, "Set zone type: %s", state);
uint8_t zone_type = find_uint8(ZONE_TYPE_BY_STR, state);
this->zone_type_ = zone_type;
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 set_bluetooth(bool enable);
void set_multi_target(bool enable);
void set_baud_rate(const std::string &state);
void set_zone_type(const std::string &state);
void set_baud_rate(const char *state);
void set_zone_type(const char *state);
void publish_zone_type();
void factory_reset();
#ifdef USE_TEXT_SENSOR

View File

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

View File

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

View File

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

View File

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

View File

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

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