ESPHome 2026.2.3
Loading...
Searching...
No Matches
valve.cpp
Go to the documentation of this file.
1#include "valve.h"
4#include "esphome/core/log.h"
6
7#include <strings.h>
8
9namespace esphome {
10namespace valve {
11
12static const char *const TAG = "valve";
13
14const float VALVE_OPEN = 1.0f;
15const float VALVE_CLOSED = 0.0f;
16
17const LogString *valve_command_to_str(float pos) {
18 if (pos == VALVE_OPEN) {
19 return LOG_STR("OPEN");
20 } else if (pos == VALVE_CLOSED) {
21 return LOG_STR("CLOSE");
22 } else {
23 return LOG_STR("UNKNOWN");
24 }
25}
26// Valve operation strings indexed by ValveOperation enum (0-2): IDLE, OPENING, CLOSING, plus UNKNOWN
27PROGMEM_STRING_TABLE(ValveOperationStrings, "IDLE", "OPENING", "CLOSING", "UNKNOWN");
28
30 return ValveOperationStrings::get_log_str(static_cast<uint8_t>(op), ValveOperationStrings::LAST_INDEX);
31}
32
34
35ValveCall::ValveCall(Valve *parent) : parent_(parent) {}
36ValveCall &ValveCall::set_command(const char *command) {
37 if (ESPHOME_strcasecmp_P(command, ESPHOME_PSTR("OPEN")) == 0) {
38 this->set_command_open();
39 } else if (ESPHOME_strcasecmp_P(command, ESPHOME_PSTR("CLOSE")) == 0) {
40 this->set_command_close();
41 } else if (ESPHOME_strcasecmp_P(command, ESPHOME_PSTR("STOP")) == 0) {
42 this->set_command_stop();
43 } else if (ESPHOME_strcasecmp_P(command, ESPHOME_PSTR("TOGGLE")) == 0) {
44 this->set_command_toggle();
45 } else {
46 ESP_LOGW(TAG, "'%s' - Unrecognized command %s", this->parent_->get_name().c_str(), command);
47 }
48 return *this;
49}
51 this->position_ = VALVE_OPEN;
52 return *this;
53}
55 this->position_ = VALVE_CLOSED;
56 return *this;
57}
59 this->stop_ = true;
60 return *this;
61}
63 this->toggle_ = true;
64 return *this;
65}
67 this->position_ = position;
68 return *this;
69}
71 ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
72 auto traits = this->parent_->get_traits();
73 this->validate_();
74 if (this->stop_) {
75 ESP_LOGD(TAG, " Command: STOP");
76 }
77 if (this->position_.has_value()) {
78 if (traits.get_supports_position()) {
79 ESP_LOGD(TAG, " Position: %.0f%%", *this->position_ * 100.0f);
80 } else {
81 ESP_LOGD(TAG, " Command: %s", LOG_STR_ARG(valve_command_to_str(*this->position_)));
82 }
83 }
84 if (this->toggle_.has_value()) {
85 ESP_LOGD(TAG, " Command: TOGGLE");
86 }
87 this->parent_->control(*this);
88}
89const optional<float> &ValveCall::get_position() const { return this->position_; }
90const optional<bool> &ValveCall::get_toggle() const { return this->toggle_; }
92 auto traits = this->parent_->get_traits();
93 if (this->position_.has_value()) {
94 auto pos = *this->position_;
95 if (!traits.get_supports_position() && pos != VALVE_OPEN && pos != VALVE_CLOSED) {
96 ESP_LOGW(TAG, "'%s' - This valve device does not support setting position!", this->parent_->get_name().c_str());
97 this->position_.reset();
98 } else if (pos < 0.0f || pos > 1.0f) {
99 ESP_LOGW(TAG, "'%s' - Position %.2f is out of range [0.0 - 1.0]", this->parent_->get_name().c_str(), pos);
100 this->position_ = clamp(pos, 0.0f, 1.0f);
101 }
102 }
103 if (this->toggle_.has_value()) {
104 if (!traits.get_supports_toggle()) {
105 ESP_LOGW(TAG, "'%s' - This valve device does not support toggle!", this->parent_->get_name().c_str());
106 this->toggle_.reset();
107 }
108 }
109 if (this->stop_) {
110 if (this->position_.has_value()) {
111 ESP_LOGW(TAG, "Cannot set position when stopping a valve!");
112 this->position_.reset();
113 }
114 if (this->toggle_.has_value()) {
115 ESP_LOGW(TAG, "Cannot set toggle when stopping a valve!");
116 this->toggle_.reset();
117 }
118 }
119}
121 this->stop_ = stop;
122 return *this;
123}
124bool ValveCall::get_stop() const { return this->stop_; }
125
126ValveCall Valve::make_call() { return {this}; }
127
128void Valve::add_on_state_callback(std::function<void()> &&f) { this->state_callback_.add(std::move(f)); }
129void Valve::publish_state(bool save) {
130 this->position = clamp(this->position, 0.0f, 1.0f);
131
132 ESP_LOGD(TAG, "'%s' >>", this->name_.c_str());
133 auto traits = this->get_traits();
134 if (traits.get_supports_position()) {
135 ESP_LOGD(TAG, " Position: %.0f%%", this->position * 100.0f);
136 } else {
137 if (this->position == VALVE_OPEN) {
138 ESP_LOGD(TAG, " State: OPEN");
139 } else if (this->position == VALVE_CLOSED) {
140 ESP_LOGD(TAG, " State: CLOSED");
141 } else {
142 ESP_LOGD(TAG, " State: UNKNOWN");
143 }
144 }
145 ESP_LOGD(TAG, " Current Operation: %s", LOG_STR_ARG(valve_operation_to_str(this->current_operation)));
146
147 this->state_callback_.call();
148#if defined(USE_VALVE) && defined(USE_CONTROLLER_REGISTRY)
150#endif
151
152 if (save) {
153 ValveRestoreState restore{};
154 memset(&restore, 0, sizeof(restore));
155 restore.position = this->position;
156 this->rtc_.save(&restore);
157 }
158}
161 ValveRestoreState recovered{};
162 if (!this->rtc_.load(&recovered))
163 return {};
164 return recovered;
165}
166
167bool Valve::is_fully_open() const { return this->position == VALVE_OPEN; }
168bool Valve::is_fully_closed() const { return this->position == VALVE_CLOSED; }
169
171 auto call = valve->make_call();
172 call.set_position(this->position);
173 return call;
174}
176 valve->position = this->position;
177 valve->publish_state();
178}
179
180} // namespace valve
181} // namespace esphome
static void notify_valve_update(valve::Valve *obj)
bool save(const T *src)
Definition preferences.h:21
const StringRef & get_name() const
ESPPreferenceObject make_entity_preference(uint32_t version=0)
Create a preference object for storing this entity's state/settings.
constexpr const char * c_str() const
Definition string_ref.h:73
bool has_value() const
Definition optional.h:92
ValveCall & set_stop(bool stop)
Set whether this valve call should stop the valve.
Definition valve.cpp:120
ValveCall & set_command_close()
Set the command to close the valve.
Definition valve.cpp:54
ValveCall & set_position(float position)
Set the call to a certain target position.
Definition valve.cpp:66
const optional< bool > & get_toggle() const
Definition valve.cpp:90
ValveCall & set_command_toggle()
Set the command to toggle the valve.
Definition valve.cpp:62
ValveCall & set_command_stop()
Set the command to stop the valve.
Definition valve.cpp:58
optional< bool > toggle_
Definition valve.h:60
const optional< float > & get_position() const
Definition valve.cpp:89
ValveCall & set_command(const char *command)
Set the command as a string, "STOP", "OPEN", "CLOSE", "TOGGLE".
Definition valve.cpp:36
optional< float > position_
Definition valve.h:59
bool get_stop() const
Definition valve.cpp:124
ValveCall(Valve *parent)
Definition valve.cpp:35
ValveCall & set_command_open()
Set the command to open the valve.
Definition valve.cpp:50
void perform()
Perform the valve call.
Definition valve.cpp:70
Base class for all valve devices.
Definition valve.h:104
optional< ValveRestoreState > restore_state_()
Definition valve.cpp:159
void publish_state(bool save=true)
Publish the current state of the valve.
Definition valve.cpp:129
LazyCallbackManager< void()> state_callback_
Definition valve.h:145
bool is_fully_closed() const
Helper method to check if the valve is fully closed. Equivalent to comparing .position against 0....
Definition valve.cpp:168
ESPPreferenceObject rtc_
Definition valve.h:147
bool is_fully_open() const
Helper method to check if the valve is fully open. Equivalent to comparing .position against 1....
Definition valve.cpp:167
float position
The position of the valve from 0.0 (fully closed) to 1.0 (fully open).
Definition valve.h:115
virtual void control(const ValveCall &call)=0
ValveCall make_call()
Construct a new valve call used to control the valve.
Definition valve.cpp:126
ValveOperation current_operation
The current operation of the valve (idle, opening, closing).
Definition valve.h:109
void add_on_state_callback(std::function< void()> &&f)
Definition valve.cpp:128
virtual ValveTraits get_traits()=0
float position
Definition cover.h:0
const char *const TAG
Definition spi.cpp:7
const LogString * valve_command_to_str(float pos)
Definition valve.cpp:17
PROGMEM_STRING_TABLE(ValveOperationStrings, "IDLE", "OPENING", "CLOSING", "UNKNOWN")
const float VALVE_OPEN
Definition valve.cpp:14
const float VALVE_CLOSED
Definition valve.cpp:15
ValveOperation
Enum encoding the current operation of a valve.
Definition valve.h:74
const LogString * valve_operation_to_str(ValveOperation op)
Definition valve.cpp:29
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
size_t size_t pos
Definition helpers.h:729
Struct used to store the restored state of a valve.
Definition valve.h:64
void apply(Valve *valve)
Apply these settings to the valve.
Definition valve.cpp:175
ValveCall to_call(Valve *valve)
Convert this struct to a valve call that can be performed.
Definition valve.cpp:170