mirror of https://github.com/arendst/Tasmota.git
Merge pull request #10819 from s-hadinger/zigbee_energy_scan
Zigbee command ``ZbScan`` to do an energy scan on each radio channel
This commit is contained in:
commit
b0fbc3538b
|
@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Command ``L1MusicSync <0|Off>|<1|On>|<2|Toggle>, 1..10, 1..100>`` to control Sonoff L1 Music Sync mode sensitivity and speed (#10722)
|
||||
- Command ``Speed2`` to control a once off fade (#10741)
|
||||
- Zigbee command ``SetOption120 1`` or ``ZbEndpointTopic 1`` to add the endpoint as suffix in topic when using ``SetOption89 1``
|
||||
- Zigbee command ``ZbScan`` to do an energy scan on each radio channel
|
||||
|
||||
### Changed
|
||||
- Maximum chars in ``AddLog_P`` logging restored from 128 to 700 (MAX_LOGSZ) to solve broken error messages
|
||||
|
|
|
@ -615,6 +615,8 @@
|
|||
#define D_CMND_ZIGBEE_CONFIG "Config"
|
||||
#define D_JSON_ZIGBEE_CONFIG "Config"
|
||||
#define D_CMND_ZIGBEE_DATA "Data"
|
||||
#define D_CMND_ZIGBEE_SCAN "Scan"
|
||||
#define D_JSON_ZIGBEE_SCAN "ZbScan"
|
||||
|
||||
// Commands xdrv_25_A4988_Stepper.ino
|
||||
#define D_CMND_MOTOR "MOTOR"
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
#include "Eeprom24C512.h"
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
|
||||
// channels numbers for Zigbee radio energy scan
|
||||
#define USE_ZIGBEE_CHANNEL_MIN 11
|
||||
#define USE_ZIGBEE_CHANNEL_MAX 26
|
||||
#define USE_ZIGBEE_CHANNEL_COUNT (USE_ZIGBEE_CHANNEL_MAX - USE_ZIGBEE_CHANNEL_MIN + 1)
|
||||
|
||||
// contains some definitions for functions used before their declarations
|
||||
|
||||
//
|
||||
|
@ -123,6 +128,9 @@ public:
|
|||
ZB_RecvMsgFunc recv_func = nullptr; // function to call when message is expected
|
||||
ZB_RecvMsgFunc recv_unexpected = nullptr; // function called when unexpected message is received
|
||||
|
||||
// Energy scan
|
||||
int8_t energy[USE_ZIGBEE_CHANNEL_COUNT];
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
uint32_t permit_end_time = 0; // timestamp when permit join ends
|
||||
uint16_t ezsp_version = 0;
|
||||
|
|
|
@ -160,6 +160,60 @@ int32_t EZ_RouteError(int32_t res, const SBuffer &buf) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle EZSP Energy Scan result
|
||||
//
|
||||
int32_t EZSP_EnergyScanResult(int32_t res, const SBuffer &buf) {
|
||||
uint8_t channel = buf.get8(2);
|
||||
int8_t energy = buf.get8(3);
|
||||
|
||||
if ((channel >= USE_ZIGBEE_CHANNEL_MIN) && (channel <= USE_ZIGBEE_CHANNEL_MAX)) {
|
||||
zigbee.energy[channel - USE_ZIGBEE_CHANNEL_MIN] = energy;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//
|
||||
// Handle EZSP Energy Scan complete
|
||||
//
|
||||
int32_t EZSP_EnergyScanComplete(int32_t res, const SBuffer &buf) {
|
||||
// uint8_t channel = buf.get8(2);
|
||||
uint8_t status = buf.get8(3);
|
||||
|
||||
if (0 == status) {
|
||||
EnergyScanResults();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Dump energu scan results
|
||||
//
|
||||
void EnergyScanResults(void) {
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_SCAN "\":["));
|
||||
for (uint32_t i = 0; i < USE_ZIGBEE_CHANNEL_COUNT; i++) {
|
||||
int8_t energy = zigbee.energy[i];
|
||||
|
||||
if (i > 0) { ResponseAppend_P(PSTR(",")); }
|
||||
ResponseAppend_P(PSTR("\"%d\":%d"), i + USE_ZIGBEE_CHANNEL_MIN, energy);
|
||||
|
||||
// display as log
|
||||
static const int32_t bar_min = -87;
|
||||
static const int32_t bar_max = 10;
|
||||
static const uint32_t bar_count = 60;
|
||||
char bar_str[bar_count + 1];
|
||||
uint32_t energy_unsigned = energy + 0x80;
|
||||
|
||||
uint32_t bars = changeUIntScale(energy_unsigned, bar_min + 0x80, bar_max + 0x80, 0, bar_count);
|
||||
for (uint32_t j = 0; j < bars; j++) { bar_str[j] = '#'; }
|
||||
bar_str[bars] = 0;
|
||||
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Channel %2d: %s"), i + USE_ZIGBEE_CHANNEL_MIN, bar_str);
|
||||
}
|
||||
ResponseAppend_P(PSTR("]}"));
|
||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
|
||||
}
|
||||
|
||||
//
|
||||
// Handle a "permitJoining" incoming message
|
||||
//
|
||||
|
@ -1817,19 +1871,18 @@ int32_t EZ_Recv_Default(int32_t res, const SBuffer &buf) {
|
|||
switch (ezsp_command_index) {
|
||||
case EZSP_incomingMessageHandler:
|
||||
return EZ_IncomingMessage(res, buf);
|
||||
break;
|
||||
case EZSP_trustCenterJoinHandler:
|
||||
return EZ_ReceiveTCJoinHandler(res, buf);
|
||||
break;
|
||||
case EZSP_incomingRouteErrorHandler:
|
||||
return EZ_RouteError(res, buf);
|
||||
break;
|
||||
case EZSP_permitJoining:
|
||||
return EZ_PermitJoinRsp(res, buf);
|
||||
break;
|
||||
case EZSP_messageSentHandler:
|
||||
return EZ_MessageSent(res, buf);
|
||||
break;
|
||||
case EZSP_energyScanResultHandler:
|
||||
return EZSP_EnergyScanResult(res, buf);
|
||||
case EZSP_scanCompleteHandler:
|
||||
return EZSP_EnergyScanComplete(res, buf);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -570,6 +570,8 @@ void ZigbeeProcessInputEZSP(SBuffer &buf) {
|
|||
case EZSP_setConcentrator: // 1000
|
||||
case EZSP_networkInit: // 1700
|
||||
case EZSP_stackStatusHandler: // 1900
|
||||
case EZSP_startScan: // 1A00
|
||||
case EZSP_scanCompleteHandler: // 1C00
|
||||
case EZSP_formNetwork: // 1E00
|
||||
case EZSP_permitJoining: // 2200
|
||||
case EZSP_getEui64: // 2600
|
||||
|
@ -580,6 +582,7 @@ void ZigbeeProcessInputEZSP(SBuffer &buf) {
|
|||
case EZSP_sendMulticast: // 3800
|
||||
case EZSP_messageSentHandler: // 3F00
|
||||
case EZSP_incomingMessageHandler: // 4500
|
||||
case EZSP_energyScanResultHandler: // 4800
|
||||
case EZSP_setConfigurationValue: // 5300
|
||||
case EZSP_setPolicy: // 5500
|
||||
case 0x0059: // 5900 - supposedly removed by still happening
|
||||
|
|
|
@ -39,7 +39,7 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
|||
D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|"
|
||||
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_OCCUPANCY "|"
|
||||
D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" D_CMND_ZIGBEE_MAP "|" D_CMND_ZIGBEE_LEAVE "|"
|
||||
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA
|
||||
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA "|" D_CMND_ZIGBEE_SCAN
|
||||
;
|
||||
|
||||
SO_SYNONYMS(kZbSynonyms,
|
||||
|
@ -60,7 +60,7 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
|
|||
&CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId,
|
||||
&CmndZbLight, &CmndZbOccupancy,
|
||||
&CmndZbRestore, &CmndZbBindState, &CmndZbMap, CmndZbLeave,
|
||||
&CmndZbConfig, CmndZbData,
|
||||
&CmndZbConfig, &CmndZbData, &CmndZbScan,
|
||||
};
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -1311,6 +1311,33 @@ void CmndZbSave(void) {
|
|||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
//
|
||||
// Command `ZbScan`
|
||||
// Run an energy scan
|
||||
//
|
||||
void CmndZbScan(void) {
|
||||
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
||||
|
||||
for (uint32_t i = 0; i < USE_ZIGBEE_CHANNEL_COUNT; i++) {
|
||||
zigbee.energy[i] = -0x80;
|
||||
}
|
||||
|
||||
#ifdef USE_ZIGBEE_ZNP
|
||||
ResponseCmndChar_P(PSTR("Unsupported command on ZNP"));
|
||||
return;
|
||||
#endif // USE_ZIGBEE_ZNP
|
||||
|
||||
#ifdef USE_ZIGBEE_EZSP
|
||||
SBuffer buf(8);
|
||||
buf.add16(EZSP_startScan);
|
||||
buf.add8(0x00); // EZSP_ENERGY_SCAN
|
||||
buf.add32(0x07FFF800); // standard channels 11-26
|
||||
buf.add8(0x04); // duration 2 ^ 4
|
||||
ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len());
|
||||
|
||||
#endif // USE_ZIGBEE_EZSP
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
// Restore a device configuration previously exported via `ZbStatus2``
|
||||
// Format:
|
||||
|
|
Loading…
Reference in New Issue