7 namespace current_based {
9 static const char *
const TAG =
"current_based.cover";
15 traits.set_supports_stop(
true);
16 traits.set_supports_position(
true);
17 traits.set_supports_toggle(
true);
18 traits.set_is_assumed_state(
false);
23 this->direction_idle_();
28 this->publish_state();
41 if (fabsf(this->
position - pos) < 0.01) {
45 this->target_position_ = pos;
46 this->start_direction_(op);
51 auto restore = this->restore_state_();
52 if (restore.has_value()) {
63 const uint32_t now =
millis();
66 if (this->malfunction_detection_ && this->is_closing_()) {
67 this->direction_idle_();
68 this->malfunction_trigger_->trigger();
69 ESP_LOGI(TAG,
"'%s' - Malfunction detected during opening. Current flow detected in close circuit",
71 }
else if (this->is_opening_blocked_()) {
72 ESP_LOGD(TAG,
"'%s' - Obstacle detected during opening.", this->name_.c_str());
73 this->direction_idle_();
74 if (this->obstacle_rollback_ != 0) {
75 this->set_timeout(
"rollback", 300, [
this]() {
76 ESP_LOGD(TAG,
"'%s' - Rollback.", this->name_.c_str());
77 this->target_position_ =
clamp(this->
position - this->obstacle_rollback_, 0.0F, 1.0F);
81 }
else if (this->is_initial_delay_finished_() && !this->is_opening_()) {
82 auto dur = (now - this->start_dir_time_) / 1e3f;
83 ESP_LOGD(TAG,
"'%s' - Open position reached. Took %.1fs.", this->name_.c_str(), dur);
87 if (this->malfunction_detection_ && this->is_opening_()) {
88 this->direction_idle_();
89 this->malfunction_trigger_->trigger();
90 ESP_LOGI(TAG,
"'%s' - Malfunction detected during closing. Current flow detected in open circuit",
92 }
else if (this->is_closing_blocked_()) {
93 ESP_LOGD(TAG,
"'%s' - Obstacle detected during closing.", this->name_.c_str());
94 this->direction_idle_();
95 if (this->obstacle_rollback_ != 0) {
96 this->set_timeout(
"rollback", 300, [
this]() {
97 ESP_LOGD(TAG,
"'%s' - Rollback.", this->name_.c_str());
98 this->target_position_ =
clamp(this->
position + this->obstacle_rollback_, 0.0F, 1.0F);
102 }
else if (this->is_initial_delay_finished_() && !this->is_closing_()) {
103 auto dur = (now - this->start_dir_time_) / 1e3f;
104 ESP_LOGD(TAG,
"'%s' - Close position reached. Took %.1fs.", this->name_.c_str(), dur);
108 if (now - this->start_dir_time_ > this->max_duration_) {
109 ESP_LOGD(TAG,
"'%s' - Max duration reached. Stopping cover.", this->name_.c_str());
110 this->direction_idle_();
114 this->recompute_position_();
117 this->direction_idle_();
122 this->publish_state(
false);
123 this->last_publish_time_ = now;
129 if (new_position != FLT_MAX) {
132 this->publish_state();
136 LOG_COVER(
"",
"Endstop Cover",
this);
137 LOG_SENSOR(
" ",
"Open Sensor", this->open_sensor_);
138 ESP_LOGCONFIG(TAG,
" Open moving current threshold: %.11fA", this->open_moving_current_threshold_);
139 if (this->open_obstacle_current_threshold_ != FLT_MAX) {
140 ESP_LOGCONFIG(TAG,
" Open obstacle current threshold: %.11fA", this->open_obstacle_current_threshold_);
142 ESP_LOGCONFIG(TAG,
" Open Duration: %.1fs", this->open_duration_ / 1e3f);
143 LOG_SENSOR(
" ",
"Close Sensor", this->close_sensor_);
144 ESP_LOGCONFIG(TAG,
" Close moving current threshold: %.11fA", this->close_moving_current_threshold_);
145 if (this->close_obstacle_current_threshold_ != FLT_MAX) {
146 ESP_LOGCONFIG(TAG,
" Close obstacle current threshold: %.11fA", this->close_obstacle_current_threshold_);
148 ESP_LOGCONFIG(TAG,
" Close Duration: %.1fs", this->close_duration_ / 1e3f);
149 ESP_LOGCONFIG(TAG,
"Obstacle Rollback: %.1f%%", this->obstacle_rollback_ * 100);
150 if (this->max_duration_ != UINT32_MAX) {
151 ESP_LOGCONFIG(TAG,
"Maximum duration: %.1fs", this->max_duration_ / 1e3f);
153 ESP_LOGCONFIG(TAG,
"Start sensing delay: %.1fs", this->start_sensing_delay_ / 1e3f);
154 ESP_LOGCONFIG(TAG,
"Malfunction detection: %s", YESNO(this->malfunction_detection_));
159 if (this->prev_command_trigger_ !=
nullptr) {
160 this->prev_command_trigger_->stop_action();
161 this->prev_command_trigger_ =
nullptr;
166 return this->open_sensor_->get_state() > this->open_moving_current_threshold_;
170 if (this->open_obstacle_current_threshold_ == FLT_MAX) {
173 return this->open_sensor_->get_state() > this->open_obstacle_current_threshold_;
177 return this->close_sensor_->get_state() > this->close_moving_current_threshold_;
181 if (this->close_obstacle_current_threshold_ == FLT_MAX) {
184 return this->close_sensor_->get_state() > this->close_obstacle_current_threshold_;
187 return millis() - this->start_dir_time_ > this->start_sensing_delay_;
191 switch (this->current_operation) {
194 if (!this->is_initial_delay_finished_())
196 return !this->is_opening_();
198 return this->
position >= this->target_position_;
201 if (!this->is_initial_delay_finished_())
203 return !this->is_closing_();
205 return this->
position <= this->target_position_;
212 if (dir == this->current_operation)
215 this->recompute_position_();
219 trig = this->stop_trigger_;
222 this->last_operation_ = dir;
223 trig = this->open_trigger_;
226 this->last_operation_ = dir;
227 trig = this->close_trigger_;
233 this->current_operation = dir;
235 this->stop_prev_trigger_();
237 this->prev_command_trigger_ = trig;
239 const auto now =
millis();
240 this->start_dir_time_ = now;
241 this->last_recompute_time_ = now;
249 switch (this->current_operation) {
252 action_dur = this->open_duration_;
256 action_dur = this->close_duration_;
262 const auto now =
millis();
263 this->
position += dir * (now - this->last_recompute_time_) / action_dur;
266 this->last_recompute_time_ = now;
void start_direction_(cover::CoverOperation dir)
void recompute_position_()
const float DATA
For components that import data from directly connected sensors like DHT.
void direction_idle_(float new_position=FLT_MAX)
CoverOperation
Enum encoding the current operation of a cover.
The cover is currently closing.
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
bool is_closing_blocked_() const
uint32_t IRAM_ATTR HOT millis()
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
bool is_initial_delay_finished_() const
bool is_opening_blocked_() const
cover::CoverTraits get_traits() override
bool is_at_target_() const
float get_setup_priority() const override
void dump_config() override
const optional< bool > & get_toggle() const
void stop_prev_trigger_()
Implementation of SPI Controller mode.
The cover is currently opening.
const optional< float > & get_position() const
void control(const cover::CoverCall &call) override