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