ESPHome  2024.3.1
mqtt_cover.cpp
Go to the documentation of this file.
1 #include "mqtt_cover.h"
2 #include "esphome/core/log.h"
3 
4 #include "mqtt_const.h"
5 
6 #ifdef USE_MQTT
7 #ifdef USE_COVER
8 
9 namespace esphome {
10 namespace mqtt {
11 
12 static const char *const TAG = "mqtt.cover";
13 
14 using namespace esphome::cover;
15 
18  auto traits = this->cover_->get_traits();
19  this->cover_->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->cover_->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->cover_->make_call();
33  call.set_position(*value / 100.0f);
34  call.perform();
35  });
36  }
37  if (traits.get_supports_tilt()) {
38  this->subscribe(this->get_tilt_command_topic(), [this](const std::string &topic, const std::string &payload) {
39  auto value = parse_number<float>(payload);
40  if (!value.has_value()) {
41  ESP_LOGW(TAG, "Invalid tilt value: '%s'", payload.c_str());
42  return;
43  }
44  auto call = this->cover_->make_call();
45  call.set_tilt(*value / 100.0f);
46  call.perform();
47  });
48  }
49 }
50 
52  ESP_LOGCONFIG(TAG, "MQTT cover '%s':", this->cover_->get_name().c_str());
53  auto traits = this->cover_->get_traits();
54  bool has_command_topic = traits.get_supports_position() || !traits.get_supports_tilt();
55  LOG_MQTT_COMPONENT(true, has_command_topic)
56  if (traits.get_supports_position()) {
57  ESP_LOGCONFIG(TAG, " Position State Topic: '%s'", this->get_position_state_topic().c_str());
58  ESP_LOGCONFIG(TAG, " Position Command Topic: '%s'", this->get_position_command_topic().c_str());
59  }
60  if (traits.get_supports_tilt()) {
61  ESP_LOGCONFIG(TAG, " Tilt State Topic: '%s'", this->get_tilt_state_topic().c_str());
62  ESP_LOGCONFIG(TAG, " Tilt Command Topic: '%s'", this->get_tilt_command_topic().c_str());
63  }
64 }
66  if (!this->cover_->get_device_class().empty())
67  root[MQTT_DEVICE_CLASS] = this->cover_->get_device_class();
68 
69  auto traits = this->cover_->get_traits();
70  if (traits.get_is_assumed_state()) {
71  root[MQTT_OPTIMISTIC] = true;
72  }
73  if (traits.get_supports_position()) {
74  root[MQTT_POSITION_TOPIC] = this->get_position_state_topic();
75  root[MQTT_SET_POSITION_TOPIC] = this->get_position_command_topic();
76  }
77  if (traits.get_supports_tilt()) {
78  root[MQTT_TILT_STATUS_TOPIC] = this->get_tilt_state_topic();
79  root[MQTT_TILT_COMMAND_TOPIC] = this->get_tilt_command_topic();
80  }
81  if (traits.get_supports_tilt() && !traits.get_supports_position()) {
82  config.command_topic = false;
83  }
84 }
85 
86 std::string MQTTCoverComponent::component_type() const { return "cover"; }
87 const EntityBase *MQTTCoverComponent::get_entity() const { return this->cover_; }
88 
91  auto traits = this->cover_->get_traits();
92  bool success = true;
93  if (traits.get_supports_position()) {
94  std::string pos = value_accuracy_to_string(roundf(this->cover_->position * 100), 0);
95  if (!this->publish(this->get_position_state_topic(), pos))
96  success = false;
97  }
98  if (traits.get_supports_tilt()) {
99  std::string pos = value_accuracy_to_string(roundf(this->cover_->tilt * 100), 0);
100  if (!this->publish(this->get_tilt_state_topic(), pos))
101  success = false;
102  }
103  const char *state_s = this->cover_->current_operation == COVER_OPERATION_OPENING ? "opening"
104  : this->cover_->current_operation == COVER_OPERATION_CLOSING ? "closing"
105  : this->cover_->position == COVER_CLOSED ? "closed"
106  : this->cover_->position == COVER_OPEN ? "open"
107  : traits.get_supports_position() ? "open"
108  : "unknown";
109  if (!this->publish(this->get_state_topic_(), state_s))
110  success = false;
111  return success;
112 }
113 
114 } // namespace mqtt
115 } // namespace esphome
116 
117 #endif
118 #endif // USE_MQTT
Base class for all cover devices.
Definition: cover.h:111
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:412
std::string get_device_class()
Get the device class, using the manual override if set.
Definition: entity_base.cpp:78
CoverCall make_call()
Construct a new cover call used to control the cover.
Definition: cover.cpp:149
CoverOperation current_operation
The current operation of the cover (idle, opening, closing).
Definition: cover.h:116
bool get_supports_position() const
Definition: cover_traits.h:12
The cover is currently closing.
Definition: cover.h:86
const float COVER_CLOSED
Definition: cover.cpp:10
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override
Definition: mqtt_cover.cpp:65
const EntityBase * get_entity() const override
Definition: mqtt_cover.cpp:87
constexpr const char *const MQTT_OPTIMISTIC
Definition: mqtt_const.h:116
bool command_topic
If the command topic should be included. Default to true.
float tilt
The current tilt value of the cover from 0.0 to 1.0.
Definition: cover.h:124
bool publish(const std::string &topic, const std::string &payload)
Send a MQTT message.
virtual CoverTraits get_traits()=0
void add_on_state_callback(std::function< void()> &&f)
Definition: cover.cpp:165
constexpr const char *const MQTT_SET_POSITION_TOPIC
Definition: mqtt_const.h:190
std::string component_type() const override
Definition: mqtt_cover.cpp:86
void subscribe(const std::string &topic, mqtt_callback_t callback, uint8_t qos=0)
Subscribe to a MQTT topic.
state state bool send_initial_state() override
Definition: mqtt_cover.cpp:89
Simple Helper struct used for Home Assistant MQTT send_discovery().
const float COVER_OPEN
Definition: cover.cpp:9
constexpr const char * c_str() const
Definition: string_ref.h:68
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
Definition: cover.h:122
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
constexpr const char *const MQTT_DEVICE_CLASS
Definition: mqtt_const.h:57
std::string get_state_topic_() const
Get the MQTT topic that new states will be shared to.
MQTTCoverComponent(cover::Cover *cover)
Definition: mqtt_cover.cpp:16
constexpr const char *const MQTT_POSITION_TOPIC
Definition: mqtt_const.h:191
std::string get_command_topic_() const
Get the MQTT topic for listening to commands.
The cover is currently opening.
Definition: cover.h:84
const StringRef & get_name() const
Definition: entity_base.cpp:10
constexpr const char *const MQTT_TILT_STATUS_TOPIC
Definition: mqtt_const.h:242
constexpr const char *const MQTT_TILT_COMMAND_TOPIC
Definition: mqtt_const.h:235