Merge pull request #16709 from s-hadinger/zigbee_multi_name

Zigbee friendly names per endpoint
This commit is contained in:
s-hadinger 2022-10-02 21:26:59 +02:00 committed by GitHub
commit 0efc93f2a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 450 additions and 86 deletions

View File

@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
## [12.1.1.3]
### Added
- ESP32-S2 and ESP32-S3 touch input support
- Zigbee friendly names per endpoint
### Changed

View File

@ -79,6 +79,12 @@ public:
_buf->buf[offset] = data;
}
}
void set16(const size_t offset, const uint16_t data) {
if (offset + 1 < _buf->len) {
_buf->buf[offset] = data & 0xFF;
_buf->buf[offset+1] = (data >> 8) & 0xFF;
}
}
size_t add8(const uint8_t data) { // append 8 bits value
if (_buf->len < _buf->size) { // do we have room for 1 byte

View File

@ -623,6 +623,7 @@
#define D_JSON_ZIGBEEZCL_RAW_RECEIVED "ZbZCLRawReceived"
#define D_JSON_ZIGBEE_DEVICE "Device"
#define D_JSON_ZIGBEE_NAME "Name"
#define D_JSON_ZIGBEE_NAMES "Names"
#define D_JSON_ZIGBEE_CONFIRM "ZbConfirm"
#define D_CMND_ZIGBEE_NAME "Name"
#define D_CMND_ZIGBEE_MODELID "ModelId"

View File

@ -258,7 +258,8 @@ String EthernetMacAddress(void);
#define TASM_FILE_DRIVER "/.drvset%03d"
#define TASM_FILE_SENSOR "/.snsset%03d"
#define TASM_FILE_TLSKEY "/tlskey" // TLS private key
#define TASM_FILE_ZIGBEE "/zb" // Zigbee devices information blob
#define TASM_FILE_ZIGBEE_LEGACY_V2 "/zb" // Zigbee devices information blob, legacy v2
#define TASM_FILE_ZIGBEE "/zbv4" // Zigbee devices information blob, now v4
#define TASM_FILE_ZIGBEE_DATA "/zbdata" // Zigbee last known values of devices
#define TASM_FILE_AUTOEXEC "/autoexec.bat" // Commands executed after restart
#define TASM_FILE_CONFIG "/config.sys" // Settings executed after restart

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "genereer ewekansige Zigbee-netwerksleutel"
#define D_ZIGBEE_UNKNOWN_DEVICE "Onbekende toestel"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Onbekende kenmerk"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Ongeldige parameter"
#define D_ZIGBEE_MISSING_PARAM "Ontbrekende parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Onbekende kenmerknaam (geïgnoreer): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Nie meer as een groep-ID per opdrag nie"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Verkeerde afbakening vir payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Onherkenbare zigbee-opdrag: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Slegs 1 opdrag toegelaat (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "Erzeuge zufälligen Zigbee Netzwerkschlüssel"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unbekanntes Gerät"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unbekanntes Attribut"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Ungültiger Parameter"
#define D_ZIGBEE_MISSING_PARAM "Fehlende Parameter"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unbekannter Attribut Name (ignoriert): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Nur eine Cluster id pro Kommando"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Falscher Delimeter für Payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unerkanntes Zigbee Kommando: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Nur 1 Kommando zulässig (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "Generando una clave aleatoria de red Zigbee"
#define D_ZIGBEE_UNKNOWN_DEVICE "Dispositivo desconocido"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Atributo desconocido"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Parámetro inválido"
#define D_ZIGBEE_MISSING_PARAM "Parámetros faltantes"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Nombre de atributo desconocido (ignorado): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No mas de un id de cluster por comando"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Delimitador incorrecto para payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Comando zigbee no reconocido: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Solo un comando es permitido (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "création d'une clé réseau ZigBee aléatoire"
#define D_ZIGBEE_UNKNOWN_DEVICE "Module inconnu"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Attribut inconnu"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Paramètre invalide"
#define D_ZIGBEE_MISSING_PARAM "Paramètres manquants"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Nom d'attribut inconnu (ignoré): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Pas plus d'un Id de Cluster par commande"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Mauvais délimiteur dans le contenu du message"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Commande ZigBee inconnue: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Une seule commande autorisée (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generearjen willekeurige Zigbee netwurksleutel"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unbekend apparaat"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unbekend attribút"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unbekende attribútenamme (negeare): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Net mear dan ien kluster-id per kommando"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Ferkearde skiedingsteken foar lading"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unerkend zigbee kommando: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Allinich 1 kommando tastien (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "véletlen Zigbee hálózati kulcs generálása"
#define D_ZIGBEE_UNKNOWN_DEVICE "Ismeretlen eszköz"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Ismeretlen tulajdonság"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Érvénytelen paraméter"
#define D_ZIGBEE_MISSING_PARAM "Hiányzó paraméter(ek)"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Ismeretlen tulajdonság név (kihagyva): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Egynél több klaszter id nem lehet parancsonként"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Hibás adatcsomag elválasztó"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Nem értelmezhető Zigbee parancs: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Csak egy parancs engedélyezett (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "Generazione chiave casuale rete Zigbee"
#define D_ZIGBEE_UNKNOWN_DEVICE "Dispositivo sconosciuto"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Attributo sconosciuto"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Parametro non valido"
#define D_ZIGBEE_MISSING_PARAM "Parametro mancante"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Nome sconosciuto attributo (ignorato): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Non più di un ID cluster per comando"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Delimitatore errato carico utile"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Comando Zigbee non riconosciuto: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "È consentito solo 1 comando (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "willekeurig Zigbee netwerk sleutel maken"
#define D_ZIGBEE_UNKNOWN_DEVICE "Onbekend apparaat"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Onbekende attribuut"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Ongeldige parameter"
#define D_ZIGBEE_MISSING_PARAM "Ontbrekende parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Onbekend attribuut naam: %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Max een cluster id per opdracht"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Fout scheidingsteken voor payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Onbekende zigbee opdracht: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Maar een opdracht toegestaan (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generuj losowo klucz sieci Zigbee"
#define D_ZIGBEE_UNKNOWN_DEVICE "Nieznane urządzenie"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Nieznany atrybut"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Zły parametr"
#define D_ZIGBEE_MISSING_PARAM "Brak parametrów"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Nieznana nazwa atrybutu (ignoruję): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Nie więcej niż jeden cluster id na komendę"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Błędny delimiter autoryzacji"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Nieznana komenda zigbee: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Tylko 1 komenda dozwolona (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "Gerando chave randomizada de rede Zigbee" // "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Dispositivo desconhecido" // "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Atributo desconhecido" // "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Parametro inválido" // "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Parametros faltantes" // "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Nome desconhecido atribuido (ignorado) %s" // "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Usar somente um Cluster ID por comando" // "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Delimitador incorreto para a carga" // "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Comando Zigbee não reconhecido: %s" // "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Somente 1 comando permitido (%d)" // "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "A gerar chave aleatória de rede Zigbee"
#define D_ZIGBEE_UNKNOWN_DEVICE "dispositivo desconhecido"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Atributo desconhecido"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Parâmetro inválido"
#define D_ZIGBEE_MISSING_PARAM "Parâmetros em falta"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Atributo de nome desconhecido (ignorado): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "Apenas um cluster id por comando"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Delimitador de payload inválido"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Comando zigbee desconhecido: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Permitido apenas 1 comando (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "正在生成 Zigbee 网络随机秘钥"
#define D_ZIGBEE_UNKNOWN_DEVICE "未知设备"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "未知属性"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "参数无效"
#define D_ZIGBEE_MISSING_PARAM "缺失参数"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "未知属性名称: %s , 忽略"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "每个命令不应有多个簇 ID"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "消息体分隔符错误"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "无法识别的 Zigbee 命令: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "只允许一个命令 (%d)"

View File

@ -495,10 +495,12 @@
#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key"
#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device"
#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute"
#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint"
#define D_ZIGBEE_INVALID_PARAM "Invalid parameter"
#define D_ZIGBEE_MISSING_PARAM "Missing parameters"
#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s"
#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command"
#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints"
#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload"
#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s"
#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)"

View File

@ -815,6 +815,114 @@ const Z_Data & Z_Data_Set::find(Z_Data_Type type, uint8_t ep) const {
return z_data_unk; // mark as unknown
}
/*********************************************************************************************\
* Class used to store friendly names of endpoints
\*********************************************************************************************/
class Z_EP_Name {
public:
Z_EP_Name() :
endpoint(0),
name(nullptr)
{}
inline const char * getName(void) const { return name != nullptr ? name : PSTR(""); }
void setName(const char *new_name);
~Z_EP_Name() { if (name) free(name); }
public:
uint8_t endpoint;
char * name;
};
class Z_EP_Name_list : public LList<Z_EP_Name> {
public:
// INVARIANT: there is at most one entry for any `endpoint` value
// INVARIANT: if an entry exists, then the name is not null nor empty string
// we don't need explicit constructor, the superclass handles it
// add or change an ep name, or remove if set to empty string
void setEPName(uint8_t ep, const char * name) {
if (name == nullptr || strlen_P(name) == 0) {
this->removeEPName(ep);
return;
}
for (auto & epn : *this) {
if (epn.endpoint == ep) {
epn.setName(name);
return; // found it, exit
}
}
// ep not found, create it
Z_EP_Name & epn = this->addToLast();
epn.endpoint = ep;
epn.setName(name);
}
// remove ep name from list
void removeEPName(uint8_t ep) {
for (auto & epn : *this) {
if (epn.endpoint == ep) {
this->remove(&epn);
return; // found it, exit
}
}
}
// find a endpoint by name, or return 0 if not found
uint8_t findEPName(const char * name) const {
if (name == nullptr || strlen_P(name) == 0) { return 0; }
for (const auto & epn : *this) {
if (strcasecmp(epn.name, name) == 0) { return epn.endpoint; }
}
return 0; // not found
}
// get ep name, or return nullptr if none
const char * getEPName(uint8_t ep) const {
for (auto & epn : *this) {
if (epn.endpoint == ep) {
return epn.name;
}
}
return nullptr;
}
// Publish endpoint names if any as `"Names":{"2":"name2","3":"name3"}`
String tojson(void) const {
String s;
if (!this->isEmpty()) {
s += '{';
bool first = true;
for (const auto & epn : *this) {
if (!first) { s += ','; }
s += '"';
s += epn.endpoint;
s += F("\":\"");
s += EscapeJSONString(epn.name);
s += '"';
first = false;
}
s += '}';
}
return s;
}
// append to JSON
void ResponseAppend(void) const {
String s = tojson();
if (s.length() > 0) {
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAMES "\":%s"), s.c_str());
}
}
};
/*********************************************************************************************\
* Structures for Rules variables related to the last received message
\*********************************************************************************************/
@ -832,6 +940,8 @@ public:
uint32_t defer_last_message_sent;
uint8_t endpoints[endpoints_max]; // static array to limit memory consumption, list of endpoints until 0x00 or end of array
// List of names for endpoints
Z_EP_Name_list ep_names;
// Used for attribute reporting
Z_attribute_list attr_list;
// sequence number for Zigbee frames
@ -927,15 +1037,18 @@ public:
bool addEndpoint(uint8_t endpoint);
void clearEndpoints(void);
uint32_t countEndpoints(void) const; // return the number of known endpoints (0 if unknown)
bool setEPName(uint8_t ep, const char * name);
void setManufId(const char * str);
void setModelId(const char * str);
void setFriendlyName(const char * str);
void setFriendlyEPName(uint8_t ep, const char * str); // ability to have friendly names for endpoints
void setLastSeenNow(void);
// multiple function to dump part of the Device state into JSON
void jsonAddDeviceNamme(Z_attribute_list & attr_list) const;
void jsonAddEPName(Z_attribute_list & attr_list) const;
void jsonAddIEEE(Z_attribute_list & attr_list) const;
void jsonAddModelManuf(Z_attribute_list & attr_list) const;
void jsonAddEndpoints(Z_attribute_list & attr_list) const;
@ -964,8 +1077,6 @@ public:
void setLightChannels(int8_t channels);
protected:
static void setStringAttribute(char*& attr, const char * str);
};
@ -1032,7 +1143,7 @@ public:
// - 0x<shortaddr> = the device's short address
Z_Device & isKnownLongAddrDevice(uint64_t longaddr) const;
Z_Device & isKnownIndexDevice(uint32_t index) const;
Z_Device & isKnownFriendlyNameDevice(const char * name) const;
Z_Device & isKnownFriendlyNameDevice(const char * name, uint8_t * ep = nullptr) const;
Z_Device & findShortAddr(uint16_t shortaddr);
const Z_Device & findShortAddr(uint16_t shortaddr) const;
@ -1044,6 +1155,7 @@ public:
inline bool foundDevice(const Z_Device & device) const { return device.valid(); }
int32_t findFriendlyName(const char * name) const;
int32_t findFriendlyNameOrEPName(const char * name, uint8_t * ep) const;
uint64_t getDeviceLongAddr(uint16_t shortaddr) const;
uint8_t findFirstEndpoint(uint16_t shortaddr) const;
@ -1110,7 +1222,7 @@ public:
void clean(void); // avoid writing to flash the last changes
// Find device by name, can be short_addr, long_addr, number_in_array or name
Z_Device & parseDeviceFromName(const char * param, uint16_t * parsed_shortaddr = nullptr, int32_t mailbox_payload = 0);
Z_Device & parseDeviceFromName(const char * param, uint16_t * parsed_shortaddr = nullptr, uint8_t * ep = nullptr, int32_t mailbox_payload = 0);
bool isTuyaProtocol(uint16_t shortaddr, uint8_t ep = 0) const;

View File

@ -118,6 +118,37 @@ int32_t Z_Devices::findFriendlyName(const char * name) const {
return -1;
}
//
// Scan all devices to find a corresponding friendlyNme
// Looks info device.friendlyName entry or the name of an endpoint
// In:
// friendlyName (null terminated, should not be empty)
// Out:
// index in _devices of entry, -1 if not found
// ep == 0 means ep not found
//
int32_t Z_Devices::findFriendlyNameOrEPName(const char * name, uint8_t * ep) const {
if (ep) { *ep = 0; }
if (!name) { return -1; } // if pointer is null
size_t name_len = strlen(name);
int32_t found = 0;
if (name_len) {
for (auto &elem : _devices) {
if (elem.friendlyName) {
if (strcasecmp(elem.friendlyName, name) == 0) { return found; }
}
uint8_t ep_found = elem.ep_names.findEPName(name);
if (ep_found) {
// found via ep name
if (ep) { *ep = ep_found; } // update ep
return found;
}
found++;
}
}
return -1;
}
Z_Device & Z_Devices::isKnownLongAddrDevice(uint64_t longaddr) const {
return (Z_Device &) findLongAddr(longaddr);
}
@ -130,10 +161,12 @@ Z_Device & Z_Devices::isKnownIndexDevice(uint32_t index) const {
}
}
Z_Device & Z_Devices::isKnownFriendlyNameDevice(const char * name) const {
Z_Device & Z_Devices::isKnownFriendlyNameDevice(const char * name, uint8_t * ep) const {
if ((!name) || (0 == strlen(name))) { return device_unk; } // Error
int32_t found = findFriendlyName(name);
uint8_t ep_found;
int32_t found = findFriendlyNameOrEPName(name, &ep_found);
if (found >= 0) {
if (ep) { *ep = ep_found; }
return devicesAt(found);
} else {
return device_unk;
@ -242,7 +275,7 @@ void Z_Device::clearEndpoints(void) {
// return true if a change was made
//
bool Z_Device::addEndpoint(uint8_t endpoint) {
if ((0x00 == endpoint) || (endpoint > 240)) { return false; }
if ((0x00 == endpoint) || (endpoint > 240 && endpoint != 0xF2)) { return false; }
for (uint32_t i = 0; i < endpoints_max; i++) {
if (endpoint == endpoints[i]) {
@ -276,8 +309,21 @@ uint8_t Z_Devices::findFirstEndpoint(uint16_t shortaddr) const {
return findShortAddr(shortaddr).endpoints[0]; // returns 0x00 if no endpoint
}
// set a name to an endpoint, must exist in the list or return `false`
bool Z_Device::setEPName(uint8_t ep, const char * name) {
if ((0x00 == ep) || (ep > 240 && ep != 0xF2)) { return false; }
for (uint32_t i = 0; i < endpoints_max; i++) {
if (ep == endpoints[i]) {
ep_names.setEPName(ep, name);
return true;
}
}
return false;
}
void Z_Device::setStringAttribute(char*& attr, const char * str) {
if (nullptr == str) { return; } // ignore a null parameter
if (nullptr == str) { str = PSTR(""); } // nullptr is considered empty string
size_t str_len = strlen(str);
if ((nullptr == attr) && (0 == str_len)) { return; } // if both empty, don't do anything
@ -320,6 +366,15 @@ void Z_Device::setFriendlyName(const char * str) {
setStringAttribute(friendlyName, str);
}
void Z_Device::setFriendlyEPName(uint8_t ep, const char * str) {
ep_names.setEPName(ep, str);
}
// needs to push the implementation here to use Z_Device static method
void Z_EP_Name::setName(const char *new_name) {
Z_Device::setStringAttribute(name, new_name);
}
void Z_Device::setLastSeenNow(void) {
// Only update time if after 2020-01-01 0000.
// Fixes issue where zigbee device pings before WiFi/NTP has set utc_time
@ -523,7 +578,13 @@ void Z_Devices::jsonAppend(uint16_t shortaddr, const Z_attribute_list &attr_list
// internal function to publish device information with respect to all `SetOption`s
//
void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_list &attr_list, bool include_time) const {
bool use_fname = (Settings->flag4.zigbee_use_names) && (friendlyName); // should we replace shortaddr with friendlyname?
const char * local_friendfly_name; // friendlyname publish can depend on the source endpoint
local_friendfly_name = ep_names.getEPName(attr_list.src_ep); // check if this ep has a specific name
if (local_friendfly_name == nullptr) {
// if no ep-specific name, get the device name
local_friendfly_name = friendlyName;
}
bool use_fname = (Settings->flag4.zigbee_use_names) && (local_friendfly_name); // should we replace shortaddr with friendlyname?
ResponseClear(); // clear string
@ -541,7 +602,7 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l
// What key do we use, shortaddr or name?
if (!Settings->flag5.zb_omit_json_addr) {
if (use_fname) {
ResponseAppend_P(PSTR("{\"%s\":"), friendlyName);
ResponseAppend_P(PSTR("{\"%s\":"), local_friendfly_name);
} else {
ResponseAppend_P(PSTR("{\"0x%04X\":"), shortaddr);
}
@ -551,8 +612,8 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l
// Add "Device":"0x...."
ResponseAppend_P(PSTR("\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\","), shortaddr);
// Add "Name":"xxx" if name is present
if (friendlyName) {
ResponseAppend_P(PSTR("\"" D_JSON_ZIGBEE_NAME "\":\"%s\","), EscapeJSONString(friendlyName).c_str());
if (local_friendfly_name) {
ResponseAppend_P(PSTR("\"" D_JSON_ZIGBEE_NAME "\":\"%s\","), EscapeJSONString(local_friendfly_name).c_str());
}
// Add all other attributes
ResponseAppend_P(PSTR("%s}"), attr_list.toString(false).c_str());
@ -571,10 +632,10 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l
if (Settings->flag4.zigbee_distinct_topics) {
char subtopic[TOPSZ];
if (Settings->flag4.zb_topic_fname && friendlyName && strlen(friendlyName)) {
if (Settings->flag4.zb_topic_fname && local_friendfly_name && strlen(local_friendfly_name)) {
// Clean special characters
char stemp[TOPSZ];
strlcpy(stemp, friendlyName, sizeof(stemp));
strlcpy(stemp, local_friendfly_name, sizeof(stemp));
MakeValidMqtt(0, stemp);
if (Settings->flag5.zigbee_hide_bridge_topic) {
snprintf_P(subtopic, sizeof(subtopic), PSTR("%s"), stemp);
@ -646,7 +707,8 @@ void Z_Devices::clean(void) {
// - a friendly name, between quotes, example: "Room_Temp"
//
// In case the device is not found, the parsed 0x.... short address is passed to *parsed_shortaddr
Z_Device & Z_Devices::parseDeviceFromName(const char * param, uint16_t * parsed_shortaddr, int32_t mailbox_payload) {
Z_Device & Z_Devices::parseDeviceFromName(const char * param, uint16_t * parsed_shortaddr, uint8_t * ep, int32_t mailbox_payload) {
if (ep) { *ep = 0; } // mark as not found
if (nullptr == param) { return device_unk; }
size_t param_len = strlen(param);
char dataBuf[param_len + 1];
@ -675,7 +737,7 @@ Z_Device & Z_Devices::parseDeviceFromName(const char * param, uint16_t * parsed_
}
} else {
// expect a Friendly Name
return isKnownFriendlyNameDevice(dataBuf);
return isKnownFriendlyNameDevice(dataBuf, ep);
}
}
@ -696,6 +758,14 @@ void Z_Device::jsonAddDeviceNamme(Z_attribute_list & attr_list) const {
}
}
// Add "Names":{"1":"name1","2":"name2"}
void Z_Device::jsonAddEPName(Z_attribute_list & attr_list) const {
String s = ep_names.tojson();
if (s.length() > 0) {
attr_list.addAttributePMEM(PSTR(D_JSON_ZIGBEE_NAMES)).setStrRaw(s.c_str());
}
}
// Add "IEEEAddr":"0x1234567812345678"
void Z_Device::jsonAddIEEE(Z_attribute_list & attr_list) const {
attr_list.addAttributePMEM(PSTR("IEEEAddr")).setHex64(longaddr);
@ -795,6 +865,7 @@ void Z_Device::jsonDumpSingleDevice(Z_attribute_list & attr_list, uint32_t dump_
jsonAddDeviceNamme(attr_list);
}
if (dump_mode >= 2) {
jsonAddEPName(attr_list);
jsonAddIEEE(attr_list);
jsonAddModelManuf(attr_list);
jsonAddEndpoints(attr_list);
@ -889,6 +960,22 @@ int32_t Z_Devices::deviceRestore(JsonParserObject json) {
}
}
// read "Names"
JsonParserToken val_names = json[PSTR("Names")];
if (val_names.isObject()) {
JsonParserObject attr_names = val_names.getObject();
// iterate on keys
for (auto key : attr_names) {
int32_t ep = key.getUInt();
if (ep > 255) { ep = 0; } // ep == 0 is invalid
const char * ep_name = key.getValue().getStr();
if (!ep || !device.setEPName(ep, ep_name)) {
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ignoring ep=%i name='%s'"), ep, ep_name);
}
}
}
// read "Config"
JsonParserToken val_config = json[PSTR("Config")];
if (val_config.isArray()) {

View File

@ -22,8 +22,9 @@
// #define Z_EEPROM_DEBUG
const static uint32_t ZIGB_NAME1 = 0x3167697A; // 'zig1' little endian
// const static uint32_t ZIGB_NAME1 = 0x3167697A; // 'zig1' little endian
const static uint32_t ZIGB_NAME2 = 0x3267697A; // 'zig2' little endian, v2
const static uint32_t ZIGB_NAME4 = 0x3467697A; // 'zig4' little endian, v2
const static uint32_t ZIGB_DATA2 = 0x32746164; // 'dat2' little endian, v2
extern FS *dfsp;
extern "C" uint32_t _FS_end;
@ -32,7 +33,7 @@ bool flash_valid(void) {
return (((uint32_t)&_FS_end) > 0x40280000) && (((uint32_t)&_FS_end) < 0x402FF000);
}
void hydrateSingleDevice(const SBuffer & buf_d);
void hydrateSingleDevice(const SBuffer & buf_d, uint32_t version);
#ifdef USE_ZIGBEE_EEPROM
// The EEPROM is 64KB in size with individually writable bytes.

View File

@ -77,6 +77,32 @@
// uint8[] - list of configuration bytes, 0xFF marks the end
// i.e. 0xFF-0xFF marks the end of the array of endpoints
//
// =======================
// v4 which provides more extensibility
// File structure: (all values are little Endian)
//
// uint8 - number of devices, 0xFF indicates invalid file (or erased Flash?)
// [Array of devices, max to number of devices]
// [starts at offset = 3]
// uint16 - length of the device record, including the length field - allows to jump to next device
// [mandatory device data]
// uint16 - short address
// uint64 - long IEEE address
//
// str - ModelID (null terminated C string, 32 chars max)
// str - Manuf (null terminated C string, 32 chars max)
// str - FriendlyName (null terminated C string, 32 chars max)
//
// [Array of endpoints]
// uint8 - endpoint number, 0xFF marks the end of endpoints
// uint8 - length of the endpoint information, excuding length byte and endpoint number
// uint8[] - list of configuration bytes, 0xFF marks the end
// str - (optional) FriendlyName for this endpoint (null terminated C string, 32 chars max), 0x00 if none
//
// [extended attributes]
// : any other data until `length of the device record` is reached
//
// Memory footprint
@ -139,9 +165,9 @@ bool hibernateDeviceConfiguration(SBuffer & buf, const class Z_Data_Set & data,
* Only supports v2 (not the legacy old one long forgotten)
\*********************************************************************************************/
SBuffer hibernateDevice(const struct Z_Device &device) {
SBuffer buf(128);
SBuffer buf(256);
buf.add8(0x00); // overall length, will be updated later
buf.add16(0x0000); // overall length, will be updated later
buf.add16(device.shortaddr);
buf.add64(device.longaddr);
@ -159,18 +185,36 @@ SBuffer hibernateDevice(const struct Z_Device &device) {
// check if we need to write fake endpoint 0x00
buf.add8(0x00);
uint32_t ep0_len_offset = buf.len(); // mark where to update the ep data length
buf.add8(0x00);
if (hibernateDeviceConfiguration(buf, device.data, 0)) {
buf.add8(0xFF); // end of configuration
buf.add8(0x00); // empty ep friendly name, as it would duplicate the global friendly name
// update the lenght of ep0_data_lenth
buf.set8(ep0_len_offset, buf.len() - ep0_len_offset - 1);
} else {
buf.setLen(buf.len()-1); // remove 1 byte header
buf.setLen(buf.len()-2); // remove 2 bytes header
}
// scan endpoints
for (uint32_t i=0; i<endpoints_max; i++) {
uint8_t endpoint = device.endpoints[i];
if (0x00 == endpoint) { break; }
buf.add8(endpoint);
uint32_t ep_len_offset = buf.len(); // mark where to update the ep data length
buf.add8(0x00);
hibernateDeviceConfiguration(buf, device.data, endpoint);
buf.add8(0xFF); // end of configuration
const char * ep_name = device.ep_names.getEPName(endpoint);
if (ep_name != nullptr) {
size_t len = strlen(ep_name);
if (len > 32) { len = 32; } // max 32 chars
buf.addBuffer(ep_name, len);
buf.add8(0x00); // end of string marker
} else {
buf.add8(0x00); // no endpoint name
}
// update the lenght of ep0_data_lenth
buf.set8(ep_len_offset, buf.len() - ep_len_offset - 1);
}
buf.add8(0xFF); // end of endpoints
@ -184,6 +228,8 @@ SBuffer hibernateDevice(const struct Z_Device &device) {
/*********************************************************************************************\
* Write Devices in EEPROM/File/Flash
*
* Updated to v4 format
*
* Writes the preamble and all devices in the Univ_Write_File structure.
* Does not close the file at the end.
* Returns true if succesful.
@ -193,9 +239,10 @@ SBuffer hibernateDevice(const struct Z_Device &device) {
bool hibernateDevices(Univ_Write_File & write_data);
bool hibernateDevices(Univ_Write_File & write_data) {
// first prefix is number of devices
uint8_t devices_size = zigbee_devices.devicesSize();
size_t devices_size = zigbee_devices.devicesSize();
if (devices_size > 250) { devices_size = 250; } // arbitrarily limit to 250 devices in EEPROM instead of 32 in Flash
write_data.writeBytes(&devices_size, sizeof(devices_size));
uint8_t devices_size8 = devices_size;
write_data.writeBytes((uint8_t*)&devices_size8, sizeof(devices_size8)); // write number of devices in file
for (const auto & device : zigbee_devices.getDevices()) {
const SBuffer buf = hibernateDevice(device);
@ -224,10 +271,10 @@ const char * hydrateSingleString(const SBuffer & buf, uint32_t *d) {
* hydrateSingleDevice
*
* Transforms a binary representation to a Zigbee device
* Supports only v2
* Supports only v2 and v4
\*********************************************************************************************/
void hydrateSingleDevice(const SBuffer & buf_d) {
uint32_t d = 1; // index in device buffer
void hydrateSingleDevice(const SBuffer & buf_d, uint32_t version) {
uint32_t d = 0; // index in device buffer
uint16_t shortaddr = buf_d.get16(d); d += 2;
uint64_t longaddr = buf_d.get64(d); d += 8;
size_t buf_len = buf_d.len();
@ -244,23 +291,52 @@ void hydrateSingleDevice(const SBuffer & buf_d) {
if (d >= buf_len) { return; }
// Hue bulbtype - if present
while (d < buf_len) {
// Read per-endpoint information
while (d < buf_len) {
uint8_t ep = buf_d.get8(d++);
if (0xFF == ep) { break; } // ep 0xFF marks the end of the endpoints
if (ep > 240) { ep = 0xFF; } // ep == 0xFF means ignore
if (ep > 240 && ep != 0xF2) { ep = 0xFF; } // ep == 0xFF means ignore
device.addEndpoint(ep); // it will ignore invalid endpoints
while (d < buf_len) {
uint8_t config_type = buf_d.get8(d++);
if (0xFF == config_type) { break; } // 0xFF marks the end of congiguration
uint8_t config = config_type & 0x0F;
Z_Data_Type type = (Z_Data_Type) (config_type >> 4);
// set the configuration
if (ep != 0xFF) {
Z_Data & z_data = device.data.getByType(type, ep);
if (&z_data != nullptr) {
z_data.setConfig(config);
Z_Data_Set::updateData(z_data);
if (version == 4) {
if (d >= buf_len) { break; } // end of buffer
uint8_t ep_len = buf_d.get8(d++);
if (d + ep_len > buf_len) { break; } // buffer is too small to contain the announced data
while (d < buf_len) {
uint8_t config_type = buf_d.get8(d++);
if (0xFF == config_type) { break; } // 0xFF marks the end of congiguration
uint8_t config = config_type & 0x0F;
Z_Data_Type type = (Z_Data_Type) (config_type >> 4);
// set the configuration
if (ep != 0xFF) {
Z_Data & z_data = device.data.getByType(type, ep);
if (&z_data != nullptr) {
z_data.setConfig(config);
Z_Data_Set::updateData(z_data);
}
}
}
// ability to have additional fields here
// friendly name for ep
if (d < buf_len) {
device.setFriendlyEPName(ep, hydrateSingleString(buf_d, &d));
}
// additional information comes here
} else {
// version == 2
while (d < buf_len) {
uint8_t config_type = buf_d.get8(d++);
if (0xFF == config_type) { break; } // 0xFF marks the end of congiguration
uint8_t config = config_type & 0x0F;
Z_Data_Type type = (Z_Data_Type) (config_type >> 4);
// set the configuration
if (ep != 0xFF) {
Z_Data & z_data = device.data.getByType(type, ep);
if (&z_data != nullptr) {
z_data.setConfig(config);
Z_Data_Set::updateData(z_data);
}
}
}
}
@ -277,11 +353,18 @@ void hydrateSingleDevice(const SBuffer & buf_d) {
bool loadZigbeeDevices(void) {
Univ_Read_File f; // universal reader
const char * storage_class = PSTR("");
uint32_t file_version = 4; // currently supporting v3 and v4
#ifdef USE_ZIGBEE_EEPROM
if (zigbee.eeprom_ready) {
f.init(ZIGB_NAME2);
storage_class = PSTR("EEPROM");
f.init(ZIGB_NAME4); // try v4 first
if (!f.valid()) {
f.init(ZIGB_NAME2); // else try v2
if (f.valid()) { file_version = 2; } // v2 found
}
if (f.valid()) {
storage_class = PSTR("EEPROM");
}
}
#endif // USE_ZIGBEE_EEPROM
@ -289,15 +372,11 @@ bool loadZigbeeDevices(void) {
File file;
if (!f.valid() && dfsp) {
file = dfsp->open(TASM_FILE_ZIGBEE, "r");
if (!file) {
file = dfsp->open(TASM_FILE_ZIGBEE_LEGACY_V2, "r");
if (file) { file_version = 2; } // v2 found
}
if (file) {
uint32_t signature = 0x0000;
file.read((uint8_t*)&signature, 4);
if (signature == ZIGB_NAME2) {
// skip another 4 bytes
file.read((uint8_t*)&signature, 4);
} else {
file.seek(0); // seek back to beginning of file
}
f.init(&file);
storage_class = PSTR("File System");
}
@ -314,10 +393,10 @@ bool loadZigbeeDevices(void) {
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Zigbee signature in Flash: %08X - %d"), flashdata.name, flashdata.len);
// Check the signature
if ( ((flashdata.name == ZIGB_NAME1) || (flashdata.name == ZIGB_NAME2))
if ( ((flashdata.name == ZIGB_NAME2) || (flashdata.name == ZIGB_NAME4))
&& (flashdata.len > 0)) {
uint16_t buf_len = flashdata.len;
// uint32_t version = (flashdata.name == ZIGB_NAME2) ? 2 : 1;
if (flashdata.name == ZIGB_NAME2) { file_version = 2; } // v2 found
f.init(z_dev_start + sizeof(Z_Flashentry), buf_len);
storage_class = PSTR("Flash");
}
@ -338,26 +417,25 @@ bool loadZigbeeDevices(void) {
uint32_t k = 1; // byte index in global buffer
for (uint32_t i = 0; (i < num_devices) && (k < file_len); i++) {
uint8_t dev_record_len = 0;
f.readBytes(&dev_record_len, sizeof(dev_record_len));
// int32_t ret = ZFS::readBytes(ZIGB_NAME2, &dev_record_len, 1, k, 1);
uint16_t dev_record_len = 0;
size_t dev_record_len_bytes = file_version >= 4 ? 2 : 1;
f.readBytes((uint8_t*)&dev_record_len, dev_record_len_bytes); // starting with v4, length is 2 bytes
if (dev_record_len == 0) {
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Invalid device information, aborting"));
zigbee_devices.clean(); // don't write back to Flash what we just loaded
return false;
}
SBuffer buf(dev_record_len);
buf.setLen(dev_record_len);
buf.set8(0, dev_record_len); // push the first byte (len including this first byte)
int32_t ret = f.readBytes(buf.buf(1), dev_record_len - 1);
// ret = ZFS::readBytes(ZIGB_NAME2, buf.getBuffer(), dev_record_len, k, dev_record_len);
if (ret != dev_record_len - 1) {
SBuffer buf(dev_record_len - dev_record_len_bytes);
buf.setLen(dev_record_len - dev_record_len_bytes);
buf.set8(0, dev_record_len - dev_record_len_bytes); // push the first byte (len including this first byte)
int32_t ret = f.readBytes(buf.buf(), dev_record_len - dev_record_len_bytes);
if (ret != dev_record_len - dev_record_len_bytes) {
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Invalid device information, aborting"));
zigbee_devices.clean(); // don't write back to Flash what we just loaded
return false;
}
hydrateSingleDevice(buf);
hydrateSingleDevice(buf, file_version);
// next iteration
k += dev_record_len;
@ -377,6 +455,7 @@ void saveZigbeeDevices(void) {
Univ_Write_File f;
const char * storage_class = PSTR("");
// TODO can we prioritize filesystem instead of eeprom?
#ifdef USE_ZIGBEE_EEPROM
if (!f.valid() && zigbee.eeprom_ready) {
f.init(ZIGB_NAME2);

View File

@ -744,7 +744,7 @@ void CmndZbSend(void) {
JsonParserToken val_device = root[PSTR(D_CMND_ZIGBEE_DEVICE)];
if (val_device) {
uint16_t parsed_shortaddr = BAD_SHORTADDR;
zcl.shortaddr = zigbee_devices.parseDeviceFromName(val_device.getStr(), &parsed_shortaddr).shortaddr;
zcl.shortaddr = zigbee_devices.parseDeviceFromName(val_device.getStr(), &parsed_shortaddr, &zcl.dstendpoint).shortaddr;
if (!zcl.validShortaddr()) {
if (parsed_shortaddr != BAD_SHORTADDR) {
// we still got a short address
@ -768,9 +768,17 @@ void CmndZbSend(void) {
// read other parameters
zcl.cluster = root.getUInt(PSTR(D_CMND_ZIGBEE_CLUSTER), zcl.cluster);
zcl.dstendpoint = root.getUInt(PSTR(D_CMND_ZIGBEE_ENDPOINT), zcl.dstendpoint);
zcl.manuf = root.getUInt(PSTR(D_CMND_ZIGBEE_MANUF), zcl.manuf);
// read dest endpoint and check if it's not in conflict with ep name
uint8_t json_endpoint = root.getUInt(PSTR(D_CMND_ZIGBEE_ENDPOINT), 0);
if (zcl.dstendpoint && json_endpoint && zcl.dstendpoint != json_endpoint) {
AddLog(LOG_LEVEL_DEBUG, PSTR("ZIG: conflicting endpoints, from name:%i from json:%i"), zcl.dstendpoint, json_endpoint);
ResponseCmndChar_P(PSTR(D_ZIGBEE_CONFLICTING_ENDPOINTS));
return;
}
zcl.dstendpoint = root.getUInt(PSTR(D_CMND_ZIGBEE_ENDPOINT), zcl.dstendpoint);
// infer endpoint
if (!zcl.validShortaddr()) {
zcl.dstendpoint = 0xFF; // endpoint not used for group addresses, so use a dummy broadcast endpoint
@ -1003,7 +1011,7 @@ void CmndZbUnbind(void) {
//
void CmndZbLeave(void) {
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload).shortaddr;
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload).shortaddr;
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
#ifdef USE_ZIGBEE_ZNP
@ -1035,7 +1043,7 @@ void CmndZbLeave(void) {
void CmndZbBindState_or_Map(bool map) {
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
uint16_t parsed_shortaddr;;
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, &parsed_shortaddr, XdrvMailbox.payload).shortaddr;
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, &parsed_shortaddr, nullptr, XdrvMailbox.payload).shortaddr;
if (BAD_SHORTADDR == shortaddr) {
if ((map) && (parsed_shortaddr != shortaddr)) {
shortaddr = parsed_shortaddr; // allow a non-existent address when ZbMap
@ -1111,7 +1119,7 @@ void CmndZbProbe(void) {
//
void CmndZbProbeOrPing(boolean probe) {
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload).shortaddr;
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload).shortaddr;
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
// set a timer for Reachable - 2s default value
@ -1140,26 +1148,40 @@ void CmndZbName(void) {
// ZbName <device_id> - display the current friendly name
// ZbName <device_id>, - remove friendly name
//
// New:
// ZbName <device_id>,<friendlyname>,<ep> - assign a friendly name to a endpoint
// ZbName <device_id>,,<ep> - remove name to endpoint
//
// Where <device_id> can be: short_addr, long_addr, device_index, friendly_name
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
// check if parameters contain a comma ','
char *p;
strtok_r(XdrvMailbox.data, ",", &p);
char *p = XdrvMailbox.data;
char *device_id = strsep(&p, ","); // zigbee identifier
bool has_comma = (p != nullptr);
char *new_friendlyname = strsep(&p, ","); // friendly name
int32_t ep = (p != nullptr) ? strtol(p, nullptr, 10) : 0; // get endpoint number, or `0` if none
// parse first part, <device_id>
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload); // it's the only case where we create a new device
Z_Device & device = zigbee_devices.parseDeviceFromName(device_id, nullptr, nullptr, XdrvMailbox.payload); // it's the only case where we create a new device
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
if (p == nullptr) {
if (!has_comma) {
const char * friendlyName = device.friendlyName;
Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), device.shortaddr, friendlyName ? friendlyName : "");
} else {
if (strlen(p) > 32) { p[32] = 0x00; } // truncate to 32 chars max
device.setFriendlyName(p);
Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), device.shortaddr, p);
if (new_friendlyname != nullptr && strlen(new_friendlyname) > 32) { new_friendlyname[32] = 0x00; } // truncate to 32 chars max
if (ep == 0) {
device.setFriendlyName(new_friendlyname);
} else {
if (!device.setEPName(ep, new_friendlyname)) {
ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_ENDPOINT)); return;
}
}
}
Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), device.shortaddr, device.friendlyName ? device.friendlyName : "");
device.ep_names.ResponseAppend();
ResponseAppend_P(PSTR("}}"));
}
//
@ -1181,7 +1203,7 @@ void CmndZbModelId(void) {
strtok_r(XdrvMailbox.data, ",", &p);
// parse first part, <device_id>
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
if (p != nullptr) {
@ -1208,7 +1230,7 @@ void CmndZbLight(void) {
strtok_r(XdrvMailbox.data, ", ", &p);
// parse first part, <device_id>
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
if (p) {
@ -1252,7 +1274,7 @@ void CmndZbOccupancy(void) {
strtok_r(XdrvMailbox.data, ", ", &p);
// parse first part, <device_id>
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
int8_t occupancy_time = -1;
@ -1279,7 +1301,7 @@ void CmndZbOccupancy(void) {
//
void CmndZbForget(void) {
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
// everything is good, we can send the command
@ -1309,7 +1331,7 @@ void CmndZbInfo(void) {
CmndZbInfo_inner(device);
}
} else { // try JSON
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
// everything is good, we can send the command
@ -1426,7 +1448,7 @@ void CmndZbenroll(void) {
if ((XdrvMailbox.data_len) && (ArgC() > 1)) { // Process parameter entry
char argument[XdrvMailbox.data_len];
Z_Device & device = zigbee_devices.parseDeviceFromName(ArgV(argument, 1), nullptr, XdrvMailbox.payload);
Z_Device & device = zigbee_devices.parseDeviceFromName(ArgV(argument, 1), nullptr, nullptr, XdrvMailbox.payload);
int enrollEndpoint = atoi(ArgV(argument, 2));
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
@ -1444,7 +1466,7 @@ void CmndZbcie(void) {
if ((XdrvMailbox.data_len) && (ArgC() > 1)) { // Process parameter entry
char argument[XdrvMailbox.data_len];
Z_Device & device = zigbee_devices.parseDeviceFromName(ArgV(argument, 1), nullptr, XdrvMailbox.payload);
Z_Device & device = zigbee_devices.parseDeviceFromName(ArgV(argument, 1), nullptr, nullptr, XdrvMailbox.payload);
int enrollEndpoint = atoi(ArgV(argument, 2));
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
@ -1512,7 +1534,7 @@ void CmndZbRestore(void) {
// do a sanity check, the first byte must equal the length of the buffer
if (buf.get8(0) == buf.len()) {
// good, we can hydrate
hydrateSingleDevice(buf);
hydrateSingleDevice(buf, 4);
} else {
ResponseCmndChar_P(PSTR("Restore failed"));
return;
@ -1684,7 +1706,7 @@ void CmndZbStatus(void) {
if (0 == XdrvMailbox.index) {
dump = zigbee_devices.dumpCoordinator();
} else {
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload);
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload);
if (XdrvMailbox.data_len > 0) {
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
dump = zigbee_devices.dumpDevice(XdrvMailbox.index, device);
@ -1716,7 +1738,7 @@ void CmndZbData(void) {
strtok_r(XdrvMailbox.data, ",", &p);
// parse first part, <device_id>
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
Z_Device & device = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload); // in case of short_addr, it must be already registered
if (!device.valid()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
if (p) {