diff --git a/tasmota/xdrv_23_zigbee_1_headers.ino b/tasmota/xdrv_23_zigbee_1_headers.ino index 203c16d5e..d88bd80d9 100644 --- a/tasmota/xdrv_23_zigbee_1_headers.ino +++ b/tasmota/xdrv_23_zigbee_1_headers.ino @@ -107,6 +107,7 @@ public: #ifdef USE_ZIGBEE_EZSP uint32_t permit_end_time = 0; // timestamp when permit join ends + uint16_t ezsp_version = 0; #elif defined(USE_ZIGBEE_ZNP) bool permit_end_time = false; // in ZNP mode it's only a boolean #endif diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index b8f678d9e..e2a060ef8 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -151,59 +151,94 @@ void ZigbeeHueGroups(String * lights) { } } +void ZigbeeSendHue(uint16_t shortaddr, uint16_t cluster, uint8_t cmd, const SBuffer & s) { + zigbeeZCLSendCmd(ZigbeeZCLSendMessage({ + shortaddr, + 0 /* groupaddr */, + cluster /*cluster*/, + 0 /* endpoint */, + cmd /* cmd */, + 0, /* manuf */ + true /* cluster specific */, + true /* response */, + false /* discover route */, + 0, /* zcl transaction id */ + (&s != nullptr) ? s.getBuffer() : nullptr, + (&s != nullptr) ? s.len() : 0 + })); +} + // Send commands // Power On/Off void ZigbeeHuePower(uint16_t shortaddr, bool power) { - zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0006, power ? 1 : 0, ""); + ZigbeeSendHue(shortaddr, 0x0006, power ? 1 : 0, *(SBuffer*)nullptr); +// zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0006, power ? 1 : 0, ""); zigbee_devices.getShortAddr(shortaddr).setPower(power, 0); } // Dimmer void ZigbeeHueDimmer(uint16_t shortaddr, uint8_t dimmer) { if (dimmer > 0xFE) { dimmer = 0xFE; } - char param[8]; - snprintf_P(param, sizeof(param), PSTR("%02X0A00"), dimmer); - zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0008, 0x04, param); + SBuffer s(4); + s.add8(dimmer); + s.add16(0x000A); // transition time = 1s + ZigbeeSendHue(shortaddr, 0x0008, 0x04, s); + // char param[8]; + // snprintf_P(param, sizeof(param), PSTR("%02X0A00"), dimmer); + // zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0008, 0x04, param); zigbee_devices.getLight(shortaddr).setDimmer(dimmer); } // CT void ZigbeeHueCT(uint16_t shortaddr, uint16_t ct) { if (ct > 0xFEFF) { ct = 0xFEFF; } - AddLog(LOG_LEVEL_INFO, PSTR("ZigbeeHueCT 0x%04X - %d"), shortaddr, ct); - char param[12]; - snprintf_P(param, sizeof(param), PSTR("%02X%02X0A00"), ct & 0xFF, ct >> 8); - uint8_t colormode = 2; // "ct" - zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0300, 0x0A, param); + // AddLog(LOG_LEVEL_INFO, PSTR("ZigbeeHueCT 0x%04X - %d"), shortaddr, ct); + SBuffer s(4); + s.add16(ct); + s.add16(0x000A); // transition time = 1s + ZigbeeSendHue(shortaddr, 0x0300, 0x0A, s); + // char param[12]; + // snprintf_P(param, sizeof(param), PSTR("%02X%02X0A00"), ct & 0xFF, ct >> 8); + // zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0300, 0x0A, param); Z_Data_Light & light = zigbee_devices.getLight(shortaddr); - light.setColorMode(colormode); + light.setColorMode(2); // "ct" light.setCT(ct); } // XY void ZigbeeHueXY(uint16_t shortaddr, uint16_t x, uint16_t y) { - char param[16]; if (x > 0xFEFF) { x = 0xFEFF; } if (y > 0xFEFF) { y = 0xFEFF; } - snprintf_P(param, sizeof(param), PSTR("%02X%02X%02X%02X0A00"), x & 0xFF, x >> 8, y & 0xFF, y >> 8); - uint8_t colormode = 1; // "xy" - zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0300, 0x07, param); + SBuffer s(8); + s.add16(x); + s.add16(y); + s.add16(0x000A); // transition time = 1s + ZigbeeSendHue(shortaddr, 0x0300, 0x07, s); + // char param[16]; + // snprintf_P(param, sizeof(param), PSTR("%02X%02X%02X%02X0A00"), x & 0xFF, x >> 8, y & 0xFF, y >> 8); + // uint8_t colormode = 1; // "xy" + // zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0300, 0x07, param); Z_Data_Light & light = zigbee_devices.getLight(shortaddr); - light.setColorMode(colormode); + light.setColorMode(1); // "xy" light.setX(x); light.setY(y); } // HueSat void ZigbeeHueHS(uint16_t shortaddr, uint16_t hue, uint8_t sat) { - char param[16]; uint8_t hue8 = changeUIntScale(hue, 0, 360, 0, 254); if (sat > 0xFE) { sat = 0xFE; } - snprintf_P(param, sizeof(param), PSTR("%02X%02X0000"), hue8, sat); - uint8_t colormode = 0; // "hs" - zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0300, 0x06, param); + SBuffer s(4); + s.add8(hue); + s.add8(sat); + s.add16(0); + ZigbeeSendHue(shortaddr, 0x0300, 0x06, s); + // char param[16]; + // snprintf_P(param, sizeof(param), PSTR("%02X%02X0000"), hue8, sat); + // uint8_t colormode = 0; // "hs" + // zigbeeZCLSendStr(shortaddr, 0, 0, true, 0, 0x0300, 0x06, param); Z_Data_Light & light = zigbee_devices.getLight(shortaddr); - light.setColorMode(colormode); + light.setColorMode(0); // "hs" light.setSat(sat); light.setHue(hue); } diff --git a/tasmota/xdrv_23_zigbee_4_persistence.ino b/tasmota/xdrv_23_zigbee_4_persistence.ino index 42549ad6b..5f21c3103 100644 --- a/tasmota/xdrv_23_zigbee_4_persistence.ino +++ b/tasmota/xdrv_23_zigbee_4_persistence.ino @@ -436,9 +436,7 @@ void restoreDumpAllDevices(void) { for (const auto & device : zigbee_devices.getDevices()) { const SBuffer buf = hibernateDevicev2(device); if (buf.len() > 0) { - char hex_char[buf.len()*2+2]; - Response_P(PSTR("{\"" D_PRFX_ZB D_CMND_ZIGBEE_RESTORE "\":\"ZbRestore %s\"}"), - ToHex_P(buf.buf(0), buf.len(), hex_char, sizeof(hex_char))); + Response_P(PSTR("{\"" D_PRFX_ZB D_CMND_ZIGBEE_RESTORE "\":\"ZbRestore %_B\"}"), &buf); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_ZB D_CMND_ZIGBEE_DATA)); } } diff --git a/tasmota/xdrv_23_zigbee_4a_nano_fs.ino b/tasmota/xdrv_23_zigbee_4a_nano_fs.ino index 007615c1b..54cbb3b54 100644 --- a/tasmota/xdrv_23_zigbee_4a_nano_fs.ino +++ b/tasmota/xdrv_23_zigbee_4a_nano_fs.ino @@ -20,7 +20,7 @@ #ifdef USE_ZIGBEE #ifdef USE_ZIGBEE_EZSP -#define Z_EEPROM_DEBUG +// #define Z_EEPROM_DEBUG // The EEPROM is 64KB in size with individually writable bytes. // They are conveniently organized in pages of 128 bytes to accelerate @@ -291,7 +291,7 @@ bool ZFS::findFileEntry(uint32_t name, ZFS_File_Entry & entry, uint8_t * _entry_ #ifdef Z_EEPROM_DEBUG // { // char hex_char[(sizeof(ZFS_File_Entry) * 2) + 2]; - // AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Read entry %d at address 0x%04X contains %s"), entry_idx, entry_addr, ToHex_P((uint8_t*)&entry, sizeof(entry), hex_char, sizeof(hex_char))); + // AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Read entry %d at address 0x%04X contains %*_H"), entry_idx, entry_addr, sizeof(entry), &entry); // } #endif if (entry.name == name) { diff --git a/tasmota/xdrv_23_zigbee_4b_eeprom.ino b/tasmota/xdrv_23_zigbee_4b_eeprom.ino index 68f768783..b42b26a75 100644 --- a/tasmota/xdrv_23_zigbee_4b_eeprom.ino +++ b/tasmota/xdrv_23_zigbee_4b_eeprom.ino @@ -89,8 +89,7 @@ int32_t hydrateSingleDevice(const SBuffer & buf, size_t start, size_t len) { #ifdef Z_EEPROM_DEBUG { if (segment_len > 3) { - char hex_char[((segment_len+1) * 2) + 2]; - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbData 0x%04X,%s"), shortaddr, ToHex_P(buf.buf(start+3), segment_len+1-3, hex_char, sizeof(hex_char))); + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbData 0x%04X,%*_H"), shortaddr, segment_len+1-3, buf.buf(start+3)); } } #endif @@ -182,16 +181,14 @@ SBuffer hibernateDeviceData(const struct Z_Device & device, bool mqtt = false) { buf.set8(0, buf.len() - 1); { - size_t buf_len = buf.len() - 3; - char hex[2*buf_len + 1]; // skip first 3 bytes - ToHex_P(buf.buf(3), buf_len, hex, sizeof(hex)); + size_t buf_len = buf.len() - 3; if (mqtt) { - Response_P(PSTR("{\"" D_PRFX_ZB D_CMND_ZIGBEE_DATA "\":\"ZbData 0x%04X,%s\"}"), device.shortaddr, hex); + Response_P(PSTR("{\"" D_PRFX_ZB D_CMND_ZIGBEE_DATA "\":\"ZbData 0x%04X,%*_H\"}"), device.shortaddr, buf_len, buf.buf(3)); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_ZB D_CMND_ZIGBEE_DATA)); } else { - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbData 0x%04X,%s"), device.shortaddr, hex); + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbData 0x%04X,%*_H"), device.shortaddr, buf_len, buf.buf(3)); } } } diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index b1e94a84c..f91b50498 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -723,8 +723,6 @@ public: void log(void) { - char hex_char[_payload.len()*2+2]; - ToHex_P((unsigned char*)_payload.getBuffer(), _payload.len(), hex_char, sizeof(hex_char)); Response_P(PSTR("{\"" D_JSON_ZIGBEEZCL_RECEIVED "\":{" "\"groupid\":%d," "\"clusterid\":\"0x%04X\"," "\"srcaddr\":\"0x%04X\"," "\"srcendpoint\":%d," "\"dstendpoint\":%d," "\"wasbroadcast\":%d," @@ -732,14 +730,14 @@ public: "\"fc\":\"0x%02X\"," "\"frametype\":%d,\"direction\":%d,\"disableresp\":%d," "\"manuf\":\"0x%04X\",\"transact\":%d," - "\"cmdid\":\"0x%02X\",\"payload\":\"%s\"}}"), + "\"cmdid\":\"0x%02X\",\"payload\":\"%_B\"}}"), _groupaddr, _cluster_id, _srcaddr, _srcendpoint, _dstendpoint, _wasbroadcast, _linkquality, _securityuse, _seqnumber, _frame_control, _frame_control.b.frame_type, _frame_control.b.direction, _frame_control.b.disable_def_resp, _manuf_code, _transact_seq, _cmd_id, - hex_char); + &_payload); if (Settings.flag3.tuya_serial_mqtt_publish) { MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR)); } else { diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 696c7ad1a..c805eab13 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -415,16 +415,16 @@ int32_t ZNP_ReceiveCheckVersion(int32_t res, SBuffer &buf) { int32_t EZ_ReceiveCheckVersion(int32_t res, SBuffer &buf) { uint8_t protocol_version = buf.get8(2); uint8_t stack_type = buf.get8(3); - uint16_t stack_version = buf.get16(4); + zigbee.ezsp_version = buf.get16(4); Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" "\"Status\":%d,\"Version\":\"%d.%d.%d.%d\",\"Protocol\":%d" ",\"Stack\":%d}}"), ZIGBEE_STATUS_EZ_VERSION, - (stack_version & 0xF000) >> 12, - (stack_version & 0x0F00) >> 8, - (stack_version & 0x00F0) >> 4, - stack_version & 0x000F, + (zigbee.ezsp_version & 0xF000) >> 12, + (zigbee.ezsp_version & 0x0F00) >> 8, + (zigbee.ezsp_version & 0x00F0) >> 4, + zigbee.ezsp_version & 0x000F, protocol_version, stack_type ); @@ -432,7 +432,7 @@ int32_t EZ_ReceiveCheckVersion(int32_t res, SBuffer &buf) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); if (0x08 == protocol_version) { - if ((stack_version & 0xFF00) == 0x6700) { + if ((zigbee.ezsp_version & 0xFF00) == 0x6700) { // If v6.7 there is a bug so we need to change the response ZBW(ZBR_SET_OK2, 0x00, 0x00 /*high*/, 0x00 /*ok*/) } diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index ccd8d2da9..84a560703 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -222,9 +222,6 @@ void ZigbeeInputLoop(void) { uint32_t frame_len = zigbee_buffer->len(); if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { - char hex_char[frame_len * 2 + 2]; - ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); - // AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); if ((frame_complete) && (frame_len >= 3)) { // frame received and has at least 3 bytes (without EOF), checking CRC @@ -246,7 +243,7 @@ void ZigbeeInputLoop(void) { // remove 2 last bytes if (crc_received != crc) { - AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %s"), crc_received, crc, hex_char); + AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %_B"), crc_received, crc, &zigbee_buffer); } else { // copy buffer SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC @@ -262,14 +259,13 @@ void ZigbeeInputLoop(void) { } } - ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "2\":\"%s\"}"), hex_char); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "2\":\"%_B\"}"), &ezsp_buffer); // now process the message ZigbeeProcessInputRaw(ezsp_buffer); } } else { // the buffer timed-out, print error and discard - AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %d"), hex_char); + AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %_B"), &zigbee_buffer); } zigbee_buffer->setLen(0); // empty buffer escape = false; @@ -352,9 +348,7 @@ void ZigbeeZNPSend(const uint8_t *msg, size_t len) { //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); } // Now send a MQTT message to report the sent message - char hex_char[(len * 2) + 2]; - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), - ToHex_P(msg, len, hex_char, sizeof(hex_char))); + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %*_H"), len, msg); } // @@ -486,17 +480,13 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { } // Now send a MQTT message to report the sent message - char hex_char[(len * 2) + 2]; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %s"), - ToHex_P(msg, len, hex_char, sizeof(hex_char))); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %*_H"), len, msg); } // Send an EZSP command and data // Ex: Version with min v8 = 000008 void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len) { - char hex_char[len*2 + 2]; - ToHex_P(msg, len, hex_char, sizeof(hex_char)); - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "ZbEZSPSend %s"), hex_char); + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "ZbEZSPSend %*_H"), len, msg); SBuffer cmd(len+3); // prefix with seq number (1 byte) and frame control bytes (2 bytes) @@ -567,11 +557,8 @@ void ZigbeeProcessInputEZSP(SBuffer &buf) { } buf.setLen(buf.len() - 3); - char hex_char[buf.len()*2 + 2]; - // log message - ToHex_P((unsigned char*)buf.getBuffer(), buf.len(), hex_char, sizeof(hex_char)); - Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "\":\"%s\"}"), hex_char); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "\":\"%_B\"}"), &buf); if (Settings.flag3.tuya_serial_mqtt_publish) { MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR)); } else { diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino index 79131078a..0bc60223d 100644 --- a/tasmota/xdrv_23_zigbee_9a_upload.ino +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -264,9 +264,7 @@ bool ZigbeeUploadBootloaderPrompt(void) { } if (buf_len) { - char hex_char[256]; - ToHex_P(serial_buffer, buf_len, hex_char, 256); - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("XMD: Rcvd %s"), hex_char); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("XMD: Rcvd %*_H"), buf_len, serial_buffer); } return ((4 == ZbUpload.byte_counter) && (millis() > XModem.flush_delay)); diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 4455c5b0a..0333c8d81 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -183,23 +183,7 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint, } } - if ((0 == endpoint) && (BAD_SHORTADDR != shortaddr)) { - // endpoint is not specified, let's try to find it from shortAddr, unless it's a group address - endpoint = zigbee_devices.findFirstEndpoint(shortaddr); - //AddLog_P(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint); - } - AddLog_P(LOG_LEVEL_DEBUG, PSTR("ZbSend: shortaddr 0x%04X, groupaddr 0x%04X, cluster 0x%04X, endpoint 0x%02X, cmd 0x%02X, data %s"), - shortaddr, groupaddr, cluster, endpoint, cmd, param); - - if ((0 == endpoint) && (BAD_SHORTADDR != shortaddr)) { // endpoint null is ok for group address - AddLog_P(LOG_LEVEL_INFO, PSTR("ZbSend: unspecified endpoint")); - return; - } - - // everything is good, we can send the command - - uint8_t seq = zigbee_devices.getNextSeqNumber(shortaddr); - ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({ + zigbeeZCLSendCmd(ZigbeeZCLSendMessage({ shortaddr, groupaddr, cluster /*cluster*/, @@ -209,14 +193,37 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint, clusterSpecific /* not cluster specific */, true /* response */, false /* discover route */, - seq, /* zcl transaction id */ + 0, /* zcl transaction id */ buf.getBuffer(), buf.len() })); +} + +void zigbeeZCLSendCmd(const class ZigbeeZCLSendMessage &msg_const) { + ZigbeeZCLSendMessage msg = msg_const; // copy to a modifiable variable + + if ((0 == msg.endpoint) && (BAD_SHORTADDR != msg.shortaddr)) { + // endpoint is not specified, let's try to find it from shortAddr, unless it's a group address + msg.endpoint = zigbee_devices.findFirstEndpoint(msg.shortaddr); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint); + } + + AddLog_P(LOG_LEVEL_DEBUG, PSTR("ZbSend: shortaddr 0x%04X, groupaddr 0x%04X, cluster 0x%04X, endpoint 0x%02X, cmd 0x%02X, data %*_H"), + msg.shortaddr, msg.groupaddr, msg.cluster, msg.endpoint, msg.cmd, msg.len, msg.msg); + + if ((0 == msg.endpoint) && (BAD_SHORTADDR != msg.shortaddr)) { // endpoint null is ok for group address + AddLog_P(LOG_LEVEL_INFO, PSTR("ZbSend: unspecified endpoint")); + return; + } + + // everything is good, we can send the command + + msg.transacId = zigbee_devices.getNextSeqNumber(msg.shortaddr); + ZigbeeZCLSend_Raw(msg); // now set the timer, if any, to read back the state later - if (clusterSpecific) { + if (msg.clusterSpecific) { if (!Settings.flag5.zb_disable_autoquery) { // read back attribute value unless it is disabled - sendHueUpdate(shortaddr, groupaddr, cluster, endpoint); + sendHueUpdate(msg.shortaddr, msg.groupaddr, msg.cluster, msg.endpoint); } } } @@ -463,7 +470,7 @@ void ZbSendSend(class JsonParserToken val_cmd, uint16_t device, uint16_t groupad const char *cmd_s = ""; // pointer to payload string bool clusterSpecific = true; - static char delim[] = ", "; // delimiters for parameters + static const char delim[] = ", "; // delimiters for parameters // probe the type of the argument // If JSON object, it's high level commands // If String, it's a low level command diff --git a/tasmota/xdrv_41_tcp_bridge.ino b/tasmota/xdrv_41_tcp_bridge.ino index 9cc0b7942..aeadfde61 100644 --- a/tasmota/xdrv_41_tcp_bridge.ino +++ b/tasmota/xdrv_41_tcp_bridge.ino @@ -90,9 +90,7 @@ void TCPLoop(void) } } if (buf_len > 0) { - char hex_char[TCP_BRIDGE_BUF_SIZE+1]; - ToHex_P(tcp_buf, buf_len, hex_char, 256); - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "from MCU: %s"), hex_char); + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "from MCU: %*_H"), buf_len, tcp_buf); for (uint32_t i=0; i 0) { - char hex_char[TCP_BRIDGE_BUF_SIZE+1]; - ToHex_P(tcp_buf, buf_len, hex_char, 256); - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "to MCU/%d: %s"), i+1, hex_char); + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "to MCU/%d: %*_H"), i+1, buf_len, tcp_buf); TCPSerial->write(tcp_buf, buf_len); } }