mirror of https://github.com/arendst/Tasmota.git
Fix zigbee attribute writes and configuration
This commit is contained in:
parent
3a356263ba
commit
e94baa84cf
|
@ -278,10 +278,12 @@ uint8_t toPercentageCR2032(uint32_t voltage) {
|
||||||
// Adds to buf:
|
// Adds to buf:
|
||||||
// - n bytes: value (typically between 1 and 4 bytes, or bigger for strings)
|
// - n bytes: value (typically between 1 and 4 bytes, or bigger for strings)
|
||||||
// returns number of bytes of attribute, or <0 if error
|
// 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) {
|
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 len = Z_getDatatypeLen(attrtype); // pre-compute length, overloaded for variable length attributes
|
||||||
uint32_t u32 = val_d;
|
bool nan = isnan(val_d);
|
||||||
int32_t i32 = val_d;
|
uint32_t u32 = nan ? 0xFFFFFFFF : roundf(val_d);
|
||||||
|
int32_t i32 = roundf(val_d);
|
||||||
float f32 = val_d;
|
float f32 = val_d;
|
||||||
|
|
||||||
switch (attrtype) {
|
switch (attrtype) {
|
||||||
|
@ -315,13 +317,13 @@ int32_t encodeSingleAttribute(SBuffer &buf, double val_d, const char *val_str, u
|
||||||
|
|
||||||
// signed 8
|
// signed 8
|
||||||
case Zint8: // int8
|
case Zint8: // int8
|
||||||
buf.add8(i32);
|
buf.add8(nan ? 0x80 : i32);
|
||||||
break;
|
break;
|
||||||
case Zint16: // int16
|
case Zint16: // int16
|
||||||
buf.add16(i32);
|
buf.add16(nan ? 0x8000 : i32);
|
||||||
break;
|
break;
|
||||||
case Zint32: // int32
|
case Zint32: // int32
|
||||||
buf.add32(i32);
|
buf.add32(nan ? 0x80000000 : i32);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Zsingle: // float
|
case Zsingle: // float
|
||||||
|
|
|
@ -1594,7 +1594,7 @@ void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uin
|
||||||
buf.add16(min_interval);
|
buf.add16(min_interval);
|
||||||
buf.add16(max_interval);
|
buf.add16(max_interval);
|
||||||
if (!Z_isDiscreteDataType(attr_matched.zigbee_type)) { // report_change is only valid for non-discrete data types (numbers)
|
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
|
// encode value
|
||||||
int32_t res = encodeSingleAttribute(buf, report_change, "", attr_matched.zigbee_type);
|
int32_t res = encodeSingleAttribute(buf, report_change, "", attr_matched.zigbee_type);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
|
|
@ -219,18 +219,20 @@ void zigbeeZCLSendCmd(class ZCLFrame &zcl) {
|
||||||
|
|
||||||
// Definitive doc for Tuya protocol:
|
// 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
|
// 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 == 0: ignore
|
||||||
// multiplier == 1: 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)) {
|
if ((0 != multiplier) && (1 != multiplier)) {
|
||||||
val_d = val_d * multiplier;
|
val_d = val_d / multiplier;
|
||||||
}
|
}
|
||||||
if ((0 != divider) && (1 != divider)) {
|
if ((0 != divider) && (1 != divider)) {
|
||||||
val_d = val_d / divider;
|
val_d = val_d * divider;
|
||||||
}
|
|
||||||
if (0 != base) {
|
|
||||||
val_d = val_d + base;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.key_is_str || attr.key_is_cmd) { return false; } // couldn't find attr if so skip
|
||||||
if (attr.isNum()) {
|
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;
|
uint32_t u32 = val_d;
|
||||||
int32_t i32 = 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.key_is_str && attr.key_is_cmd) { return false; } // couldn't find attr if so skip
|
||||||
if (attr.isNum()) {
|
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
|
// push the value in the buffer
|
||||||
|
@ -419,9 +421,14 @@ void ZbSendReportWrite(class JsonParserToken val_pubwrite, class ZCLFrame & zcl)
|
||||||
// read ReportableChange
|
// read ReportableChange
|
||||||
JsonParserToken val_attr_rc = attr_config[PSTR("ReportableChange")];
|
JsonParserToken val_attr_rc = attr_config[PSTR("ReportableChange")];
|
||||||
if (val_attr_rc) {
|
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();
|
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
|
// read TimeoutPeriod
|
||||||
|
|
Loading…
Reference in New Issue