mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-05-24 06:38:29 +02:00
2f07225984
* Move stop/is_running implementation to Action base class Try to fix issue #1105. Until now if an UpdateComponentAction, a LambdaAction, or any action that can contain those inside their "else" or "then" action lists, resulted in a call to script.stop on the script that contains them, the script would continue running, because they didn't implement a stop() method. Basically only the asynchronous ones did: DelayAction, WaitUntilAction and ScriptWaitAction. With this change num_running_ in Action replaces DelayAction::num_running_ and WaitUntilAction::triggered_ to provide the same is_running logic to other actions. * Make some Action methods protected Apparently play()/stop() etc. are not meant to be called directly by users of the class and if they're called directly that would not give the expected result for the classes that have an empty play(). Make all methods except play_complex, stop_comples and is_running protected. While there also make RemoteTransmitterActionBase::encode protected. * lint * format Co-authored-by: Guillermo Ruffino <glm.net@gmail.com>
112 lines
3.0 KiB
C++
112 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include "esphome/core/component.h"
|
|
#include "esphome/core/automation.h"
|
|
#include "esphome/components/sensor/sensor.h"
|
|
|
|
namespace esphome {
|
|
namespace sensor {
|
|
|
|
class SensorStateTrigger : public Trigger<float> {
|
|
public:
|
|
explicit SensorStateTrigger(Sensor *parent) {
|
|
parent->add_on_state_callback([this](float value) { this->trigger(value); });
|
|
}
|
|
};
|
|
|
|
class SensorRawStateTrigger : public Trigger<float> {
|
|
public:
|
|
explicit SensorRawStateTrigger(Sensor *parent) {
|
|
parent->add_on_raw_state_callback([this](float value) { this->trigger(value); });
|
|
}
|
|
};
|
|
|
|
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:
|
|
Sensor *sensor_;
|
|
};
|
|
|
|
class ValueRangeTrigger : public Trigger<float>, public Component {
|
|
public:
|
|
explicit ValueRangeTrigger(Sensor *parent) : parent_(parent) {}
|
|
|
|
template<typename V> void set_min(V min) { this->min_ = min; }
|
|
template<typename V> void set_max(V max) { this->max_ = max; }
|
|
|
|
void setup() override {
|
|
this->rtc_ = global_preferences.make_preference<bool>(this->parent_->get_object_id_hash());
|
|
bool initial_state;
|
|
if (this->rtc_.load(&initial_state)) {
|
|
this->previous_in_range_ = initial_state;
|
|
}
|
|
|
|
this->parent_->add_on_state_callback([this](float state) { this->on_state_(state); });
|
|
}
|
|
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
|
|
|
protected:
|
|
void on_state_(float state) {
|
|
if (isnan(state))
|
|
return;
|
|
|
|
float local_min = this->min_.value(state);
|
|
float local_max = this->max_.value(state);
|
|
|
|
bool in_range;
|
|
if (isnan(local_min) && isnan(local_max)) {
|
|
in_range = this->previous_in_range_;
|
|
} else if (isnan(local_min)) {
|
|
in_range = state <= local_max;
|
|
} else if (isnan(local_max)) {
|
|
in_range = state >= local_min;
|
|
} else {
|
|
in_range = local_min <= state && state <= local_max;
|
|
}
|
|
|
|
if (in_range != this->previous_in_range_ && in_range) {
|
|
this->trigger(state);
|
|
}
|
|
|
|
this->previous_in_range_ = in_range;
|
|
this->rtc_.save(&in_range);
|
|
}
|
|
|
|
Sensor *parent_;
|
|
ESPPreferenceObject rtc_;
|
|
bool previous_in_range_{false};
|
|
TemplatableValue<float, float> min_{NAN};
|
|
TemplatableValue<float, float> max_{NAN};
|
|
};
|
|
|
|
template<typename... Ts> class SensorInRangeCondition : public Condition<Ts...> {
|
|
public:
|
|
SensorInRangeCondition(Sensor *parent) : parent_(parent) {}
|
|
|
|
void set_min(float min) { this->min_ = min; }
|
|
void set_max(float max) { this->max_ = max; }
|
|
bool check(Ts... x) override {
|
|
const float state = this->parent_->state;
|
|
if (isnan(this->min_)) {
|
|
return state <= this->max_;
|
|
} else if (isnan(this->max_)) {
|
|
return state >= this->min_;
|
|
} else {
|
|
return this->min_ <= state && state <= this->max_;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
Sensor *parent_;
|
|
float min_{NAN};
|
|
float max_{NAN};
|
|
};
|
|
|
|
} // namespace sensor
|
|
} // namespace esphome
|