Merge branch 'pr/balrog-kun/1004' into dev

This commit is contained in:
Guillermo Ruffino 2020-06-28 19:36:04 -03:00
commit c99b2b59c2
28 changed files with 121 additions and 109 deletions

View file

@ -29,6 +29,7 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
template<typename T> void add_variable(std::string key, T value) { template<typename T> void add_variable(std::string key, T value) {
this->variables_.push_back(TemplatableKeyValuePair<Ts...>(key, value)); this->variables_.push_back(TemplatableKeyValuePair<Ts...>(key, value));
} }
void play(Ts... x) override { void play(Ts... x) override {
HomeassistantServiceResponse resp; HomeassistantServiceResponse resp;
resp.service = this->service_.value(x...); resp.service = this->service_.value(x...);

View file

@ -137,6 +137,7 @@ template<typename... Ts> class BinarySensorPublishAction : public Action<Ts...>
public: public:
explicit BinarySensorPublishAction(BinarySensor *sensor) : sensor_(sensor) {} explicit BinarySensorPublishAction(BinarySensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(bool, state) TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override { void play(Ts... x) override {
auto val = this->state_.value(x...); auto val = this->state_.value(x...);
this->sensor_->publish_state(val); this->sensor_->publish_state(val);

View file

@ -41,6 +41,10 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
public: public:
explicit ControlAction(Cover *cover) : cover_(cover) {} explicit ControlAction(Cover *cover) : cover_(cover) {}
TEMPLATABLE_VALUE(bool, stop)
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
void play(Ts... x) override { void play(Ts... x) override {
auto call = this->cover_->make_call(); auto call = this->cover_->make_call();
if (this->stop_.has_value()) if (this->stop_.has_value())
@ -52,10 +56,6 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
call.perform(); call.perform();
} }
TEMPLATABLE_VALUE(bool, stop)
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
protected: protected:
Cover *cover_; Cover *cover_;
}; };
@ -63,6 +63,10 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
template<typename... Ts> class CoverPublishAction : public Action<Ts...> { template<typename... Ts> class CoverPublishAction : public Action<Ts...> {
public: public:
CoverPublishAction(Cover *cover) : cover_(cover) {} CoverPublishAction(Cover *cover) : cover_(cover) {}
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
TEMPLATABLE_VALUE(CoverOperation, current_operation)
void play(Ts... x) override { void play(Ts... x) override {
if (this->position_.has_value()) if (this->position_.has_value())
this->cover_->position = this->position_.value(x...); this->cover_->position = this->position_.value(x...);
@ -73,10 +77,6 @@ template<typename... Ts> class CoverPublishAction : public Action<Ts...> {
this->cover_->publish_state(); this->cover_->publish_state();
} }
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
TEMPLATABLE_VALUE(CoverOperation, current_operation)
protected: protected:
Cover *cover_; Cover *cover_;
}; };

View file

@ -104,7 +104,6 @@ class DFPlayer : public uart::UARTDevice, public Component {
#define DFPLAYER_SIMPLE_ACTION(ACTION_CLASS, ACTION_METHOD) \ #define DFPLAYER_SIMPLE_ACTION(ACTION_CLASS, ACTION_METHOD) \
template<typename... Ts> class ACTION_CLASS : public Action<Ts...>, public Parented<DFPlayer> { \ template<typename... Ts> class ACTION_CLASS : public Action<Ts...>, public Parented<DFPlayer> { \
public: \
void play(Ts... x) override { this->parent_->ACTION_METHOD(); } \ void play(Ts... x) override { this->parent_->ACTION_METHOD(); } \
}; };
@ -115,6 +114,7 @@ template<typename... Ts> class PlayFileAction : public Action<Ts...>, public Par
public: public:
TEMPLATABLE_VALUE(uint16_t, file) TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(boolean, loop) TEMPLATABLE_VALUE(boolean, loop)
void play(Ts... x) override { void play(Ts... x) override {
auto file = this->file_.value(x...); auto file = this->file_.value(x...);
auto loop = this->loop_.value(x...); auto loop = this->loop_.value(x...);
@ -131,6 +131,7 @@ template<typename... Ts> class PlayFolderAction : public Action<Ts...>, public P
TEMPLATABLE_VALUE(uint16_t, folder) TEMPLATABLE_VALUE(uint16_t, folder)
TEMPLATABLE_VALUE(uint16_t, file) TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(boolean, loop) TEMPLATABLE_VALUE(boolean, loop)
void play(Ts... x) override { void play(Ts... x) override {
auto folder = this->folder_.value(x...); auto folder = this->folder_.value(x...);
auto file = this->file_.value(x...); auto file = this->file_.value(x...);
@ -146,6 +147,7 @@ template<typename... Ts> class PlayFolderAction : public Action<Ts...>, public P
template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Parented<DFPlayer> { template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Parented<DFPlayer> {
public: public:
TEMPLATABLE_VALUE(Device, device) TEMPLATABLE_VALUE(Device, device)
void play(Ts... x) override { void play(Ts... x) override {
auto device = this->device_.value(x...); auto device = this->device_.value(x...);
this->parent_->set_device(device); this->parent_->set_device(device);
@ -155,6 +157,7 @@ template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Pa
template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Parented<DFPlayer> { template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Parented<DFPlayer> {
public: public:
TEMPLATABLE_VALUE(uint8_t, volume) TEMPLATABLE_VALUE(uint8_t, volume)
void play(Ts... x) override { void play(Ts... x) override {
auto volume = this->volume_.value(x...); auto volume = this->volume_.value(x...);
this->parent_->set_volume(volume); this->parent_->set_volume(volume);
@ -164,6 +167,7 @@ template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Pa
template<typename... Ts> class SetEqAction : public Action<Ts...>, public Parented<DFPlayer> { template<typename... Ts> class SetEqAction : public Action<Ts...>, public Parented<DFPlayer> {
public: public:
TEMPLATABLE_VALUE(EqPreset, eq) TEMPLATABLE_VALUE(EqPreset, eq)
void play(Ts... x) override { void play(Ts... x) override {
auto eq = this->eq_.value(x...); auto eq = this->eq_.value(x...);
this->parent_->set_eq(eq); this->parent_->set_eq(eq);

View file

@ -391,6 +391,7 @@ class Image {
template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> { template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
public: public:
TEMPLATABLE_VALUE(DisplayPage *, page) TEMPLATABLE_VALUE(DisplayPage *, page)
void play(Ts... x) override { void play(Ts... x) override {
auto *page = this->page_.value(x...); auto *page = this->page_.value(x...);
if (page != nullptr) { if (page != nullptr) {
@ -402,18 +403,18 @@ template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
template<typename... Ts> class DisplayPageShowNextAction : public Action<Ts...> { template<typename... Ts> class DisplayPageShowNextAction : public Action<Ts...> {
public: public:
DisplayPageShowNextAction(DisplayBuffer *buffer) : buffer_(buffer) {} DisplayPageShowNextAction(DisplayBuffer *buffer) : buffer_(buffer) {}
void play(Ts... x) override { this->buffer_->show_next_page(); } void play(Ts... x) override { this->buffer_->show_next_page(); }
protected:
DisplayBuffer *buffer_; DisplayBuffer *buffer_;
}; };
template<typename... Ts> class DisplayPageShowPrevAction : public Action<Ts...> { template<typename... Ts> class DisplayPageShowPrevAction : public Action<Ts...> {
public: public:
DisplayPageShowPrevAction(DisplayBuffer *buffer) : buffer_(buffer) {} DisplayPageShowPrevAction(DisplayBuffer *buffer) : buffer_(buffer) {}
void play(Ts... x) override { this->buffer_->show_prev_page(); } void play(Ts... x) override { this->buffer_->show_prev_page(); }
protected:
DisplayBuffer *buffer_; DisplayBuffer *buffer_;
}; };

View file

@ -43,7 +43,6 @@ template<typename... Ts> class SetFrequencyAction : public Action<Ts...> {
this->parent_->update_frequency(freq); this->parent_->update_frequency(freq);
} }
protected:
ESP8266PWM *parent_; ESP8266PWM *parent_;
}; };

View file

@ -25,7 +25,6 @@ template<typename... Ts> class TurnOnAction : public Action<Ts...> {
call.perform(); call.perform();
} }
protected:
FanState *state_; FanState *state_;
}; };
@ -35,7 +34,6 @@ template<typename... Ts> class TurnOffAction : public Action<Ts...> {
void play(Ts... x) override { this->state_->turn_off().perform(); } void play(Ts... x) override { this->state_->turn_off().perform(); }
protected:
FanState *state_; FanState *state_;
}; };
@ -45,7 +43,6 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
void play(Ts... x) override { this->state_->toggle().perform(); } void play(Ts... x) override { this->state_->toggle().perform(); }
protected:
FanState *state_; FanState *state_;
}; };

View file

@ -37,6 +37,7 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice {
template<typename... Ts> class MHZ19CalibrateZeroAction : public Action<Ts...> { template<typename... Ts> class MHZ19CalibrateZeroAction : public Action<Ts...> {
public: public:
MHZ19CalibrateZeroAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} MHZ19CalibrateZeroAction(MHZ19Component *mhz19) : mhz19_(mhz19) {}
void play(Ts... x) override { this->mhz19_->calibrate_zero(); } void play(Ts... x) override { this->mhz19_->calibrate_zero(); }
protected: protected:
@ -46,6 +47,7 @@ template<typename... Ts> class MHZ19CalibrateZeroAction : public Action<Ts...> {
template<typename... Ts> class MHZ19ABCEnableAction : public Action<Ts...> { template<typename... Ts> class MHZ19ABCEnableAction : public Action<Ts...> {
public: public:
MHZ19ABCEnableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} MHZ19ABCEnableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {}
void play(Ts... x) override { this->mhz19_->abc_enable(); } void play(Ts... x) override { this->mhz19_->abc_enable(); }
protected: protected:
@ -55,6 +57,7 @@ template<typename... Ts> class MHZ19ABCEnableAction : public Action<Ts...> {
template<typename... Ts> class MHZ19ABCDisableAction : public Action<Ts...> { template<typename... Ts> class MHZ19ABCDisableAction : public Action<Ts...> {
public: public:
MHZ19ABCDisableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} MHZ19ABCDisableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {}
void play(Ts... x) override { this->mhz19_->abc_disable(); } void play(Ts... x) override { this->mhz19_->abc_disable(); }
protected: protected:

View file

@ -316,6 +316,7 @@ template<typename... Ts> class MQTTPublishJsonAction : public Action<Ts...> {
TEMPLATABLE_VALUE(bool, retain) TEMPLATABLE_VALUE(bool, retain)
void set_payload(std::function<void(Ts..., JsonObject &)> payload) { this->payload_ = payload; } void set_payload(std::function<void(Ts..., JsonObject &)> payload) { this->payload_ = payload; }
void play(Ts... x) override { void play(Ts... x) override {
auto f = std::bind(&MQTTPublishJsonAction<Ts...>::encode_, this, x..., std::placeholders::_1); auto f = std::bind(&MQTTPublishJsonAction<Ts...>::encode_, this, x..., std::placeholders::_1);
auto topic = this->topic_.value(x...); auto topic = this->topic_.value(x...);

View file

@ -33,6 +33,7 @@ template<typename... Ts> class SetLevelAction : public Action<Ts...> {
SetLevelAction(FloatOutput *output) : output_(output) {} SetLevelAction(FloatOutput *output) : output_(output) {}
TEMPLATABLE_VALUE(float, level) TEMPLATABLE_VALUE(float, level)
void play(Ts... x) override { this->output_->set_level(this->level_.value(x...)); } void play(Ts... x) override { this->output_->set_level(this->level_.value(x...)); }
protected: protected:

View file

@ -71,6 +71,10 @@ template<typename... Ts> class PIDAutotuneAction : public Action<Ts...> {
public: public:
PIDAutotuneAction(PIDClimate *parent) : parent_(parent) {} PIDAutotuneAction(PIDClimate *parent) : parent_(parent) {}
void set_noiseband(float noiseband) { noiseband_ = noiseband; }
void set_positive_output(float positive_output) { positive_output_ = positive_output; }
void set_negative_output(float negative_output) { negative_output_ = negative_output; }
void play(Ts... x) { void play(Ts... x) {
auto tuner = make_unique<PIDAutotuner>(); auto tuner = make_unique<PIDAutotuner>();
tuner->set_noiseband(this->noiseband_); tuner->set_noiseband(this->noiseband_);
@ -79,10 +83,6 @@ template<typename... Ts> class PIDAutotuneAction : public Action<Ts...> {
this->parent_->start_autotune(std::move(tuner)); this->parent_->start_autotune(std::move(tuner));
} }
void set_noiseband(float noiseband) { noiseband_ = noiseband; }
void set_positive_output(float positive_output) { positive_output_ = positive_output; }
void set_negative_output(float negative_output) { negative_output_ = negative_output; }
protected: protected:
float noiseband_; float noiseband_;
float positive_output_; float positive_output_;

View file

@ -23,6 +23,7 @@ DECLARE_REMOTE_PROTOCOL(JVC)
template<typename... Ts> class JVCAction : public RemoteTransmitterActionBase<Ts...> { template<typename... Ts> class JVCAction : public RemoteTransmitterActionBase<Ts...> {
public: public:
TEMPLATABLE_VALUE(uint32_t, data) TEMPLATABLE_VALUE(uint32_t, data)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
JVCData data{}; JVCData data{};
data.data = this->data_.value(x...); data.data = this->data_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class LGAction : public RemoteTransmitterActionBase<Ts.
public: public:
TEMPLATABLE_VALUE(uint32_t, data) TEMPLATABLE_VALUE(uint32_t, data)
TEMPLATABLE_VALUE(uint8_t, nbits) TEMPLATABLE_VALUE(uint8_t, nbits)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
LGData data{}; LGData data{};
data.data = this->data_.value(x...); data.data = this->data_.value(x...);

View file

@ -25,6 +25,7 @@ template<typename... Ts> class NECAction : public RemoteTransmitterActionBase<Ts
public: public:
TEMPLATABLE_VALUE(uint16_t, address) TEMPLATABLE_VALUE(uint16_t, address)
TEMPLATABLE_VALUE(uint16_t, command) TEMPLATABLE_VALUE(uint16_t, command)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
NECData data{}; NECData data{};
data.address = this->address_.value(x...); data.address = this->address_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class PanasonicAction : public RemoteTransmitterActionB
public: public:
TEMPLATABLE_VALUE(uint16_t, address) TEMPLATABLE_VALUE(uint16_t, address)
TEMPLATABLE_VALUE(uint32_t, command) TEMPLATABLE_VALUE(uint32_t, command)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
PanasonicData data{}; PanasonicData data{};
data.address = this->address_.value(x...); data.address = this->address_.value(x...);

View file

@ -25,6 +25,7 @@ template<typename... Ts> class PioneerAction : public RemoteTransmitterActionBas
public: public:
TEMPLATABLE_VALUE(uint16_t, rc_code_1) TEMPLATABLE_VALUE(uint16_t, rc_code_1)
TEMPLATABLE_VALUE(uint16_t, rc_code_2) TEMPLATABLE_VALUE(uint16_t, rc_code_2)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
PioneerData data{}; PioneerData data{};
data.rc_code_1 = this->rc_code_1_.value(x...); data.rc_code_1 = this->rc_code_1_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class RC5Action : public RemoteTransmitterActionBase<Ts
public: public:
TEMPLATABLE_VALUE(uint8_t, address) TEMPLATABLE_VALUE(uint8_t, address)
TEMPLATABLE_VALUE(uint8_t, command) TEMPLATABLE_VALUE(uint8_t, command)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
RC5Data data{}; RC5Data data{};
data.address = this->address_.value(x...); data.address = this->address_.value(x...);

View file

@ -323,6 +323,9 @@ template<typename... Ts> class RemoteTransmitterActionBase : public Action<Ts...
public: public:
void set_parent(RemoteTransmitterBase *parent) { this->parent_ = parent; } void set_parent(RemoteTransmitterBase *parent) { this->parent_ = parent; }
TEMPLATABLE_VALUE(uint32_t, send_times);
TEMPLATABLE_VALUE(uint32_t, send_wait);
void play(Ts... x) override { void play(Ts... x) override {
auto call = this->parent_->transmit(); auto call = this->parent_->transmit();
this->encode(call.get_data(), x...); this->encode(call.get_data(), x...);
@ -331,12 +334,9 @@ template<typename... Ts> class RemoteTransmitterActionBase : public Action<Ts...
call.perform(); call.perform();
} }
protected:
virtual void encode(RemoteTransmitData *dst, Ts... x) = 0; virtual void encode(RemoteTransmitData *dst, Ts... x) = 0;
TEMPLATABLE_VALUE(uint32_t, send_times);
TEMPLATABLE_VALUE(uint32_t, send_wait);
protected:
RemoteTransmitterBase *parent_{}; RemoteTransmitterBase *parent_{};
}; };

View file

@ -24,6 +24,7 @@ DECLARE_REMOTE_PROTOCOL(Samsung)
template<typename... Ts> class SamsungAction : public RemoteTransmitterActionBase<Ts...> { template<typename... Ts> class SamsungAction : public RemoteTransmitterActionBase<Ts...> {
public: public:
TEMPLATABLE_VALUE(uint32_t, data) TEMPLATABLE_VALUE(uint32_t, data)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
SamsungData data{}; SamsungData data{};
data.data = this->data_.value(x...); data.data = this->data_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class SonyAction : public RemoteTransmitterActionBase<T
public: public:
TEMPLATABLE_VALUE(uint32_t, data) TEMPLATABLE_VALUE(uint32_t, data)
TEMPLATABLE_VALUE(uint8_t, nbits) TEMPLATABLE_VALUE(uint8_t, nbits)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
SonyData data{}; SonyData data{};
data.data = this->data_.value(x...); data.data = this->data_.value(x...);

View file

@ -74,6 +74,7 @@ template<typename... Ts> class RotaryEncoderSetValueAction : public Action<Ts...
public: public:
RotaryEncoderSetValueAction(RotaryEncoderSensor *encoder) : encoder_(encoder) {} RotaryEncoderSetValueAction(RotaryEncoderSensor *encoder) : encoder_(encoder) {}
TEMPLATABLE_VALUE(int, value) TEMPLATABLE_VALUE(int, value)
void play(Ts... x) override { this->encoder_->set_value(this->value_.value(x...)); } void play(Ts... x) override { this->encoder_->set_value(this->value_.value(x...)); }
protected: protected:

View file

@ -53,41 +53,34 @@ template<typename... Ts> class ScriptWaitAction : public Action<Ts...>, public C
public: public:
ScriptWaitAction(Script *script) : script_(script) {} ScriptWaitAction(Script *script) : script_(script) {}
void play(Ts... x) { /* ignore - see play_complex */
}
void play_complex(Ts... x) override { void play_complex(Ts... x) override {
this->num_running_++;
// Check if we can continue immediately. // Check if we can continue immediately.
if (!this->script_->is_running()) { if (!this->script_->is_running()) {
this->triggered_ = false; this->play_next_(x...);
this->play_next(x...);
return; return;
} }
this->var_ = std::make_tuple(x...); this->var_ = std::make_tuple(x...);
this->triggered_ = true;
this->loop(); this->loop();
} }
void stop() override { this->triggered_ = false; }
void loop() override { void loop() override {
if (!this->triggered_) if (this->num_running_ == 0)
return; return;
if (this->script_->is_running()) if (this->script_->is_running())
return; return;
this->triggered_ = false; this->play_next_tuple_(this->var_);
this->play_next_tuple(this->var_);
} }
float get_setup_priority() const override { return setup_priority::DATA; } float get_setup_priority() const override { return setup_priority::DATA; }
bool is_running() override { return this->triggered_ || this->is_running_next(); } void play(Ts... x) override { /* ignore - see play_complex */
}
protected: protected:
Script *script_; Script *script_;
bool triggered_{false};
std::tuple<Ts...> var_{}; std::tuple<Ts...> var_{};
}; };

View file

@ -25,6 +25,7 @@ template<typename... Ts> class SensorPublishAction : public Action<Ts...> {
public: public:
SensorPublishAction(Sensor *sensor) : sensor_(sensor) {} SensorPublishAction(Sensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(float, state) TEMPLATABLE_VALUE(float, state)
void play(Ts... x) override { this->sensor_->publish_state(this->state_.value(x...)); } void play(Ts... x) override { this->sensor_->publish_state(this->state_.value(x...)); }
protected: protected:

View file

@ -64,6 +64,7 @@ template<typename... Ts> class ServoWriteAction : public Action<Ts...> {
public: public:
ServoWriteAction(Servo *servo) : servo_(servo) {} ServoWriteAction(Servo *servo) : servo_(servo) {}
TEMPLATABLE_VALUE(float, value) TEMPLATABLE_VALUE(float, value)
void play(Ts... x) override { this->servo_->write(this->value_.value(x...)); } void play(Ts... x) override { this->servo_->write(this->value_.value(x...)); }
protected: protected:
@ -73,6 +74,7 @@ template<typename... Ts> class ServoWriteAction : public Action<Ts...> {
template<typename... Ts> class ServoDetachAction : public Action<Ts...> { template<typename... Ts> class ServoDetachAction : public Action<Ts...> {
public: public:
ServoDetachAction(Servo *servo) : servo_(servo) {} ServoDetachAction(Servo *servo) : servo_(servo) {}
void play(Ts... x) override { this->servo_->detach(); } void play(Ts... x) override { this->servo_->detach(); }
protected: protected:

View file

@ -73,6 +73,7 @@ template<typename... Ts> class SwitchPublishAction : public Action<Ts...> {
public: public:
SwitchPublishAction(Switch *a_switch) : switch_(a_switch) {} SwitchPublishAction(Switch *a_switch) : switch_(a_switch) {}
TEMPLATABLE_VALUE(bool, state) TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override { this->switch_->publish_state(this->state_.value(x...)); } void play(Ts... x) override { this->switch_->publish_state(this->state_.value(x...)); }
protected: protected:

View file

@ -30,6 +30,7 @@ template<typename... Ts> class TextSensorPublishAction : public Action<Ts...> {
public: public:
TextSensorPublishAction(TextSensor *sensor) : sensor_(sensor) {} TextSensorPublishAction(TextSensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(std::string, state) TEMPLATABLE_VALUE(std::string, state)
void play(Ts... x) override { this->sensor_->publish_state(this->state_.value(x...)); } void play(Ts... x) override { this->sensor_->publish_state(this->state_.value(x...)); }
protected: protected:

View file

@ -75,45 +75,55 @@ template<typename... Ts> class ActionList;
template<typename... Ts> class Action { template<typename... Ts> class Action {
public: public:
virtual void play(Ts... x) = 0;
virtual void play_complex(Ts... x) { virtual void play_complex(Ts... x) {
this->num_running_++;
this->play(x...); this->play(x...);
this->play_next(x...); this->play_next_(x...);
} }
void play_next(Ts... x) { virtual void stop_complex() {
if (this->next_ != nullptr) { if (num_running_) {
this->next_->play_complex(x...); this->stop();
this->num_running_ = 0;
}
this->stop_next_();
}
virtual bool is_running() { return this->num_running_ > 0 || this->is_running_next_(); }
protected:
friend ActionList<Ts...>;
virtual void play(Ts... x) = 0;
void play_next_(Ts... x) {
if (this->num_running_ > 0) {
this->num_running_--;
if (this->next_ != nullptr) {
this->next_->play_complex(x...);
}
} }
} }
virtual void stop() {} template<int... S> void play_next_tuple_(const std::tuple<Ts...> &tuple, seq<S...>) {
virtual void stop_complex() { this->play_next_(std::get<S>(tuple)...);
this->stop();
this->stop_next();
} }
void stop_next() { void play_next_tuple_(const std::tuple<Ts...> &tuple) {
this->play_next_tuple_(tuple, typename gens<sizeof...(Ts)>::type());
}
virtual void stop() {}
void stop_next_() {
if (this->next_ != nullptr) { if (this->next_ != nullptr) {
this->next_->stop_complex(); this->next_->stop_complex();
} }
} }
virtual bool is_running() { return this->is_running_next(); }
bool is_running_next() { bool is_running_next_() {
if (this->next_ == nullptr) if (this->next_ == nullptr)
return false; return false;
return this->next_->is_running(); return this->next_->is_running();
} }
void play_next_tuple(const std::tuple<Ts...> &tuple) {
this->play_next_tuple_(tuple, typename gens<sizeof...(Ts)>::type());
}
protected:
friend ActionList<Ts...>;
template<int... S> void play_next_tuple_(const std::tuple<Ts...> &tuple, seq<S...>) {
this->play_next(std::get<S>(tuple)...);
}
Action<Ts...> *next_ = nullptr; Action<Ts...> *next_ = nullptr;
int num_running_{0};
}; };
template<typename... Ts> class ActionList { template<typename... Ts> class ActionList {

View file

@ -108,34 +108,23 @@ template<typename... Ts> class DelayAction : public Action<Ts...>, public Compon
TEMPLATABLE_VALUE(uint32_t, delay) TEMPLATABLE_VALUE(uint32_t, delay)
void stop() override {
this->cancel_timeout("");
this->num_running_ = 0;
}
void play(Ts... x) override { /* ignore - see play_complex */
}
void play_complex(Ts... x) override { void play_complex(Ts... x) override {
auto f = std::bind(&DelayAction<Ts...>::delay_end_, this, x...); auto f = std::bind(&DelayAction<Ts...>::play_next_, this, x...);
this->num_running_++; this->num_running_++;
this->set_timeout(this->delay_.value(x...), f); this->set_timeout(this->delay_.value(x...), f);
} }
float get_setup_priority() const override { return setup_priority::HARDWARE; } float get_setup_priority() const override { return setup_priority::HARDWARE; }
bool is_running() override { return this->num_running_ > 0 || this->is_running_next(); } void play(Ts... x) override { /* ignore - see play_complex */
protected:
void delay_end_(Ts... x) {
this->num_running_--;
this->play_next(x...);
} }
int num_running_{0};
void stop() override { this->cancel_timeout(""); }
}; };
template<typename... Ts> class LambdaAction : public Action<Ts...> { template<typename... Ts> class LambdaAction : public Action<Ts...> {
public: public:
explicit LambdaAction(std::function<void(Ts...)> &&f) : f_(std::move(f)) {} explicit LambdaAction(std::function<void(Ts...)> &&f) : f_(std::move(f)) {}
void play(Ts... x) override { this->f_(x...); } void play(Ts... x) override { this->f_(x...); }
protected: protected:
@ -148,41 +137,40 @@ template<typename... Ts> class IfAction : public Action<Ts...> {
void add_then(const std::vector<Action<Ts...> *> &actions) { void add_then(const std::vector<Action<Ts...> *> &actions) {
this->then_.add_actions(actions); this->then_.add_actions(actions);
this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next(x...); })); this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next_(x...); }));
} }
void add_else(const std::vector<Action<Ts...> *> &actions) { void add_else(const std::vector<Action<Ts...> *> &actions) {
this->else_.add_actions(actions); this->else_.add_actions(actions);
this->else_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next(x...); })); this->else_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next_(x...); }));
}
void play(Ts... x) override { /* ignore - see play_complex */
} }
void play_complex(Ts... x) override { void play_complex(Ts... x) override {
this->num_running_++;
bool res = this->condition_->check(x...); bool res = this->condition_->check(x...);
if (res) { if (res) {
if (this->then_.empty()) { if (this->then_.empty()) {
this->play_next(x...); this->play_next_(x...);
} else { } else if (this->num_running_ > 0) {
this->then_.play(x...); this->then_.play(x...);
} }
} else { } else {
if (this->else_.empty()) { if (this->else_.empty()) {
this->play_next(x...); this->play_next_(x...);
} else { } else if (this->num_running_ > 0) {
this->else_.play(x...); this->else_.play(x...);
} }
} }
} }
void play(Ts... x) override { /* ignore - see play_complex */
}
void stop() override { void stop() override {
this->then_.stop(); this->then_.stop();
this->else_.stop(); this->else_.stop();
} }
bool is_running() override { return this->then_.is_running() || this->else_.is_running() || this->is_running_next(); }
protected: protected:
Condition<Ts...> *condition_; Condition<Ts...> *condition_;
ActionList<Ts...> then_; ActionList<Ts...> then_;
@ -196,37 +184,40 @@ template<typename... Ts> class WhileAction : public Action<Ts...> {
void add_then(const std::vector<Action<Ts...> *> &actions) { void add_then(const std::vector<Action<Ts...> *> &actions) {
this->then_.add_actions(actions); this->then_.add_actions(actions);
this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) {
if (this->condition_->check_tuple(this->var_)) { if (this->num_running_ > 0 && this->condition_->check_tuple(this->var_)) {
// play again // play again
this->then_.play_tuple(this->var_); if (this->num_running_ > 0) {
this->then_.play_tuple(this->var_);
}
} else { } else {
// condition false, play next // condition false, play next
this->play_next_tuple(this->var_); this->play_next_tuple_(this->var_);
} }
})); }));
} }
void play(Ts... x) override { /* ignore - see play_complex */
}
void play_complex(Ts... x) override { void play_complex(Ts... x) override {
this->num_running_++;
// Store loop parameters // Store loop parameters
this->var_ = std::make_tuple(x...); this->var_ = std::make_tuple(x...);
// Initial condition check // Initial condition check
if (!this->condition_->check_tuple(this->var_)) { if (!this->condition_->check_tuple(this->var_)) {
// If new condition check failed, stop loop if running // If new condition check failed, stop loop if running
this->then_.stop(); this->then_.stop();
this->play_next_tuple(this->var_); this->play_next_tuple_(this->var_);
return; return;
} }
this->then_.play_tuple(this->var_); if (this->num_running_ > 0) {
this->then_.play_tuple(this->var_);
}
}
void play(Ts... x) override { /* ignore - see play_complex */
} }
void stop() override { this->then_.stop(); } void stop() override { this->then_.stop(); }
bool is_running() override { return this->then_.is_running() || this->is_running_next(); }
protected: protected:
Condition<Ts...> *condition_; Condition<Ts...> *condition_;
ActionList<Ts...> then_; ActionList<Ts...> then_;
@ -237,48 +228,44 @@ template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Co
public: public:
WaitUntilAction(Condition<Ts...> *condition) : condition_(condition) {} WaitUntilAction(Condition<Ts...> *condition) : condition_(condition) {}
void play(Ts... x) { /* ignore - see play_complex */
}
void play_complex(Ts... x) override { void play_complex(Ts... x) override {
this->num_running_++;
// Check if we can continue immediately. // Check if we can continue immediately.
if (this->condition_->check(x...)) { if (this->condition_->check(x...)) {
this->triggered_ = false; if (this->num_running_ > 0) {
this->play_next(x...); this->play_next_(x...);
}
return; return;
} }
this->var_ = std::make_tuple(x...); this->var_ = std::make_tuple(x...);
this->triggered_ = true;
this->loop(); this->loop();
} }
void stop() override { this->triggered_ = false; }
void loop() override { void loop() override {
if (!this->triggered_) if (this->num_running_ == 0)
return; return;
if (!this->condition_->check_tuple(this->var_)) { if (!this->condition_->check_tuple(this->var_)) {
return; return;
} }
this->triggered_ = false; this->play_next_tuple_(this->var_);
this->play_next_tuple(this->var_);
} }
float get_setup_priority() const override { return setup_priority::DATA; } float get_setup_priority() const override { return setup_priority::DATA; }
bool is_running() override { return this->triggered_ || this->is_running_next(); } void play(Ts... x) override { /* ignore - see play_complex */
}
protected: protected:
Condition<Ts...> *condition_; Condition<Ts...> *condition_;
bool triggered_{false};
std::tuple<Ts...> var_{}; std::tuple<Ts...> var_{};
}; };
template<typename... Ts> class UpdateComponentAction : public Action<Ts...> { template<typename... Ts> class UpdateComponentAction : public Action<Ts...> {
public: public:
UpdateComponentAction(PollingComponent *component) : component_(component) {} UpdateComponentAction(PollingComponent *component) : component_(component) {}
void play(Ts... x) override { this->component_->update(); } void play(Ts... x) override { this->component_->update(); }
protected: protected: