7 Commits

Author SHA1 Message Date
Proddy
c8b4a38bb6 Merge pull request #2829 from proddy/dev
HA fixes part 3
2025-12-19 16:36:17 +01:00
proddy
eec373e2ae publish ha only if ha is enabled 2025-12-19 16:35:55 +01:00
proddy
48b261317d 3.7.3-dev.39 2025-12-19 16:35:40 +01:00
proddy
e6beb01075 package update 2025-12-19 16:35:29 +01:00
proddy
ecc6e9286a tidy up add_ha_dev_section 2025-12-19 08:55:33 +01:00
proddy
179351cb6b add back force, fix for non-HA 2025-12-19 08:54:59 +01:00
proddy
778fe43012 package update 2025-12-19 08:54:30 +01:00
12 changed files with 40 additions and 39 deletions

View File

@@ -67,5 +67,5 @@
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^6.0.3"
},
"packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402"
"packageManager": "pnpm@10.26.1+sha512.664074abc367d2c9324fdc18037097ce0a8f126034160f709928e9e9f95d98714347044e5c3164d65bd5da6c59c6be362b107546292a8eecb7999196e5ce58fa"
}

View File

@@ -1027,8 +1027,8 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
baseline-browser-mapping@2.9.10:
resolution: {integrity: sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==}
baseline-browser-mapping@2.9.11:
resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==}
hasBin: true
bin-build@3.0.0:
@@ -1117,8 +1117,8 @@ packages:
resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==}
engines: {node: '>=0.10.0'}
caniuse-lite@1.0.30001760:
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
caniuse-lite@1.0.30001761:
resolution: {integrity: sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==}
caw@2.0.1:
resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==}
@@ -3958,7 +3958,7 @@ snapshots:
base64-js@1.5.1: {}
baseline-browser-mapping@2.9.10: {}
baseline-browser-mapping@2.9.11: {}
bin-build@3.0.0:
dependencies:
@@ -4015,8 +4015,8 @@ snapshots:
browserslist@4.28.1:
dependencies:
baseline-browser-mapping: 2.9.10
caniuse-lite: 1.0.30001760
baseline-browser-mapping: 2.9.11
caniuse-lite: 1.0.30001761
electron-to-chromium: 1.5.267
node-releases: 2.0.27
update-browserslist-db: 1.2.3(browserslist@4.28.1)
@@ -4075,7 +4075,7 @@ snapshots:
camelcase@2.1.1: {}
caniuse-lite@1.0.30001760: {}
caniuse-lite@1.0.30001761: {}
caw@2.0.1:
dependencies:

View File

@@ -15,5 +15,5 @@
"itty-router": "^5.0.22",
"prettier": "^3.7.4"
},
"packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402"
"packageManager": "pnpm@10.26.1+sha512.664074abc367d2c9324fdc18037097ce0a8f126034160f709928e9e9f95d98714347044e5c3164d65bd5da6c59c6be362b107546292a8eecb7999196e5ce58fa"
}

View File

@@ -804,7 +804,7 @@ void AnalogSensor::publish_values(const bool force) {
config["def_ent_id"] = topic_str.substr(0, topic_str.find("/")) + "." + uniq_s;
// dev section with model is only created on the 1st sensor
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Analog Sensors", nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_dev_created);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Analog Sensors", !ha_dev_created);
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());

View File

@@ -1106,14 +1106,14 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// add origin
JsonObject origin_json = doc["o"].to<JsonObject>();
origin_json["name"] = "EMS-ESP";
origin_json["sw"] = EMSESP_APP_VERSION;
origin_json["sw"] = "v" + std::string(EMSESP_APP_VERSION);
origin_json["url"] = "https://emsesp.org";
// add dev section
if (device_type == EMSdevice::DeviceType::SYSTEM) {
add_ha_dev_section(doc.as<JsonObject>(), nullptr, nullptr, nullptr, nullptr, false);
add_ha_dev_section(doc.as<JsonObject>());
} else {
add_ha_dev_section(doc.as<JsonObject>(), EMSdevice::device_type_2_device_name(device_type), model, brand, version, create_device_config);
add_ha_dev_section(doc.as<JsonObject>(), EMSdevice::device_type_2_device_name(device_type), create_device_config, model, brand, version);
}
return queue_ha(topic, doc.as<JsonObject>());
@@ -1414,8 +1414,8 @@ bool Mqtt::publish_ha_climate_config(const DeviceValue & dv, const bool has_room
doc["ic"] = icon;
}
add_ha_dev_section(doc.as<JsonObject>(), devicename, nullptr, nullptr, nullptr, false); // add dev section
add_ha_avty_section(doc.as<JsonObject>(), topic_t, seltemp_cond, has_roomtemp ? currtemp_cond : nullptr, hc_mode_cond); // add availability section
add_ha_dev_section(doc.as<JsonObject>(), devicename);
add_ha_avty_section(doc.as<JsonObject>(), topic_t, seltemp_cond, has_roomtemp ? currtemp_cond : nullptr, hc_mode_cond);
return queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
}
@@ -1442,7 +1442,7 @@ std::string Mqtt::tag_to_topic(uint8_t device_type, int8_t tag) {
// add devs section to an existing doc, only for HA
// under devs node it will create ids and name and optional mf, mdl, via_device
// name could be EMSdevice::device_type_2_device_name(dv.device_type));
void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const char * model, const char * brand, const char * version, const bool create_model) {
void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const bool create_model, const char * model, const char * brand, const char * version) {
// only works for HA
if (discovery_type() != discoveryType::HOMEASSISTANT) {
return;
@@ -1472,14 +1472,12 @@ void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const char * mo
dev_json["name"] = Mqtt::basename();
}
// add mf, mdl, sw and via_device
// add mf (manufacturer/brand), mdl (model), sw (software version) and via_device
dev_json["mf"] = brand != nullptr ? brand : "EMS-ESP";
if (model != nullptr) {
dev_json["mdl"] = model;
}
if (version != nullptr) {
dev_json["sw"] = version;
}
dev_json["sw"] = version != nullptr ? version : "v" + std::string(EMSESP_APP_VERSION);
dev_json["via_device"] = Mqtt::basename();
}
}

View File

@@ -259,7 +259,12 @@ class Mqtt {
static void
add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8_t type, const uint8_t uom, const char * entity = nullptr, bool is_discovery = true);
static void add_ha_dev_section(JsonObject doc, const char * name, const char * model, const char * brand, const char * version, const bool create_model);
static void add_ha_dev_section(JsonObject doc,
const char * name = nullptr,
const bool create_model = false,
const char * model = nullptr,
const char * brand = nullptr,
const char * version = nullptr);
static void add_ha_avty_section(JsonObject doc,
const char * state_t = nullptr,
const char * cond1 = nullptr,

View File

@@ -210,7 +210,7 @@ void Shower::create_ha_discovery() {
doc["stat_t"] = "~/shower_active";
Mqtt::add_ha_bool(doc.as<JsonObject>());
Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensors", nullptr, nullptr, nullptr, false);
Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensors", true);
Mqtt::add_ha_avty_section(doc.as<JsonObject>()); // no conditions
snprintf(topic, sizeof(topic), "binary_sensor/%s/shower_active/config", Mqtt::basename().c_str());
@@ -239,7 +239,7 @@ void Shower::create_ha_discovery() {
doc["dev_cla"] = "duration";
// doc["ent_cat"] = "diagnostic";
Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensors", nullptr, "EMS-ESP", EMSESP_APP_VERSION, true);
Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensors");
Mqtt::add_ha_avty_section(doc.as<JsonObject>(), "~/shower_data", "value_json.duration is defined");
snprintf(topic, sizeof(topic), "sensor/%s/shower_duration/config", Mqtt::basename().c_str());

View File

@@ -545,7 +545,7 @@ void TemperatureSensor::publish_values(const bool force) {
config["name"] = (const char *)sensor.name();
// dev section with model is only created on the 1st sensor
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Temperature Sensors", nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_dev_created);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Temperature Sensors", !ha_dev_created);
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.3-dev.38"
#define EMSESP_APP_VERSION "3.7.3-dev.39"

View File

@@ -383,12 +383,6 @@ void WebCustomEntityService::publish() {
return;
}
if (Mqtt::publish_single()) {
for (CustomEntityItem & entityItem : *customEntityItems_) {
publish_single(entityItem);
}
}
JsonDocument doc;
JsonObject output = doc.to<JsonObject>();
bool ha_created = ha_configdone_;
@@ -399,7 +393,7 @@ void WebCustomEntityService::publish() {
}
render_value(output, entityItem);
// create HA config
if (!ha_configdone_) {
if (Mqtt::ha_enabled() && !ha_configdone_) {
JsonDocument config;
config["~"] = Mqtt::base();
@@ -457,7 +451,7 @@ void WebCustomEntityService::publish() {
config["def_ent_id"] = topic_str.substr(0, topic_str.find("/")) + "." + uniq_s;
Mqtt::add_ha_classes(config.as<JsonObject>(), EMSdevice::DeviceType::SYSTEM, entityItem.value_type, entityItem.uom);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Custom Entities", nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_created);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Custom Entities", !ha_created);
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());

View File

@@ -216,12 +216,16 @@ void WebSchedulerService::publish_single(const char * name, const bool state) {
}
// publish to Mqtt
void WebSchedulerService::publish() {
void WebSchedulerService::publish(const bool force) {
if (force) {
ha_configdone_ = false;
}
if (!Mqtt::enabled() || scheduleItems_->empty()) {
return;
}
if (Mqtt::publish_single()) {
if (Mqtt::publish_single() && force) {
for (const ScheduleItem & scheduleItem : *scheduleItems_) {
publish_single(scheduleItem.name, scheduleItem.active);
}
@@ -235,7 +239,7 @@ void WebSchedulerService::publish() {
Mqtt::add_value_bool(output, (const char *)scheduleItem.name, scheduleItem.active);
// create HA config
if (!ha_configdone_) {
if (Mqtt::ha_enabled() && !ha_configdone_) {
JsonDocument config;
config["~"] = Mqtt::base();
@@ -269,7 +273,7 @@ void WebSchedulerService::publish() {
config["cmd_t"] = command_topic;
Mqtt::add_ha_bool(config.as<JsonObject>());
Mqtt::add_ha_dev_section(config.as<JsonObject>(), F_(scheduler), nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_created);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), F_(scheduler), !ha_created);
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());

View File

@@ -78,7 +78,7 @@ class WebSchedulerService : public StatefulService<WebScheduler> {
void begin();
void loop();
void publish_single(const char * name, const bool state);
void publish();
void publish(const bool force = false);
bool command_setvalue(const char * value, const int8_t id, const char * name);
bool get_value_info(JsonObject output, const char * cmd);
void get_value_json(JsonObject output, const ScheduleItem & scheduleItem);