ESPHome 2026.1.4
Loading...
Searching...
No Matches
mqtt_valve.cpp
Go to the documentation of this file.
1#include "mqtt_valve.h"
2#include "esphome/core/log.h"
3
4#include "mqtt_const.h"
5
6#ifdef USE_MQTT
7#ifdef USE_VALVE
8
9namespace esphome::mqtt {
10
11static const char *const TAG = "mqtt.valve";
12
13using namespace esphome::valve;
14
17 auto traits = this->valve_->get_traits();
18 this->valve_->add_on_state_callback([this]() { this->publish_state(); });
19 this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {
20 auto call = this->valve_->make_call();
21 call.set_command(payload.c_str());
22 call.perform();
23 });
24 if (traits.get_supports_position()) {
25 this->subscribe(this->get_position_command_topic(), [this](const std::string &topic, const std::string &payload) {
26 auto value = parse_number<float>(payload);
27 if (!value.has_value()) {
28 ESP_LOGW(TAG, "Invalid position value: '%s'", payload.c_str());
29 return;
30 }
31 auto call = this->valve_->make_call();
32 call.set_position(*value / 100.0f);
33 call.perform();
34 });
35 }
36}
37
39 ESP_LOGCONFIG(TAG, "MQTT valve '%s':", this->valve_->get_name().c_str());
40 auto traits = this->valve_->get_traits();
41 bool has_command_topic = traits.get_supports_position();
42 LOG_MQTT_COMPONENT(true, has_command_topic)
43 if (traits.get_supports_position()) {
44 ESP_LOGCONFIG(TAG,
45 " Position State Topic: '%s'\n"
46 " Position Command Topic: '%s'",
47 this->get_position_state_topic().c_str(), this->get_position_command_topic().c_str());
48 }
49}
51 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
52 const auto device_class = this->valve_->get_device_class_ref();
53 if (!device_class.empty()) {
54 root[MQTT_DEVICE_CLASS] = device_class;
55 }
56 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
57
58 auto traits = this->valve_->get_traits();
59 if (traits.get_is_assumed_state()) {
60 root[MQTT_OPTIMISTIC] = true;
61 }
62 if (traits.get_supports_position()) {
63 root[MQTT_POSITION_TOPIC] = this->get_position_state_topic();
64 root[MQTT_SET_POSITION_TOPIC] = this->get_position_command_topic();
65 }
66}
67
69const EntityBase *MQTTValveComponent::get_entity() const { return this->valve_; }
70
73 auto traits = this->valve_->get_traits();
74 bool success = true;
75 if (traits.get_supports_position()) {
76 char pos[VALUE_ACCURACY_MAX_LEN];
77 size_t len = value_accuracy_to_buf(pos, roundf(this->valve_->position * 100), 0);
78 if (!this->publish(this->get_position_state_topic(), pos, len))
79 success = false;
80 }
81 const char *state_s = this->valve_->current_operation == VALVE_OPERATION_OPENING ? "opening"
83 : this->valve_->position == VALVE_CLOSED ? "closed"
84 : this->valve_->position == VALVE_OPEN ? "open"
85 : traits.get_supports_position() ? "open"
86 : "unknown";
87 if (!this->publish(this->get_state_topic_(), state_s))
88 success = false;
89 return success;
90}
91
92} // namespace esphome::mqtt
93
94#endif
95#endif // USE_MQTT
StringRef get_device_class_ref() const
Get the device class as StringRef.
const StringRef & get_name() const
constexpr const char * c_str() const
Definition string_ref.h:73
bool publish(const std::string &topic, const std::string &payload)
Send a MQTT message.
std::string get_state_topic_() const
Get the MQTT topic that new states will be shared to.
std::string get_command_topic_() const
Get the MQTT topic for listening to commands.
void subscribe(const std::string &topic, mqtt_callback_t callback, uint8_t qos=0)
Subscribe to a MQTT topic.
state bool send_initial_state() override
MQTTValveComponent(valve::Valve *valve)
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override
ValveCall & set_position(float position)
Set the call to a certain target position.
Definition valve.cpp:70
ValveCall & set_command(const char *command)
Set the command as a string, "STOP", "OPEN", "CLOSE", "TOGGLE".
Definition valve.cpp:40
void perform()
Perform the valve call.
Definition valve.cpp:74
Base class for all valve devices.
Definition valve.h:106
float position
The position of the valve from 0.0 (fully closed) to 1.0 (fully open).
Definition valve.h:117
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:111
void add_on_state_callback(std::function< void()> &&f)
Definition valve.cpp:132
virtual ValveTraits get_traits()=0
bool get_supports_position() const
MQTT_COMPONENT_TYPE(MQTTAlarmControlPanelComponent, "alarm_control_panel") const EntityBase *MQTTAlarmControlPanelComponent
const float VALVE_OPEN
Definition valve.cpp:12
const float VALVE_CLOSED
Definition valve.cpp:13
@ VALVE_OPERATION_OPENING
The valve is currently opening.
Definition valve.h:80
@ VALVE_OPERATION_CLOSING
The valve is currently closing.
Definition valve.h:82
size_t value_accuracy_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals)
Format value with accuracy to buffer, returns chars written (excluding null)
Definition helpers.cpp:448
std::string size_t len
Definition helpers.h:595
optional< T > parse_number(const char *str)
Parse an unsigned decimal number from a null-terminated string.
Definition helpers.h:640
Simple Helper struct used for Home Assistant MQTT send_discovery().