Merge pull request #16778 from s-hadinger/zigbee_plugin_optim

Zigbee plugin optimize memory
This commit is contained in:
s-hadinger 2022-10-09 22:03:31 +02:00 committed by GitHub
commit b2f1cc2c55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 18 deletions

View File

@ -264,6 +264,28 @@ EF00_0372,last_irrigation_duration
*/
void Z_setString(char*& attr, const char * str) {
if (nullptr == str) { str = PSTR(""); } // nullptr is considered empty string
size_t str_len = strlen(str);
if ((nullptr == attr) && (0 == str_len)) { return; } // if both empty, don't do anything
if (attr) {
// we already have a value
if (strcmp(attr, str) != 0) {
// new value
free(attr); // free previous value
attr = nullptr;
} else {
return; // same value, don't change anything
}
}
if (str_len) {
if (str_len > 31) { str_len = 31; }
attr = (char*) malloc(str_len + 1);
strlcpy(attr, str, str_len + 1);
}
}
//
//
// Class for a single attribute from a plugin
@ -275,12 +297,22 @@ public:
Z_plugin_attribute(void) :
type(Zunk),
multiplier(1), divider(1), base(0),
cluster(0xFFFF), attribute(0xFFFF), manuf(0)
cluster(0xFFFF), attribute(0xFFFF), manuf(0),
name(nullptr)
{};
~Z_plugin_attribute(void) {
if (name != nullptr) { free((void*)name); }
}
void set(uint16_t cluster, uint16_t attribute, const char *name, uint8_t type = Zunk) {
inline void setName(const char *_name) {
Z_setString(this->name, _name);
}
void set(uint16_t cluster, uint16_t attribute, const char *_name, uint8_t type = Zunk) {
this->cluster = cluster;
this->attribute = attribute;
Z_setString(this->name, _name);
this->name = name;
this->type = type;
}
@ -292,7 +324,7 @@ public:
uint16_t cluster; // cluster number
uint16_t attribute; // attribute number
uint16_t manuf; // manufacturer code, 0 if none
String name; // name of attribute once converted
char * name; // name of attribute once converted
};
//
@ -337,9 +369,18 @@ public:
Z_plugin_matcher(void) {};
inline void setModelManuf(const char *_model, const char *_manuf) {
model = (const char*)_model;
manufacturer = (const char*)_manuf;
inline void setModel(const char *_model) {
Z_setString(this->model, _model);
}
inline void setManuf(const char *_manuf) {
Z_setString(this->manufacturer, _manuf);
}
~Z_plugin_matcher(void) {
if (model) { free((void*)model); }
if (manufacturer) { free((void*)manufacturer); }
}
// check if a matches b, return true if so
@ -372,18 +413,18 @@ public:
bool match(const char *match_model, const char *match_manuf) const {
bool match = true;
if (!matchStar(model.c_str(), match_model)) {
if (!matchStar(model, match_model)) {
match = false;
}
if (!matchStar(manufacturer.c_str(), match_manuf)) {
if (!matchStar(manufacturer, match_manuf)) {
match = false;
}
// AddLog(LOG_LEVEL_DEBUG, ">match device(%s, %s) compared to (%s, %s) = %i", match_model, match_manuf, model.c_str(), manufacturer.c_str(), match);
// AddLog(LOG_LEVEL_DEBUG, ">match device(%s, %s) compared to (%s, %s) = %i", match_model, match_manuf, model ? model : "", manufacturer ? manufacturer : "", match);
return match;
}
String model;
String manufacturer;
char * model = nullptr;
char * manufacturer = nullptr;
};
//
@ -468,7 +509,7 @@ const Z_plugin_attribute * Z_plugin_templates::matchAttributeByName(const char *
if (mtch.match(model, manufacturer)) {
// got a match, apply template
for (const Z_plugin_attribute & attr : attributes) {
if (attr.name.equals(name)) {
if (0 == strcasecmp_P(name, attr.name ? attr.name : "")) {
return &attr;
}
}

View File

@ -58,7 +58,7 @@ Z_attribute_match Z_plugin_matchAttributeById(const char *model, const char *man
if (attr_tmpl != nullptr) {
attr.cluster = attr_tmpl->cluster;
attr.attribute = attr_tmpl->attribute;
attr.name = attr_tmpl->name.c_str();
attr.name = attr_tmpl->name;
attr.zigbee_type = attr_tmpl->type;
attr.multiplier = attr_tmpl->multiplier;
attr.divider = attr_tmpl->divider;
@ -80,7 +80,7 @@ Z_attribute_match Z_plugin_matchAttributeByName(const char *model, const char *m
if (attr_tmpl != nullptr) {
attr.cluster = attr_tmpl->cluster;
attr.attribute = attr_tmpl->attribute;
attr.name = attr_tmpl->name.c_str();
attr.name = attr_tmpl->name;
attr.zigbee_type = attr_tmpl->type;
attr.multiplier = attr_tmpl->multiplier;
attr.divider = attr_tmpl->divider;
@ -203,11 +203,11 @@ bool ZbLoad(const char *filename_raw) {
char *token = strtok_r(rest, ",", &rest);
Z_plugin_matcher & matcher = tmpl->matchers.addToLast();
if (token != nullptr) {
matcher.model = token;
matcher.setModel(token);
}
token = strtok_r(rest, ",", &rest);
if (token != nullptr) {
matcher.manufacturer = token;
matcher.setManuf(token);
}
} else {
if (tmpl == nullptr) {
@ -285,7 +285,7 @@ bool ZbLoad(const char *filename_raw) {
plugin_attr.cluster = cluster_id;
plugin_attr.attribute = attr_id;
plugin_attr.type = type_id;
plugin_attr.name = name;
plugin_attr.setName(name);
plugin_attr.multiplier = multiplier;
plugin_attr.divider = divider;
plugin_attr.base = base;
@ -413,7 +413,7 @@ void ZbLoadDump(void) {
AddLog(LOG_LEVEL_INFO, PSTR("%s"), buf);
} else {
for (const Z_plugin_matcher & matcher : tmpl.matchers) {
ext_snprintf_P(buf, sizeof(buf), ":%s,%s", matcher.model.c_str(), matcher.manufacturer.c_str());
ext_snprintf_P(buf, sizeof(buf), ":%s,%s", matcher.model ? matcher.model : "", matcher.manufacturer ? matcher.manufacturer : "");
AddLog(LOG_LEVEL_INFO, PSTR("%s"), buf);
}
}
@ -430,6 +430,7 @@ void ZbLoadDump(void) {
Z_getTypeByNumber(type_str, sizeof(type_str), attr.type);
ext_snprintf_P(buf, sizeof(buf), "%s%%%s", buf, type_str);
}
ext_snprintf_P(buf, sizeof(buf), "%s,%s", buf, attr.name);
Z_AppendModifiers(buf, sizeof(buf), attr.multiplier, attr.divider, attr.base, attr.manuf);
AddLog(LOG_LEVEL_INFO, PSTR("%s"), buf);
}