diff --git a/esphome/components/mqtt/__init__.py b/esphome/components/mqtt/__init__.py
index 88e5d43509..901b77474d 100644
--- a/esphome/components/mqtt/__init__.py
+++ b/esphome/components/mqtt/__init__.py
@@ -16,6 +16,7 @@ from esphome.const import (
CONF_DISCOVERY_PREFIX,
CONF_DISCOVERY_RETAIN,
CONF_DISCOVERY_UNIQUE_ID_GENERATOR,
+ CONF_DISCOVERY_OBJECT_ID_GENERATOR,
CONF_ID,
CONF_KEEPALIVE,
CONF_LEVEL,
@@ -105,6 +106,12 @@ MQTT_DISCOVERY_UNIQUE_ID_GENERATOR_OPTIONS = {
"mac": MQTTDiscoveryUniqueIdGenerator.MQTT_MAC_ADDRESS_UNIQUE_ID_GENERATOR,
}
+MQTTDiscoveryObjectIdGenerator = mqtt_ns.enum("MQTTDiscoveryObjectIdGenerator")
+MQTT_DISCOVERY_OBJECT_ID_GENERATOR_OPTIONS = {
+ "none": MQTTDiscoveryObjectIdGenerator.MQTT_NONE_OBJECT_ID_GENERATOR,
+ "device_name": MQTTDiscoveryObjectIdGenerator.MQTT_DEVICE_NAME_OBJECT_ID_GENERATOR,
+}
+
def validate_config(value):
# Populate default fields
@@ -166,6 +173,9 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_DISCOVERY_UNIQUE_ID_GENERATOR, default="legacy"): cv.enum(
MQTT_DISCOVERY_UNIQUE_ID_GENERATOR_OPTIONS
),
+ cv.Optional(CONF_DISCOVERY_OBJECT_ID_GENERATOR, default="none"): cv.enum(
+ MQTT_DISCOVERY_OBJECT_ID_GENERATOR_OPTIONS
+ ),
cv.Optional(CONF_USE_ABBREVIATIONS, default=True): cv.boolean,
cv.Optional(CONF_BIRTH_MESSAGE): MQTT_MESSAGE_SCHEMA,
cv.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_SCHEMA,
@@ -245,19 +255,27 @@ async def to_code(config):
discovery_retain = config[CONF_DISCOVERY_RETAIN]
discovery_prefix = config[CONF_DISCOVERY_PREFIX]
discovery_unique_id_generator = config[CONF_DISCOVERY_UNIQUE_ID_GENERATOR]
+ discovery_object_id_generator = config[CONF_DISCOVERY_OBJECT_ID_GENERATOR]
if not discovery:
cg.add(var.disable_discovery())
elif discovery == "CLEAN":
cg.add(
var.set_discovery_info(
- discovery_prefix, discovery_unique_id_generator, discovery_retain, True
+ discovery_prefix,
+ discovery_unique_id_generator,
+ discovery_object_id_generator,
+ discovery_retain,
+ True,
)
)
elif CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config:
cg.add(
var.set_discovery_info(
- discovery_prefix, discovery_unique_id_generator, discovery_retain
+ discovery_prefix,
+ discovery_unique_id_generator,
+ discovery_object_id_generator,
+ discovery_retain,
)
)
diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp
index 67063d4c72..148316672a 100644
--- a/esphome/components/mqtt/mqtt_client.cpp
+++ b/esphome/components/mqtt/mqtt_client.cpp
@@ -538,9 +538,11 @@ void MQTTClientComponent::set_birth_message(MQTTMessage &&message) {
void MQTTClientComponent::set_shutdown_message(MQTTMessage &&message) { this->shutdown_message_ = std::move(message); }
void MQTTClientComponent::set_discovery_info(std::string &&prefix, MQTTDiscoveryUniqueIdGenerator unique_id_generator,
- bool retain, bool clean) {
+ MQTTDiscoveryObjectIdGenerator object_id_generator, bool retain,
+ bool clean) {
this->discovery_info_.prefix = std::move(prefix);
this->discovery_info_.unique_id_generator = unique_id_generator;
+ this->discovery_info_.object_id_generator = object_id_generator;
this->discovery_info_.retain = retain;
this->discovery_info_.clean = clean;
}
diff --git a/esphome/components/mqtt/mqtt_client.h b/esphome/components/mqtt/mqtt_client.h
index a6a7025c6f..58a4fbe166 100644
--- a/esphome/components/mqtt/mqtt_client.h
+++ b/esphome/components/mqtt/mqtt_client.h
@@ -61,6 +61,12 @@ enum MQTTDiscoveryUniqueIdGenerator {
MQTT_MAC_ADDRESS_UNIQUE_ID_GENERATOR,
};
+/// available discovery object_id generators
+enum MQTTDiscoveryObjectIdGenerator {
+ MQTT_NONE_OBJECT_ID_GENERATOR = 0,
+ MQTT_DEVICE_NAME_OBJECT_ID_GENERATOR,
+};
+
/** Internal struct for MQTT Home Assistant discovery
*
* See MQTT Discovery.
@@ -70,6 +76,7 @@ struct MQTTDiscoveryInfo {
bool retain; ///< Whether to retain discovery messages.
bool clean;
MQTTDiscoveryUniqueIdGenerator unique_id_generator;
+ MQTTDiscoveryObjectIdGenerator object_id_generator;
};
enum MQTTClientState {
@@ -106,10 +113,11 @@ class MQTTClientComponent : public Component {
* See MQTT Discovery.
* @param prefix The Home Assistant discovery prefix.
* @param unique_id_generator Controls how UniqueId is generated.
+ * @param object_id_generator Controls how ObjectId is generated.
* @param retain Whether to retain discovery messages.
*/
- void set_discovery_info(std::string &&prefix, MQTTDiscoveryUniqueIdGenerator unique_id_generator, bool retain,
- bool clean = false);
+ void set_discovery_info(std::string &&prefix, MQTTDiscoveryUniqueIdGenerator unique_id_generator,
+ MQTTDiscoveryObjectIdGenerator object_id_generator, bool retain, bool clean = false);
/// Get Home Assistant discovery info.
const MQTTDiscoveryInfo &get_discovery_info() const;
/// Globally disable Home Assistant discovery.
diff --git a/esphome/components/mqtt/mqtt_component.cpp b/esphome/components/mqtt/mqtt_component.cpp
index 341ac50e37..cf228efd1b 100644
--- a/esphome/components/mqtt/mqtt_component.cpp
+++ b/esphome/components/mqtt/mqtt_component.cpp
@@ -111,12 +111,11 @@ bool MQTTComponent::send_discovery_() {
root[MQTT_PAYLOAD_NOT_AVAILABLE] = this->availability_->payload_not_available;
}
- const std::string &node_name = App.get_name();
std::string unique_id = this->unique_id();
+ const MQTTDiscoveryInfo &discovery_info = global_mqtt_client->get_discovery_info();
if (!unique_id.empty()) {
root[MQTT_UNIQUE_ID] = unique_id;
} else {
- const MQTTDiscoveryInfo &discovery_info = global_mqtt_client->get_discovery_info();
if (discovery_info.unique_id_generator == MQTT_MAC_ADDRESS_UNIQUE_ID_GENERATOR) {
char friendly_name_hash[9];
sprintf(friendly_name_hash, "%08x", fnv1_hash(this->friendly_name()));
@@ -129,6 +128,10 @@ bool MQTTComponent::send_discovery_() {
}
}
+ const std::string &node_name = App.get_name();
+ if (discovery_info.object_id_generator == MQTT_DEVICE_NAME_OBJECT_ID_GENERATOR)
+ root[MQTT_OBJECT_ID] = node_name + "_" + this->get_default_object_id_();
+
JsonObject device_info = root.createNestedObject(MQTT_DEVICE);
device_info[MQTT_DEVICE_IDENTIFIERS] = get_mac_address();
device_info[MQTT_DEVICE_NAME] = node_name;
diff --git a/esphome/components/mqtt/mqtt_const.h b/esphome/components/mqtt/mqtt_const.h
index 52ca0ed7c0..7f74197ab4 100644
--- a/esphome/components/mqtt/mqtt_const.h
+++ b/esphome/components/mqtt/mqtt_const.h
@@ -107,6 +107,7 @@ constexpr const char *const MQTT_MODE_STATE_TOPIC = "mode_stat_t";
constexpr const char *const MQTT_MODE_STATE_TEMPLATE = "mode_stat_tpl";
constexpr const char *const MQTT_MODES = "modes";
constexpr const char *const MQTT_NAME = "name";
+constexpr const char *const MQTT_OBJECT_ID = "obj_id";
constexpr const char *const MQTT_OFF_DELAY = "off_dly";
constexpr const char *const MQTT_ON_COMMAND_TYPE = "on_cmd_type";
constexpr const char *const MQTT_OPTIONS = "ops";
@@ -360,6 +361,7 @@ constexpr const char *const MQTT_MODE_STATE_TOPIC = "mode_state_topic";
constexpr const char *const MQTT_MODE_STATE_TEMPLATE = "mode_state_template";
constexpr const char *const MQTT_MODES = "modes";
constexpr const char *const MQTT_NAME = "name";
+constexpr const char *const MQTT_OBJECT_ID = "object_id";
constexpr const char *const MQTT_OFF_DELAY = "off_delay";
constexpr const char *const MQTT_ON_COMMAND_TYPE = "on_command_type";
constexpr const char *const MQTT_OPTIONS = "options";
diff --git a/esphome/const.py b/esphome/const.py
index 61b152654a..dcd6fea31f 100644
--- a/esphome/const.py
+++ b/esphome/const.py
@@ -168,6 +168,7 @@ CONF_DIRECTION = "direction"
CONF_DIRECTION_OUTPUT = "direction_output"
CONF_DISABLED_BY_DEFAULT = "disabled_by_default"
CONF_DISCOVERY = "discovery"
+CONF_DISCOVERY_OBJECT_ID_GENERATOR = "discovery_object_id_generator"
CONF_DISCOVERY_PREFIX = "discovery_prefix"
CONF_DISCOVERY_RETAIN = "discovery_retain"
CONF_DISCOVERY_UNIQUE_ID_GENERATOR = "discovery_unique_id_generator"