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 hue; // last Hue: 0..359
|
||||
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;
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -147,6 +149,10 @@ public:
|
|||
const char * getModelId(uint16_t shortaddr) const;
|
||||
const char * getManufacturerId(uint16_t shortaddr) const;
|
||||
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)
|
||||
uint8_t getNextSeqNumber(uint16_t shortaddr);
|
||||
|
@ -294,6 +300,8 @@ Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) {
|
|||
200, // ct
|
||||
0, // hue
|
||||
0, 0, // x, y
|
||||
0xFF, // lqi, 0xFF = unknown
|
||||
0xFF // battery percentage x 2, 0xFF means unknown
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
uint8_t Z_Devices::getNextSeqNumber(uint16_t shortaddr) {
|
||||
int32_t short_found = findShortAddr(shortaddr);
|
||||
|
|
|
@ -128,6 +128,7 @@ enum Z_ConvOperators {
|
|||
Z_AqaraSensor, // decode prioprietary Aqara Sensor message
|
||||
Z_AqaraVibration, // decode Aqara vibration modes
|
||||
Z_AqaraCube, // decode Aqara cube
|
||||
Z_BatteryPercentage, // memorize Battery Percentage in RAM
|
||||
};
|
||||
|
||||
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 },
|
||||
{ Zuint8, Cx0001, 0x0001, Z(MainsFrequency), 1, Z_Nop },
|
||||
{ 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
|
||||
{ Zint16, Cx0002, 0x0000, Z(CurrentTemperature), 1, Z_Nop },
|
||||
|
@ -1176,16 +1177,19 @@ void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) {
|
|||
// ======================================================================
|
||||
// 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) {
|
||||
json[new_name] = value;
|
||||
zigbee_devices.setManufId(shortaddr, value.as<const char*>());
|
||||
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) {
|
||||
json[new_name] = value;
|
||||
zigbee_devices.setModelId(shortaddr, value.as<const char*>());
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
|
@ -1219,8 +1207,6 @@ int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu
|
|||
|
||||
// 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) {
|
||||
json[new_name] = value; // copy the original value
|
||||
|
||||
const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown
|
||||
String modelId((char*) modelId_c);
|
||||
|
||||
|
@ -1353,7 +1339,13 @@ int32_t Z_AqaraSensorFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObj
|
|||
json.remove(tmp);
|
||||
bool translated = false; // were we able to translate to a known format?
|
||||
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);
|
||||
} else if ((nullptr != modelId) && (0 == zcl->getManufCode())) {
|
||||
translated = true;
|
||||
|
@ -1431,6 +1423,9 @@ int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje
|
|||
case Z_AqaraCube:
|
||||
func = &Z_AqaraCubeFunc;
|
||||
break;
|
||||
case Z_BatteryPercentage:
|
||||
func = &Z_BatteryPercentageKeepFunc;
|
||||
break;
|
||||
};
|
||||
|
||||
if (func) {
|
||||
|
|
|
@ -758,7 +758,7 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) {
|
|||
timestamp);
|
||||
zcl_received.log();
|
||||
|
||||
ZdSetLinkQuality(srcaddr, linkquality);
|
||||
zigbee_devices.setLQI(srcaddr, linkquality);
|
||||
|
||||
char shortaddr[8];
|
||||
snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr);
|
||||
|
|
|
@ -1068,44 +1068,6 @@ void CmndZbConfig(void) {
|
|||
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
|
||||
\*********************************************************************************************/
|
||||
|
@ -1128,9 +1090,9 @@ void ZigbeeShow(bool json)
|
|||
name = spart1;
|
||||
}
|
||||
snprintf_P(spart2, sizeof(spart2), PSTR("-"));
|
||||
uint8_t lq = ZdGetLinkQuality(shortaddr);
|
||||
if (lq) {
|
||||
snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lq);
|
||||
uint8_t lqi = zigbee_devices.getLQI(shortaddr);
|
||||
if (0xFF != lqi) {
|
||||
snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lqi);
|
||||
}
|
||||
|
||||
WSContentSend_PD(PSTR("{s}%s{m}LQI %s{e}"), name, spart2);
|
||||
|
|
Loading…
Reference in New Issue