27static constexpr size_t MQTT_DISCOVERY_PREFIX_MAX_LEN = 64;
29static constexpr size_t MQTT_DISCOVERY_TOPIC_MAX_LEN = MQTT_DISCOVERY_PREFIX_MAX_LEN + 1 + MQTT_COMPONENT_TYPE_MAX_LEN +
30 1 + ESPHOME_DEVICE_NAME_MAX_LEN + 1 + OBJECT_ID_MAX_LEN + 7 + 1;
32void log_mqtt_component(
const char *tag, MQTTComponent *obj,
bool state_topic,
bool command_topic);
34#define LOG_MQTT_COMPONENT(state_topic, command_topic) log_mqtt_component(TAG, this, state_topic, command_topic)
38#define MQTT_COMPONENT_TYPE(class_name, type_str) \
39 const char *class_name::component_type() const { return type_str; } \
40 static_assert(sizeof(type_str) - 1 <= MQTT_COMPONENT_TYPE_MAX_LEN, \
41 #class_name "::component_type() exceeds MQTT_COMPONENT_TYPE_MAX_LEN");
46#define MQTT_COMPONENT_CUSTOM_TOPIC_(name, type) \
47 static_assert(sizeof(#name "/" #type) - 1 <= MQTT_SUFFIX_MAX_LEN, \
48 "topic suffix " #name "/" #type " exceeds MQTT_SUFFIX_MAX_LEN"); \
51 std::string custom_##name##_##type##_topic_{}; \
54 void set_custom_##name##_##type##_topic(const std::string &topic) { this->custom_##name##_##type##_topic_ = topic; } \
55 StringRef get_##name##_##type##_topic_to(std::span<char, MQTT_DEFAULT_TOPIC_MAX_LEN> buf) const { \
56 if (!this->custom_##name##_##type##_topic_.empty()) \
57 return StringRef(this->custom_##name##_##type##_topic_.data(), this->custom_##name##_##type##_topic_.size()); \
58 return this->get_default_topic_for_to_(buf, #name "/" #type, sizeof(#name "/" #type) - 1); \
60 MQTTTopicSource get_##name##_##type##_topic_source() const { \
61 using Self = std::remove_cvref_t<decltype(*this)>; \
62 return this->topic_source_<Self, &Self::get_##name##_##type##_topic_to>(); \
64 std::string get_##name##_##type##_topic() const { \
65 if (this->custom_##name##_##type##_topic_.empty()) \
66 return this->get_default_topic_for_(#name "/" #type); \
67 return this->custom_##name##_##type##_topic_; \
70#define MQTT_COMPONENT_CUSTOM_TOPIC(name, type) MQTT_COMPONENT_CUSTOM_TOPIC_(name, type)
142 void set_availability(std::string topic, std::string payload_available, std::string payload_not_available);
159 bool publish(
const std::string &topic,
const std::string &payload);
167 bool publish(
const std::string &topic,
const char *payload,
size_t payload_length);
174 bool publish(
const std::string &topic,
const char *payload) {
175 return this->
publish(topic.c_str(), payload, strlen(payload));
184 bool publish(
const char *topic,
const char *payload,
size_t payload_length);
193 return this->
publish(topic.
c_str(), payload, payload_length);
201 bool publish(
const char *topic,
const char *payload);
260 template<
typename T,
typename F>
void subscribe(T &&topic, F &&callback, uint8_t qos = 0) {
273 template<
typename T,
typename F>
void subscribe_json(T &&topic, F &&callback, uint8_t qos = 0) {
294 size_t suffix_len)
const;
310 ESPDEPRECATED(
"Use log_name_() for logging. Removed in 2027.5.0",
"2026.11.0")
330 template<typename C,
StringRef (C::*Getter)(
std::span<
char, MQTT_DEFAULT_TOPIC_MAX_LEN>) const>
332 return {[](
const void *context, std::span<char, MQTT_DEFAULT_TOPIC_MAX_LEN> buf) {
333 return (
static_cast<const C *
>(context)->*Getter)(buf);
335 static_cast<const C *
>(
this)};
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
Primary TemplatableValue: stores either a constant value or a function pointer.
void subscribe(MQTTTopicSource topic, F &&callback, uint8_t qos=0)
Subscribe to an MQTT topic and call callback when a message is received.
void subscribe_json(T &&topic, F &&callback, uint8_t qos=0)
Subscribe to a MQTT topic and automatically parse JSON payload.
MQTTComponent is the base class for all components that interact with MQTT to expose certain function...
StringRef get_command_topic_to_(std::span< char, MQTT_DEFAULT_TOPIC_MAX_LEN > buf) const
Get the MQTT command topic into a buffer (no heap allocation for non-lambda custom topics).
TemplatableValue< std::string > custom_state_topic_
TemplatableValue< std::string > custom_command_topic_
static constexpr uint32_t SEND_DEFER_ID
void disable_availability()
bool publish_json(StringRef topic, const json::json_build_t &f)
Construct and send a JSON MQTT message (no heap allocation for topic).
std::unique_ptr< Availability > availability_
StringRef get_discovery_topic_to_(std::span< char, MQTT_DISCOVERY_TOPIC_MAX_LEN > buf, const MQTTDiscoveryInfo &discovery_info) const
Helper method to get the discovery topic for this component into a buffer.
bool is_connected_() const
bool is_disabled_by_default_() const
Get whether the underlying Entity is disabled by default.
MQTTComponent()
Constructs a MQTTComponent.
const LogString * log_name_() const
Entity name for a "%s" log argument.
void subscribe(T &&topic, F &&callback, uint8_t qos=0)
Subscribe to a MQTT topic.
MQTTTopicSource command_topic_source_() const
The command topic as a subscription source. A lambda topic is read once and copied,...
void set_custom_command_topic(T &&custom_command_topic)
Set a custom command topic before setup(); a later change only reaches the broker after a reconnect.
bool is_internal() const
Returns cached is_internal result (computed once during setup).
bool publish(StringRef topic, ProgmemStr payload)
Send a MQTT message with a PROGMEM string payload (no heap allocation for topic).
void set_qos(uint8_t qos)
Set QOS for state messages.
StringRef get_default_topic_for_to_(std::span< char, MQTT_DEFAULT_TOPIC_MAX_LEN > buf, const char *suffix, size_t suffix_len) const
Get this components state/command/... topic into a buffer.
bool is_discovery_enabled() const
void schedule_resend_state()
Internal method for the MQTT client base to schedule a resend of the state on reconnect.
bool publish(StringRef topic, const char *payload, size_t payload_length)
Send a MQTT message (no heap allocation for topic).
bool publish(const std::string &topic, const std::string &payload)
Send a MQTT message.
void set_command_retain(bool command_retain)
Set whether command message should be retained.
bool send_discovery_()
Internal method to start sending discovery info, this will call send_discovery().
bool publish(const std::string &topic, const char *payload)
Send a MQTT message.
bool is_internal_
Cached result of compute_is_internal_(), set during setup.
void set_subscribe_qos(uint8_t qos)
Set the QOS for subscribe messages (used in discovery).
void call_setup() override
Override setup_ so that we can call send_discovery() when needed.
void subscribe_json(T &&topic, F &&callback, uint8_t qos=0)
Subscribe to a MQTT topic and automatically parse JSON payload.
bool publish_float_(StringRef topic, float value, int8_t accuracy)
Publish a float formatted to accuracy, or "None" for NaN when publish_nan_as_none is set.
bool publish_json(const std::string &topic, const json::json_build_t &f)
Construct and send a JSON MQTT message.
std::string get_default_topic_for_(const std::string &suffix) const
Get this components state/command/... topic (allocates std::string).
void process_resend()
Process pending resend if needed (called by MQTTClientComponent)
StringRef get_default_object_id_to_(std::span< char, OBJECT_ID_MAX_LEN > buf) const
Get the object ID for this MQTT component, writing to the provided buffer.
void set_retain(bool retain)
Set whether state message should be retained.
virtual const EntityBase * get_entity() const =0
Gets the Entity served by this MQTT component.
std::string get_state_topic_() const
Get the MQTT topic that new states will be shared to (allocates std::string).
MQTTTopicSource topic_source_() const
A topic built by one of this component's get_*_topic_to getters, rebuilt when needed.
virtual void send_discovery(JsonObject root, SendDiscoveryConfig &config)=0
Send discovery info the Home Assistant, override this.
ESPDEPRECATED("Use log_name_() for logging. Removed in 2027.5.0", "2026.11.0") const StringRef &friendly_name_() const
StringRef get_state_topic_to_(std::span< char, MQTT_DEFAULT_TOPIC_MAX_LEN > buf) const
Get the MQTT state topic into a buffer (no heap allocation for non-lambda custom topics).
bool compute_is_internal_()
Compute is_internal status based on topics and entity state.
friend void log_mqtt_component(const char *tag, MQTTComponent *obj, bool state_topic, bool command_topic)
void set_custom_state_topic(T &&custom_state_topic)
Set a custom state topic. Do not set for default behavior.
virtual bool send_initial_state()=0
void disable_discovery()
Disable discovery. Sets friendly name to "".
bool is_resend_pending() const
Check if a resend is pending (called by MQTTClientComponent to rate-limit work)
float get_setup_priority() const override
MQTT_COMPONENT setup priority.
void set_availability(std::string topic, std::string payload_available, std::string payload_not_available)
Set the Home Assistant availability data.
std::string get_command_topic_() const
Get the MQTT topic for listening to commands (allocates std::string).
bool publish(StringRef topic, const char *payload)
Send a MQTT message (no heap allocation for topic).
virtual const char * component_type() const =0
Override this method to return the component type (e.g. "light", "sensor", ...)
std::function< void(JsonObject)> json_build_t
Callback function typedef for building JsonObjects.
MQTTClientComponent * global_mqtt_client
void log_mqtt_component(const char *tag, MQTTComponent *obj, bool state_topic, bool command_topic)
const __FlashStringHelper * ProgmemStr
Internal struct for MQTT Home Assistant discovery.
Where a subscription's topic comes from. The topic is rebuilt whenever it is needed,...
Simple Helper struct used for Home Assistant MQTT send_discovery().
bool command_topic
If the command topic should be included. Default to true.
bool state_topic
If the state topic should be included. Defaults to true.