mirror of https://github.com/arendst/Tasmota.git
Moved LQI to Zigbee devices
This commit is contained in:
parent
609b0309fa
commit
4af6b7d540
|
@ -71,6 +71,8 @@ typedef struct Z_Device {
|
||||||
uint16_t ct; // last CT: 153-500
|
uint16_t ct; // last CT: 153-500
|
||||||
uint16_t hue; // last Hue: 0..359
|
uint16_t hue; // last Hue: 0..359
|
||||||
uint16_t x, y; // last color [x,y]
|
uint16_t x, y; // last color [x,y]
|
||||||
|
uint8_t linkquality; // lqi from last message, 0xFF means unknown
|
||||||
|
uint8_t batterypercentx2;// battery percentage x 2 (0..200), 0xFF means unknwon
|
||||||
} Z_Device;
|
} Z_Device;
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -147,6 +149,10 @@ public:
|
||||||
const char * getModelId(uint16_t shortaddr) const;
|
const char * getModelId(uint16_t shortaddr) const;
|
||||||
const char * getManufacturerId(uint16_t shortaddr) const;
|
const char * getManufacturerId(uint16_t shortaddr) const;
|
||||||
void setReachable(uint16_t shortaddr, bool reachable);
|
void setReachable(uint16_t shortaddr, bool reachable);
|
||||||
|
void setLQI(uint16_t shortaddr, uint8_t lqi);
|
||||||
|
uint8_t getLQI(uint16_t shortaddr) const;
|
||||||
|
void setBatteryPercentx2(uint16_t shortaddr, uint8_t bpx2);
|
||||||
|
uint8_t getBatteryPercentx2(uint16_t shortaddr) const;
|
||||||
|
|
||||||
// get next sequence number for (increment at each all)
|
// get next sequence number for (increment at each all)
|
||||||
uint8_t getNextSeqNumber(uint16_t shortaddr);
|
uint8_t getNextSeqNumber(uint16_t shortaddr);
|
||||||
|
@ -294,6 +300,8 @@ Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) {
|
||||||
200, // ct
|
200, // ct
|
||||||
0, // hue
|
0, // hue
|
||||||
0, 0, // x, y
|
0, 0, // x, y
|
||||||
|
0xFF, // lqi, 0xFF = unknown
|
||||||
|
0xFF // battery percentage x 2, 0xFF means unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
device_alloc->json_buffer = new DynamicJsonBuffer(16);
|
device_alloc->json_buffer = new DynamicJsonBuffer(16);
|
||||||
|
@ -619,6 +627,36 @@ void Z_Devices::setReachable(uint16_t shortaddr, bool reachable) {
|
||||||
bitWrite(device.power, 7, reachable);
|
bitWrite(device.power, 7, reachable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Z_Devices::setLQI(uint16_t shortaddr, uint8_t lqi) {
|
||||||
|
Z_Device & device = getShortAddr(shortaddr);
|
||||||
|
if (&device == nullptr) { return; } // don't crash if not found
|
||||||
|
device.linkquality = lqi;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Z_Devices::getLQI(uint16_t shortaddr) const {
|
||||||
|
int32_t found = findShortAddr(shortaddr);
|
||||||
|
if (found >= 0) {
|
||||||
|
const Z_Device & device = devicesAt(found);
|
||||||
|
return device.linkquality;
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z_Devices::setBatteryPercentx2(uint16_t shortaddr, uint8_t bpx2) {
|
||||||
|
Z_Device & device = getShortAddr(shortaddr);
|
||||||
|
if (&device == nullptr) { return; } // don't crash if not found
|
||||||
|
device.batterypercentx2 = bpx2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Z_Devices::getBatteryPercentx2(uint16_t shortaddr) const {
|
||||||
|
int32_t found = findShortAddr(shortaddr);
|
||||||
|
if (found >= 0) {
|
||||||
|
const Z_Device & device = devicesAt(found);
|
||||||
|
return device.batterypercentx2;
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
// get the next sequance number for the device, or use the global seq number if device is unknown
|
// get the next sequance number for the device, or use the global seq number if device is unknown
|
||||||
uint8_t Z_Devices::getNextSeqNumber(uint16_t shortaddr) {
|
uint8_t Z_Devices::getNextSeqNumber(uint16_t shortaddr) {
|
||||||
int32_t short_found = findShortAddr(shortaddr);
|
int32_t short_found = findShortAddr(shortaddr);
|
||||||
|
|
|
@ -128,6 +128,7 @@ enum Z_ConvOperators {
|
||||||
Z_AqaraSensor, // decode prioprietary Aqara Sensor message
|
Z_AqaraSensor, // decode prioprietary Aqara Sensor message
|
||||||
Z_AqaraVibration, // decode Aqara vibration modes
|
Z_AqaraVibration, // decode Aqara vibration modes
|
||||||
Z_AqaraCube, // decode Aqara cube
|
Z_AqaraCube, // decode Aqara cube
|
||||||
|
Z_BatteryPercentage, // memorize Battery Percentage in RAM
|
||||||
};
|
};
|
||||||
|
|
||||||
ZF(ZCLVersion) ZF(AppVersion) ZF(StackVersion) ZF(HWVersion) ZF(Manufacturer) ZF(ModelId)
|
ZF(ZCLVersion) ZF(AppVersion) ZF(StackVersion) ZF(HWVersion) ZF(Manufacturer) ZF(ModelId)
|
||||||
|
@ -238,7 +239,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
||||||
{ Zuint16, Cx0001, 0x0000, Z(MainsVoltage), 1, Z_Nop },
|
{ Zuint16, Cx0001, 0x0000, Z(MainsVoltage), 1, Z_Nop },
|
||||||
{ Zuint8, Cx0001, 0x0001, Z(MainsFrequency), 1, Z_Nop },
|
{ Zuint8, Cx0001, 0x0001, Z(MainsFrequency), 1, Z_Nop },
|
||||||
{ Zuint8, Cx0001, 0x0020, Z(BatteryVoltage), -10,Z_Nop }, // divide by 10
|
{ Zuint8, Cx0001, 0x0020, Z(BatteryVoltage), -10,Z_Nop }, // divide by 10
|
||||||
{ Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), -2, Z_Nop }, // divide by 2
|
{ Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), -2, Z_BatteryPercentage }, // divide by 2
|
||||||
|
|
||||||
// Device Temperature Configuration cluster
|
// Device Temperature Configuration cluster
|
||||||
{ Zint16, Cx0002, 0x0000, Z(CurrentTemperature), 1, Z_Nop },
|
{ Zint16, Cx0002, 0x0000, Z(CurrentTemperature), 1, Z_Nop },
|
||||||
|
@ -1176,16 +1177,19 @@ void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) {
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
// Record Manuf
|
// Record Manuf
|
||||||
int32_t Z_ManufKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
int32_t Z_ManufKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
||||||
json[new_name] = value;
|
|
||||||
zigbee_devices.setManufId(shortaddr, value.as<const char*>());
|
zigbee_devices.setManufId(shortaddr, value.as<const char*>());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//
|
// Record ModelId
|
||||||
int32_t Z_ModelKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
int32_t Z_ModelKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
||||||
json[new_name] = value;
|
|
||||||
zigbee_devices.setModelId(shortaddr, value.as<const char*>());
|
zigbee_devices.setModelId(shortaddr, value.as<const char*>());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
// Record BatteryPercentage
|
||||||
|
int32_t Z_BatteryPercentageKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
||||||
|
zigbee_devices.setBatteryPercentx2(shortaddr, value.as<uint8_t>());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Add pressure unit
|
// Add pressure unit
|
||||||
int32_t Z_AddPressureUnitFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
int32_t Z_AddPressureUnitFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
||||||
|
@ -1193,22 +1197,6 @@ int32_t Z_AddPressureUnitFunc(const class ZCLFrame *zcl, uint16_t shortaddr, Jso
|
||||||
return 0; // keep original key
|
return 0; // keep original key
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert int to float and divide by 100
|
|
||||||
int32_t Z_FloatDiv100Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
|
||||||
json[new_name] = ((float)value) / 100.0f;
|
|
||||||
return 1; // remove original key
|
|
||||||
}
|
|
||||||
// Convert int to float and divide by 10
|
|
||||||
int32_t Z_FloatDiv10Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
|
||||||
json[new_name] = ((float)value) / 10.0f;
|
|
||||||
return 1; // remove original key
|
|
||||||
}
|
|
||||||
// Convert int to float and divide by 10
|
|
||||||
int32_t Z_FloatDiv2Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
|
||||||
json[new_name] = ((float)value) / 2.0f;
|
|
||||||
return 1; // remove original key
|
|
||||||
}
|
|
||||||
|
|
||||||
// Publish a message for `"Occupancy":0` when the timer expired
|
// Publish a message for `"Occupancy":0` when the timer expired
|
||||||
int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
||||||
DynamicJsonBuffer jsonBuffer;
|
DynamicJsonBuffer jsonBuffer;
|
||||||
|
@ -1219,8 +1207,6 @@ int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu
|
||||||
|
|
||||||
// Aqara Cube
|
// Aqara Cube
|
||||||
int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) {
|
||||||
json[new_name] = value; // copy the original value
|
|
||||||
|
|
||||||
const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown
|
const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown
|
||||||
String modelId((char*) modelId_c);
|
String modelId((char*) modelId_c);
|
||||||
|
|
||||||
|
@ -1353,7 +1339,13 @@ int32_t Z_AqaraSensorFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObj
|
||||||
json.remove(tmp);
|
json.remove(tmp);
|
||||||
bool translated = false; // were we able to translate to a known format?
|
bool translated = false; // were we able to translate to a known format?
|
||||||
if (0x01 == attrid) {
|
if (0x01 == attrid) {
|
||||||
json[F(D_JSON_VOLTAGE)] = val / 1000.0f;
|
float batteryvoltage = val / 1000.0f;
|
||||||
|
json[F("BatteryVoltage")] = batteryvoltage;
|
||||||
|
uint8_t batterypercentage = toPercentageCR2032(val);
|
||||||
|
json[F("BatteryPercentage")] = batterypercentage;
|
||||||
|
zigbee_devices.setBatteryPercentx2(shortaddr, batterypercentage * 2);
|
||||||
|
// deprecated
|
||||||
|
json[F(D_JSON_VOLTAGE)] = batteryvoltage;
|
||||||
json[F("Battery")] = toPercentageCR2032(val);
|
json[F("Battery")] = toPercentageCR2032(val);
|
||||||
} else if ((nullptr != modelId) && (0 == zcl->getManufCode())) {
|
} else if ((nullptr != modelId) && (0 == zcl->getManufCode())) {
|
||||||
translated = true;
|
translated = true;
|
||||||
|
@ -1431,6 +1423,9 @@ int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje
|
||||||
case Z_AqaraCube:
|
case Z_AqaraCube:
|
||||||
func = &Z_AqaraCubeFunc;
|
func = &Z_AqaraCubeFunc;
|
||||||
break;
|
break;
|
||||||
|
case Z_BatteryPercentage:
|
||||||
|
func = &Z_BatteryPercentageKeepFunc;
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (func) {
|
if (func) {
|
||||||
|
|
|
@ -758,7 +758,7 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) {
|
||||||
timestamp);
|
timestamp);
|
||||||
zcl_received.log();
|
zcl_received.log();
|
||||||
|
|
||||||
ZdSetLinkQuality(srcaddr, linkquality);
|
zigbee_devices.setLQI(srcaddr, linkquality);
|
||||||
|
|
||||||
char shortaddr[8];
|
char shortaddr[8];
|
||||||
snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr);
|
snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr);
|
||||||
|
|
|
@ -1068,44 +1068,6 @@ void CmndZbConfig(void) {
|
||||||
hex_precfgkey_l, hex_precfgkey_h);
|
hex_precfgkey_l, hex_precfgkey_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
|
||||||
* Database of linkqualities - there must be a better way to implement this ...
|
|
||||||
\*********************************************************************************************/
|
|
||||||
|
|
||||||
const uint8_t MAX_ZBRECORDS = 16;
|
|
||||||
|
|
||||||
typedef struct Z_DevRecord_t {
|
|
||||||
uint16_t shortaddr;
|
|
||||||
uint8_t linkquality;
|
|
||||||
} Z_DevRecord_t;
|
|
||||||
|
|
||||||
Z_DevRecord_t Z_DevRecord[MAX_ZBRECORDS];
|
|
||||||
uint8_t Z_DevIndex = 0;
|
|
||||||
|
|
||||||
void ZdSetLinkQuality(uint16_t shortaddr, uint8_t linkquality) {
|
|
||||||
if (Z_DevIndex < MAX_ZBRECORDS -1) {
|
|
||||||
uint32_t i;
|
|
||||||
for (i = 0; i < Z_DevIndex; i++) {
|
|
||||||
if (shortaddr == Z_DevRecord[i].shortaddr) {
|
|
||||||
Z_DevRecord[i].linkquality = linkquality;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Z_DevRecord[i].shortaddr = shortaddr;
|
|
||||||
Z_DevRecord[i].linkquality = linkquality;
|
|
||||||
Z_DevIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ZdGetLinkQuality(uint16_t shortaddr) {
|
|
||||||
for (uint32_t i = 0; i < Z_DevIndex; i++) {
|
|
||||||
if (shortaddr == Z_DevRecord[i].shortaddr) {
|
|
||||||
return Z_DevRecord[i].linkquality;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Presentation
|
* Presentation
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -1128,9 +1090,9 @@ void ZigbeeShow(bool json)
|
||||||
name = spart1;
|
name = spart1;
|
||||||
}
|
}
|
||||||
snprintf_P(spart2, sizeof(spart2), PSTR("-"));
|
snprintf_P(spart2, sizeof(spart2), PSTR("-"));
|
||||||
uint8_t lq = ZdGetLinkQuality(shortaddr);
|
uint8_t lqi = zigbee_devices.getLQI(shortaddr);
|
||||||
if (lq) {
|
if (0xFF != lqi) {
|
||||||
snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lq);
|
snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lqi);
|
||||||
}
|
}
|
||||||
|
|
||||||
WSContentSend_PD(PSTR("{s}%s{m}LQI %s{e}"), name, spart2);
|
WSContentSend_PD(PSTR("{s}%s{m}LQI %s{e}"), name, spart2);
|
||||||
|
|
Loading…
Reference in New Issue