mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-16 12:49:56 +03:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -709,9 +709,10 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
LOG_DEBUG("Recreating HA config for analog sensor GPIO %02d", sensor.gpio());
|
||||
|
||||
JsonDocument config;
|
||||
config["~"] = Mqtt::base();
|
||||
|
||||
char stat_t[50];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::base().c_str(), F_(analogsensor)); // use base path
|
||||
snprintf(stat_t, sizeof(stat_t), "~/%s_data", F_(analogsensor)); // use base path
|
||||
config["stat_t"] = stat_t;
|
||||
|
||||
char val_obj[50];
|
||||
@@ -741,6 +742,7 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_%02d", F_(analogsensor), sensor.gpio());
|
||||
}
|
||||
|
||||
config["~"] = Mqtt::base();
|
||||
config["uniq_id"] = uniq_s;
|
||||
|
||||
char name[50];
|
||||
|
||||
@@ -632,9 +632,6 @@ void EMSdevice::add_device_value(int8_t tag, // to b
|
||||
devicevalues_.emplace_back(
|
||||
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
|
||||
|
||||
// add to index for fast lookup by (tag, short_name)
|
||||
devicevalue_index_[{static_cast<uint8_t>(tag), short_name}] = devicevalues_.size() - 1;
|
||||
|
||||
// add a new command if it has a function attached
|
||||
if (has_cmd) {
|
||||
uint8_t flags = CommandFlag::ADMIN_ONLY; // executing commands require admin privileges
|
||||
@@ -2212,13 +2209,14 @@ std::string EMSdevice::name() {
|
||||
// copy a raw value (i.e. without applying the numeric_operator) to the output buffer.
|
||||
// returns true on success.
|
||||
int EMSdevice::get_modbus_value(uint8_t tag, const std::string & shortname, std::vector<uint16_t> & result) {
|
||||
// find device value by shortname using hash map index
|
||||
auto index_it = devicevalue_index_.find({tag, shortname});
|
||||
if (index_it == devicevalue_index_.end()) {
|
||||
// find device value by shortname
|
||||
// TODO replace linear search which is inefficient
|
||||
const auto & it = std::find_if(devicevalues_.begin(), devicevalues_.end(), [&](const DeviceValue & x) { return x.tag == tag && x.short_name == shortname; });
|
||||
if (it == devicevalues_.end() && (it->short_name != shortname || it->tag != tag)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto & dv = devicevalues_[index_it->second];
|
||||
auto & dv = *it;
|
||||
|
||||
// check if it exists, there is a value for the entity. Set the flag to ACTIVE
|
||||
// not that this will override any previously removed states
|
||||
@@ -2299,13 +2297,13 @@ int EMSdevice::get_modbus_value(uint8_t tag, const std::string & shortname, std:
|
||||
int EMSdevice::modbus_value_to_json(uint8_t tag, const std::string & shortname, const std::vector<uint8_t> & modbus_data, JsonObject jsonValue) {
|
||||
// LOG_DEBUG("modbus_value_to_json(%d,%s,[%d bytes])\n", tag, shortname.c_str(), modbus_data.size());
|
||||
|
||||
// find device value by shortname using hash map index
|
||||
auto index_it = devicevalue_index_.find({tag, shortname});
|
||||
if (index_it == devicevalue_index_.end()) {
|
||||
// find device value by shortname
|
||||
const auto & it = std::find_if(devicevalues_.begin(), devicevalues_.end(), [&](const DeviceValue & x) { return x.tag == tag && x.short_name == shortname; });
|
||||
if (it == devicevalues_.end() && (it->short_name != shortname || it->tag != tag)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto & dv = devicevalues_[index_it->second];
|
||||
auto & dv = *it;
|
||||
|
||||
// handle Booleans
|
||||
if (dv.type == DeviceValueType::BOOL) {
|
||||
|
||||
@@ -556,26 +556,6 @@ class EMSdevice {
|
||||
#endif
|
||||
std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types
|
||||
std::vector<DeviceValue> devicevalues_; // all the device values
|
||||
|
||||
// added for modbus
|
||||
// Hash map for O(1) lookup of device values by (tag, short_name) key
|
||||
struct DeviceValueKey {
|
||||
uint8_t tag;
|
||||
std::string short_name;
|
||||
|
||||
bool operator==(const DeviceValueKey & other) const {
|
||||
return tag == other.tag && short_name == other.short_name;
|
||||
}
|
||||
};
|
||||
|
||||
struct DeviceValueKeyHash {
|
||||
std::size_t operator()(const DeviceValueKey & key) const {
|
||||
// Combine hash of tag and short_name
|
||||
return std::hash<uint8_t>()(key.tag) ^ (std::hash<std::string>()(key.short_name) << 1);
|
||||
}
|
||||
};
|
||||
|
||||
std::unordered_map<DeviceValueKey, size_t, DeviceValueKeyHash> devicevalue_index_; // index: key -> devicevalues_ position
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -197,6 +197,8 @@ void Shower::create_ha_discovery() {
|
||||
char str[70];
|
||||
char stat_t[50];
|
||||
|
||||
doc["~"] = Mqtt::base();
|
||||
|
||||
// shower active
|
||||
doc["name"] = "Shower Active";
|
||||
|
||||
@@ -207,9 +209,7 @@ void Shower::create_ha_discovery() {
|
||||
}
|
||||
doc["uniq_id"] = str;
|
||||
doc["def_ent_id"] = (std::string) "binary_sensor." + str;
|
||||
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/shower_active", Mqtt::base().c_str());
|
||||
doc["stat_t"] = stat_t;
|
||||
doc["stat_t"] = "~/shower_active";
|
||||
|
||||
Mqtt::add_ha_bool(doc.as<JsonObject>());
|
||||
Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensor", nullptr, nullptr, nullptr, false);
|
||||
@@ -225,10 +225,7 @@ void Shower::create_ha_discovery() {
|
||||
|
||||
doc["uniq_id"] = str;
|
||||
doc["def_ent_id"] = (std::string) "sensor." + str;
|
||||
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/shower_data", Mqtt::base().c_str());
|
||||
doc["stat_t"] = stat_t;
|
||||
|
||||
doc["stat_t"] = "~/shower_data",
|
||||
doc["name"] = "Shower Duration";
|
||||
|
||||
// don't bother with value template conditions if using Domoticz which doesn't fully support MQTT Discovery
|
||||
@@ -248,29 +245,6 @@ void Shower::create_ha_discovery() {
|
||||
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/shower_duration/config", Mqtt::basename().c_str());
|
||||
Mqtt::queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
|
||||
|
||||
//
|
||||
// shower timestamp
|
||||
//
|
||||
/* commented out as the publish of timestamp
|
||||
doc.clear();
|
||||
|
||||
snprintf(str, sizeof(str), "%s_shower_timestamp", Mqtt::basename().c_str());
|
||||
|
||||
doc["uniq_id"] = str;
|
||||
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/shower_data", Mqtt::base().c_str());
|
||||
doc["stat_t"] = stat_t;
|
||||
|
||||
doc["name"] = "Shower Timestamp";
|
||||
doc["val_tpl"] = "{{value_json.timestamp if value_json.timestamp is defined else 0}}";
|
||||
// doc["ent_cat"] = "diagnostic";
|
||||
|
||||
Mqtt::add_ha_sections_to_doc("shower", stat_t, doc, false, "value_json.timestamp is defined");
|
||||
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/shower_timestamp/config", Mqtt::basename().c_str());
|
||||
Mqtt::queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -507,11 +507,12 @@ void TemperatureSensor::publish_values(const bool force) {
|
||||
LOG_DEBUG("Recreating HA config for sensor ID %s", sensor.id().c_str());
|
||||
|
||||
JsonDocument config;
|
||||
config["~"] = Mqtt::base();
|
||||
config["dev_cla"] = "temperature";
|
||||
config["stat_cla"] = "measurement";
|
||||
|
||||
char stat_t[50];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::base().c_str(), F_(temperaturesensor)); // use base path
|
||||
snprintf(stat_t, sizeof(stat_t), "~/%s_data", F_(temperaturesensor)); // use base path
|
||||
config["stat_t"] = stat_t;
|
||||
|
||||
config["unit_of_meas"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.7.3-dev.33"
|
||||
#define EMSESP_APP_VERSION "3.7.3-dev.34"
|
||||
|
||||
@@ -411,8 +411,10 @@ void WebCustomEntityService::publish(const bool force) {
|
||||
// create HA config
|
||||
if (Mqtt::ha_enabled() && !ha_registered_) {
|
||||
JsonDocument config;
|
||||
config["~"] = Mqtt::base();
|
||||
|
||||
char stat_t[50];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::base().c_str(), F_(custom));
|
||||
snprintf(stat_t, sizeof(stat_t), "~/%s_data", F_(custom));
|
||||
config["stat_t"] = stat_t;
|
||||
|
||||
char val_obj[50];
|
||||
@@ -445,7 +447,7 @@ void WebCustomEntityService::publish(const bool force) {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(custom), entityItem.name.c_str());
|
||||
}
|
||||
char command_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::base().c_str(), F_(custom), entityItem.name.c_str());
|
||||
snprintf(command_topic, sizeof(command_topic), "~/%s/%s", F_(custom), entityItem.name.c_str());
|
||||
config["cmd_t"] = command_topic;
|
||||
} else {
|
||||
if (entityItem.value_type == DeviceValueType::BOOL) {
|
||||
|
||||
@@ -263,9 +263,12 @@ void WebSchedulerService::publish(const bool force) {
|
||||
|
||||
// create HA config
|
||||
if (Mqtt::ha_enabled() && !ha_registered_) {
|
||||
|
||||
JsonDocument config;
|
||||
config["~"] = Mqtt::base();
|
||||
|
||||
char stat_t[50];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::base().c_str(), F_(scheduler));
|
||||
snprintf(stat_t, sizeof(stat_t), "~/%s_data", F_(scheduler));
|
||||
config["stat_t"] = stat_t;
|
||||
|
||||
char val_obj[50];
|
||||
@@ -290,7 +293,7 @@ void WebSchedulerService::publish(const bool force) {
|
||||
char command_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
|
||||
snprintf(topic, sizeof(topic), "switch/%s/%s_%s/config", Mqtt::basename().c_str(), F_(scheduler), scheduleItem.name.c_str());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::base().c_str(), F_(scheduler), scheduleItem.name.c_str());
|
||||
snprintf(command_topic, sizeof(command_topic), "~/%s/%s", F_(scheduler), scheduleItem.name.c_str());
|
||||
config["cmd_t"] = command_topic;
|
||||
|
||||
Mqtt::add_ha_bool(config.as<JsonObject>());
|
||||
|
||||
Reference in New Issue
Block a user