From 43b4adc618262331ddd8ec93ea37060c596b0f45 Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 28 Dec 2022 15:39:34 +0100 Subject: [PATCH] changes to #828 --- lib/framework/MqttSettingsService.cpp | 24 +++++------ lib/framework/MqttSettingsService.h | 8 +--- scripts/dump_entities.py | 5 ++- scripts/dump_entities.sh | 6 ++- src/default_settings.h | 4 ++ src/emsdevice.cpp | 61 ++++++++++++++++++++++++--- src/emsdevice.h | 2 + src/emsesp.cpp | 2 +- src/mqtt.cpp | 7 ++- 9 files changed, 85 insertions(+), 34 deletions(-) diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 7491691c5..cc6354c32 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -178,18 +178,17 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting MqttSettings newSettings = {}; bool changed = false; - newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED; - newSettings.host = root["host"] | FACTORY_MQTT_HOST; - newSettings.port = root["port"] | FACTORY_MQTT_PORT; - newSettings.base = root["base"] | FACTORY_MQTT_BASE; - newSettings.username = root["username"] | FACTORY_MQTT_USERNAME; - newSettings.password = root["password"] | FACTORY_MQTT_PASSWORD; - newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID; - newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE; - newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION; - newSettings.entity_format = root["entity_format"] | FACTORY_MQTT_ENTITY_FORMAT; - newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS; - newSettings.mqtt_retain = root["mqtt_retain"] | EMSESP_DEFAULT_MQTT_RETAIN; + newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED; + newSettings.host = root["host"] | FACTORY_MQTT_HOST; + newSettings.port = root["port"] | FACTORY_MQTT_PORT; + newSettings.base = root["base"] | FACTORY_MQTT_BASE; + newSettings.username = root["username"] | FACTORY_MQTT_USERNAME; + newSettings.password = root["password"] | FACTORY_MQTT_PASSWORD; + newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID; + newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE; + newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION; + newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS; + newSettings.mqtt_retain = root["mqtt_retain"] | EMSESP_DEFAULT_MQTT_RETAIN; newSettings.publish_time_boiler = root["publish_time_boiler"] | EMSESP_DEFAULT_PUBLISH_TIME; newSettings.publish_time_thermostat = root["publish_time_thermostat"] | EMSESP_DEFAULT_PUBLISH_TIME; @@ -205,6 +204,7 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting newSettings.publish_single = root["publish_single"] | EMSESP_DEFAULT_PUBLISH_SINGLE; newSettings.publish_single2cmd = root["publish_single2cmd"] | EMSESP_DEFAULT_PUBLISH_SINGLE2CMD; newSettings.send_response = root["send_response"] | EMSESP_DEFAULT_SEND_RESPONSE; + newSettings.entity_format = root["entity_format"] | EMSESP_DEFAULT_ENTITY_FORMAT; if (newSettings.enabled != settings.enabled) { changed = true; diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index d4ec575cc..78ca7df7a 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -57,10 +57,6 @@ static String generateClientId() { #define FACTORY_MQTT_MAX_TOPIC_LENGTH 128 #endif -#ifndef FACTORY_MQTT_ENTITY_FORMAT -#define FACTORY_MQTT_ENTITY_FORMAT 1 // use shortnames -#endif - class MqttSettings { public: // host and port - if enabled @@ -79,9 +75,6 @@ class MqttSettings { uint16_t keepAlive; bool cleanSession; - // multiple instances - uint8_t entity_format; - // proddy EMS-ESP specific String base; uint16_t publish_time_boiler; @@ -99,6 +92,7 @@ class MqttSettings { bool publish_single; bool publish_single2cmd; bool send_response; + uint8_t entity_format; static void read(MqttSettings & settings, JsonObject & root); static StateUpdateResult update(JsonObject & root, MqttSettings & settings); diff --git a/scripts/dump_entities.py b/scripts/dump_entities.py index 7efc0fe0c..df1a65215 100644 --- a/scripts/dump_entities.py +++ b/scripts/dump_entities.py @@ -1,5 +1,6 @@ -# use like -# make clean; make ARGS=-DEMSESP_STANDALONE_DUMP; echo "test dump" | ./emsesp | python3 ./scripts/dump_entities.py +# strips out lines between two markers +# pipe a file into, for example: +# make clean; make ARGS=-DEMSESP_STANDALONE_DUMP; echo "test dump" | ./emsesp | python3 ./scripts/dump_entities.py import fileinput with fileinput.input() as f_input: diff --git a/scripts/dump_entities.sh b/scripts/dump_entities.sh index 76c7fb824..3ba5ad62f 100644 --- a/scripts/dump_entities.sh +++ b/scripts/dump_entities.sh @@ -2,4 +2,8 @@ # creates an CSV file called "dump_entities.cvs" with all devices and their entities # run from top folder like `sh ./scripts/dump_entities.sh` -make clean; make ARGS=-DEMSESP_STANDALONE_DUMP; echo "test dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv +rm -f dump_entities.csv +make clean; +make ARGS=-DEMSESP_STANDALONE_DUMP; +echo "test dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv +cat dump_entities.csv \ No newline at end of file diff --git a/src/default_settings.h b/src/default_settings.h index 230ae9c7f..4366eb4c7 100644 --- a/src/default_settings.h +++ b/src/default_settings.h @@ -209,6 +209,10 @@ #define EMSESP_DEFAULT_WEBLOG_COMPACT true #endif +#ifndef EMSESP_DEFAULT_ENTITY_FORMAT +#define EMSESP_DEFAULT_ENTITY_FORMAT 1 // in MQTT discovery, use shortnames and not multiple (prefixed with base) +#endif + // matches Web UI settings enum { diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 58176d889..4d3cc0dd4 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1063,7 +1063,8 @@ void EMSdevice::getCustomEntities(std::vector & entity_ids) { } #if defined(EMSESP_STANDALONE_DUMP) -// device name, device type, shortname, fullname, type [(enum values) | (min/max)], uom, readable, writeable, visible +// dumps all entity values in native English +// device name,device type,product_id,shortname,fullname,type [(enum values) | (min/max)],uom,writeable,discovery_entityid void EMSdevice::dump_value_info() { for (auto & dv : devicevalues_) { Serial.print(name_); @@ -1071,9 +1072,13 @@ void EMSdevice::dump_value_info() { Serial.print(device_type_name().c_str()); Serial.print(','); + Serial.print(product_id_); + Serial.print(','); + Serial.print(dv.short_name); Serial.print(','); - Serial.print(dv.get_fullname().c_str()); + + Serial.print(dv.fullname[0]); Serial.print(','); // type and optional enum values and min/max @@ -1161,12 +1166,54 @@ void EMSdevice::dump_value_info() { } Serial.print(","); - // readable, writeable, visible flags - Serial.print(!dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE) ? "true" : "false"); + // writeable flag + Serial.print(dv.has_cmd ? "true" : "false"); Serial.print(","); - Serial.print((dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY)) ? "true" : "false"); - Serial.print(","); - Serial.print(!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) ? "true" : "false"); + + // MQTT Discovery entity name, assuming we're using the default v3.5 option + char entity_with_tag[50]; + if (dv.tag >= DeviceValueTAG::TAG_HC1) { + snprintf(entity_with_tag, + sizeof(entity_with_tag), + "%s_%s_%s", + device_type_2_device_name(device_type_), + EMSdevice::tag_to_mqtt(dv.tag).c_str(), + dv.short_name); + } else { + // should really test for which device types have tags (like hc, wwc etc) + // snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_[_]%s", device_type_2_device_name(device_type_), dv.short_name); + snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_%s", device_type_2_device_name(device_type_), dv.short_name); + } + + char entityid[150]; + if (dv.has_cmd) { + switch (dv.type) { + case DeviceValueType::INT: + case DeviceValueType::UINT: + case DeviceValueType::SHORT: + case DeviceValueType::USHORT: + case DeviceValueType::ULONG: + snprintf(entityid, sizeof(entityid), "number.%s", entity_with_tag); + break; + case DeviceValueType::BOOL: + snprintf(entityid, sizeof(entityid), "switch.%s", entity_with_tag); + break; + case DeviceValueType::ENUM: + snprintf(entityid, sizeof(entityid), "select.%s", entity_with_tag); + break; + default: + snprintf(entityid, sizeof(entityid), "sensor.%s", entity_with_tag); + break; + } + } else { + if (dv.type == DeviceValueType::BOOL) { + snprintf(entityid, sizeof(entityid), "binary_sensor.%s", entity_with_tag); // binary sensor (for booleans) + } else { + snprintf(entityid, sizeof(entityid), "sensor.%s", entity_with_tag); // normal HA sensor + } + } + + Serial.print(entityid); Serial.println(); } diff --git a/src/emsdevice.h b/src/emsdevice.h index dde3da85c..f5d3937c1 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -201,7 +201,9 @@ class EMSdevice { bool get_value_info(JsonObject & root, const char * cmd, const int8_t id); void get_dv_info(JsonObject & json); +#if defined(EMSESP_STANDALONE_DUMP) void dump_value_info(); +#endif enum OUTPUT_TARGET : uint8_t { API_VERBOSE, API_SHORTNAMES, MQTT, CONSOLE }; bool generate_values(JsonObject & output, const uint8_t tag_filter, const bool nested, const uint8_t output_target); diff --git a/src/emsesp.cpp b/src/emsesp.cpp index be7aeea5c..792e6c229 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -313,7 +313,7 @@ void EMSESP::show_ems(uuid::console::Shell & shell) { void EMSESP::dump_all_values(uuid::console::Shell & shell) { Serial.println("---- CSV START ----"); // marker use by py script // add header for CSV - Serial.print("device name,device type,shortname,fullname,type [(enum values) | (min/max)],uom,readable,writeable,visible"); + Serial.print("device name,device type,product_id,shortname,fullname,type [(enum values) | (min/max)],uom,writeable,discovery_entityid"); Serial.println(); for (const auto & device_class : EMSFactory::device_handlers()) { diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 76a87da0e..d9d5cb456 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -992,12 +992,11 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // prefix base name to each uniq_id and use the shortname snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); } else if (Mqtt::entity_format() == 1) { - // shortname, no mqtt base + // shortname, no mqtt base. This is the default version. snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); } else { - // entity_format is 0 - // old v3.4 style - // take en_name and replace all spaces and lowercase it + // entity_format is 0, the old v3.4 style + // take en_name and replace all spaces char uniq_s[60]; strlcpy(uniq_s, en_name, sizeof(uniq_s)); Helpers::replace_char(uniq_s, ' ', '_');