mirror of https://github.com/arendst/Tasmota.git
Merge pull request #16567 from s-hadinger/zigbee_fix_attr_write
Fix zigbee attribute writes and configuration
This commit is contained in:
commit
67239431f5
|
@ -278,10 +278,12 @@ uint8_t toPercentageCR2032(uint32_t voltage) {
|
|||
// Adds to buf:
|
||||
// - n bytes: value (typically between 1 and 4 bytes, or bigger for strings)
|
||||
// returns number of bytes of attribute, or <0 if error
|
||||
// If the value is `NAN`, the value encoded is the "zigbee invalid value"
|
||||
int32_t encodeSingleAttribute(SBuffer &buf, double val_d, const char *val_str, uint8_t attrtype) {
|
||||
uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute length, overloaded for variable length attributes
|
||||
uint32_t u32 = val_d;
|
||||
int32_t i32 = val_d;
|
||||
bool nan = isnan(val_d);
|
||||
uint32_t u32 = nan ? 0xFFFFFFFF : roundf(val_d);
|
||||
int32_t i32 = roundf(val_d);
|
||||
float f32 = val_d;
|
||||
|
||||
switch (attrtype) {
|
||||
|
@ -315,13 +317,13 @@ int32_t encodeSingleAttribute(SBuffer &buf, double val_d, const char *val_str, u
|
|||
|
||||
// signed 8
|
||||
case Zint8: // int8
|
||||
buf.add8(i32);
|
||||
buf.add8(nan ? 0x80 : i32);
|
||||
break;
|
||||
case Zint16: // int16
|
||||
buf.add16(i32);
|
||||
buf.add16(nan ? 0x8000 : i32);
|
||||
break;
|
||||
case Zint32: // int32
|
||||
buf.add32(i32);
|
||||
buf.add32(nan ? 0x80000000 : i32);
|
||||
break;
|
||||
|
||||
case Zsingle: // float
|
||||
|
|
|
@ -1594,7 +1594,7 @@ void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uin
|
|||
buf.add16(min_interval);
|
||||
buf.add16(max_interval);
|
||||
if (!Z_isDiscreteDataType(attr_matched.zigbee_type)) { // report_change is only valid for non-discrete data types (numbers)
|
||||
ZbApplyMultiplier(report_change, attr_matched.multiplier, attr_matched.divider, attr_matched.base);
|
||||
ZbApplyMultiplierForWrites(report_change, attr_matched.multiplier, attr_matched.divider, attr_matched.base);
|
||||
// encode value
|
||||
int32_t res = encodeSingleAttribute(buf, report_change, "", attr_matched.zigbee_type);
|
||||
if (res < 0) {
|
||||
|
|
|
@ -219,18 +219,20 @@ void zigbeeZCLSendCmd(class ZCLFrame &zcl) {
|
|||
|
||||
// Definitive doc for Tuya protocol:
|
||||
// https://developer.tuya.com/en/docs/iot-device-dev/tuya-zigbee-universal-docking-access-standard?id=K9ik6zvofpzql#subtitle-6-Private%20cluster
|
||||
// Special encoding for multiplier:
|
||||
|
||||
// Special encoding for multiplier when sending writes or reportable attributes,
|
||||
// I.e. multipliers and dividers are inversed
|
||||
// multiplier == 0: ignore
|
||||
// multiplier == 1: ignore
|
||||
void ZbApplyMultiplier(double &val_d, int8_t multiplier, int8_t divider, int8_t base) {
|
||||
void ZbApplyMultiplierForWrites(double &val_d, int8_t multiplier, int8_t divider, int8_t base) {
|
||||
if (0 != base) {
|
||||
val_d = val_d - base;
|
||||
}
|
||||
if ((0 != multiplier) && (1 != multiplier)) {
|
||||
val_d = val_d * multiplier;
|
||||
val_d = val_d / multiplier;
|
||||
}
|
||||
if ((0 != divider) && (1 != divider)) {
|
||||
val_d = val_d / divider;
|
||||
}
|
||||
if (0 != base) {
|
||||
val_d = val_d + base;
|
||||
val_d = val_d * divider;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +245,7 @@ bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
|
|||
|
||||
if (attr.key_is_str || attr.key_is_cmd) { return false; } // couldn't find attr if so skip
|
||||
if (attr.isNum()) {
|
||||
ZbApplyMultiplier(val_d, attr.attr_multiplier, attr.attr_divider, 0);
|
||||
ZbApplyMultiplierForWrites(val_d, attr.attr_multiplier, attr.attr_divider, 0);
|
||||
}
|
||||
uint32_t u32 = val_d;
|
||||
int32_t i32 = val_d;
|
||||
|
@ -302,7 +304,7 @@ bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_stat
|
|||
|
||||
if (attr.key_is_str && attr.key_is_cmd) { return false; } // couldn't find attr if so skip
|
||||
if (attr.isNum()) {
|
||||
ZbApplyMultiplier(val_d, attr.attr_multiplier, attr.attr_divider, 0);
|
||||
ZbApplyMultiplierForWrites(val_d, attr.attr_multiplier, attr.attr_divider, 0);
|
||||
}
|
||||
|
||||
// push the value in the buffer
|
||||
|
@ -419,9 +421,14 @@ void ZbSendReportWrite(class JsonParserToken val_pubwrite, class ZCLFrame & zcl)
|
|||
// read ReportableChange
|
||||
JsonParserToken val_attr_rc = attr_config[PSTR("ReportableChange")];
|
||||
if (val_attr_rc) {
|
||||
val_d = val_attr_rc.getFloat();
|
||||
// If value is `null` then we send 0xFFFF for invalid value
|
||||
val_str = val_attr_rc.getStr();
|
||||
ZbApplyMultiplier(val_d, attr.attr_multiplier, attr.attr_divider, 0);
|
||||
if (!val_attr_rc.isNull()) {
|
||||
val_d = val_attr_rc.getFloat();
|
||||
ZbApplyMultiplierForWrites(val_d, attr.attr_multiplier, attr.attr_divider, 0);
|
||||
} else {
|
||||
val_d = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
// read TimeoutPeriod
|
||||
|
|
Loading…
Reference in New Issue