Null topic_prefix disables MQTT publishing/subscription unless topic is explicitly configured (#5644)

This commit is contained in:
kahrendt 2023-11-05 20:19:03 -05:00 committed by GitHub
parent e0cee472c3
commit ff8b904097
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 43 deletions

View file

@ -133,33 +133,47 @@ def validate_config(value):
# Populate default fields # Populate default fields
out = value.copy() out = value.copy()
topic_prefix = value[CONF_TOPIC_PREFIX] topic_prefix = value[CONF_TOPIC_PREFIX]
# If the topic prefix is not null and these messages are not configured, then set them to the default
# If the topic prefix is null and these messages are not configured, then set them to null
if CONF_BIRTH_MESSAGE not in value: if CONF_BIRTH_MESSAGE not in value:
if topic_prefix != "":
out[CONF_BIRTH_MESSAGE] = { out[CONF_BIRTH_MESSAGE] = {
CONF_TOPIC: f"{topic_prefix}/status", CONF_TOPIC: f"{topic_prefix}/status",
CONF_PAYLOAD: "online", CONF_PAYLOAD: "online",
CONF_QOS: 0, CONF_QOS: 0,
CONF_RETAIN: True, CONF_RETAIN: True,
} }
else:
out[CONF_BIRTH_MESSAGE] = {}
if CONF_WILL_MESSAGE not in value: if CONF_WILL_MESSAGE not in value:
if topic_prefix != "":
out[CONF_WILL_MESSAGE] = { out[CONF_WILL_MESSAGE] = {
CONF_TOPIC: f"{topic_prefix}/status", CONF_TOPIC: f"{topic_prefix}/status",
CONF_PAYLOAD: "offline", CONF_PAYLOAD: "offline",
CONF_QOS: 0, CONF_QOS: 0,
CONF_RETAIN: True, CONF_RETAIN: True,
} }
else:
out[CONF_WILL_MESSAGE] = {}
if CONF_SHUTDOWN_MESSAGE not in value: if CONF_SHUTDOWN_MESSAGE not in value:
if topic_prefix != "":
out[CONF_SHUTDOWN_MESSAGE] = { out[CONF_SHUTDOWN_MESSAGE] = {
CONF_TOPIC: f"{topic_prefix}/status", CONF_TOPIC: f"{topic_prefix}/status",
CONF_PAYLOAD: "offline", CONF_PAYLOAD: "offline",
CONF_QOS: 0, CONF_QOS: 0,
CONF_RETAIN: True, CONF_RETAIN: True,
} }
else:
out[CONF_SHUTDOWN_MESSAGE] = {}
if CONF_LOG_TOPIC not in value: if CONF_LOG_TOPIC not in value:
if topic_prefix != "":
out[CONF_LOG_TOPIC] = { out[CONF_LOG_TOPIC] = {
CONF_TOPIC: f"{topic_prefix}/debug", CONF_TOPIC: f"{topic_prefix}/debug",
CONF_QOS: 0, CONF_QOS: 0,
CONF_RETAIN: True, CONF_RETAIN: True,
} }
else:
out[CONF_LOG_TOPIC] = {}
return out return out

View file

@ -23,8 +23,13 @@ std::string MQTTComponent::get_discovery_topic_(const MQTTDiscoveryInfo &discove
} }
std::string MQTTComponent::get_default_topic_for_(const std::string &suffix) const { std::string MQTTComponent::get_default_topic_for_(const std::string &suffix) const {
return global_mqtt_client->get_topic_prefix() + "/" + this->component_type() + "/" + this->get_default_object_id_() + const std::string &topic_prefix = global_mqtt_client->get_topic_prefix();
"/" + suffix; if (topic_prefix.empty()) {
// If the topic_prefix is null, the default topic should be null
return "";
}
return topic_prefix + "/" + this->component_type() + "/" + this->get_default_object_id_() + "/" + suffix;
} }
std::string MQTTComponent::get_state_topic_() const { std::string MQTTComponent::get_state_topic_() const {
@ -245,17 +250,25 @@ std::string MQTTComponent::friendly_name() const { return this->get_entity()->ge
std::string MQTTComponent::get_icon() const { return this->get_entity()->get_icon(); } std::string MQTTComponent::get_icon() const { return this->get_entity()->get_icon(); }
bool MQTTComponent::is_disabled_by_default() const { return this->get_entity()->is_disabled_by_default(); } bool MQTTComponent::is_disabled_by_default() const { return this->get_entity()->is_disabled_by_default(); }
bool MQTTComponent::is_internal() { bool MQTTComponent::is_internal() {
if ((this->get_state_topic_().empty()) || (this->get_command_topic_().empty())) { if (this->has_custom_state_topic_) {
// If both state_topic and command_topic are empty, then the entity is internal to mqtt // If the custom state_topic is null, return true as it is internal and should not publish
// else, return false, as it is explicitly set to a topic, so it is not internal and should publish
return this->get_state_topic_().empty();
}
if (this->has_custom_command_topic_) {
// If the custom command_topic is null, return true as it is internal and should not publish
// else, return false, as it is explicitly set to a topic, so it is not internal and should publish
return this->get_command_topic_().empty();
}
// No custom topics have been set
if (this->get_default_topic_for_("").empty()) {
// If the default topic prefix is null, then the component, by default, is internal and should not publish
return true; return true;
} }
if (this->has_custom_state_topic_ || this->has_custom_command_topic_) { // Use ESPHome's component internal state if topic_prefix is not null with no custom state_topic or command_topic
// If a custom state_topic or command_topic is set, then the entity is not internal to mqtt
return false;
}
// Use ESPHome's entity internal state
return this->get_entity()->is_internal(); return this->get_entity()->is_internal();
} }

View file

@ -24,6 +24,13 @@ ethernet:
network: network:
enable_ipv6: true enable_ipv6: true
mqtt:
broker: test.mosquitto.org
port: 1883
discovery: true
discovery_prefix: homeassistant
topic_prefix:
api: api:
i2c: i2c:
@ -32,12 +39,12 @@ i2c:
scan: false scan: false
spi: spi:
- id: spi_id_1 - id: spi_id_1
clk_pin: GPIO21 clk_pin: GPIO21
mosi_pin: GPIO22 mosi_pin: GPIO22
miso_pin: GPIO23 miso_pin: GPIO23
interface: hardware interface: hardware
- id: spi_id_2 - id: spi_id_2
clk_pin: GPIO32 clk_pin: GPIO32
mosi_pin: GPIO33 mosi_pin: GPIO33
interface: hardware interface: hardware
@ -281,6 +288,7 @@ sensor:
id: a01nyub_sensor id: a01nyub_sensor
name: "a01nyub Distance" name: "a01nyub Distance"
uart_id: uart9600 uart_id: uart9600
state_topic: "esphome/sensor/a01nyub_sensor/state"
# #
# platform sensor.apds9960 requires component apds9960 # platform sensor.apds9960 requires component apds9960
@ -764,7 +772,6 @@ speaker:
i2s_dout_pin: GPIO25 i2s_dout_pin: GPIO25
mode: mono mode: mono
voice_assistant: voice_assistant:
microphone: mic_id_external microphone: mic_id_external
speaker: speaker_id speaker: speaker_id