mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 16:59:50 +03:00
optimizations and show # entities and languages
This commit is contained in:
@@ -44,56 +44,39 @@ using string_vector = std::vector<const char *>;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
|
#define FPSTR(pstr_pointer) pstr_pointer
|
||||||
|
#define MAKE_WORD_CUSTOM(string_name, string_literal) static const char __pstr__##string_name[] = string_literal;
|
||||||
|
#define MAKE_WORD(string_name) MAKE_WORD_CUSTOM(string_name, #string_name)
|
||||||
|
|
||||||
|
#define F_(string_name) (__pstr__##string_name)
|
||||||
|
#define FL_(list_name) (__pstr__L_##list_name)
|
||||||
|
|
||||||
|
// Translation counter - capture baseline before any MAKE_TRANSLATION calls
|
||||||
|
enum { EMSESP_TRANSLATION_COUNT_START = __COUNTER__ };
|
||||||
|
|
||||||
#define FPSTR(pstr_pointer) pstr_pointer
|
// The language settings below must match system.cpp
|
||||||
#define MAKE_WORD_CUSTOM(string_name, string_literal) static const char __pstr__##string_name[] = string_literal;
|
#if defined(EMSESP_EN_ONLY)
|
||||||
#define MAKE_WORD(string_name) MAKE_WORD_CUSTOM(string_name, #string_name)
|
// EN only
|
||||||
|
#define MAKE_WORD_TRANSLATION(list_name, en, ...) static const char * const __pstr__L_##list_name[] = {en, nullptr};
|
||||||
#define F_(string_name) (__pstr__##string_name)
|
#define MAKE_TRANSLATION(list_name, shortname, en, ...) static constexpr int __translation_counter_##list_name = __COUNTER__; static const char * const __pstr__L_##list_name[] = {shortname, en, nullptr};
|
||||||
#define FL_(list_name) (__pstr__L_##list_name)
|
#elif defined(EMSESP_TEST) || defined(EMSESP_DE_ONLY)
|
||||||
|
// EN + DE (Test mode uses two languages to save flash memory)
|
||||||
// Counter for translations created by MAKE_TRANSLATION
|
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {en, de, nullptr};
|
||||||
extern uint32_t translation_count_;
|
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static constexpr int __translation_counter_##list_name = __COUNTER__; static const char * const __pstr__L_##list_name[] = {shortname, en, de, nullptr};
|
||||||
#include <set>
|
#else
|
||||||
#include <string>
|
// All languages
|
||||||
inline void increment_translation_count_impl(const char * translation_name) {
|
#define MAKE_WORD_TRANSLATION(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
||||||
// Use a static set to track which translations we've already counted by name
|
#define MAKE_TRANSLATION(list_name, ...) static constexpr int __translation_counter_##list_name = __COUNTER__; static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
||||||
// Using std::string ensures we compare by value, not by pointer address
|
#endif
|
||||||
// This ensures we only count each unique translation once, even if included in multiple files
|
|
||||||
static std::set<std::string> counted_translations;
|
#define MAKE_NOTRANSLATION(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
||||||
std::string name(translation_name);
|
|
||||||
if (counted_translations.find(name) == counted_translations.end()) {
|
// fixed strings, no translations
|
||||||
extern uint32_t translation_count_;
|
#define MAKE_ENUM_FIXED(enum_name, ...) static const char * const __pstr__L_##enum_name[] = {__VA_ARGS__, nullptr};
|
||||||
translation_count_++;
|
|
||||||
counted_translations.insert(name);
|
// with translations
|
||||||
}
|
#define MAKE_ENUM(enum_name, ...) static const char * const * __pstr__L_##enum_name[] = {__VA_ARGS__, nullptr};
|
||||||
}
|
|
||||||
|
|
||||||
// The language settings below must match system.cpp
|
|
||||||
#if defined(EMSESP_TEST)
|
|
||||||
// in Test mode use two languages (en & de) to save flash memory needed for the tests
|
|
||||||
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {en, de, nullptr};
|
|
||||||
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, de, nullptr}; static int __translation_counter_##list_name = (increment_translation_count_impl(#list_name), 0);
|
|
||||||
#elif defined(EMSESP_EN_ONLY)
|
|
||||||
// EN only
|
|
||||||
#define MAKE_WORD_TRANSLATION(list_name, en, ...) static const char * const __pstr__L_##list_name[] = {en, nullptr};
|
|
||||||
#define MAKE_TRANSLATION(list_name, shortname, en, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, nullptr}; static int __translation_counter_##list_name = (increment_translation_count_impl(#list_name), 0);
|
|
||||||
#elif defined(EMSESP_DE_ONLY)
|
|
||||||
// EN + DE
|
|
||||||
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {en, de, nullptr};
|
|
||||||
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, de, nullptr}; static int __translation_counter_##list_name = (increment_translation_count_impl(#list_name), 0);
|
|
||||||
#else
|
|
||||||
#define MAKE_WORD_TRANSLATION(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
|
||||||
#define MAKE_TRANSLATION(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr}; static int __translation_counter_##list_name = (increment_translation_count_impl(#list_name), 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAKE_NOTRANSLATION(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
|
||||||
|
|
||||||
// fixed strings, no translations
|
|
||||||
#define MAKE_ENUM_FIXED(enum_name, ...) static const char * const __pstr__L_##enum_name[] = {__VA_ARGS__, nullptr};
|
|
||||||
|
|
||||||
// with translations
|
|
||||||
#define MAKE_ENUM(enum_name, ...) static const char * const * __pstr__L_##enum_name[] = {__VA_ARGS__, nullptr};
|
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@@ -101,4 +84,8 @@ inline void increment_translation_count_impl(const char * translation_name) {
|
|||||||
#include "locale_translations.h"
|
#include "locale_translations.h"
|
||||||
#include "locale_common.h"
|
#include "locale_common.h"
|
||||||
|
|
||||||
|
// Translation count - dynamically calculated at compile-time
|
||||||
|
enum { EMSESP_TRANSLATION_COUNT_END = __COUNTER__ };
|
||||||
|
static constexpr uint16_t EMSESP_TRANSLATION_COUNT = EMSESP_TRANSLATION_COUNT_END - EMSESP_TRANSLATION_COUNT_START - 1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ static_assert(uuid::thread_safe, "uuid-common must be thread-safe");
|
|||||||
static_assert(uuid::log::thread_safe, "uuid-log must be thread-safe");
|
static_assert(uuid::log::thread_safe, "uuid-log must be thread-safe");
|
||||||
static_assert(uuid::console::thread_safe, "uuid-console must be thread-safe");
|
static_assert(uuid::console::thread_safe, "uuid-console must be thread-safe");
|
||||||
|
|
||||||
// Translation counter - incremented by MAKE_TRANSLATION macro (must be global, not in namespace)
|
|
||||||
uint32_t translation_count_ = 0;
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
// Static member definitions
|
// Static member definitions
|
||||||
@@ -99,18 +96,35 @@ Preferences EMSESP::nvs_; // NV Storage
|
|||||||
// for a specific EMS device go and request data values
|
// for a specific EMS device go and request data values
|
||||||
// or if device_id is 0 it will fetch from all our known and active devices
|
// or if device_id is 0 it will fetch from all our known and active devices
|
||||||
void EMSESP::fetch_device_values(const uint8_t device_id) {
|
void EMSESP::fetch_device_values(const uint8_t device_id) {
|
||||||
for (const auto & emsdevice : emsdevices) {
|
// Early return if no devices
|
||||||
if ((device_id == 0) || emsdevice->is_device_id(device_id)) {
|
if (emsdevices.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If device_id is 0, fetch all
|
||||||
|
if (device_id == 0) {
|
||||||
|
for (const auto & emsdevice : emsdevices) {
|
||||||
emsdevice->fetch_values();
|
emsdevice->fetch_values();
|
||||||
if (device_id != 0) {
|
}
|
||||||
return; // quit, we only want to return the selected device
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch specific device
|
||||||
|
for (const auto & emsdevice : emsdevices) {
|
||||||
|
if (emsdevice->is_device_id(device_id)) {
|
||||||
|
emsdevice->fetch_values();
|
||||||
|
return; // quit, we only want to return the selected device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if the deviceID exists
|
// see if the deviceID exists
|
||||||
bool EMSESP::valid_device(const uint8_t device_id) {
|
bool EMSESP::valid_device(const uint8_t device_id) {
|
||||||
|
// Early return if devices list is empty
|
||||||
|
if (emsdevices.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice && emsdevice->is_device_id(device_id)) {
|
if (emsdevice && emsdevice->is_device_id(device_id)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -121,6 +135,10 @@ bool EMSESP::valid_device(const uint8_t device_id) {
|
|||||||
|
|
||||||
// for a specific EMS device type go and request data values
|
// for a specific EMS device type go and request data values
|
||||||
void EMSESP::fetch_device_values_type(const uint8_t device_type) {
|
void EMSESP::fetch_device_values_type(const uint8_t device_type) {
|
||||||
|
if (emsdevices.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||||
emsdevice->fetch_values();
|
emsdevice->fetch_values();
|
||||||
@@ -129,6 +147,10 @@ void EMSESP::fetch_device_values_type(const uint8_t device_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EMSESP::cmd_is_readonly(const uint8_t device_type, const uint8_t device_id, const char * cmd, const int8_t id) {
|
bool EMSESP::cmd_is_readonly(const uint8_t device_type, const uint8_t device_id, const char * cmd, const int8_t id) {
|
||||||
|
if (emsdevices.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice && (emsdevice->device_type() == device_type) && (!device_id || emsdevice->device_id() == device_id)) {
|
if (emsdevice && (emsdevice->device_type() == device_type) && (!device_id || emsdevice->device_id() == device_id)) {
|
||||||
return emsdevice->is_readonly(cmd, id);
|
return emsdevice->is_readonly(cmd, id);
|
||||||
@@ -138,6 +160,10 @@ bool EMSESP::cmd_is_readonly(const uint8_t device_type, const uint8_t device_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EMSESP::device_id_from_cmd(const uint8_t device_type, const char * cmd, const int8_t id) {
|
uint8_t EMSESP::device_id_from_cmd(const uint8_t device_type, const char * cmd, const int8_t id) {
|
||||||
|
if (emsdevices.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice && emsdevice->device_type() == device_type && emsdevice->has_cmd(cmd, id)) {
|
if (emsdevice && emsdevice->device_type() == device_type && emsdevice->has_cmd(cmd, id)) {
|
||||||
return emsdevice->device_id();
|
return emsdevice->device_id();
|
||||||
@@ -154,10 +180,14 @@ void EMSESP::clear_all_devices() {
|
|||||||
|
|
||||||
// return number of devices of a known type
|
// return number of devices of a known type
|
||||||
uint8_t EMSESP::count_devices(const uint8_t device_type) {
|
uint8_t EMSESP::count_devices(const uint8_t device_type) {
|
||||||
|
if (emsdevices.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice) {
|
if (emsdevice && emsdevice->device_type() == device_type) {
|
||||||
count += (emsdevice->device_type() == device_type);
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
@@ -165,10 +195,14 @@ uint8_t EMSESP::count_devices(const uint8_t device_type) {
|
|||||||
|
|
||||||
// return total number of devices excluding the Controller
|
// return total number of devices excluding the Controller
|
||||||
uint8_t EMSESP::count_devices() {
|
uint8_t EMSESP::count_devices() {
|
||||||
|
if (emsdevices.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice) {
|
if (emsdevice && emsdevice->device_type() != EMSdevice::DeviceType::CONTROLLER) {
|
||||||
count += (emsdevice->device_type() != EMSdevice::DeviceType::CONTROLLER);
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
@@ -177,20 +211,22 @@ uint8_t EMSESP::count_devices() {
|
|||||||
// returns the index of a device if there are more of the same type
|
// returns the index of a device if there are more of the same type
|
||||||
// or 0 if there is only one or none
|
// or 0 if there is only one or none
|
||||||
uint8_t EMSESP::device_index(const uint8_t device_type, const uint8_t unique_id) {
|
uint8_t EMSESP::device_index(const uint8_t device_type, const uint8_t unique_id) {
|
||||||
if (count_devices(device_type) <= 1) {
|
uint8_t count = 0;
|
||||||
return 0; // none or only 1 device exists
|
uint8_t index = 0;
|
||||||
}
|
uint8_t current_index = 1;
|
||||||
uint8_t index = 1;
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice->device_type() == device_type) {
|
if (emsdevice->device_type() == device_type) {
|
||||||
// did we find it?
|
count++;
|
||||||
if (emsdevice->unique_id() == unique_id) {
|
if (emsdevice->unique_id() == unique_id) {
|
||||||
return index;
|
index = current_index;
|
||||||
}
|
}
|
||||||
index++;
|
current_index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0; // didn't find it
|
|
||||||
|
// Return 0 if only one device exists or not found
|
||||||
|
return (count <= 1) ? 0 : index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scans for new devices
|
// scans for new devices
|
||||||
@@ -245,13 +281,8 @@ uint8_t EMSESP::bus_status() {
|
|||||||
uint32_t total_fail = txservice_.telegram_read_fail_count() + txservice_.telegram_write_fail_count();
|
uint32_t total_fail = txservice_.telegram_read_fail_count() + txservice_.telegram_write_fail_count();
|
||||||
|
|
||||||
// nothing sent and also no errors - must be ok
|
// nothing sent and also no errors - must be ok
|
||||||
if ((total_sent == 0) && (total_fail == 0)) {
|
if (total_sent == 0) {
|
||||||
return BUS_STATUS_CONNECTED;
|
return (total_fail == 0) ? BUS_STATUS_CONNECTED : BUS_STATUS_TX_ERRORS;
|
||||||
}
|
|
||||||
|
|
||||||
// nothing sent, but have Tx errors
|
|
||||||
if ((total_sent == 0) && (total_fail != 0)) {
|
|
||||||
return BUS_STATUS_TX_ERRORS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx Failure rate > 10%
|
// Tx Failure rate > 10%
|
||||||
@@ -849,41 +880,55 @@ std::string EMSESP::pretty_telegram(std::shared_ptr<const Telegram> telegram) {
|
|||||||
std::string src_name("");
|
std::string src_name("");
|
||||||
std::string dest_name("");
|
std::string dest_name("");
|
||||||
std::string type_name("");
|
std::string type_name("");
|
||||||
|
|
||||||
|
// Single loop to find all device information
|
||||||
|
bool src_found = false;
|
||||||
|
bool dest_found = false;
|
||||||
|
bool type_found = false;
|
||||||
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
// get src & dest
|
// get src name
|
||||||
if (emsdevice->is_device_id(src)) {
|
if (!src_found && emsdevice->is_device_id(src)) {
|
||||||
src_name = emsdevice->device_type_name();
|
src_name = emsdevice->device_type_name();
|
||||||
} else if (emsdevice->is_device_id(dest)) {
|
src_found = true;
|
||||||
dest_name = emsdevice->device_type_name();
|
|
||||||
}
|
}
|
||||||
// get the type name
|
|
||||||
if (type_name.empty()) {
|
// get dest name
|
||||||
|
if (!dest_found && emsdevice->is_device_id(dest)) {
|
||||||
|
dest_name = emsdevice->device_type_name();
|
||||||
|
dest_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the type name (try primary conditions first)
|
||||||
|
if (!type_found) {
|
||||||
if ((telegram->operation == Telegram::Operation::RX_READ && emsdevice->is_device_id(dest))
|
if ((telegram->operation == Telegram::Operation::RX_READ && emsdevice->is_device_id(dest))
|
||||||
|| (telegram->operation != Telegram::Operation::RX_READ && dest == 0 && emsdevice->is_device_id(src))
|
|| (telegram->operation != Telegram::Operation::RX_READ && dest == 0 && emsdevice->is_device_id(src))
|
||||||
|| (telegram->operation != Telegram::Operation::RX_READ && src == EMSbus::ems_bus_id() && emsdevice->is_device_id(dest))) {
|
|| (telegram->operation != Telegram::Operation::RX_READ && src == EMSbus::ems_bus_id() && emsdevice->is_device_id(dest))) {
|
||||||
type_name = emsdevice->telegram_type_name(telegram);
|
type_name = emsdevice->telegram_type_name(telegram);
|
||||||
|
if (!type_name.empty()) {
|
||||||
|
type_found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Early exit if we found everything
|
||||||
|
if (src_found && dest_found && type_found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type_name.empty()) {
|
|
||||||
// fallback, get the type name from src
|
// Fallback for type name if not found - try src or dest
|
||||||
|
if (!type_found && telegram->operation != Telegram::Operation::RX_READ) {
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (telegram->operation != Telegram::Operation::RX_READ && emsdevice->is_device_id(src)) {
|
if (emsdevice->is_device_id(src) || emsdevice->is_device_id(dest)) {
|
||||||
type_name = emsdevice->telegram_type_name(telegram);
|
type_name = emsdevice->telegram_type_name(telegram);
|
||||||
break;
|
if (!type_name.empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type_name.empty()) {
|
|
||||||
// 2nd fallback, get the type name from dest
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
|
||||||
if (telegram->operation != Telegram::Operation::RX_READ && emsdevice->is_device_id(dest)) {
|
|
||||||
type_name = emsdevice->telegram_type_name(telegram);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if we can't find names for the devices, use their hex values
|
// if we can't find names for the devices, use their hex values
|
||||||
if (src_name.empty()) {
|
if (src_name.empty()) {
|
||||||
src_name = device_tostring(src);
|
src_name = device_tostring(src);
|
||||||
@@ -1012,11 +1057,16 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
|
|||||||
if (telegram->offset != 0) {
|
if (telegram->offset != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t msg_len = telegram->message_length;
|
||||||
|
|
||||||
// for empty telegram add device with empty product, version and brand
|
// for empty telegram add device with empty product, version and brand
|
||||||
if (telegram->message_length == 0) {
|
if (msg_len == 0) {
|
||||||
(void)add_device(telegram->src, 0, "00.00", 0);
|
(void)add_device(telegram->src, 0, "00.00", 0);
|
||||||
return;
|
return;
|
||||||
} else if (telegram->message_length < 3) {
|
}
|
||||||
|
|
||||||
|
if (msg_len < 3) {
|
||||||
(void)add_device(telegram->src, telegram->message_data[0], "00.00", 0);
|
(void)add_device(telegram->src, telegram->message_data[0], "00.00", 0);
|
||||||
send_read_request(EMSdevice::EMS_TYPE_NAME, telegram->src, 27);
|
send_read_request(EMSdevice::EMS_TYPE_NAME, telegram->src, 27);
|
||||||
return;
|
return;
|
||||||
@@ -1026,7 +1076,7 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
|
|||||||
uint8_t offset = 0;
|
uint8_t offset = 0;
|
||||||
if (telegram->message_data[0] == 0x00) {
|
if (telegram->message_data[0] == 0x00) {
|
||||||
// see if we have a 2nd subscriber
|
// see if we have a 2nd subscriber
|
||||||
if (telegram->message_length > 5 && telegram->message_data[3] != 0x00) {
|
if (msg_len > 5 && telegram->message_data[3] != 0x00) {
|
||||||
offset = 3;
|
offset = 3;
|
||||||
} else {
|
} else {
|
||||||
return; // ignore whole telegram
|
return; // ignore whole telegram
|
||||||
@@ -1043,7 +1093,7 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
|
|||||||
|
|
||||||
// some devices store the protocol type (HT3, Buderus) in the last byte
|
// some devices store the protocol type (HT3, Buderus) in the last byte
|
||||||
uint8_t brand;
|
uint8_t brand;
|
||||||
if (telegram->message_length >= 10) {
|
if (msg_len >= 10) {
|
||||||
brand = EMSdevice::decode_brand(telegram->message_data[9]);
|
brand = EMSdevice::decode_brand(telegram->message_data[9]);
|
||||||
} else {
|
} else {
|
||||||
brand = EMSdevice::Brand::NO_BRAND; // unknown
|
brand = EMSdevice::Brand::NO_BRAND; // unknown
|
||||||
@@ -1119,57 +1169,53 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// calls the associated process function for that EMS device
|
// calls the associated process function for that EMS device
|
||||||
// returns false if the device_id doesn't recognize it
|
// returns false if the device_id doesn't recognize it
|
||||||
// after the telegram has been processed, see if there have been values changed and we need to do a MQTT publish
|
// after the telegram has been processed, see if there have been values changed and we need to do a MQTT publish
|
||||||
bool telegram_found = false;
|
bool telegram_found = false;
|
||||||
uint8_t device_found = 0;
|
uint8_t device_found = 0;
|
||||||
// broadcast or send to us
|
EMSdevice * found_device = nullptr;
|
||||||
|
|
||||||
|
// Combined loop: check all conditions in a single pass
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
|
// broadcast or send to us
|
||||||
if (emsdevice->is_device_id(telegram->src) && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) {
|
if (emsdevice->is_device_id(telegram->src) && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) {
|
||||||
telegram_found = emsdevice->handle_telegram(telegram);
|
telegram_found = emsdevice->handle_telegram(telegram);
|
||||||
device_found = emsdevice->unique_id();
|
found_device = emsdevice.get();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!telegram_found) {
|
|
||||||
// check for command to the device
|
// check for command to the device
|
||||||
for (const auto & emsdevice : emsdevices) {
|
if (!telegram_found && emsdevice->is_device_id(telegram->dest) && telegram->src != EMSbus::ems_bus_id()) {
|
||||||
if (emsdevice->is_device_id(telegram->dest) && telegram->src != EMSbus::ems_bus_id()) {
|
telegram_found = emsdevice->handle_telegram(telegram);
|
||||||
telegram_found = emsdevice->handle_telegram(telegram);
|
found_device = emsdevice.get();
|
||||||
device_found = emsdevice->unique_id();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!telegram_found) {
|
|
||||||
// check for sends to master thermostat
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
|
||||||
if (emsdevice->is_device_id(telegram->src) && telegram->dest == 0x10) {
|
|
||||||
telegram_found = emsdevice->handle_telegram(telegram);
|
|
||||||
device_found = emsdevice->unique_id();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
|
||||||
if (emsdevice->unique_id() == device_found) {
|
|
||||||
if (!telegram_found && telegram->message_length > 0) {
|
|
||||||
emsdevice->add_handlers_ignored(telegram->type_id);
|
|
||||||
}
|
|
||||||
if (wait_validate_ == telegram->type_id) {
|
|
||||||
wait_validate_ = 0;
|
|
||||||
}
|
|
||||||
if (Mqtt::connected() && telegram_found
|
|
||||||
&& ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update())
|
|
||||||
|| (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id()))) {
|
|
||||||
if (telegram->type_id == publish_id_) {
|
|
||||||
publish_id_ = 0;
|
|
||||||
}
|
|
||||||
emsdevice->has_update(false); // reset flag
|
|
||||||
if (!Mqtt::publish_single()) {
|
|
||||||
publish_device_values(emsdevice->device_type()); // publish to MQTT if we explicitly have too
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// check for sends to master thermostat
|
||||||
|
if (!telegram_found && emsdevice->is_device_id(telegram->src) && telegram->dest == 0x10) {
|
||||||
|
telegram_found = emsdevice->handle_telegram(telegram);
|
||||||
|
found_device = emsdevice.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_device) {
|
||||||
|
device_found = found_device->unique_id();
|
||||||
|
|
||||||
|
// Process the found device directly without another loop
|
||||||
|
if (!telegram_found && telegram->message_length > 0) {
|
||||||
|
found_device->add_handlers_ignored(telegram->type_id);
|
||||||
|
}
|
||||||
|
if (wait_validate_ == telegram->type_id) {
|
||||||
|
wait_validate_ = 0;
|
||||||
|
}
|
||||||
|
if (Mqtt::connected() && telegram_found
|
||||||
|
&& ((mqtt_.get_publish_onchange(found_device->device_type()) && found_device->has_update())
|
||||||
|
|| (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id()))) {
|
||||||
|
if (telegram->type_id == publish_id_) {
|
||||||
|
publish_id_ = 0;
|
||||||
|
}
|
||||||
|
found_device->has_update(false); // reset flag
|
||||||
|
if (!Mqtt::publish_single()) {
|
||||||
|
publish_device_values(found_device->device_type()); // publish to MQTT if we explicitly have too
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// handle unknown broadcasted telegrams (or send to us)
|
// handle unknown broadcasted telegrams (or send to us)
|
||||||
if (!telegram_found && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) {
|
if (!telegram_found && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) {
|
||||||
@@ -1187,6 +1233,10 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
|||||||
|
|
||||||
// return true if we have this device already registered
|
// return true if we have this device already registered
|
||||||
bool EMSESP::device_exists(const uint8_t device_id) {
|
bool EMSESP::device_exists(const uint8_t device_id) {
|
||||||
|
if (emsdevices.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice && emsdevice->is_device_id(device_id)) {
|
if (emsdevice && emsdevice->is_device_id(device_id)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -1254,16 +1304,14 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first check to see if we already have it, if so update the record
|
// first check to see if we already have it, if so update the record
|
||||||
auto it = emsdevices.begin();
|
for (auto it = emsdevices.begin(); it != emsdevices.end(); ++it) {
|
||||||
for (const auto & emsdevice : emsdevices) {
|
if ((*it) && (*it)->is_device_id(device_id)) {
|
||||||
if (emsdevice && emsdevice->is_device_id(device_id)) {
|
if (product_id == 0 || (*it)->product_id() != 0) { // update only with valid product_id
|
||||||
if (product_id == 0 || emsdevice->product_id() != 0) { // update only with valid product_id
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
emsdevices.erase(it); // erase the old device without product_id and re detect
|
emsdevices.erase(it); // erase the old device without product_id and re detect
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
it++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// look up the rest of the details using the product_id and create the new device object
|
// look up the rest of the details using the product_id and create the new device object
|
||||||
@@ -1694,7 +1742,7 @@ void EMSESP::start() {
|
|||||||
device_library_ = {
|
device_library_ = {
|
||||||
#include "device_library.h"
|
#include "device_library.h"
|
||||||
};
|
};
|
||||||
LOG_INFO("Library loaded: %d EMS devices, %d device entities, %s", device_library_.size(), ::translation_count_, system_.languages_string().c_str());
|
LOG_INFO("Library loaded: %d EMS devices, %d device entities, %s", device_library_.size(), EMSESP_TRANSLATION_COUNT, system_.languages_string().c_str());
|
||||||
|
|
||||||
system_.reload_settings(); // ... and store some of the settings locally
|
system_.reload_settings(); // ... and store some of the settings locally
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user