From 1626c26c6ee5a669745b5e0aee7cb63dbab95b9a Mon Sep 17 00:00:00 2001 From: ksaye Date: Thu, 13 May 2021 12:12:21 -0500 Subject: [PATCH 1/8] Small changes to document changes for Azure --- tasmota/my_user_config.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 2cfb1b875..a9b853734 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -419,7 +419,14 @@ // Any valid fingerprint with the old algo will be automatically updated to the new algo. // Enable this if you want to disable the old algo check, which should be more secure // for USE_4K_RSA (support for 4096 bits certificates, instead of 2048), you need to uncommend `-DUSE_4K_RSA` in `build_flags` from `platform.ini` or `platform_override.ini` -// #define USE_MQTT_AZURE_IOT // Enable MQTT for Azure IoT Hub (+1k code) + +// -- MQTT - TLS - Azure IoT & IoT Central --------- +// Starting with version v9.4.0.3 added support for both Azure IoT Hub and IoT Central +//#define USE_MQTT_TLS // REQUIRED Use TLS for MQTT connection (+34.5k code, +7.0k mem and +4.8k additional during connection handshake) +// #define USE_MQTT_AZURE_IOT // REQUIRED Enable accesss to IoT Hub without DPS using a preshared key: https://tasmota.github.io/docs/Azure-IoT-Hub/ Enable MQTT for Azure IoT Hub (+1k code) +// #define USE_MQTT_AZURE_DPS_SCOPEID // OPTIONAL Enables Azure Device Provisioning Service (DPS) for provision at scale, REQUIRED for IoT Central. Uses the REST over HTTPS protocol (+4k memory) +// #define USE_MQTT_AZURE_DPS_PRESHAREDKEY // OPTIONAL The Preshared Key of DPS https://github.com/tasmota/docs/blob/development/docs/Azure-IoT-Central.md +// #define USE_MQTT_AZURE_DPS_SCOPE_ENDPOINT // OPTIONAL Defaults to "https://global.azure-devices-provisioning.net/", can be changed for Azure China, Azure Germany or others. // -- Telegram Protocol --------------------------- //#define USE_TELEGRAM // Support for Telegram protocol (+49k code, +7.0k mem and +4.8k additional during connection handshake) From 5a3f49c698de83cf65718d7c99c60de789cecebe Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Sat, 15 May 2021 10:20:22 +0200 Subject: [PATCH 2/8] Bump version to 9.4.0.4 --- tasmota/tasmota_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 897dfde36..8ac5280fa 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,6 +20,6 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x09040003; +const uint32_t VERSION = 0x09040004; #endif // _TASMOTA_VERSION_H_ From ea83c8acd1b21cca1195d67df2d2b3bc870c3093 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 15 May 2021 10:56:07 +0200 Subject: [PATCH 3/8] Update changelog --- CHANGELOG.md | 8 ++++++-- RELEASENOTES.md | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 248acf597..1a1214b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,18 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [9.4.0.3] +## [9.4.0.4] +### Added +- Version bump to signal new features to Hass + +## [9.4.0.3] 20210515 ### Added - Make Telegram command ``TmState`` persistent (#11965) - Zigbee firmware for Tube's Zigbee coordinator based on EFR32 and ESP32 - Zigbee firmware 6.7.9 for Sonoff ZBBridge - Defines ``USER_RULE1``, ``USER_RULE2`` and ``USER_RULE3`` to store rules at compile time - Define ``USER_BACKLOG`` to store commands at compile time to be executed at firmware load or when executing command ``reset`` -- LVGL add support for TrueType fonts via FreeType library +- LVGL support for TrueType fonts via FreeType library ## [9.4.0.2] 20210430 ### Added diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 1b5274626..765c3a488 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -76,7 +76,7 @@ The binaries can be downloaded from either https://github.com/arendst/Tasmota/tr [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v9.4.0.2 +## Changelog v9.4.0.4 ### Added - Initial support for optional ``Template`` JSON fieldpair ``"CMND":"||..."`` [#11788](https://github.com/arendst/Tasmota/issues/11788) - ESP32 pulldown buttons ``Button_d`` and ``Button_id`` and switches ``Switch_d`` [#10814](https://github.com/arendst/Tasmota/issues/10814) @@ -86,6 +86,7 @@ The binaries can be downloaded from either https://github.com/arendst/Tasmota/tr - Zigbee firmware 6.7.9 for Sonoff ZBBridge - Defines ``USER_RULE1``, ``USER_RULE2`` and ``USER_RULE3`` to store rules at compile time - Define ``USER_BACKLOG`` to store commands at compile time to be executed at firmware load or when executing command ``reset`` +- LVGL support for TrueType fonts via FreeType library ### Breaking Changed From dd624c3ce6529a3c38b012eff35f2f1e526d38c4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 15 May 2021 11:53:37 +0200 Subject: [PATCH 4/8] Add more checks to MQTT file upload --- tasmota/xdrv_02_mqtt_1_file.ino | 67 +++++---- tasmota/xdrv_02_mqtt_9_impl.ino | 9 +- ...mo_9.4.0.3.dmp => Config_demo_9.4.0.4.dmp} | Bin 4096 -> 4096 bytes tools/mqtt-file/upload-ota-201.py | 142 ------------------ tools/mqtt-file/upload-ota.py | 2 +- tools/mqtt-file/upload-settings.py | 2 +- 6 files changed, 49 insertions(+), 173 deletions(-) rename tools/mqtt-file/{Config_demo_9.4.0.3.dmp => Config_demo_9.4.0.4.dmp} (91%) delete mode 100644 tools/mqtt-file/upload-ota-201.py diff --git a/tasmota/xdrv_02_mqtt_1_file.ino b/tasmota/xdrv_02_mqtt_1_file.ino index c484364e2..ec1a9e698 100644 --- a/tasmota/xdrv_02_mqtt_1_file.ino +++ b/tasmota/xdrv_02_mqtt_1_file.ino @@ -23,11 +23,14 @@ /*********************************************************************************************\ * MQTT file transfer * - * Supports base64 encoded binary data transfer + * Supports both binary and base64 encoded binary data transfer \*********************************************************************************************/ +#include #include +extern PubSubClient MqttClient; + struct FMQTT { uint32_t file_pos = 0; // MQTT file position during upload/download uint32_t file_size = 0; // MQTT total file size @@ -40,10 +43,6 @@ struct FMQTT { uint8_t file_id = 0; // MQTT unique file id during upload/download } FMqtt; -void MqttTopicSize(uint32_t topic_size) { - FMqtt.topic_size = topic_size +1; -} - /* The download chunk size is the data size before it is encoded to base64. It is smaller than the upload chunksize as it is bound by MESSZ @@ -55,18 +54,20 @@ const uint32_t mqtt_file_chuck_size = (((MESSZ - FileTransferHeaderSize) / 4) * uint32_t FileUploadChunckSize(void) { /* - The upload chunk size is the data size before it is encoded to base64. + The upload chunk size is the data size of the payload. It can be larger than the download chunksize which is bound by MESSZ The PubSubClient upload buffer with length MQTT_MAX_PACKET_SIZE (1200) contains - Header of 5 bytes (MQTT_MAX_HEADER_SIZE) - Topic string terminated with a zero (stat/demo/FILEUPLOAD) - - Payload ({"Id":116,"Data":""}) + - Payload ({"Id":116,"Data":""}) or () */ const uint32_t PubSubClientHeaderSize = 5; // MQTT_MAX_HEADER_SIZE - return MQTT_MAX_PACKET_SIZE - PubSubClientHeaderSize - FMqtt.topic_size - FileTransferHeaderSize; + return MqttClient.getBufferSize() - PubSubClientHeaderSize - FMqtt.topic_size -1; } uint32_t MqttFileUploadValidate(uint32_t rcv_id) { + if (XdrvMailbox.grpflg) { return 5; } + if ((0 == FMqtt.file_id) && (rcv_id > 0) && (FMqtt.file_size > 0) && (FMqtt.file_type > 0)) { FMqtt.file_buffer = nullptr; // Init upload buffer @@ -74,7 +75,12 @@ uint32_t MqttFileUploadValidate(uint32_t rcv_id) { return 1; // Invalid password } - if (UPL_SETTINGS != FMqtt.file_type) { // Check enough flash space for intermediate upload + // Check buffer size + if (UPL_SETTINGS == FMqtt.file_type) { + if (FMqtt.file_size > 4096) { + return 2; // Settings supports max 4k size + } + } else { // Check enough flash space for intermediate upload uint32_t head_room = (FlashWriteMaxSector() - FlashWriteStartSector()) * SPI_FLASH_SEC_SIZE; uint32_t rounded_size = (FMqtt.file_size + SPI_FLASH_SEC_SIZE -1) & (~(SPI_FLASH_SEC_SIZE - 1)); if (rounded_size > head_room) { @@ -82,9 +88,11 @@ uint32_t MqttFileUploadValidate(uint32_t rcv_id) { } } + // Init file_buffer if (UPL_TASMOTA == FMqtt.file_type) { if (Update.begin(FMqtt.file_size)) { FMqtt.file_buffer = &FMqtt.file_id; // Dummy buffer +// TasmotaGlobal.blinkstate = true; // Stay lit SettingsSave(1); // Free flash for OTA update } } @@ -122,24 +130,31 @@ uint32_t MqttFileUploadValidate(uint32_t rcv_id) { void CmndFileUpload(void) { /* - Upload (binary) max 700 bytes chunks of data base64 encoded with MD5 hash over base64 decoded data - FileUpload 0 - Abort current upload - FileUpload {"File":"Config_wemos10_9.4.0.3.dmp","Id":116,"Type":2,"Size":4096} - FileUpload {"Id":116,"Data":"CRJcTQ9fYGF ... OT1BRUlNUVVZXWFk="} - FileUpload {"Id":116,"Data":" ... "} - FileUpload {"Id":116,"Md5":"496fcbb433bbca89833063174d2c5747"} -*/ - if (XdrvMailbox.grpflg) { return; } + Upload bytes chunks of data either base64 encoded or binary with MD5 hash + Supported Type: + 1 - OTA firmware + 2 - Settings + + FileUpload 0 - Abort current upload + + Start an upload session: + FileUpload {"Password":"","File":"Config_wemos10_9.4.0.3.dmp","Id":116,"Type":2,"Size":4096} + + Upload data using base64: + FileUpload {"Id":116,"Data":"CRJcTQ9fYGF ... OT1BRUlNUVVZXWFk="} + FileUpload {"Id":116,"Data":" ... "} + Or binary: + FileUpload201 + + Finish upload session: + FileUpload {"Id":116,"Md5":"496fcbb433bbca89833063174d2c5747"} +*/ const char* base64_data = nullptr; uint32_t rcv_id = 0; char* dataBuf = (char*)XdrvMailbox.data; - bool binary_data = false; - if (XdrvMailbox.index > 199) { // Check for raw data - XdrvMailbox.index -= 200; - binary_data = true; - } + bool binary_data = (XdrvMailbox.index > 199); // Check for raw data if (!binary_data) { if (strlen(dataBuf) > 8) { // Workaround exception if empty JSON like {} - Needs checks @@ -156,7 +171,7 @@ void CmndFileUpload(void) { if (val) { FMqtt.file_md5 = val.getStr(); } val = root[PSTR("DATA")]; if (val) { base64_data = val.getStr(); } - val = root[PSTR("PASS")]; + val = root[PSTR("PASSWORD")]; if (val) { FMqtt.file_password = val.getStr(); } } } @@ -170,7 +185,7 @@ void CmndFileUpload(void) { TasmotaGlobal.masterlog_level = LOG_LEVEL_NONE; // Enable logging - char error_txt[TOPSZ]; + char error_txt[20]; snprintf_P(error_txt, sizeof(error_txt), PSTR(D_JSON_ERROR " %d"), error); ResponseCmndChar(error_txt); } @@ -209,7 +224,7 @@ void CmndFileUpload(void) { if ((FMqtt.file_pos > rcvd_bytes) && ((FMqtt.file_pos % 102400) <= rcvd_bytes)) { TasmotaGlobal.masterlog_level = LOG_LEVEL_NONE; // Enable logging - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Progress %d kB"), FMqtt.file_pos / 1024); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Progress %d kB"), (FMqtt.file_pos / 10240) * 10); TasmotaGlobal.masterlog_level = LOG_LEVEL_DEBUG_MORE; // Hide upload data logging } } @@ -219,7 +234,7 @@ void CmndFileUpload(void) { uint32_t chunk_size = FileUploadChunckSize(); if (!binary_data) { - chunk_size = ((chunk_size / 4) * 3) -2; // Calculate base64 chunk size + chunk_size = (((chunk_size - FileTransferHeaderSize) / 4) * 3) -2; // Calculate base64 chunk size } // {"Id":116,"MaxSize":"765"} Response_P(PSTR("{\"Id\":%d,\"MaxSize\":%d}"), FMqtt.file_id, chunk_size); diff --git a/tasmota/xdrv_02_mqtt_9_impl.ino b/tasmota/xdrv_02_mqtt_9_impl.ino index 6e55b927c..beca7778d 100644 --- a/tasmota/xdrv_02_mqtt_9_impl.ino +++ b/tasmota/xdrv_02_mqtt_9_impl.ino @@ -522,6 +522,12 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len } } +#ifdef USE_MQTT_FILE + FMqtt.topic_size = strlen(mqtt_topic); +#endif // USE_MQTT_FILE + +// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "BufferSize %d, Topic |%s|, Length %d, data_len %d"), MqttClient.getBufferSize(), mqtt_topic, strlen(mqtt_topic), data_len); + // Save MQTT data ASAP as it's data is discarded by PubSubClient with next publish as used in MQTTlog char topic[TOPSZ]; #ifdef USE_MQTT_AZURE_IOT @@ -544,9 +550,6 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len #else strlcpy(topic, mqtt_topic, sizeof(topic)); #endif // USE_MQTT_AZURE_IOT -#ifdef USE_MQTT_FILE - MqttTopicSize(strlen(topic)); -#endif // USE_MQTT_FILE mqtt_data[data_len] = 0; char data[data_len +1]; memcpy(data, mqtt_data, sizeof(data)); diff --git a/tools/mqtt-file/Config_demo_9.4.0.3.dmp b/tools/mqtt-file/Config_demo_9.4.0.4.dmp similarity index 91% rename from tools/mqtt-file/Config_demo_9.4.0.3.dmp rename to tools/mqtt-file/Config_demo_9.4.0.4.dmp index e195bbb485ea30ed06168e19cfeb3f9955176db7..ea3de4f3f2d4b3fe0d1e9eae11a80ac50ad61906 100644 GIT binary patch delta 201 zcmV;)05<=CAb=nc2@+gQ0$yNYW@BJ%&Swi?kr0)C|0Qv7W@2o9A}1_M?n>gMZ(hKGoW-R|My{l1`)l9QB`mY0~Bvp@mC4FOn_0uS~Ga>~m!`oMrh DuK`X1 delta 178 zcmV;j08RgZAb=nc2@+gQnqOdHVPjxyIA@iGkr0(>yH-R|TvS9=R0u43d1-5BcQrmY zXM1ITbUij2e|d0m9}poDBTz(DN=IEwSS(^_X)u0#GhljgaCCe+b8~TeKO`*Mv|>fYn&;*O7y gk&?vm`1$0isk1-. - -Requirements: - - Python 3.x and Pip: - sudo apt-get install python3 python3-pip - pip3 install paho-mqtt json - -Instructions: - Edit file and change parameters in User Configuration Section - - Then execute command upload-ota-201.py - -""" - -import paho.mqtt.client as mqtt -import time -import base64 -import hashlib -import json - -# **** Start of User Configuration Section - -broker = "domus1" # MQTT broker ip address or name -broker_port = 1883 # MQTT broker port - -mytopic = "demo" # Tasmota MQTT topic -#myfile = "../../build_output/firmware/tasmota32.bin" # Tasmota esp32 firmware file name -myfile = "../../build_output/firmware/tasmota.bin.gz" # Tasmota esp8266 firmware file name -myfiletype = 1 # Tasmota firmware file type - -# **** End of User Configuration Section - -# Derive fulltopic from broker LWT message -mypublish = "cmnd/"+mytopic+"/fileupload" -mysubscribe = "stat/"+mytopic+"/FILEUPLOAD" # Case sensitive - -Ack_flag = False - -file_id = 114 # Even id between 2 and 254 -file_chunk_size = 700 # Default Tasmota MQTT max message size - -# The callback for when mysubscribe message is received -def on_message(client, userdata, msg): - global Ack_flag - global file_chunk_size - - rcv_code = "" - rcv_id = 0 - -# print("Received message =",str(msg.payload.decode("utf-8"))) - - root = json.loads(msg.payload.decode("utf-8")) - if "Command" in root: rcv_code = root["Command"] - if rcv_code == "Error": - print("Error: Command error") - return - - if "Id" in root: rcv_id = root["Id"] - if rcv_id == file_id: - if "MaxSize" in root: file_chunk_size = root["MaxSize"] - - Ack_flag = False - -def wait_for_ack(): - global Ack_flag - timeout = 100 - while Ack_flag and timeout > 0: - time.sleep(0.01) - timeout = timeout -1 - - if Ack_flag: - print("Error: Ack timeout") - - return Ack_flag - -client = mqtt.Client() -client.on_message = on_message -client.connect(broker, broker_port) -client.loop_start() # Start loop to process received messages -client.subscribe(mysubscribe) - -time_start = time.time() -print("Uploading file "+myfile+" to "+mytopic+" ...") - -fo = open(myfile,"rb") -fo.seek(0, 2) # os.SEEK_END -file_size = fo.tell() -fo.seek(0, 0) # os.SEEK_SET - -client.publish(mypublish, "{\"File\":\""+myfile+"\",\"Id\":"+str("%3d"%file_id)+",\"Type\":"+str(myfiletype)+",\"Size\":"+str(file_size)+"}") -Ack_flag = True - -out_hash_md5 = hashlib.md5() - -Run_flag = True -while Run_flag: - if wait_for_ack(): # We use Ack here - Run_flag = False - - else: - chunk = fo.read(file_chunk_size) - if chunk: - out_hash_md5.update(chunk) # Update hash - -# base64_encoded_data = base64.b64encode(chunk) -# base64_data = base64_encoded_data.decode('utf-8') - # Message length used by Tasmota (FileTransferHeaderSize) -# client.publish(mypublish, "{\"Id\":"+str("%3d"%file_id)+",\"Data\":\""+base64_data+"\"}") - client.publish(mypublish+"201", chunk) - Ack_flag = True - - else: - md5_hash = out_hash_md5.hexdigest() - client.publish(mypublish, "{\"Id\":"+str("%3d"%file_id)+",\"Md5\":\""+md5_hash+"\"}") - Run_flag = False - -fo.close() - -time_taken = time.time() - time_start -print("Done in "+str("%.2f"%time_taken)+" seconds") - -client.disconnect() # Disconnect -client.loop_stop() # Stop loop diff --git a/tools/mqtt-file/upload-ota.py b/tools/mqtt-file/upload-ota.py index c58e6ae44..791c9b1ae 100644 --- a/tools/mqtt-file/upload-ota.py +++ b/tools/mqtt-file/upload-ota.py @@ -113,7 +113,7 @@ fo.seek(0, 2) # os.SEEK_END file_size = fo.tell() fo.seek(0, 0) # os.SEEK_SET -client.publish(mypublish, "{\"Pass\":\""+mypassword+"\",\"File\":\""+myfile+"\",\"Id\":"+str("%3d"%file_id)+",\"Type\":"+str(myfiletype)+",\"Size\":"+str(file_size)+"}") +client.publish(mypublish, "{\"Password\":\""+mypassword+"\",\"File\":\""+myfile+"\",\"Id\":"+str("%3d"%file_id)+",\"Type\":"+str(myfiletype)+",\"Size\":"+str(file_size)+"}") Ack_flag = True out_hash_md5 = hashlib.md5() diff --git a/tools/mqtt-file/upload-settings.py b/tools/mqtt-file/upload-settings.py index 34984116c..e5cb717cc 100644 --- a/tools/mqtt-file/upload-settings.py +++ b/tools/mqtt-file/upload-settings.py @@ -112,7 +112,7 @@ fo.seek(0, 2) # os.SEEK_END file_size = fo.tell() fo.seek(0, 0) # os.SEEK_SET -client.publish(mypublish, "{\"Pass\":\""+mypassword+"\",\"File\":\""+myfile+"\",\"Id\":"+str("%3d"%file_id)+",\"Type\":"+str(myfiletype)+",\"Size\":"+str(file_size)+"}") +client.publish(mypublish, "{\"Password\":\""+mypassword+"\",\"File\":\""+myfile+"\",\"Id\":"+str("%3d"%file_id)+",\"Type\":"+str(myfiletype)+",\"Size\":"+str(file_size)+"}") Ack_flag = True out_hash_md5 = hashlib.md5() From 2e1ac3581f77e0bf68cf038f74de7669ee278fc5 Mon Sep 17 00:00:00 2001 From: Barbudor Date: Sat, 15 May 2021 17:32:18 +0200 Subject: [PATCH 5/8] move response for unresolved ip into poll --- tasmota/xdrv_38_ping.ino | 59 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino index 0974697fe..349fa7898 100644 --- a/tasmota/xdrv_38_ping.ino +++ b/tasmota/xdrv_38_ping.ino @@ -246,14 +246,13 @@ extern "C" { int32_t t_ping_start(const char *hostname, uint32_t count) { IPAddress ipfull; if (!WiFi.hostByName(hostname, ipfull)) { - return -2; + ipfull = 0xFFFFFFFF; } uint32_t ip = ipfull; - if (0xFFFFFFFF == ip) { return -2; } // invalid address // check if pings are already ongoing for this IP - if (t_ping_find(ip)) { + if (0xFFFFFFFF != ip && t_ping_find(ip)) { return -1; } @@ -271,6 +270,12 @@ extern "C" { ping->next = ping_head; ping_head = ping; // insert at head + if (0xFFFFFFFF == ip) { // If invalid address, set as completed + ping->done = true; + return -2; + } + + // send t_ping_register_pcb(); t_ping_send(t_ping_pcb, ping); @@ -293,24 +298,34 @@ void PingResponsePoll(void) { uint32_t success = ping->success_count; uint32_t ip = ping->ip; - Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{" - "\"Reachable\":%s" - ",\"IP\":\"%d.%d.%d.%d\"" - ",\"Success\":%d" - ",\"Timeout\":%d" - ",\"MinTime\":%d" - ",\"MaxTime\":%d" - ",\"AvgTime\":%d" - "}}}"), - ping->hostname.c_str(), - success ? PSTR("true") : PSTR("false"), - ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24, - success, - ping->timeout_count, - success ? ping->min_time : 0, - ping->max_time, - success ? ping->sum_time / success : 0 - ); + if (0xFFFFFFFF == ip) { + Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{" + "\"Reachable\":false" + ",\"IP\":\"\"" + ",\"Success\":false" + "}}}"), + ping->hostname.c_str() + ); + } else { + Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{" + "\"Reachable\":%s" + ",\"IP\":\"%d.%d.%d.%d\"" + ",\"Success\":%d" + ",\"Timeout\":%d" + ",\"MinTime\":%d" + ",\"MaxTime\":%d" + ",\"AvgTime\":%d" + "}}}"), + ping->hostname.c_str(), + success ? PSTR("true") : PSTR("false"), + ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24, + success, + ping->timeout_count, + success ? ping->min_time : 0, + ping->max_time, + success ? ping->sum_time / success : 0 + ); + } MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); // remove from linked list @@ -342,6 +357,7 @@ void CmndPing(void) { } else if (-1 == res) { ResponseCmndChar_P(PSTR("Ping already ongoing for this IP")); } else { + /* Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{" "\"Reachable\":false" ",\"IP\":\"\"" @@ -350,6 +366,7 @@ void CmndPing(void) { XdrvMailbox.data ); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); + */ ResponseCmndChar_P(PSTR("Unable to resolve IP address")); } } From 823e6b84d2001da7a48da982160c4a70e2e7c25f Mon Sep 17 00:00:00 2001 From: Barbudor Date: Sat, 15 May 2021 17:33:18 +0200 Subject: [PATCH 6/8] cleanup --- tasmota/xdrv_38_ping.ino | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino index 349fa7898..38e21485f 100644 --- a/tasmota/xdrv_38_ping.ino +++ b/tasmota/xdrv_38_ping.ino @@ -357,16 +357,6 @@ void CmndPing(void) { } else if (-1 == res) { ResponseCmndChar_P(PSTR("Ping already ongoing for this IP")); } else { - /* - Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{" - "\"Reachable\":false" - ",\"IP\":\"\"" - ",\"Success\":false" - "}}}"), - XdrvMailbox.data - ); - MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); - */ ResponseCmndChar_P(PSTR("Unable to resolve IP address")); } } From 2740c48e22739c492227d4b641f882e5312a24be Mon Sep 17 00:00:00 2001 From: Barbudor Date: Sun, 16 May 2021 16:18:00 +0200 Subject: [PATCH 7/8] extract power value as 3 bytes from Tuya frame --- tasmota/xdrv_16_tuyamcu.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index f34c56af2..91abb8d76 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -729,7 +729,7 @@ void TuyaProcessStatePacket(void) { if (RtcTime.valid) { if (Tuya.lastPowerCheckTime != 0 && Energy.active_power[0] > 0) { - Energy.kWhtoday += (float)Energy.active_power[0] * (Rtc.utc_time - Tuya.lastPowerCheckTime) / 36; + Energy.kWhtoday += Energy.active_power[0] * (float)(Rtc.utc_time - Tuya.lastPowerCheckTime) / 36.0; EnergyUpdateToday(); } Tuya.lastPowerCheckTime = Rtc.utc_time; @@ -856,12 +856,13 @@ void TuyaProcessStatePacket(void) { Energy.current[0] = (float)packetValue / 1000; AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Current=%d"), Tuya.buffer[dpidStart], packetValue); } else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER) { + uint32_t packetValue = Tuya.buffer[dpidStart + 5] << 16 |Tuya.buffer[dpidStart + 6] << 8 | Tuya.buffer[dpidStart + 7]; Energy.active_power[0] = (float)packetValue / 10; AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Active_Power=%d"), Tuya.buffer[dpidStart], packetValue); if (RtcTime.valid) { if (Tuya.lastPowerCheckTime != 0 && Energy.active_power[0] > 0) { - Energy.kWhtoday += (float)Energy.active_power[0] * (Rtc.utc_time - Tuya.lastPowerCheckTime) / 36; + Energy.kWhtoday += Energy.active_power[0] * (float)(Rtc.utc_time - Tuya.lastPowerCheckTime) / 36.0; EnergyUpdateToday(); } Tuya.lastPowerCheckTime = Rtc.utc_time; From fa0565b40fbed1b341bdb2f6f8ec54ba38c2db8e Mon Sep 17 00:00:00 2001 From: Barbudor Date: Sun, 16 May 2021 18:09:53 +0200 Subject: [PATCH 8/8] improve reactive_power calculation range --- tasmota/xdrv_03_energy.ino | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index b9697dfca..7c675e19e 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -985,7 +985,12 @@ void EnergyShow(bool json) if ((Energy.current[i] > 0.005) && ((difference > 15) || (difference > (uint32_t)(apparent_power * 100 / 1000)))) { // calculating reactive power only if current is greater than 0.005A and // difference between active and apparent power is greater than 1.5W or 1% - reactive_power = (float)(RoundSqrtInt((uint32_t)(apparent_power * apparent_power * 100) - (uint32_t)(Energy.active_power[i] * Energy.active_power[i] * 100))) / 10; + //reactive_power = (float)(RoundSqrtInt((uint64_t)(apparent_power * apparent_power * 100) - (uint64_t)(Energy.active_power[i] * Energy.active_power[i] * 100))) / 10; + float power_diff = apparent_power * apparent_power - Energy.active_power[i] * Energy.active_power[i]; + if (power_diff < 10737418) // 2^30 / 100 (RoundSqrtInt is limited to 2^30-1) + reactive_power = (float)(RoundSqrtInt((uint32_t)(power_diff * 100.0))) / 10.0; + else + reactive_power = (float)(SqrtInt((uint32_t)(power_diff))); } }