Skip to content

Commit

Permalink
fix MQTT base with paths not working in HA [emsesp#1393]
Browse files Browse the repository at this point in the history
  • Loading branch information
proddy committed Nov 6, 2023
1 parent 58cbfbc commit bf5b40c
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGELOG_LATEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Writeable Text entities have moved from type `sensor` to `text` in Home Assistan
## Fixed

- fixed helper text in Web Device Entity dialog box for numerical ranges
- MQTT base with paths not working in HA [#1393](https://github.com/emsesp/EMS-ESP32/issues/1393)

## Changed

Expand Down
10 changes: 5 additions & 5 deletions src/analogsensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ void AnalogSensor::publish_values(const bool force) {
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;

char stat_t[50];
snprintf(stat_t, sizeof(stat_t), "%s/analogsensor_data", Mqtt::basename().c_str()); // use basename
snprintf(stat_t, sizeof(stat_t), "%s/analogsensor_data", Mqtt::base().c_str()); // use basename
config["stat_t"] = stat_t;

char val_obj[50];
Expand Down Expand Up @@ -560,7 +560,7 @@ void AnalogSensor::publish_values(const bool force) {
if (sensor.type() == AnalogType::DIGITAL_OUT) {
#endif
snprintf(topic, sizeof(topic), "switch/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::base().c_str(), sensor.name().c_str());
config["cmd_t"] = command_topic;
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
config["pl_on"] = true;
Expand All @@ -575,23 +575,23 @@ void AnalogSensor::publish_values(const bool force) {
}
} else if (sensor.type() == AnalogType::DIGITAL_OUT) { // DAC
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::base().c_str(), sensor.name().c_str());
config["cmd_t"] = command_topic;
config["min"] = 0;
config["max"] = 255;
config["mode"] = "box"; // auto, slider or box
config["step"] = 1;
} else if (sensor.type() >= AnalogType::PWM_0) {
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::base().c_str(), sensor.name().c_str());
config["cmd_t"] = command_topic;
config["min"] = 0;
config["max"] = 100;
config["mode"] = "box"; // auto, slider or box
config["step"] = 0.1;
} else if (sensor.type() == AnalogType::COUNTER) {
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::base().c_str(), sensor.name().c_str());
config["cmd_t"] = command_topic;
config["stat_cla"] = "total_increasing";
// config["mode"] = "box"; // auto, slider or box
Expand Down
30 changes: 15 additions & 15 deletions src/mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) {
// show subscriptions
shell.printfln("MQTT topic subscriptions:");
for (const auto & mqtt_subfunction : mqtt_subfunctions_) {
shell.printfln(" %s/%s", mqtt_base_.c_str(), mqtt_subfunction.topic_.c_str());
shell.printfln(" %s/%s", Mqtt::base().c_str(), mqtt_subfunction.topic_.c_str());
}
shell.println();

Expand Down Expand Up @@ -247,7 +247,7 @@ void Mqtt::on_message(const char * topic, const uint8_t * payload, size_t len) c
for (const auto & mf : mqtt_subfunctions_) {
// add the base back
char full_topic[MQTT_TOPIC_MAX_SIZE];
snprintf(full_topic, sizeof(full_topic), "%s/%s", mqtt_base_.c_str(), mf.topic_.c_str());
snprintf(full_topic, sizeof(full_topic), "%s/%s", Mqtt::base().c_str(), mf.topic_.c_str());

if ((!strcmp(topic, full_topic)) && (mf.mqtt_subfunction_)) {
if (!(mf.mqtt_subfunction_)(message)) {
Expand Down Expand Up @@ -355,8 +355,8 @@ void Mqtt::load_settings() {
publish_time_heartbeat_ = mqttSettings.publish_time_heartbeat * 1000;
});

// create basename from base
// by taking the MQTT base path and replacing all / with underscores
// create basename from the mqtt base
// and replacing all / with underscores, in case it's a path
mqtt_basename_ = mqtt_base_;
std::replace(mqtt_basename_.begin(), mqtt_basename_.end(), '/', '_');
}
Expand All @@ -382,8 +382,8 @@ void Mqtt::start() {

// create last will topic with the base prefixed. It has to be static because asyncmqttclient destroys the reference
static char will_topic[MQTT_TOPIC_MAX_SIZE];
if (!mqtt_base_.empty()) {
snprintf(will_topic, MQTT_TOPIC_MAX_SIZE, "%s/status", mqtt_base_.c_str());
if (!Mqtt::base().empty()) {
snprintf(will_topic, MQTT_TOPIC_MAX_SIZE, "%s/status", Mqtt::base().c_str());
} else {
snprintf(will_topic, MQTT_TOPIC_MAX_SIZE, "status");
}
Expand Down Expand Up @@ -524,15 +524,15 @@ void Mqtt::ha_status() {

char uniq[70];
if (Mqtt::entity_format() == entityFormat::MULTI_SHORT) {
snprintf(uniq, sizeof(uniq), "%s_system_status", mqtt_basename_.c_str());
snprintf(uniq, sizeof(uniq), "%s_system_status", Mqtt::basename().c_str());
} else {
strcpy(uniq, "system_status");
}

doc["uniq_id"] = uniq;
doc["obj_id"] = uniq;

doc["stat_t"] = mqtt_basename_ + "/status";
doc["stat_t"] = Mqtt::base() + "/status";
doc["name"] = "System status";
doc["pl_on"] = "online";
doc["pl_off"] = "offline";
Expand All @@ -544,7 +544,7 @@ void Mqtt::ha_status() {
// doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes

JsonObject dev = doc.createNestedObject("dev");
dev["name"] = Mqtt::basename(); // take basename
dev["name"] = Mqtt::basename();
dev["sw"] = "v" + std::string(EMSESP_APP_VERSION);
dev["mf"] = "proddy";
dev["mdl"] = "EMS-ESP";
Expand Down Expand Up @@ -620,7 +620,7 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con
strlcpy(fulltopic, topic.c_str(), sizeof(fulltopic)); // leave discovery topic as it is
} else {
// it's not a discovery topic, added the mqtt base to the topic path
snprintf(fulltopic, sizeof(fulltopic), "%s/%s", mqtt_base_.c_str(), topic.c_str()); // uses base
snprintf(fulltopic, sizeof(fulltopic), "%s/%s", Mqtt::base().c_str(), topic.c_str());
}

if (operation == Operation::PUBLISH) {
Expand Down Expand Up @@ -982,7 +982,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev

// state topic
char stat_t[MQTT_TOPIC_MAX_SIZE];
snprintf(stat_t, sizeof(stat_t), "%s/%s", mqtt_basename_.c_str(), tag_to_topic(device_type, tag).c_str());
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), tag_to_topic(device_type, tag).c_str());
doc["stat_t"] = stat_t;

// friendly name = <tag> <name>
Expand Down Expand Up @@ -1158,7 +1158,7 @@ bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp,
char min_s[10];
char max_s[10];

snprintf(topic, sizeof(topic), "climate/%s/thermostat_hc%d/config", mqtt_basename_.c_str(), hc_num);
snprintf(topic, sizeof(topic), "climate/%s/thermostat_hc%d/config", Mqtt::basename().c_str(), hc_num);
if (remove) {
return queue_remove_topic(topic); // publish empty payload with retain flag
}
Expand Down Expand Up @@ -1201,7 +1201,7 @@ bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp,
snprintf(name_s, sizeof(name_s), "Hc%d", hc_num);

if (Mqtt::entity_format() == entityFormat::MULTI_SHORT) {
snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_thermostat_hc%d", mqtt_basename_.c_str(), hc_num); // add basename
snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_thermostat_hc%d", Mqtt::basename().c_str(), hc_num); // add basename
} else {
snprintf(uniq_id_s, sizeof(uniq_id_s), "thermostat_hc%d", hc_num); // backward compatible with v3.4
}
Expand All @@ -1211,7 +1211,7 @@ bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp,

StaticJsonDocument<EMSESP_JSON_SIZE_XLARGE> doc; // 1024 is not enough

doc["~"] = mqtt_base_;
doc["~"] = Mqtt::base();
doc["uniq_id"] = uniq_id_s;
doc["obj_id"] = uniq_id_s; // same as uniq_id
doc["name"] = name_s;
Expand Down Expand Up @@ -1278,7 +1278,7 @@ void Mqtt::add_avty_to_doc(const char * state_t, const JsonObject & doc, const c

StaticJsonDocument<512> avty_json;

snprintf(tpl, sizeof(tpl), "%s/status", mqtt_base_.c_str());
snprintf(tpl, sizeof(tpl), "%s/status", Mqtt::base().c_str());
avty_json["t"] = tpl;
snprintf(tpl, sizeof(tpl), tpl_draft, "value == 'online'");
avty_json["val_tpl"] = tpl;
Expand Down
6 changes: 3 additions & 3 deletions src/shower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ void Shower::set_shower_state(bool state, bool force) {
doc["uniq_id"] = str;
doc["object_id"] = str;

snprintf(stat_t, sizeof(stat_t), "%s/shower_active", Mqtt::basename().c_str());
snprintf(stat_t, sizeof(stat_t), "%s/shower_active", Mqtt::base().c_str());
doc["stat_t"] = stat_t;

if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
Expand Down Expand Up @@ -229,7 +229,7 @@ void Shower::set_shower_state(bool state, bool force) {
doc["uniq_id"] = str;
doc["object_id"] = str;

snprintf(stat_t, sizeof(stat_t), "%s/shower_data", Mqtt::basename().c_str());
snprintf(stat_t, sizeof(stat_t), "%s/shower_data", Mqtt::base().c_str());
doc["stat_t"] = stat_t;

doc["name"] = "Shower Duration";
Expand Down Expand Up @@ -258,7 +258,7 @@ void Shower::set_shower_state(bool state, bool force) {
doc["uniq_id"] = str;
doc["object_id"] = str;

snprintf(stat_t, sizeof(stat_t), "%s/shower_data", Mqtt::basename().c_str());
snprintf(stat_t, sizeof(stat_t), "%s/shower_data", Mqtt::base().c_str());
doc["stat_t"] = stat_t;

doc["name"] = "Shower Timestamp";
Expand Down
2 changes: 1 addition & 1 deletion src/temperaturesensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ void TemperatureSensor::publish_values(const bool force) {
config["dev_cla"] = "temperature";

char stat_t[50];
snprintf(stat_t, sizeof(stat_t), "%s/temperaturesensor_data", Mqtt::basename().c_str());
snprintf(stat_t, sizeof(stat_t), "%s/temperaturesensor_data", Mqtt::base().c_str());
config["stat_t"] = stat_t;

config["unit_of_meas"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
Expand Down
2 changes: 1 addition & 1 deletion src/web/WebCustomEntityService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ void WebCustomEntityService::publish(const bool force) {
if (Mqtt::ha_enabled() && !ha_registered_) {
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
char stat_t[50];
snprintf(stat_t, sizeof(stat_t), "%s/custom_data", Mqtt::basename().c_str());
snprintf(stat_t, sizeof(stat_t), "%s/custom_data", Mqtt::base().c_str());
config["stat_t"] = stat_t;

char val_obj[50];
Expand Down
4 changes: 2 additions & 2 deletions src/web/WebSchedulerService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ void WebSchedulerService::publish(const bool force) {
if (Mqtt::ha_enabled() && !ha_registered_) {
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
char stat_t[50];
snprintf(stat_t, sizeof(stat_t), "%s/scheduler_data", Mqtt::basename().c_str());
snprintf(stat_t, sizeof(stat_t), "%s/scheduler_data", Mqtt::base().c_str());
config["stat_t"] = stat_t;

char val_obj[50];
Expand All @@ -273,7 +273,7 @@ void WebSchedulerService::publish(const bool force) {
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
char command_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
snprintf(topic, sizeof(topic), "switch/%s/scheduler_%s/config", Mqtt::basename().c_str(), scheduleItem.name.c_str());
snprintf(command_topic, sizeof(command_topic), "%s/scheduler/%s", Mqtt::basename().c_str(), scheduleItem.name.c_str());
snprintf(command_topic, sizeof(command_topic), "%s/scheduler/%s", Mqtt::base().c_str(), scheduleItem.name.c_str());
config["cmd_t"] = command_topic;
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
config["pl_on"] = true;
Expand Down

0 comments on commit bf5b40c

Please sign in to comment.