mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
fix MQTT discovery of custom entity doesn't consider type of data #1587
This commit is contained in:
211
src/mqtt.cpp
211
src/mqtt.cpp
@@ -909,9 +909,6 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
|||||||
doc["uniq_id"] = uniq_id;
|
doc["uniq_id"] = uniq_id;
|
||||||
doc["obj_id"] = uniq_id; // same as unique_id
|
doc["obj_id"] = uniq_id; // same as unique_id
|
||||||
|
|
||||||
const char * ic_ha = "ic"; // icon - only set this if there is no device class
|
|
||||||
const char * uom_ha = "unit_of_meas"; // unit of measure
|
|
||||||
|
|
||||||
char sample_val[30] = "0"; // sample, correct(!) entity value, used only to prevent warning/error in HA if real value is not published yet
|
char sample_val[30] = "0"; // sample, correct(!) entity value, used only to prevent warning/error in HA if real value is not published yet
|
||||||
|
|
||||||
// we add the command topic parameter for commands
|
// we add the command topic parameter for commands
|
||||||
@@ -970,10 +967,10 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
|||||||
case DeviceValueUOM::DEGREES:
|
case DeviceValueUOM::DEGREES:
|
||||||
case DeviceValueUOM::DEGREES_R:
|
case DeviceValueUOM::DEGREES_R:
|
||||||
case DeviceValueUOM::K:
|
case DeviceValueUOM::K:
|
||||||
doc[ic_ha] = F_(icondegrees);
|
doc["ic"] = F_(icondegrees);
|
||||||
break;
|
break;
|
||||||
case DeviceValueUOM::PERCENT:
|
case DeviceValueUOM::PERCENT:
|
||||||
doc[ic_ha] = F_(iconpercent);
|
doc["ic"] = F_(iconpercent);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1027,9 +1024,35 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
|||||||
doc["pl_off"] = Helpers::render_boolean(result, false);
|
doc["pl_off"] = Helpers::render_boolean(result, false);
|
||||||
snprintf(sample_val, sizeof(sample_val), "'%s'", Helpers::render_boolean(result, false));
|
snprintf(sample_val, sizeof(sample_val), "'%s'", Helpers::render_boolean(result, false));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// always set the uom, using the standards except for hours/minutes/seconds
|
|
||||||
// using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py
|
doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}";
|
||||||
|
|
||||||
|
// Add the state class, device class and sometimes the icon. Used only for read-only sensors like Sensor and Binary Sensor
|
||||||
|
if (readonly_sensors) {
|
||||||
|
// first set the catagory for System entities
|
||||||
|
// https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873
|
||||||
|
if (device_type == EMSdevice::DeviceType::SYSTEM) {
|
||||||
|
doc["ent_cat"] = "diagnostic";
|
||||||
|
}
|
||||||
|
|
||||||
|
add_ha_uom(doc.as<JsonObject>(), type, uom, entity); // add the UoM, device and state class
|
||||||
|
}
|
||||||
|
|
||||||
|
doc["dev"] = dev_json; // add the dev json object to the end
|
||||||
|
add_ha_sections_to_doc(nullptr, stat_t, doc, false, val_cond); // no name, since the "dev" has already been added
|
||||||
|
|
||||||
|
return queue_ha(topic, doc.as<JsonObject>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) {
|
||||||
|
const char * dc_ha = "dev_cla"; // device class
|
||||||
|
const char * sc_ha = "stat_cla"; // state class
|
||||||
|
const char * uom_ha = "unit_of_meas"; // unit of measure
|
||||||
|
|
||||||
|
// set icon, except for booleans
|
||||||
|
// using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py
|
||||||
|
if (type != DeviceValueType::BOOL) {
|
||||||
if (uom == DeviceValueUOM::HOURS) {
|
if (uom == DeviceValueUOM::HOURS) {
|
||||||
doc[uom_ha] = "h";
|
doc[uom_ha] = "h";
|
||||||
} else if (uom == DeviceValueUOM::MINUTES) {
|
} else if (uom == DeviceValueUOM::MINUTES) {
|
||||||
@@ -1041,105 +1064,87 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}";
|
// set state and device class
|
||||||
|
switch (uom) {
|
||||||
// Add the state class, device class and sometimes the icon. Used only for read-only sensors Sensor and Binary Sensor
|
case DeviceValueUOM::DEGREES:
|
||||||
if (readonly_sensors) {
|
case DeviceValueUOM::DEGREES_R:
|
||||||
// first set the catagory for System entities
|
case DeviceValueUOM::K:
|
||||||
// https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873
|
doc[sc_ha] = F_(measurement);
|
||||||
if (device_type == EMSdevice::DeviceType::SYSTEM) {
|
doc[dc_ha] = "temperature";
|
||||||
doc["ent_cat"] = "diagnostic";
|
break;
|
||||||
}
|
case DeviceValueUOM::PERCENT:
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
const char * dc_ha = "dev_cla"; // device class
|
doc[dc_ha] = "power_factor";
|
||||||
const char * sc_ha = "stat_cla"; // state class
|
break;
|
||||||
|
case DeviceValueUOM::SECONDS:
|
||||||
switch (uom) {
|
case DeviceValueUOM::MINUTES:
|
||||||
case DeviceValueUOM::DEGREES:
|
case DeviceValueUOM::HOURS:
|
||||||
case DeviceValueUOM::DEGREES_R:
|
if (type == DeviceValueType::TIME) {
|
||||||
case DeviceValueUOM::K:
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
doc[dc_ha] = "temperature"; // no icon needed
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::PERCENT:
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
doc[dc_ha] = "power_factor"; // no icon needed
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::SECONDS:
|
|
||||||
case DeviceValueUOM::MINUTES:
|
|
||||||
case DeviceValueUOM::HOURS:
|
|
||||||
if (type == DeviceValueType::TIME) {
|
|
||||||
doc[sc_ha] = F_(total_increasing);
|
|
||||||
} else {
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
}
|
|
||||||
doc[dc_ha] = "duration"; // https://github.com/emsesp/EMS-ESP32/issues/822
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::KB:
|
|
||||||
doc[ic_ha] = F_(iconkb);
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::LMIN:
|
|
||||||
doc[ic_ha] = F_(iconlmin);
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::WH:
|
|
||||||
if (entity == FL_(energyToday)[0]) {
|
|
||||||
doc[sc_ha] = F_(total_increasing);
|
|
||||||
} else {
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
}
|
|
||||||
doc[dc_ha] = "energy";
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::KWH:
|
|
||||||
doc[sc_ha] = F_(total_increasing);
|
doc[sc_ha] = F_(total_increasing);
|
||||||
doc[dc_ha] = "energy";
|
} else {
|
||||||
break;
|
|
||||||
case DeviceValueUOM::UA:
|
|
||||||
doc[ic_ha] = F_(iconua);
|
|
||||||
doc[sc_ha] = F_(measurement);
|
doc[sc_ha] = F_(measurement);
|
||||||
break;
|
|
||||||
case DeviceValueUOM::BAR:
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
doc[dc_ha] = "pressure";
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::W:
|
|
||||||
case DeviceValueUOM::KW:
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
doc[dc_ha] = "power";
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::DBM:
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
doc[dc_ha] = "signal_strength";
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::CONNECTIVITY:
|
|
||||||
doc[sc_ha] = F_(measurement);
|
|
||||||
doc[dc_ha] = "connectivity";
|
|
||||||
break;
|
|
||||||
case DeviceValueUOM::NONE:
|
|
||||||
// for device entities which have numerical values, with no UOM
|
|
||||||
if ((type != DeviceValueType::STRING)
|
|
||||||
&& (type == DeviceValueType::INT || type == DeviceValueType::UINT || type == DeviceValueType::SHORT || type == DeviceValueType::USHORT
|
|
||||||
|| type == DeviceValueType::ULONG)) {
|
|
||||||
doc[ic_ha] = F_(iconnum); // set icon
|
|
||||||
// determine if its a measurement or total increasing
|
|
||||||
// most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart
|
|
||||||
// all the starts are increasing, and they are ULONGs
|
|
||||||
if (type == DeviceValueType::ULONG) {
|
|
||||||
doc[sc_ha] = F_(total_increasing);
|
|
||||||
} else {
|
|
||||||
doc[sc_ha] = F_(measurement); // default to measurement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
doc[dc_ha] = "duration"; // https://github.com/emsesp/EMS-ESP32/issues/822
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::KB:
|
||||||
|
doc["ic"] = F_(iconkb);
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::LMIN:
|
||||||
|
doc["ic"] = F_(iconlmin);
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::WH:
|
||||||
|
if (entity == FL_(energyToday)[0]) {
|
||||||
|
doc[sc_ha] = F_(total_increasing);
|
||||||
|
} else {
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
|
}
|
||||||
|
doc[dc_ha] = "energy";
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::KWH:
|
||||||
|
doc[sc_ha] = F_(total_increasing);
|
||||||
|
doc[dc_ha] = "energy";
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::UA:
|
||||||
|
doc["ic"] = F_(iconua);
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::BAR:
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
|
doc[dc_ha] = "pressure";
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::W:
|
||||||
|
case DeviceValueUOM::KW:
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
|
doc[dc_ha] = "power";
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::DBM:
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
|
doc[dc_ha] = "signal_strength";
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::CONNECTIVITY:
|
||||||
|
doc[sc_ha] = F_(measurement);
|
||||||
|
doc[dc_ha] = "connectivity";
|
||||||
|
break;
|
||||||
|
case DeviceValueUOM::NONE:
|
||||||
|
// for device entities which have numerical values, with no UOM
|
||||||
|
if ((type != DeviceValueType::STRING)
|
||||||
|
&& (type == DeviceValueType::INT || type == DeviceValueType::UINT || type == DeviceValueType::SHORT || type == DeviceValueType::USHORT
|
||||||
|
|| type == DeviceValueType::ULONG)) {
|
||||||
|
doc["ic"] = F_(iconnum); // set icon
|
||||||
|
// determine if its a measurement or total increasing
|
||||||
|
// most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart
|
||||||
|
// all the starts are increasing, and they are ULONGs
|
||||||
|
if (type == DeviceValueType::ULONG) {
|
||||||
|
doc[sc_ha] = F_(total_increasing);
|
||||||
|
} else {
|
||||||
|
doc[sc_ha] = F_(measurement); // default to measurement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc["dev"] = dev_json; // add the dev json object to the end
|
|
||||||
add_ha_sections_to_doc(nullptr, stat_t, doc, false, val_cond); // no name, since the "dev" has already been added
|
|
||||||
|
|
||||||
return queue_ha(topic, doc.as<JsonObject>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) {
|
bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) {
|
||||||
|
|||||||
@@ -221,6 +221,8 @@ class Mqtt {
|
|||||||
|
|
||||||
static std::string tag_to_topic(uint8_t device_type, uint8_t tag);
|
static std::string tag_to_topic(uint8_t device_type, uint8_t tag);
|
||||||
|
|
||||||
|
static void add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity = nullptr);
|
||||||
|
|
||||||
static void add_ha_sections_to_doc(const char * name,
|
static void add_ha_sections_to_doc(const char * name,
|
||||||
const char * state_t,
|
const char * state_t,
|
||||||
JsonDocument & config,
|
JsonDocument & config,
|
||||||
|
|||||||
@@ -441,6 +441,8 @@ void WebCustomEntityService::publish(const bool force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mqtt::add_ha_uom(config.as<JsonObject>(), entityItem.value_type, entityItem.uom); // add uom
|
||||||
|
|
||||||
Mqtt::add_ha_sections_to_doc("custom", stat_t, config, !ha_created, val_cond);
|
Mqtt::add_ha_sections_to_doc("custom", stat_t, config, !ha_created, val_cond);
|
||||||
|
|
||||||
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());
|
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class CustomEntityItem {
|
|||||||
uint16_t type_id;
|
uint16_t type_id;
|
||||||
uint8_t offset;
|
uint8_t offset;
|
||||||
int8_t value_type;
|
int8_t value_type;
|
||||||
uint8_t uom;
|
uint8_t uom; // DeviceValueUOM
|
||||||
std::string name;
|
std::string name;
|
||||||
double factor;
|
double factor;
|
||||||
bool writeable;
|
bool writeable;
|
||||||
|
|||||||
Reference in New Issue
Block a user