mirror of https://github.com/arendst/Tasmota.git
Zigbee added ``ZbMap`` command to describe Zigbee topology
This commit is contained in:
parent
7ce5365cf6
commit
a0801b11da
|
@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
|
|||
- TLS in binary tasmota-zbbridge (#9635)
|
||||
- Support for EZO O2 sensors by Christopher Tremblay (#9619)
|
||||
- Zigbee reduce battery drain (#9642)
|
||||
- Zigbee added ``ZbMap`` command to describe Zigbee topology
|
||||
|
||||
### Changed
|
||||
- PlatformIO library structure redesigned for compilation speed by Jason2866
|
||||
|
|
|
@ -565,6 +565,8 @@
|
|||
#define D_JSON_ZIGBEE_UNBIND "ZbUnbind"
|
||||
#define D_CMND_ZIGBEE_BIND_STATE "BindState"
|
||||
#define D_JSON_ZIGBEE_BIND_STATE "ZbBindState"
|
||||
#define D_CMND_ZIGBEE_MAP "Map"
|
||||
#define D_JSON_ZIGBEE_MAP "ZbMap"
|
||||
#define D_JSON_ZIGBEE_PARENT "ZbParent"
|
||||
#define D_CMND_ZIGBEE_PING "Ping"
|
||||
#define D_JSON_ZIGBEE_PING "ZbPing"
|
||||
|
|
|
@ -925,6 +925,7 @@ int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle MgMt Bind Rsp incoming message
|
||||
//
|
||||
|
@ -1002,6 +1003,116 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Return false, true or null (if unknown)
|
||||
const char * TrueFalseNull(uint32_t value) {
|
||||
if (value == 0) {
|
||||
return PSTR("false");
|
||||
} else if (value == 1) {
|
||||
return PSTR("true");
|
||||
} else {
|
||||
return PSTR("null");
|
||||
}
|
||||
}
|
||||
|
||||
const char * Z_DeviceRelationship(uint32_t value) {
|
||||
switch (value) {
|
||||
case 0: return PSTR("Parent");
|
||||
case 1: return PSTR("Child");
|
||||
case 2: return PSTR("Sibling");
|
||||
case 4: return PSTR("Previous");
|
||||
case 3:
|
||||
default: return PSTR("None");
|
||||
}
|
||||
}
|
||||
|
||||
const char * Z_DeviceType(uint32_t value) {
|
||||
switch (value) {
|
||||
case 0: return PSTR("Coordinator");
|
||||
case 1: return PSTR("Router");
|
||||
case 2: return PSTR("Device");
|
||||
default: return PSTR("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle MgMt Bind Rsp incoming message
|
||||
//
|
||||
int32_t Z_MgmtLqiRsp(int32_t res, const class SBuffer &buf) {
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
uint16_t shortaddr = buf.get16(2);
|
||||
uint8_t status = buf.get8(4);
|
||||
uint8_t lqi_total = buf.get8(5);
|
||||
uint8_t lqi_start = buf.get8(6);
|
||||
uint8_t lqi_len = buf.get8(7);
|
||||
const size_t prefix_len = 8;
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
uint16_t shortaddr = buf.get16(buf.len()-2);
|
||||
uint8_t status = buf.get8(0);
|
||||
uint8_t lqi_total = buf.get8(1);
|
||||
uint8_t lqi_start = buf.get8(2);
|
||||
uint8_t lqi_len = buf.get8(3);
|
||||
const size_t prefix_len = 4;
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr);
|
||||
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_MAP "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), shortaddr);
|
||||
if (friendlyName) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName);
|
||||
}
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
||||
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
||||
",\"MapTotal\":%d"
|
||||
",\"MapStart\":%d"
|
||||
",\"Map\":["
|
||||
), status, getZigbeeStatusMessage(status).c_str(), lqi_total, lqi_start + 1);
|
||||
|
||||
uint32_t idx = prefix_len;
|
||||
for (uint32_t i = 0; i < lqi_len; i++) {
|
||||
if (idx + 22 > buf.len()) { break; } // size 22 for EZSP
|
||||
|
||||
//uint64_t extpanid = buf.get16(idx); // unused
|
||||
// uint64_t m_longaddr = buf.get64(idx + 8);
|
||||
uint16_t m_shortaddr = buf.get16(idx + 16);
|
||||
uint8_t m_dev_type = buf.get8(idx + 18);
|
||||
uint8_t m_permitjoin = buf.get8(idx + 19);
|
||||
uint8_t m_depth = buf.get8(idx + 20);
|
||||
uint8_t m_lqi = buf.get8(idx + 21);
|
||||
idx += 22;
|
||||
|
||||
if (i > 0) {
|
||||
ResponseAppend_P(PSTR(","));
|
||||
}
|
||||
ResponseAppend_P(PSTR("{\"Device\":\"0x%04X\","), m_shortaddr);
|
||||
|
||||
const char * friendlyName = zigbee_devices.getFriendlyName(m_shortaddr);
|
||||
if (friendlyName) {
|
||||
ResponseAppend_P(PSTR("\"Name\":\"%s\","), friendlyName);
|
||||
}
|
||||
ResponseAppend_P(PSTR("\"DeviceType\":\"%s\","
|
||||
"\"RxOnWhenIdle\":%s,"
|
||||
"\"Relationship\":\"%s\","
|
||||
"\"PermitJoin\":%s,"
|
||||
"\"Depth\":%d,"
|
||||
"\"LinkQuality\":%d"
|
||||
"}"
|
||||
),
|
||||
Z_DeviceType(m_dev_type & 0x03),
|
||||
TrueFalseNull((m_dev_type & 0x0C) >> 2),
|
||||
Z_DeviceRelationship((m_dev_type & 0x70) >> 4),
|
||||
TrueFalseNull(m_permitjoin & 0x02),
|
||||
m_depth,
|
||||
m_lqi);
|
||||
}
|
||||
|
||||
ResponseAppend_P(PSTR("]}}"));
|
||||
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_MAP));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
//
|
||||
// Handle Parent Annonce Rsp incoming message
|
||||
|
@ -1524,6 +1635,8 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) {
|
|||
return Z_BindRsp(res, zdo_buf);
|
||||
case ZDO_Unbind_rsp:
|
||||
return Z_UnbindRsp(res, zdo_buf);
|
||||
case ZDO_Mgmt_Lqi_rsp:
|
||||
return Z_MgmtLqiRsp(res, zdo_buf);
|
||||
case ZDO_Mgmt_Bind_rsp:
|
||||
return Z_MgmtBindRsp(res, zdo_buf);
|
||||
case ZDO_Parent_annce:
|
||||
|
@ -1697,6 +1810,7 @@ const Z_Dispatcher Z_DispatchTable[] PROGMEM = {
|
|||
{ { Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP }, &Z_ReceiveIEEEAddr }, // 4581
|
||||
{ { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &Z_BindRsp }, // 45A1
|
||||
{ { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &Z_UnbindRsp }, // 45A2
|
||||
{ { Z_AREQ | Z_ZDO, ZDO_MGMT_LQI_RSP }, &Z_MgmtLqiRsp }, // 45B1
|
||||
{ { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &Z_MgmtBindRsp }, // 45B3
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
|||
D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" D_CMND_ZIGBEE_PROBE "|"
|
||||
D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|"
|
||||
D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|"
|
||||
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|"
|
||||
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" D_CMND_ZIGBEE_MAP "|"
|
||||
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA
|
||||
;
|
||||
|
||||
|
@ -47,7 +47,7 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
|
|||
&CmndZbStatus, &CmndZbReset, &CmndZbSend, &CmndZbProbe,
|
||||
&CmndZbForget, &CmndZbSave, &CmndZbName,
|
||||
&CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId,
|
||||
&CmndZbLight, &CmndZbRestore, &CmndZbBindState,
|
||||
&CmndZbLight, &CmndZbRestore, &CmndZbBindState, &CmndZbMap,
|
||||
&CmndZbConfig, CmndZbData,
|
||||
};
|
||||
|
||||
|
@ -937,11 +937,7 @@ void CmndZbUnbind(void) {
|
|||
ZbBindUnbind(true);
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbBindState`
|
||||
// `ZbBindState<x>` as index if it does not fit. If default, `1` starts at the beginning
|
||||
//
|
||||
void CmndZbBindState(void) {
|
||||
void CmndZbBindState_or_Map(uint16_t zdo_cmd) {
|
||||
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
||||
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||
|
@ -950,7 +946,7 @@ void CmndZbBindState(void) {
|
|||
#ifdef USE_ZIGBEE_ZNP
|
||||
SBuffer buf(10);
|
||||
buf.add8(Z_SREQ | Z_ZDO); // 25
|
||||
buf.add8(ZDO_MGMT_BIND_REQ); // 33
|
||||
buf.add8(zdo_cmd); // 33
|
||||
buf.add16(shortaddr); // shortaddr
|
||||
buf.add8(index); // StartIndex = 0
|
||||
|
||||
|
@ -962,12 +958,28 @@ void CmndZbBindState(void) {
|
|||
// ZDO message payload (see Zigbee spec 2.4.3.3.4)
|
||||
uint8_t buf[] = { index }; // index = 0
|
||||
|
||||
EZ_SendZDO(shortaddr, ZDO_Mgmt_Bind_req, buf, sizeof(buf));
|
||||
EZ_SendZDO(shortaddr, zdo_cmd, buf, sizeof(buf));
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbBindState`
|
||||
// `ZbBindState<x>` as index if it does not fit. If default, `1` starts at the beginning
|
||||
//
|
||||
void CmndZbBindState(void) {
|
||||
CmndZbBindState_or_Map(ZDO_Mgmt_Bind_req);
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbMap`
|
||||
// `ZbMap<x>` as index if it does not fit. If default, `1` starts at the beginning
|
||||
//
|
||||
void CmndZbMap(void) {
|
||||
CmndZbBindState_or_Map(ZDO_Mgmt_Lqi_req);
|
||||
}
|
||||
|
||||
// Probe a specific device to get its endpoints and supported clusters
|
||||
void CmndZbProbe(void) {
|
||||
CmndZbProbeOrPing(true);
|
||||
|
|
Loading…
Reference in New Issue