ESPHome  2024.11.1
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 
9 namespace esphome {
10 namespace mqtt {
11 
12 static const char *const TAG = "mqtt.valve";
13 
14 using namespace esphome::valve;
15 
18  auto traits = this->valve_->get_traits();
19  this->valve_->add_on_state_callback([this]() { this->publish_state(); });
20  this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {
21  auto call = this->valve_->make_call();
22  call.set_command(payload.c_str());
23  call.perform();
24  });
25  if (traits.get_supports_position()) {
26  this->subscribe(this->get_position_command_topic(), [this](const std::string &topic, const std::string &payload) {
27  auto value = parse_number<float>(payload);
28  if (!value.has_value()) {
29  ESP_LOGW(TAG, "Invalid position value: '%s'", payload.c_str());
30  return;
31  }
32  auto call = this->valve_->make_call();
33  call.set_position(*value / 100.0f);
34  call.perform();
35  });
36  }
37 }
38 
40  ESP_LOGCONFIG(TAG, "MQTT valve '%s':", this->valve_->get_name().c_str());
41  auto traits = this->valve_->get_traits();
42  bool has_command_topic = traits.get_supports_position();
43  LOG_MQTT_COMPONENT(true, has_command_topic)
44  if (traits.get_supports_position()) {
45  ESP_LOGCONFIG(TAG, " Position State Topic: '%s'", this->get_position_state_topic().c_str());
46  ESP_LOGCONFIG(TAG, " Position Command Topic: '%s'", this->get_position_command_topic().c_str());
47  }
48 }
50  if (!this->valve_->get_device_class().empty())
51  root[MQTT_DEVICE_CLASS] = this->valve_->get_device_class();
52 
53  auto traits = this->valve_->get_traits();
54  if (traits.get_is_assumed_state()) {
55  root[MQTT_OPTIMISTIC] = true;
56  }
57  if (traits.get_supports_position()) {
58  root[MQTT_POSITION_TOPIC] = this->get_position_state_topic();
59  root[MQTT_SET_POSITION_TOPIC] = this->get_position_command_topic();
60  }
61 }
62 
63 std::string MQTTValveComponent::component_type() const { return "valve"; }
64 const EntityBase *MQTTValveComponent::get_entity() const { return this->valve_; }
65 
68  auto traits = this->valve_->get_traits();
69  bool success = true;
70  if (traits.get_supports_position()) {
71  std::string pos = value_accuracy_to_string(roundf(this->valve_->position * 100), 0);
72  if (!this->publish(this->get_position_state_topic(), pos))
73  success = false;
74  }
75  const char *state_s = this->valve_->current_operation == VALVE_OPERATION_OPENING ? "opening"
76  : this->valve_->current_operation == VALVE_OPERATION_CLOSING ? "closing"
77  : this->valve_->position == VALVE_CLOSED ? "closed"
78  : this->valve_->position == VALVE_OPEN ? "open"
79  : traits.get_supports_position() ? "open"
80  : "unknown";
81  if (!this->publish(this->get_state_topic_(), state_s))
82  success = false;
83  return success;
84 }
85 
86 } // namespace mqtt
87 } // namespace esphome
88 
89 #endif
90 #endif // USE_MQTT
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals)
Create a string from a value and an accuracy in decimals.
Definition: helpers.cpp:415
std::string get_device_class()
Get the device class, using the manual override if set.
Definition: entity_base.cpp:78
float position
The position of the valve from 0.0 (fully closed) to 1.0 (fully open).
Definition: valve.h:116
void add_on_state_callback(std::function< void()> &&f)
Definition: valve.cpp:129
MQTTValveComponent(valve::Valve *valve)
Definition: mqtt_valve.cpp:16
constexpr const char *const MQTT_OPTIMISTIC
Definition: mqtt_const.h:124
virtual ValveTraits get_traits()=0
The valve is currently opening.
Definition: valve.h:79
bool publish(const std::string &topic, const std::string &payload)
Send a MQTT message.
ValveCall make_call()
Construct a new valve call used to control the valve.
Definition: valve.cpp:127
constexpr const char *const MQTT_SET_POSITION_TOPIC
Definition: mqtt_const.h:203
The valve is currently closing.
Definition: valve.h:81
void subscribe(const std::string &topic, mqtt_callback_t callback, uint8_t qos=0)
Subscribe to a MQTT topic.
Simple Helper struct used for Home Assistant MQTT send_discovery().
bool get_supports_position() const
Definition: valve_traits.h:12
state bool send_initial_state() override
Definition: mqtt_valve.cpp:66
const float VALVE_OPEN
Definition: valve.cpp:9
constexpr const char * c_str() const
Definition: string_ref.h:68
const EntityBase * get_entity() const override
Definition: mqtt_valve.cpp:64
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override
Definition: mqtt_valve.cpp:49
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
Base class for all valve devices.
Definition: valve.h:105
ValveOperation current_operation
The current operation of the valve (idle, opening, closing).
Definition: valve.h:110
std::string component_type() const override
Definition: mqtt_valve.cpp:63
constexpr const char *const MQTT_DEVICE_CLASS
Definition: mqtt_const.h:58
std::string get_state_topic_() const
Get the MQTT topic that new states will be shared to.
constexpr const char *const MQTT_POSITION_TOPIC
Definition: mqtt_const.h:175
std::string get_command_topic_() const
Get the MQTT topic for listening to commands.
const StringRef & get_name() const
Definition: entity_base.cpp:10
const float VALVE_CLOSED
Definition: valve.cpp:10