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) {
this->variables_.push_back(TemplatableKeyValuePair<Ts...>(key, value));
}
void play(Ts... x) override {
HomeassistantServiceResponse resp;
resp.service = this->service_.value(x...);

View File

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

View File

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

View File

@ -104,7 +104,6 @@ class DFPlayer : public uart::UARTDevice, public Component {
#define DFPLAYER_SIMPLE_ACTION(ACTION_CLASS, ACTION_METHOD) \
template<typename... Ts> class ACTION_CLASS : public Action<Ts...>, public Parented<DFPlayer> { \
public: \
void play(Ts... x) override { this->parent_->ACTION_METHOD(); } \
};
@ -115,6 +114,7 @@ template<typename... Ts> class PlayFileAction : public Action<Ts...>, public Par
public:
TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(boolean, loop)
void play(Ts... x) override {
auto file = this->file_.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, file)
TEMPLATABLE_VALUE(boolean, loop)
void play(Ts... x) override {
auto folder = this->folder_.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> {
public:
TEMPLATABLE_VALUE(Device, device)
void play(Ts... x) override {
auto device = this->device_.value(x...);
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> {
public:
TEMPLATABLE_VALUE(uint8_t, volume)
void play(Ts... x) override {
auto volume = this->volume_.value(x...);
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> {
public:
TEMPLATABLE_VALUE(EqPreset, eq)
void play(Ts... x) override {
auto eq = this->eq_.value(x...);
this->parent_->set_eq(eq);

View File

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

View File

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

View File

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

View File

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

View File

@ -316,6 +316,7 @@ template<typename... Ts> class MQTTPublishJsonAction : public Action<Ts...> {
TEMPLATABLE_VALUE(bool, retain)
void set_payload(std::function<void(Ts..., JsonObject &)> payload) { this->payload_ = payload; }
void play(Ts... x) override {
auto f = std::bind(&MQTTPublishJsonAction<Ts...>::encode_, this, x..., std::placeholders::_1);
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) {}
TEMPLATABLE_VALUE(float, level)
void play(Ts... x) override { this->output_->set_level(this->level_.value(x...)); }
protected:

View File

@ -71,6 +71,10 @@ template<typename... Ts> class PIDAutotuneAction : public Action<Ts...> {
public:
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) {
auto tuner = make_unique<PIDAutotuner>();
tuner->set_noiseband(this->noiseband_);
@ -79,10 +83,6 @@ template<typename... Ts> class PIDAutotuneAction : public Action<Ts...> {
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:
float noiseband_;
float positive_output_;

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@ template<typename... Ts> class PioneerAction : public RemoteTransmitterActionBas
public:
TEMPLATABLE_VALUE(uint16_t, rc_code_1)
TEMPLATABLE_VALUE(uint16_t, rc_code_2)
void encode(RemoteTransmitData *dst, Ts... x) override {
PioneerData data{};
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:
TEMPLATABLE_VALUE(uint8_t, address)
TEMPLATABLE_VALUE(uint8_t, command)
void encode(RemoteTransmitData *dst, Ts... x) override {
RC5Data data{};
data.address = this->address_.value(x...);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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