From 5f6c10650795d1b20996227eb0c75321ce7b3fef Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 15 Apr 2020 08:11:54 +0200 Subject: [PATCH 01/34] scripter esp32 script size expansion --- tasmota/xdrv_10_scripter.ino | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index e086adedb..88400ff0d 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -65,6 +65,35 @@ keywords if then else endif, or, and are better readable for beginners (others m uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); +#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) + +#include "FS.h" +#include "SPIFFS.h" +void SaveFile(const char *name,const uint8_t *buf,uint32_t len) { + File file = SPIFFS.open(name, FILE_WRITE); + if (!file) return; + file.write(buf, len); + file.close(); +} + +#define FORMAT_SPIFFS_IF_FAILED true +uint8_t spiffs_mounted=0; + +void LoadFile(const char *name,uint8_t *buf,uint32_t len) { + if (!spiffs_mounted) { + if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){ + //Serial.println("SPIFFS Mount Failed"); + return; + } + spiffs_mounted=1; + } + File file = SPIFFS.open(name); + if (!file) return; + file.read(buf, len); + file.close(); +} +#endif + // offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution #define EPOCH_OFFSET 1546300800 @@ -3597,6 +3626,11 @@ void ScriptSaveSettings(void) { } #endif +#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) + if (glob_script_mem.flags&1) { + SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,ESP32_SCRIPT_SIZE); + } +#endif } if (glob_script_mem.script_mem) { @@ -4820,6 +4854,11 @@ bool Xdrv10(uint8_t function) switch (function) { case FUNC_PRE_INIT: +#ifdef USE_WEBCAM + if (Settings.module==ESP32_CAM_AITHINKER) { + webcam_setup(); + } +#endif // set defaults to rules memory glob_script_mem.script_ram=Settings.rules[0]; glob_script_mem.script_size=MAX_SCRIPT_SIZE; @@ -4889,6 +4928,21 @@ bool Xdrv10(uint8_t function) } #endif + +#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) + char *script; + script=(char*)calloc(ESP32_SCRIPT_SIZE+4,1); + if (!script) break; + LoadFile("/script.txt",(uint8_t*)script,ESP32_SCRIPT_SIZE); + glob_script_mem.script_ram=script; + glob_script_mem.script_size=ESP32_SCRIPT_SIZE; + script[ESP32_SCRIPT_SIZE-1]=0; + // use rules storage for permanent vars + glob_script_mem.script_pram=(uint8_t*)Settings.rules[0]; + glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE; + glob_script_mem.flags=1; +#endif + // assure permanent memory is 4 byte aligned { uint32_t ptr=(uint32_t)glob_script_mem.script_pram; ptr&=0xfffffffc; From 7d85ccb793d4255304097fccece9498a68670a61 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 15 Apr 2020 08:21:43 +0200 Subject: [PATCH 02/34] Update xdrv_10_scripter.ino --- tasmota/xdrv_10_scripter.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 88400ff0d..9199d3b90 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -4854,11 +4854,13 @@ bool Xdrv10(uint8_t function) switch (function) { case FUNC_PRE_INIT: + /* #ifdef USE_WEBCAM if (Settings.module==ESP32_CAM_AITHINKER) { webcam_setup(); } #endif +*/ // set defaults to rules memory glob_script_mem.script_ram=Settings.rules[0]; glob_script_mem.script_size=MAX_SCRIPT_SIZE; From 57f836cc9eae8a68b4b7a0212faf8a6613219bdd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Apr 2020 09:58:38 +0200 Subject: [PATCH 03/34] Remove possible Webserver naming ambuigity --- tasmota/Parsing.cpp | 6 +- tasmota/support_flash_log.ino | 8 +- tasmota/xdrv_01_webserver.ino | 176 +++++++++++++++---------------- tasmota/xdrv_02_mqtt.ino | 4 +- tasmota/xdrv_07_domoticz.ino | 4 +- tasmota/xdrv_09_timers.ino | 6 +- tasmota/xdrv_10_scripter.ino | 44 ++++---- tasmota/xdrv_11_knx.ino | 42 ++++---- tasmota/xdrv_20_hue.ino | 12 +-- tasmota/xdrv_21_wemo.ino | 10 +- tasmota/xdrv_23_zigbee_3_hue.ino | 4 +- tasmota/xdrv_28_pcf8574.ino | 8 +- tasmota/xsns_34_hx711.ino | 8 +- tasmota/xsns_60_GPS.ino | 18 ++-- tasmota/xsns_91_prometheus.ino | 2 +- 15 files changed, 178 insertions(+), 174 deletions(-) diff --git a/tasmota/Parsing.cpp b/tasmota/Parsing.cpp index 145b72572..a7665d7b1 100644 --- a/tasmota/Parsing.cpp +++ b/tasmota/Parsing.cpp @@ -19,6 +19,8 @@ Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) */ +#ifdef ESP8266 + // Use patched Parsing.cpp to fix ALEXA parsing issue in v2.4.2 #include #if defined(ARDUINO_ESP8266_RELEASE_2_4_2) @@ -620,4 +622,6 @@ bool ESP8266WebServer::_parseFormUploadAborted(){ return false; } -#endif // ARDUINO_ESP8266_RELEASE \ No newline at end of file +#endif // ARDUINO_ESP8266_RELEASE + +#endif // ESP8266 diff --git a/tasmota/support_flash_log.ino b/tasmota/support_flash_log.ino index cf64de6d5..5f73c4078 100644 --- a/tasmota/support_flash_log.ino +++ b/tasmota/support_flash_log.ino @@ -371,13 +371,13 @@ void FLOG::stopRecording(void){ * * @param size: size of the data entry/record in bytes, i.e. sizeof(myStruct) * @param sendHeader: should implement at least something like: - * @example WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); // This is very likely unknown!! - * WebServer->sendHeader(F("Content-Disposition"), F("attachment; filename=myfile.txt")); + * @example Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN); // This is very likely unknown!! + * Webserver->sendHeader(F("Content-Disposition"), F("attachment; filename=myfile.txt")); * @param sendRecord: will receive the memory address as "uint8_t* addr" and should consume the current entry/record * @example myStruct_t *entry = (myStruct_t*)addr; - * Then make useful Strings and send it, i.e.: WebServer->sendContent_P(myString); + * Then make useful Strings and send it, i.e.: Webserver->sendContent_P(myString); * @param sendFooter: finish the download, should implement at least: - * @example WebServer->sendContent(""); + * @example Webserver->sendContent(""); */ void FLOG::startDownload(size_t size, CallbackNoArgs sendHeader, CallbackWithArgs sendRecord, CallbackNoArgs sendFooter){ diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 178502150..18df7fa4a 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -109,7 +109,7 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "}" "};" "if (rfsh) {" - "x.open('GET','.?m=1'+a,true);" // ?m related to WebServer->hasArg("m") + "x.open('GET','.?m=1'+a,true);" // ?m related to Webserver->hasArg("m") "x.send();" "lt=setTimeout(la,%d);" // Settings.web_refresh "}" @@ -146,7 +146,7 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "eb('l1').innerHTML=s;" "}" "};" - "x.open('GET','.?m=1'+a,true);" // ?m related to WebServer->hasArg("m") + "x.open('GET','.?m=1'+a,true);" // ?m related to Webserver->hasArg("m") "x.send();" "lt=setTimeout(la,%d);" // Settings.web_refresh "}"; @@ -205,7 +205,7 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = "sn=t.scrollTop;" "}" "};" - "x.open('GET','cs?c2='+id+o,true);" // Related to WebServer->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) + "x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) "x.send();" "}" "lt=setTimeout(l,%d);" @@ -301,10 +301,10 @@ const char HTTP_SCRIPT_TEMPLATE[] PROGMEM = "}" #ifdef USE_JAVASCRIPT_ES6 - "sl=()=>ld('tp?m=1',x2);" // ?m related to WebServer->hasArg("m") + "sl=()=>ld('tp?m=1',x2);" // ?m related to Webserver->hasArg("m") #else "function sl(){" - "ld('tp?m=1',x2);" // ?m related to WebServer->hasArg("m") + "ld('tp?m=1',x2);" // ?m related to Webserver->hasArg("m") "}" #endif @@ -325,11 +325,11 @@ const char HTTP_SCRIPT_MODULE2[] PROGMEM = "sk(%d," STR(ADC0_PIN) ");" "}" "function sl(){" - "ld('md?m=1',x1);" // ?m related to WebServer->hasArg("m") - "ld('md?g=1',x2);" // ?g related to WebServer->hasArg("g") + "ld('md?m=1',x1);" // ?m related to Webserver->hasArg("m") + "ld('md?g=1',x2);" // ?g related to Webserver->hasArg("g") // "if(eb('g17')){" "if(eb('g" STR(ADC0_PIN) "')){" - "ld('md?a=1',x3);" // ?a related to WebServer->hasArg("a") + "ld('md?a=1',x3);" // ?a related to Webserver->hasArg("a") "}" "}" "wl(sl);"; @@ -544,7 +544,7 @@ const uint16_t DNS_PORT = 53; enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY}; DNSServer *DnsServer; -ESP8266WebServer *WebServer; +ESP8266WebServer *Webserver; struct WEB { String chunk_buffer = ""; // Could be max 2 * CHUNKED_BUFFER_SIZE @@ -561,7 +561,7 @@ struct WEB { // Helper function to avoid code duplication (saves 4k Flash) static void WebGetArg(const char* arg, char* out, size_t max) { - String s = WebServer->arg(arg); + String s = Webserver->arg(arg); strlcpy(out, s.c_str(), max); // out[max-1] = '\0'; // Ensure terminating NUL } @@ -574,7 +574,7 @@ void ShowWebSource(uint32_t source) { if ((source > 0) && (source < SRC_MAX)) { char stemp1[20]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SRC: %s from %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), WebServer->client().remoteIP().toString().c_str()); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SRC: %s from %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), Webserver->client().remoteIP().toString().c_str()); } } @@ -589,28 +589,28 @@ void StartWebserver(int type, IPAddress ipweb) { if (!Settings.web_refresh) { Settings.web_refresh = HTTP_REFRESH_TIME; } if (!Web.state) { - if (!WebServer) { - WebServer = new ESP8266WebServer((HTTP_MANAGER == type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT); - WebServer->on("/", HandleRoot); - WebServer->onNotFound(HandleNotFound); - WebServer->on("/up", HandleUpgradeFirmware); - WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA - WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop); - WebServer->on("/u2", HTTP_OPTIONS, HandlePreflightRequest); - WebServer->on("/cs", HTTP_GET, HandleConsole); - WebServer->on("/cs", HTTP_OPTIONS, HandlePreflightRequest); - WebServer->on("/cm", HandleHttpCommand); + if (!Webserver) { + Webserver = new ESP8266WebServer((HTTP_MANAGER == type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT); + Webserver->on("/", HandleRoot); + Webserver->onNotFound(HandleNotFound); + Webserver->on("/up", HandleUpgradeFirmware); + Webserver->on("/u1", HandleUpgradeFirmwareStart); // OTA + Webserver->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop); + Webserver->on("/u2", HTTP_OPTIONS, HandlePreflightRequest); + Webserver->on("/cs", HTTP_GET, HandleConsole); + Webserver->on("/cs", HTTP_OPTIONS, HandlePreflightRequest); + Webserver->on("/cm", HandleHttpCommand); #ifndef FIRMWARE_MINIMAL - WebServer->on("/cn", HandleConfiguration); - WebServer->on("/md", HandleModuleConfiguration); - WebServer->on("/wi", HandleWifiConfiguration); - WebServer->on("/lg", HandleLoggingConfiguration); - WebServer->on("/tp", HandleTemplateConfiguration); - WebServer->on("/co", HandleOtherConfiguration); - WebServer->on("/dl", HandleBackupConfiguration); - WebServer->on("/rs", HandleRestoreConfiguration); - WebServer->on("/rt", HandleResetConfiguration); - WebServer->on("/in", HandleInformation); + Webserver->on("/cn", HandleConfiguration); + Webserver->on("/md", HandleModuleConfiguration); + Webserver->on("/wi", HandleWifiConfiguration); + Webserver->on("/lg", HandleLoggingConfiguration); + Webserver->on("/tp", HandleTemplateConfiguration); + Webserver->on("/co", HandleOtherConfiguration); + Webserver->on("/dl", HandleBackupConfiguration); + Webserver->on("/rs", HandleRestoreConfiguration); + Webserver->on("/rt", HandleResetConfiguration); + Webserver->on("/in", HandleInformation); XdrvCall(FUNC_WEB_ADD_HANDLER); XsnsCall(FUNC_WEB_ADD_HANDLER); #endif // Not FIRMWARE_MINIMAL @@ -619,9 +619,9 @@ void StartWebserver(int type, IPAddress ipweb) // Collect User-Agent for Alexa Hue Emulation // This is used in xdrv_20_hue.ino in function findEchoGeneration() - WebServer->collectHeaders(HEADER_KEYS, sizeof(HEADER_KEYS)/sizeof(char*)); + Webserver->collectHeaders(HEADER_KEYS, sizeof(HEADER_KEYS)/sizeof(char*)); - WebServer->begin(); // Web server start + Webserver->begin(); // Web server start } if (Web.state != type) { #if LWIP_IPV6 @@ -639,7 +639,7 @@ void StartWebserver(int type, IPAddress ipweb) void StopWebserver(void) { if (Web.state) { - WebServer->close(); + Webserver->close(); Web.state = HTTP_OFF; AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_STOPPED)); } @@ -684,7 +684,7 @@ void WifiManagerBegin(bool reset_only) void PollDnsWebserver(void) { if (DnsServer) { DnsServer->processNextRequest(); } - if (WebServer) { WebServer->handleClient(); } + if (Webserver) { Webserver->handleClient(); } } /*********************************************************************************************/ @@ -692,7 +692,7 @@ void PollDnsWebserver(void) bool WebAuthenticate(void) { if (strlen(SettingsText(SET_WEBPWD)) && (HTTP_MANAGER_RESET_ONLY != Web.state)) { - return WebServer->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD)); + return Webserver->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD)); } else { return true; } @@ -705,7 +705,7 @@ bool HttpCheckPriviledgedAccess(bool autorequestauth = true) return false; } if (autorequestauth && !WebAuthenticate()) { - WebServer->requestAuthentication(); + Webserver->requestAuthentication(); return false; } return true; @@ -714,15 +714,15 @@ bool HttpCheckPriviledgedAccess(bool autorequestauth = true) void HttpHeaderCors(void) { if (strlen(SettingsText(SET_CORS))) { - WebServer->sendHeader(F("Access-Control-Allow-Origin"), SettingsText(SET_CORS)); + Webserver->sendHeader(F("Access-Control-Allow-Origin"), SettingsText(SET_CORS)); } } void WSHeaderSend(void) { - WebServer->sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate")); - WebServer->sendHeader(F("Pragma"), F("no-cache")); - WebServer->sendHeader(F("Expires"), F("-1")); + Webserver->sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate")); + Webserver->sendHeader(F("Pragma"), F("no-cache")); + Webserver->sendHeader(F("Expires"), F("-1")); HttpHeaderCors(); } @@ -733,7 +733,7 @@ void WSHeaderSend(void) void WSSend(int code, int ctype, const String& content) { char ct[25]; // strlen("application/octet-stream") +1 = Longest Content type string - WebServer->send(code, GetTextIndexed(ct, sizeof(ct), ctype, kContentTypes), content); + Webserver->send(code, GetTextIndexed(ct, sizeof(ct), ctype, kContentTypes), content); } /********************************************************************************************** @@ -742,13 +742,13 @@ void WSSend(int code, int ctype, const String& content) void WSContentBegin(int code, int ctype) { - WebServer->client().flush(); + Webserver->client().flush(); WSHeaderSend(); #ifdef ARDUINO_ESP8266_RELEASE_2_3_0 - WebServer->sendHeader(F("Accept-Ranges"),F("none")); - WebServer->sendHeader(F("Transfer-Encoding"),F("chunked")); + Webserver->sendHeader(F("Accept-Ranges"),F("none")); + Webserver->sendHeader(F("Transfer-Encoding"),F("chunked")); #endif - WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); + Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN); WSSend(code, ctype, ""); // Signal start of chunked content Web.chunk_buffer = ""; } @@ -761,9 +761,9 @@ void _WSContentSend(const String& content) // Low level sendContent for a const char * footer = "\r\n"; char chunk_size[11]; sprintf(chunk_size, "%x\r\n", len); - WebServer->sendContent(String() + chunk_size + content + footer); + Webserver->sendContent(String() + chunk_size + content + footer); #else - WebServer->sendContent(content); + Webserver->sendContent(content); #endif #ifdef USE_DEBUG_DRIVER @@ -849,8 +849,8 @@ void WSContentSend_PD(const char* formatP, ...) // Content send snprintf_P ch void WSContentStart_P(const char* title, bool auth) { - if (auth && strlen(SettingsText(SET_WEBPWD)) && !WebServer->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD))) { - return WebServer->requestAuthentication(); + if (auth && strlen(SettingsText(SET_WEBPWD)) && !Webserver->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD))) { + return Webserver->requestAuthentication(); } WSContentBegin(200, CT_HTML); @@ -961,7 +961,7 @@ void WSContentEnd(void) { WSContentFlush(); // Flush chunk buffer _WSContentSend(""); // Signal end of chunked content - WebServer->client().stop(); + Webserver->client().stop(); } void WSContentStop(void) @@ -1043,17 +1043,17 @@ void HandleRoot(void) { if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page. - if (WebServer->hasArg("rst")) { + if (Webserver->hasArg("rst")) { WebRestart(0); return; } if (WifiIsInManagerMode()) { #ifndef FIRMWARE_MINIMAL - if (strlen(SettingsText(SET_WEBPWD)) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1")) && HTTP_MANAGER_RESET_ONLY != Web.state) { + if (strlen(SettingsText(SET_WEBPWD)) && !(Webserver->hasArg("USER1")) && !(Webserver->hasArg("PASS1")) && HTTP_MANAGER_RESET_ONLY != Web.state) { HandleWifiLogin(); } else { - if (!strlen(SettingsText(SET_WEBPWD)) || (((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == SettingsText(SET_WEBPWD) )) || HTTP_MANAGER_RESET_ONLY == Web.state)) { + if (!strlen(SettingsText(SET_WEBPWD)) || (((Webserver->arg("USER1") == WEB_USERNAME ) && (Webserver->arg("PASS1") == SettingsText(SET_WEBPWD) )) || HTTP_MANAGER_RESET_ONLY == Web.state)) { HandleWifiConfiguration(); } else { // wrong user and pass @@ -1243,11 +1243,11 @@ void HandleRoot(void) bool HandleRootStatusRefresh(void) { if (!WebAuthenticate()) { - WebServer->requestAuthentication(); + Webserver->requestAuthentication(); return true; } - if (!WebServer->hasArg("m")) { // Status refresh requested + if (!Webserver->hasArg("m")) { // Status refresh requested return false; } @@ -1429,7 +1429,7 @@ void HandleTemplateConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { TemplateSaveSettings(); WebRestart(1); return; @@ -1437,7 +1437,7 @@ void HandleTemplateConfiguration(void) char stemp[30]; // Template number and Sensor name - if (WebServer->hasArg("m")) { + if (Webserver->hasArg("m")) { WSContentBegin(200, CT_PLAIN); for (uint32_t i = 0; i < sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'0'>Sonoff Basic (1)}3" uint32_t midx = pgm_read_byte(kModuleNiceList + i); @@ -1548,7 +1548,7 @@ void TemplateSaveSettings(void) uint32_t flag = atoi(tmp); for (uint32_t i = 0; i < GPIO_FLAG_USED; i++) { snprintf_P(webindex, sizeof(webindex), PSTR("c%d"), i); - uint32_t state = WebServer->hasArg(webindex) << i +4; // FLAG + uint32_t state = Webserver->hasArg(webindex) << i +4; // FLAG flag += state; } WebGetArg("g99", tmp, sizeof(tmp)); // BASE @@ -1564,7 +1564,7 @@ void HandleModuleConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { ModuleSaveSettings(); WebRestart(1); return; @@ -1575,7 +1575,7 @@ void HandleModuleConfiguration(void) myio cmodule; ModuleGpios(&cmodule); - if (WebServer->hasArg("m")) { + if (Webserver->hasArg("m")) { WSContentBegin(200, CT_PLAIN); uint32_t vidx = 0; for (uint32_t i = 0; i <= sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'255'>UserTemplate (0)}3" - "}2'0'>Sonoff Basic (1)}3" @@ -1592,7 +1592,7 @@ void HandleModuleConfiguration(void) return; } - if (WebServer->hasArg("g")) { + if (Webserver->hasArg("g")) { WSContentBegin(200, CT_PLAIN); for (uint32_t j = 0; j < sizeof(kGpioNiceList); j++) { midx = pgm_read_byte(kGpioNiceList + j); @@ -1605,7 +1605,7 @@ void HandleModuleConfiguration(void) } #ifndef USE_ADC_VCC - if (WebServer->hasArg("a")) { + if (Webserver->hasArg("a")) { WSContentBegin(200, CT_PLAIN); for (uint32_t j = 0; j < ADC0_END; j++) { WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, j, GetTextIndexed(stemp, sizeof(stemp), j, kAdc0Names), j); @@ -1720,7 +1720,7 @@ void HandleWifiConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI); - if (WebServer->hasArg("save") && HTTP_MANAGER_RESET_ONLY != Web.state) { + if (Webserver->hasArg("save") && HTTP_MANAGER_RESET_ONLY != Web.state) { WifiSaveSettings(); WebRestart(2); return; @@ -1731,7 +1731,7 @@ void HandleWifiConfiguration(void) WSContentSendStyle(); if (HTTP_MANAGER_RESET_ONLY != Web.state) { - if (WebServer->hasArg("scan")) { + if (Webserver->hasArg("scan")) { #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION @@ -1844,7 +1844,7 @@ void HandleLoggingConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_LOGGING); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { LoggingSaveSettings(); HandleConfiguration(); return; @@ -1909,7 +1909,7 @@ void HandleOtherConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_OTHER); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { OtherSaveSettings(); WebRestart(1); return; @@ -1973,7 +1973,7 @@ void OtherSaveSettings(void) WebGetArg("wp", tmp, sizeof(tmp)); SettingsUpdateText(SET_WEBPWD, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? SettingsText(SET_WEBPWD) : tmp); - Settings.flag.mqtt_enabled = WebServer->hasArg("b1"); // SetOption3 - Enable MQTT + Settings.flag.mqtt_enabled = Webserver->hasArg("b1"); // SetOption3 - Enable MQTT #ifdef USE_EMULATION UdpDisconnect(); #if defined(USE_EMULATION_WEMO) || defined(USE_EMULATION_HUE) @@ -1994,7 +1994,7 @@ void OtherSaveSettings(void) /* // This sometimes provides intermittent watchdog - bool template_activate = WebServer->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command + bool template_activate = Webserver->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command WebGetArg("t1", tmp, sizeof(tmp)); if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} char svalue[128]; @@ -2010,7 +2010,7 @@ void OtherSaveSettings(void) */ WebGetArg("t1", tmp, sizeof(tmp)); if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} - snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (WebServer->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : ""); + snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (Webserver->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : ""); ExecuteWebCommand(message, SRC_WEBGUI); } } @@ -2025,8 +2025,8 @@ void HandleBackupConfiguration(void) if (!SettingsBufferAlloc()) { return; } - WiFiClient myClient = WebServer->client(); - WebServer->setContentLength(sizeof(Settings)); + WiFiClient myClient = Webserver->client(); + Webserver->setContentLength(sizeof(Settings)); char attachment[TOPSZ]; @@ -2036,7 +2036,7 @@ void HandleBackupConfiguration(void) char hostname[sizeof(my_hostname)]; snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(hostname, my_hostname), my_version); - WebServer->sendHeader(F("Content-Disposition"), attachment); + Webserver->sendHeader(F("Content-Disposition"), attachment); WSSend(200, CT_STREAM, ""); @@ -2336,7 +2336,7 @@ void HandleUploadLoop(void) return; } - HTTPUpload& upload = WebServer->upload(); + HTTPUpload& upload = Webserver->upload(); if (UPLOAD_FILE_START == upload.status) { restart_flag = 60; @@ -2549,8 +2549,8 @@ void HandleUploadLoop(void) void HandlePreflightRequest(void) { HttpHeaderCors(); - WebServer->sendHeader(F("Access-Control-Allow-Methods"), F("GET, POST")); - WebServer->sendHeader(F("Access-Control-Allow-Headers"), F("authorization")); + Webserver->sendHeader(F("Access-Control-Allow-Methods"), F("GET, POST")); + Webserver->sendHeader(F("Access-Control-Allow-Headers"), F("authorization")); WSSend(200, CT_HTML, ""); } @@ -2574,7 +2574,7 @@ void HandleHttpCommand(void) WSContentBegin(200, CT_JSON); if (valid) { uint32_t curridx = web_log_index; - String svalue = WebServer->arg("cmnd"); + String svalue = Webserver->arg("cmnd"); if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND); if (web_log_index != curridx) { @@ -2620,7 +2620,7 @@ void HandleConsole(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("c2")) { // Console refresh requested + if (Webserver->hasArg("c2")) { // Console refresh requested HandleConsoleRefresh(); return; } @@ -2640,7 +2640,7 @@ void HandleConsoleRefresh(void) bool cflg = true; uint32_t counter = 0; // Initial start, should never be 0 again - String svalue = WebServer->arg("c1"); + String svalue = Webserver->arg("c1"); if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), svalue.c_str()); ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE); @@ -2685,13 +2685,13 @@ void HandleConsoleRefresh(void) void HandleNotFound(void) { -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), WebServer->uri().c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), Webserver->uri().c_str()); if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the error page. #ifdef USE_EMULATION #ifdef USE_EMULATION_HUE - String path = WebServer->uri(); + String path = Webserver->uri(); if ((EMUL_HUE == Settings.flag2.emulation) && (path.startsWith("/api"))) { HandleHueApi(&path); } else @@ -2699,9 +2699,9 @@ void HandleNotFound(void) #endif // USE_EMULATION { WSContentBegin(404, CT_PLAIN); - WSContentSend_P(PSTR(D_FILE_NOT_FOUND "\n\nURI: %s\nMethod: %s\nArguments: %d\n"), WebServer->uri().c_str(), (WebServer->method() == HTTP_GET) ? "GET" : "POST", WebServer->args()); - for (uint32_t i = 0; i < WebServer->args(); i++) { - WSContentSend_P(PSTR(" %s: %s\n"), WebServer->argName(i).c_str(), WebServer->arg(i).c_str()); + WSContentSend_P(PSTR(D_FILE_NOT_FOUND "\n\nURI: %s\nMethod: %s\nArguments: %d\n"), Webserver->uri().c_str(), (Webserver->method() == HTTP_GET) ? "GET" : "POST", Webserver->args()); + for (uint32_t i = 0; i < Webserver->args(); i++) { + WSContentSend_P(PSTR(" %s: %s\n"), Webserver->argName(i).c_str(), Webserver->arg(i).c_str()); } WSContentEnd(); } @@ -2711,12 +2711,12 @@ void HandleNotFound(void) bool CaptivePortal(void) { // Possible hostHeader: connectivitycheck.gstatic.com or 192.168.4.1 - if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader().c_str())) { + if ((WifiIsInManagerMode()) && !ValidIpAddress(Webserver->hostHeader().c_str())) { AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED)); - WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true); + Webserver->sendHeader(F("Location"), String("http://") + Webserver->client().localIP().toString(), true); WSSend(302, CT_PLAIN, ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - WebServer->client().stop(); // Stop is needed because we sent no content length + Webserver->client().stop(); // Stop is needed because we sent no content length return true; } return false; diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 780d94c98..6ad843980 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -1252,7 +1252,7 @@ void HandleMqttConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MQTT); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { MqttSaveSettings(); WebRestart(1); return; @@ -1334,7 +1334,7 @@ bool Xdrv02(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_MQTT); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration); + Webserver->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration); break; #endif // USE_WEBSERVER case FUNC_COMMAND: diff --git a/tasmota/xdrv_07_domoticz.ino b/tasmota/xdrv_07_domoticz.ino index 1fddf5890..ef7202fa7 100644 --- a/tasmota/xdrv_07_domoticz.ino +++ b/tasmota/xdrv_07_domoticz.ino @@ -559,7 +559,7 @@ void HandleDomoticzConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { DomoticzSaveSettings(); WebRestart(1); return; @@ -651,7 +651,7 @@ bool Xdrv07(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_DOMOTICZ); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration); + Webserver->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration); break; #endif // USE_WEBSERVER case FUNC_MQTT_SUBSCRIBE: diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index f751d853f..a5cb67f41 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -702,7 +702,7 @@ void HandleTimerConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_TIMER); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { TimerSaveSettings(); HandleConfiguration(); return; @@ -740,7 +740,7 @@ void TimerSaveSettings(void) char message[LOGSZ]; Timer timer; - Settings.flag3.timers_enable = WebServer->hasArg("e0"); // CMND_TIMERS + Settings.flag3.timers_enable = Webserver->hasArg("e0"); // CMND_TIMERS WebGetArg("t0", tmp, sizeof(tmp)); char *p = tmp; snprintf_P(message, sizeof(message), PSTR(D_LOG_MQTT D_CMND_TIMERS " %d"), Settings.flag3.timers_enable); // CMND_TIMERS @@ -781,7 +781,7 @@ bool Xdrv09(uint8_t function) #endif // USE_RULES break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_TIMER, HandleTimerConfiguration); + Webserver->on("/" WEB_HANDLE_TIMER, HandleTimerConfiguration); break; #endif // USE_TIMERS_WEB #endif // USE_WEBSERVER diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index e086adedb..e57f1ea80 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -3341,8 +3341,8 @@ void Script_FileUploadConfiguration(void) if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("download")) { - String stmp = WebServer->arg("download"); + if (Webserver->hasArg("download")) { + String stmp = Webserver->arg("download"); char *cp=(char*)stmp.c_str(); if (DownloadFile(cp)) { // is directory @@ -3386,7 +3386,7 @@ void script_upload(void) { //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload")); - HTTPUpload& upload = WebServer->upload(); + HTTPUpload& upload = Webserver->upload(); if (upload.status == UPLOAD_FILE_START) { char npath[48]; sprintf(npath,"%s/%s",path,upload.filename.c_str()); @@ -3402,7 +3402,7 @@ void script_upload(void) { } } else { Web.upload_error=1; - WebServer->send(500, "text/plain", "500: couldn't create file"); + Webserver->send(500, "text/plain", "500: couldn't create file"); } } @@ -3428,8 +3428,8 @@ uint8_t DownloadFile(char *file) { uint32_t flen=download_file.size(); - download_Client = WebServer->client(); - WebServer->setContentLength(flen); + download_Client = Webserver->client(); + Webserver->setContentLength(flen); char attachment[100]; char *cp; @@ -3440,7 +3440,7 @@ uint8_t DownloadFile(char *file) { } } snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"),cp); - WebServer->sendHeader(F("Content-Disposition"), attachment); + Webserver->sendHeader(F("Content-Disposition"), attachment); WSSend(200, CT_STREAM, ""); uint8_t buff[512]; @@ -3472,7 +3472,7 @@ uint8_t DownloadFile(char *file) { void HandleScriptTextareaConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { ScriptSaveSettings(); HandleConfiguration(); return; @@ -3486,13 +3486,13 @@ void HandleScriptConfiguration(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_SCRIPT); #ifdef USE_SCRIPT_FATFS - if (WebServer->hasArg("d1")) { + if (Webserver->hasArg("d1")) { DownloadFile(glob_script_mem.flink[0]); } - if (WebServer->hasArg("d2")) { + if (Webserver->hasArg("d2")) { DownloadFile(glob_script_mem.flink[1]); } - if (WebServer->hasArg("upl")) { + if (Webserver->hasArg("upl")) { Script_FileUploadConfiguration(); } #endif @@ -3532,14 +3532,14 @@ void HandleScriptConfiguration(void) { void ScriptSaveSettings(void) { - if (WebServer->hasArg("c1")) { + if (Webserver->hasArg("c1")) { bitWrite(Settings.rule_enabled,0,1); } else { bitWrite(Settings.rule_enabled,0,0); } - String str = WebServer->arg("t1"); + String str = Webserver->arg("t1"); if (*str.c_str()) { @@ -3990,11 +3990,11 @@ void Script_Handle_Hue(String *path) { uint8_t device = DecodeLightId(atoi(path->c_str())); uint8_t index = device-devices_present-1; - if (WebServer->args()) { + if (Webserver->args()) { response = "["; StaticJsonBuffer<400> jsonBuffer; - JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1)); + JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1)); if (hue_json.containsKey("on")) { response += FPSTR(sHUE_LIGHT_RESPONSE_JSON); @@ -4436,8 +4436,8 @@ void Script_Check_HTML_Setvars(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("sv")) { - String stmp = WebServer->arg("sv"); + if (Webserver->hasArg("sv")) { + String stmp = Webserver->arg("sv"); char cmdbuf[64]; memset(cmdbuf,0,sizeof(cmdbuf)); char *cp=cmdbuf; @@ -4932,13 +4932,13 @@ bool Xdrv10(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_RULES); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration); - WebServer->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration); + Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration); + Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration); #ifdef USE_SCRIPT_FATFS - WebServer->on("/u3", HTTP_POST,[]() { WebServer->sendHeader("Location","/u3");WebServer->send(303);},script_upload); - WebServer->on("/u3", HTTP_GET,ScriptFileUploadSuccess); - WebServer->on("/upl", HTTP_GET,Script_FileUploadConfiguration); + Webserver->on("/u3", HTTP_POST,[]() { Webserver->sendHeader("Location","/u3");Webserver->send(303);},script_upload); + Webserver->on("/u3", HTTP_GET,ScriptFileUploadSuccess); + Webserver->on("/upl", HTTP_GET,Script_FileUploadConfiguration); #endif break; #endif // USE_WEBSERVER diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino index b8177c1ad..d6f2864dc 100644 --- a/tasmota/xdrv_11_knx.ino +++ b/tasmota/xdrv_11_knx.ino @@ -809,22 +809,22 @@ void HandleKNXConfiguration(void) char tmp[100]; String stmp; - if ( WebServer->hasArg("save") ) { + if ( Webserver->hasArg("save") ) { KNX_Save_Settings(); HandleConfiguration(); } else { - if ( WebServer->hasArg("btn_add") ) { - if ( WebServer->arg("btn_add") == "1" ) { + if ( Webserver->hasArg("btn_add") ) { + if ( Webserver->arg("btn_add") == "1" ) { - stmp = WebServer->arg("GAop"); //option selected + stmp = Webserver->arg("GAop"); //option selected uint8_t GAop = stmp.toInt(); - stmp = WebServer->arg("GA_FNUM"); + stmp = Webserver->arg("GA_FNUM"); uint8_t GA_FNUM = stmp.toInt(); - stmp = WebServer->arg("GA_AREA"); + stmp = Webserver->arg("GA_AREA"); uint8_t GA_AREA = stmp.toInt(); - stmp = WebServer->arg("GA_FDEF"); + stmp = Webserver->arg("GA_FDEF"); uint8_t GA_FDEF = stmp.toInt(); if (GAop) { @@ -834,13 +834,13 @@ void HandleKNXConfiguration(void) else { - stmp = WebServer->arg("CBop"); //option selected + stmp = Webserver->arg("CBop"); //option selected uint8_t CBop = stmp.toInt(); - stmp = WebServer->arg("CB_FNUM"); + stmp = Webserver->arg("CB_FNUM"); uint8_t CB_FNUM = stmp.toInt(); - stmp = WebServer->arg("CB_AREA"); + stmp = Webserver->arg("CB_AREA"); uint8_t CB_AREA = stmp.toInt(); - stmp = WebServer->arg("CB_FDEF"); + stmp = Webserver->arg("CB_FDEF"); uint8_t CB_FDEF = stmp.toInt(); if (CBop) { @@ -848,19 +848,19 @@ void HandleKNXConfiguration(void) } } } - else if ( WebServer->hasArg("btn_del_ga") ) + else if ( Webserver->hasArg("btn_del_ga") ) { - stmp = WebServer->arg("btn_del_ga"); + stmp = Webserver->arg("btn_del_ga"); uint8_t GA_NUM = stmp.toInt(); KNX_DEL_GA(GA_NUM); } - else if ( WebServer->hasArg("btn_del_cb") ) + else if ( Webserver->hasArg("btn_del_cb") ) { - stmp = WebServer->arg("btn_del_cb"); + stmp = Webserver->arg("btn_del_cb"); uint8_t CB_NUM = stmp.toInt(); KNX_DEL_CB(CB_NUM); @@ -954,16 +954,16 @@ void KNX_Save_Settings(void) String stmp; address_t KNX_addr; - Settings.flag.knx_enabled = WebServer->hasArg("b1"); - Settings.flag.knx_enable_enhancement = WebServer->hasArg("b2"); + Settings.flag.knx_enabled = Webserver->hasArg("b1"); + Settings.flag.knx_enable_enhancement = Webserver->hasArg("b2"); AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_KNX D_ENABLED ": %d, " D_KNX_ENHANCEMENT ": %d"), Settings.flag.knx_enabled, Settings.flag.knx_enable_enhancement ); - stmp = WebServer->arg("area"); + stmp = Webserver->arg("area"); KNX_addr.pa.area = stmp.toInt(); - stmp = WebServer->arg("line"); + stmp = Webserver->arg("line"); KNX_addr.pa.line = stmp.toInt(); - stmp = WebServer->arg("member"); + stmp = Webserver->arg("member"); KNX_addr.pa.member = stmp.toInt(); Settings.knx_physsical_addr = KNX_addr.value; knx.physical_address_set( KNX_addr ); // Set Physical KNX Address of the device @@ -1224,7 +1224,7 @@ bool Xdrv11(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_KNX); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/kn", HandleKNXConfiguration); + Webserver->on("/kn", HandleKNXConfiguration); break; #endif // USE_KNX_WEB_MENU #endif // USE_WEBSERVER diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index 32a852b50..f9e21c3a3 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -448,7 +448,7 @@ static const char * FIRST_GEN_UA[] = { // list of User-Agents signature // Check if the Echo device is of 1st generation, which triggers different results uint32_t findEchoGeneration(void) { // result is 1 for 1st gen, 2 for 2nd gen and further - String user_agent = WebServer->header("User-Agent"); + String user_agent = Webserver->header("User-Agent"); uint32_t gen = 2; for (uint32_t i = 0; i < sizeof(FIRST_GEN_UA)/sizeof(char*); i++) { @@ -521,11 +521,11 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { const size_t buf_size = 100; char * buf = (char*) malloc(buf_size); - if (WebServer->args()) { + if (Webserver->args()) { response = "["; StaticJsonBuffer<300> jsonBuffer; - JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1)); + JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1)); if (hue_json.containsKey("on")) { on = hue_json["on"]; snprintf_P(buf, buf_size, @@ -827,8 +827,8 @@ void HandleHueApi(String *path) path->remove(0, 4); // remove /api uint16_t apilen = path->length(); AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_API " (%s)"), path->c_str()); // HTP: Hue API (//lights/1/state - for (args = 0; args < WebServer->args(); args++) { - String json = WebServer->arg(args); + for (args = 0; args < Webserver->args(); args++) { + String json = Webserver->arg(args); AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_POST_ARGS " (%s)"), json.c_str()); // HTP: Hue POST args ({"on":false}) } @@ -861,7 +861,7 @@ bool Xdrv20(uint8_t function) #endif switch (function) { case FUNC_WEB_ADD_HANDLER: - WebServer->on(F("/description.xml"), HandleUpnpSetupHue); + Webserver->on(F("/description.xml"), HandleUpnpSetupHue); break; } } diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino index cb3566f89..eef509e2a 100644 --- a/tasmota/xdrv_21_wemo.ino +++ b/tasmota/xdrv_21_wemo.ino @@ -198,7 +198,7 @@ void HandleUpnpEvent(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT)); char event[500]; - strlcpy(event, WebServer->arg(0).c_str(), sizeof(event)); + strlcpy(event, Webserver->arg(0).c_str(), sizeof(event)); // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), event); @@ -259,10 +259,10 @@ bool Xdrv21(uint8_t function) if (devices_present && (EMUL_WEMO == Settings.flag2.emulation)) { switch (function) { case FUNC_WEB_ADD_HANDLER: - WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent); - WebServer->on("/eventservice.xml", HandleUpnpService); - WebServer->on("/metainfoservice.xml", HandleUpnpMetaService); - WebServer->on("/setup.xml", HandleUpnpSetupWemo); + Webserver->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent); + Webserver->on("/eventservice.xml", HandleUpnpService); + Webserver->on("/metainfoservice.xml", HandleUpnpMetaService); + Webserver->on("/setup.xml", HandleUpnpSetupWemo); break; } } diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index 0d00ad9e0..e534134dc 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -190,11 +190,11 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) { const size_t buf_size = 100; char * buf = (char*) malloc(buf_size); - if (WebServer->args()) { + if (Webserver->args()) { response = "["; StaticJsonBuffer<300> jsonBuffer; - JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1)); + JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1)); if (hue_json.containsKey("on")) { on = hue_json["on"]; snprintf_P(buf, buf_size, diff --git a/tasmota/xdrv_28_pcf8574.ino b/tasmota/xdrv_28_pcf8574.ino index 95074fab8..888f34fee 100644 --- a/tasmota/xdrv_28_pcf8574.ino +++ b/tasmota/xdrv_28_pcf8574.ino @@ -160,7 +160,7 @@ void HandlePcf8574(void) AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_PCF8574)); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { Pcf8574SaveSettings(); WebRestart(1); return; @@ -193,9 +193,9 @@ void Pcf8574SaveSettings(void) char stemp[7]; char tmp[100]; - //AddLog_P(LOG_LEVEL_DEBUG, PSTR("PCF: Start working on Save arguements: inverted:%d")), WebServer->hasArg("b1"); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("PCF: Start working on Save arguements: inverted:%d")), Webserver->hasArg("b1"); - Settings.flag3.pcf8574_ports_inverted = WebServer->hasArg("b1"); // SetOption81 - Invert all ports on PCF8574 devices + Settings.flag3.pcf8574_ports_inverted = Webserver->hasArg("b1"); // SetOption81 - Invert all ports on PCF8574 devices for (byte idx = 0; idx < Pcf8574.max_devices; idx++) { byte count=0; byte n = Settings.pcf8574_config[idx]; @@ -248,7 +248,7 @@ bool Xdrv28(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_PCF8574); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_PCF8574, HandlePcf8574); + Webserver->on("/" WEB_HANDLE_PCF8574, HandlePcf8574); break; #endif // USE_WEBSERVER } diff --git a/tasmota/xsns_34_hx711.ino b/tasmota/xsns_34_hx711.ino index 44bb9036c..86e920945 100644 --- a/tasmota/xsns_34_hx711.ino +++ b/tasmota/xsns_34_hx711.ino @@ -494,7 +494,7 @@ void HandleHxAction(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_HX711); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { HxSaveSettings(); HandleConfiguration(); return; @@ -502,7 +502,7 @@ void HandleHxAction(void) char stemp1[20]; - if (WebServer->hasArg("reset")) { + if (Webserver->hasArg("reset")) { snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 1")); // Reset ExecuteWebCommand(stemp1, SRC_WEBGUI); @@ -510,7 +510,7 @@ void HandleHxAction(void) return; } - if (WebServer->hasArg("calibrate")) { + if (Webserver->hasArg("calibrate")) { WebGetArg("p1", stemp1, sizeof(stemp1)); Settings.weight_reference = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToFloat(stemp1) * 1000); @@ -593,7 +593,7 @@ bool Xsns34(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_HX711); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_HX711, HandleHxAction); + Webserver->on("/" WEB_HANDLE_HX711, HandleHxAction); break; #endif // USE_HX711_GUI #endif // USE_WEBSERVER diff --git a/tasmota/xsns_60_GPS.ino b/tasmota/xsns_60_GPS.ino index 966b3a609..87e15d6a2 100644 --- a/tasmota/xsns_60_GPS.ino +++ b/tasmota/xsns_60_GPS.ino @@ -98,7 +98,7 @@ The serial pins are GPS_RX and GPS_TX, no further installation steps needed. To set latitude and longitude in settings + sensor60 14 - open virtual serial port over TCP, usable for u-center + open virtual serial port over TCP, usable for u-center + sensor60 15 pause virtual serial port over TCP @@ -137,7 +137,7 @@ const char kUBXTypes[] PROGMEM = "UBX"; #define UBX_SERIAL_BUFFER_SIZE 256 #define UBX_TCP_PORT 1234 -#define NTP_MILLIS_OFFSET 50 // estimated latency in milliseconds +#define NTP_MILLIS_OFFSET 50 // estimated latency in milliseconds /********************************************************************************************\ | *globals @@ -504,8 +504,8 @@ uint32_t UBXprocessGPS() #ifdef USE_FLOG void UBXsendHeader(void) { - WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); - WebServer->sendHeader(F("Content-Disposition"), F("attachment; filename=TASMOTA.gpx")); + Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN); + Webserver->sendHeader(F("Content-Disposition"), F("attachment; filename=TASMOTA.gpx")); WSSend(200, CT_STREAM, F( "\r\n" "lon/10000000.0f,7,lon); snprintf_P(record, sizeof(record),PSTR("\n\t\n\n"),lat ,lon, stime); // DEBUG_SENSOR_LOG(PSTR("FLOG: DL %u %u"), Flog->sector.dword_buffer[k+j],Flog->sector.dword_buffer[k+j+1]); - WebServer->sendContent_P(record); + Webserver->sendContent_P(record); } void UBXsendFooter(void) { - WebServer->sendContent(F("\n\n")); - WebServer->sendContent(""); + Webserver->sendContent(F("\n\n")); + Webserver->sendContent(""); Rtc.user_time_entry = false; // we have blocked the main loop and want a new valid time } @@ -707,7 +707,7 @@ void UBXHandleTIME() if (UBX.mode.forceUTCupdate || Rtc.user_time_entry == false){ AddLog_P(LOG_LEVEL_INFO, PSTR("UBX: UTC-Time is valid, set system time")); Rtc.utc_time = UBX.rec_buffer.values.time; - } + } Rtc.user_time_entry = true; } } @@ -928,7 +928,7 @@ bool Xsns60(uint8_t function) break; #ifdef USE_FLOG case FUNC_WEB_ADD_HANDLER: - WebServer->on("/UBX", UBXsendFile); + Webserver->on("/UBX", UBXsendFile); break; #endif //USE_FLOG case FUNC_JSON_APPEND: diff --git a/tasmota/xsns_91_prometheus.ino b/tasmota/xsns_91_prometheus.ino index ea4c0047a..f5b0eba9d 100644 --- a/tasmota/xsns_91_prometheus.ino +++ b/tasmota/xsns_91_prometheus.ino @@ -90,7 +90,7 @@ bool Xsns91(uint8_t function) switch (function) { case FUNC_WEB_ADD_HANDLER: - WebServer->on("/metrics", HandleMetrics); + Webserver->on("/metrics", HandleMetrics); break; } return result; From 97abf686129ab6169e5df86eecabc01482eedd6b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Apr 2020 10:14:16 +0200 Subject: [PATCH 04/34] Fix HTTP authorization response code Fix HTTP authorization response code (#8170) --- tasmota/xdrv_01_webserver.ino | 72 +++++++++++++++++------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 18df7fa4a..5d286bf2e 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2562,54 +2562,54 @@ void HandleHttpCommand(void) AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND)); - bool valid = true; if (strlen(SettingsText(SET_WEBPWD))) { char tmp1[33]; WebGetArg("user", tmp1, sizeof(tmp1)); char tmp2[strlen(SettingsText(SET_WEBPWD)) +1]; WebGetArg("password", tmp2, sizeof(tmp2)); - if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) { valid = false; } + if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) { + WSContentBegin(401, CT_JSON); + WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}")); + WSContentEnd(); + return; + } } WSContentBegin(200, CT_JSON); - if (valid) { - uint32_t curridx = web_log_index; - String svalue = Webserver->arg("cmnd"); - if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { - ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND); - if (web_log_index != curridx) { - uint32_t counter = curridx; - WSContentSend_P(PSTR("{")); - bool cflg = false; - do { - char* tmp; - size_t len; - GetLog(counter, &tmp, &len); - if (len) { - // [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] - char* JSON = (char*)memchr(tmp, '{', len); - if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) - size_t JSONlen = len - (JSON - tmp); - if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); } - char stemp[JSONlen]; - strlcpy(stemp, JSON +1, JSONlen -2); - WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp); - cflg = true; - } + uint32_t curridx = web_log_index; + String svalue = Webserver->arg("cmnd"); + if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { + ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND); + if (web_log_index != curridx) { + uint32_t counter = curridx; + WSContentSend_P(PSTR("{")); + bool cflg = false; + do { + char* tmp; + size_t len; + GetLog(counter, &tmp, &len); + if (len) { + // [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] + char* JSON = (char*)memchr(tmp, '{', len); + if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) + size_t JSONlen = len - (JSON - tmp); + if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); } + char stemp[JSONlen]; + strlcpy(stemp, JSON +1, JSONlen -2); + WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp); + cflg = true; } - counter++; - counter &= 0xFF; - if (!counter) counter++; // Skip 0 as it is not allowed - } while (counter != web_log_index); - WSContentSend_P(PSTR("}")); - } else { - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}")); - } + } + counter++; + counter &= 0xFF; + if (!counter) counter++; // Skip 0 as it is not allowed + } while (counter != web_log_index); + WSContentSend_P(PSTR("}")); } else { - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENTER_COMMAND " cmnd=\"}")); + WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}")); } } else { - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}")); + WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENTER_COMMAND " cmnd=\"}")); } WSContentEnd(); } From b7454d7bd8a4891d4e8ad435e2b202c8e8552667 Mon Sep 17 00:00:00 2001 From: Paul C Diem Date: Wed, 15 Apr 2020 08:40:18 -0500 Subject: [PATCH 05/34] Add DevGroupStatus command, Include member add/remove logging --- tasmota/i18n.h | 1 + tasmota/support_command.ino | 9 +++-- tasmota/support_device_groups.ino | 60 ++++++++++++++++++------------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 35a840acf..9f99d7c1d 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -297,6 +297,7 @@ #define D_CMND_DEVGROUP_NAME "DevGroupName" #define D_CMND_DEVGROUP_SEND "DevGroupSend" #define D_CMND_DEVGROUP_SHARE "DevGroupShare" +#define D_CMND_DEVGROUPSTATUS "DevGroupStatus" #define D_CMND_SERIALSEND "SerialSend" #define D_CMND_SERIALDELIMITER "SerialDelimiter" #define D_CMND_BAUDRATE "Baudrate" diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index bfbd38078..6897384d0 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -36,7 +36,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix #ifdef USE_DEVICE_GROUPS_SEND D_CMND_DEVGROUP_SEND "|" #endif // USE_DEVICE_GROUPS_SEND - D_CMND_DEVGROUP_SHARE "|" + D_CMND_DEVGROUP_SHARE "|" D_CMND_DEVGROUPSTATUS "|" #endif // USE_DEVICE_GROUPS D_CMND_SENSOR "|" D_CMND_DRIVER; @@ -59,7 +59,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #ifdef USE_DEVICE_GROUPS_SEND &CmndDevGroupSend, #endif // USE_DEVICE_GROUPS_SEND - &CmndDevGroupShare, + &CmndDevGroupShare, &CmndDevGroupStatus, #endif // USE_DEVICE_GROUPS &CmndSensor, &CmndDriver }; @@ -1793,6 +1793,11 @@ void CmndDevGroupShare(void) Settings.device_group_share_out = parm[1]; Response_P(PSTR("{\"" D_CMND_DEVGROUP_SHARE "\":{\"In\":\"%X\",\"Out\":\"%X\"}}"), Settings.device_group_share_in, Settings.device_group_share_out); } + +void CmndDevGroupStatus(void) +{ + DeviceGroupStatus((XdrvMailbox.usridx ? XdrvMailbox.index - 1 : 0)); +} #endif // USE_DEVICE_GROUPS void CmndSensor(void) diff --git a/tasmota/support_device_groups.ino b/tasmota/support_device_groups.ino index e1719f59e..3a9258a60 100644 --- a/tasmota/support_device_groups.ino +++ b/tasmota/support_device_groups.ino @@ -34,6 +34,7 @@ struct device_group_member { IPAddress ip_address; uint16_t received_sequence; uint16_t acked_sequence; + uint32_t unicast_count; }; struct device_group { @@ -48,7 +49,6 @@ struct device_group { bool local; char group_name[TOPSZ]; char message[128]; - uint8_t group_member_count; struct device_group_member * device_group_members; #ifdef USE_DEVICE_GROUPS_SEND uint8_t values_8bit[DGR_ITEM_LAST_8BIT]; @@ -77,7 +77,7 @@ void DeviceGroupsInit(void) // Initialize the device information for each device group. device_groups = (struct device_group *)calloc(device_group_count, sizeof(struct device_group)); if (device_groups == nullptr) { - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating %u-element device group array"), device_group_count); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error allocating %u-element device group array"), device_group_count); device_groups_initialization_failed = true; return; } @@ -169,7 +169,7 @@ void SendDeviceGroupPacket(IPAddress ip, char * packet, int len, const char * la } delay(10); } - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error sending %s packet"), label); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error sending %s packet"), label); } void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType message_type, ...) @@ -184,7 +184,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes if (processing_remote_device_message && message_type != DGR_MSGTYPE_UPDATE_COMMAND) return; // Get a pointer to the device information for this device. - device_group * device_group = &device_groups[device_group_index]; + struct device_group * device_group = &device_groups[device_group_index]; // If we're still sending initial status requests, ignore this request. if (device_group->initial_status_requests_remaining) return; @@ -551,7 +551,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes // Multicast the packet. #ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8); #endif // DEVICE_GROUPS_DEBUG SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Multicast")); @@ -598,12 +598,10 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length) if (!device_group_member) { device_group_member = (struct device_group_member *)calloc(1, sizeof(struct device_group_member)); if (device_group_member == nullptr) { - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating device group member block")); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error allocating device group member block")); return; } -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: adding member %s (%p)"), IPAddressToString(remote_ip), device_group_member); -#endif // DEVICE_GROUPS_DEBUG + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Adding member %s"), IPAddressToString(remote_ip)); device_group_member->ip_address = remote_ip; *flink = device_group_member; break; @@ -720,7 +718,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length) case DGR_ITEM_LIGHT_CHANNELS: break; default: - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: ********** invalid item=%u received from device group %s member %s"), item, device_group->group_name, IPAddressToString(remote_ip)); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: ********** Invalid item=%u received from device group %s member %s"), item, device_group->group_name, IPAddressToString(remote_ip)); } #endif // DEVICE_GROUPS_DEBUG @@ -802,13 +800,28 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length) return; badmsg: - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: malformed message received from %s"), IPAddressToString(remote_ip)); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Malformed message received from %s"), IPAddressToString(remote_ip)); #ifdef DEVICE_GROUPS_DEBUG AddLog_P2(LOG_LEVEL_DEBUG, PSTR("packet_length=%u, offset=%u"), packet_length, message_ptr - packet); #endif // DEVICE_GROUPS_DEBUG processing_remote_device_message = false; } +void DeviceGroupStatus(uint8_t device_group_index) +{ + if (Settings.flag4.device_groups_enabled && device_group_index < device_group_count) { + char buffer[1024]; + int member_count = 0; + struct device_group * device_group = &device_groups[device_group_index]; + buffer[0] = buffer[1] = 0; + for (struct device_group_member * device_group_member = device_group->device_group_members; device_group_member; device_group_member = device_group_member->flink) { + snprintf(buffer, sizeof(buffer), PSTR("%s,{\"IPAddress\":\"%s\",\"ResendCount\":%u,\"LastRcvdSeq\":%u,\"LastAckedSeq\":%u}"), buffer, IPAddressToString(device_group_member->ip_address), device_group_member->unicast_count, device_group_member->received_sequence, device_group_member->acked_sequence); + member_count++; + } + Response_P(PSTR("{\"" D_CMND_DEVGROUPSTATUS "\":{\"Index\":%u,\"GroupName\":\"%s\",\"MessageSeq\":%u,\"MemberCount\":%d,\"Members\":[%s]}"), device_group_index, device_group->group_name, outgoing_sequence, member_count, &buffer[1]); + } +} + void DeviceGroupsLoop(void) { if (!Settings.flag4.device_groups_enabled) return; @@ -822,16 +835,16 @@ void DeviceGroupsLoop(void) if (!device_groups_initialized) DeviceGroupsInit(); if (device_groups_initialization_failed) return; - // Load the status request message for all device groups. This message will be multicast 5 - // times. + // Load the status request message for all device groups. This message will be multicast 10 + // times at 200ms intervals. next_check_time = now + 3000; for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++) { device_group * device_group = &device_groups[device_group_index]; device_group->message_length = BeginDeviceGroupMessage(device_group, DGR_FLAG_RESET | DGR_FLAG_STATUS_REQUEST) - device_group->message; - device_group->initial_status_requests_remaining = 5; + device_group->initial_status_requests_remaining = 10; device_group->next_ack_check_time = next_check_time; } - + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: (Re)discovering device groups")); } if (device_groups_initialization_failed) return; @@ -856,15 +869,15 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex if (device_group->initial_status_requests_remaining) { if (--device_group->initial_status_requests_remaining) { #ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending initial status request for group %s"), device_group->group_name); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending initial status request for group %s"), device_group->group_name); #endif // DEVICE_GROUPS_DEBUG SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Initial")); device_group->message[device_group->message_header_length + 2] = DGR_FLAG_STATUS_REQUEST; // The reset flag is on only for the first packet - turn it off now device_group->next_ack_check_time = now + 200; } - // If we've sent the initial status request message 5 times, send our status to all - // the members. + // If we've sent the initial status request message the set number of times, send our + // status to all the members. else { device_group->next_ack_check_time = 0; _SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_FULL_STATUS); @@ -874,7 +887,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex // If we're done initializing, iterate through the group memebers, ... else { #ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: checking for ack's")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Checking for ack's")); #endif // DEVICE_GROUPS_DEBUG bool acked = true; struct device_group_member ** flink = &device_group->device_group_members; @@ -887,9 +900,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex // If we haven't receive an ack from this member in DGR_MEMBER_TIMEOUT ms, assume // they're offline and remove them from the group. if (device_group->member_timeout_time < now) { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: removing member %s (%p)"), IPAddressToString(device_group_member->ip_address), device_group_member); -#endif // DEVICE_GROUPS_DEBUG + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Removing member %s"), IPAddressToString(device_group_member->ip_address)); *flink = device_group_member->flink; free(device_group_member); } @@ -897,9 +908,10 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex // Otherwise, unicast the last message directly to this member. else { #ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via unicast to %s, sequence %u, last message acked=%u"), device_group->message_length, device_group->group_name, IPAddressToString(device_group_member->ip_address), outgoing_sequence, device_group_member->acked_sequence); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending %u-byte device group %s packet via unicast to %s, sequence %u, last message acked=%u"), device_group->message_length, device_group->group_name, IPAddressToString(device_group_member->ip_address), outgoing_sequence, device_group_member->acked_sequence); #endif // DEVICE_GROUPS_DEBUG SendDeviceGroupPacket(device_group_member->ip_address, device_group->message, device_group->message_length, PSTR("Unicast")); + device_group_member->unicast_count++; acked = false; flink = &device_group_member->flink; } @@ -940,7 +952,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex #endif // DEVICE_GROUPS_DEBUG if (device_group->next_announcement_time <= now) { #ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending device group %s announcement"), device_group->group_name); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending device group %s announcement"), device_group->group_name); #endif // DEVICE_GROUPS_DEBUG SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, PSTR("Announcement")); device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL + random(10000); From 3a4cf26abad51bd981c8262826970a5ab462816d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Apr 2020 16:22:20 +0200 Subject: [PATCH 06/34] Enable single PIN mode for SR04 sensor Enable single PIN mode for SR04 sensor (#8189) --- tasmota/xsns_22_sr04.ino | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/tasmota/xsns_22_sr04.ino b/tasmota/xsns_22_sr04.ino index 636992a57..a23a38117 100644 --- a/tasmota/xsns_22_sr04.ino +++ b/tasmota/xsns_22_sr04.ino @@ -32,40 +32,39 @@ #define XSNS_22 22 uint8_t sr04_type = 1; -int sr04_echo_pin = 0; -int sr04_trig_pin = 0; real64_t distance; NewPing* sonar = nullptr; TasmotaSerial* sonar_serial = nullptr; - - uint8_t Sr04TModeDetect(void) { sr04_type = 0; - if (pin[GPIO_SR04_ECHO]>=99) return sr04_type; + if (99 == pin[GPIO_SR04_ECHO]) { return sr04_type; } - sr04_echo_pin = pin[GPIO_SR04_ECHO]; - sr04_trig_pin = (pin[GPIO_SR04_TRIG] < 99) ? pin[GPIO_SR04_TRIG] : -1; + int sr04_echo_pin = pin[GPIO_SR04_ECHO]; + int sr04_trig_pin = (pin[GPIO_SR04_TRIG] < 99) ? pin[GPIO_SR04_TRIG] : -1; sonar_serial = new TasmotaSerial(sr04_echo_pin, sr04_trig_pin, 1); if (sonar_serial->begin(9600,1)) { DEBUG_SENSOR_LOG(PSTR("SR04: Detect mode")); - if (sr04_trig_pin!=-1) { - sr04_type = (Sr04TMiddleValue(Sr04TMode3Distance(),Sr04TMode3Distance(),Sr04TMode3Distance())!=NO_ECHO)?3:1; + if (sr04_trig_pin != -1) { + sr04_type = (Sr04TMiddleValue(Sr04TMode3Distance(), Sr04TMode3Distance(), Sr04TMode3Distance()) != NO_ECHO) ? 3 : 1; } else { - sr04_type = 2; + sr04_type = 2; } } else { sr04_type = 1; } if (sr04_type < 2) { - delete sonar_serial; - sonar_serial = nullptr; - sonar = new NewPing(sr04_trig_pin, sr04_echo_pin, 300); + delete sonar_serial; + sonar_serial = nullptr; + if (-1 == sr04_trig_pin) { + sr04_trig_pin = pin[GPIO_SR04_ECHO]; // if GPIO_SR04_TRIG is not configured use single PIN mode with GPIO_SR04_ECHO only + } + sonar = new NewPing(sr04_trig_pin, sr04_echo_pin, 300); } else { if (sonar_serial->hardwareSerial()) { ClaimSerial(); From 71717c3f4ec6061ad40fd8fff05b30226e82f00a Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 15 Apr 2020 18:54:20 +0200 Subject: [PATCH 07/34] Improved and simplified Ping --- tasmota/xdrv_38_ping.ino | 351 +++++++++++++++++++++++++++++---------- 1 file changed, 263 insertions(+), 88 deletions(-) diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino index 0156314a7..d30c0093d 100644 --- a/tasmota/xdrv_38_ping.ino +++ b/tasmota/xdrv_38_ping.ino @@ -21,7 +21,10 @@ #define XDRV_38 38 -#include +#include "lwip/icmp.h" +#include "lwip/inet_chksum.h" +#include "lwip/raw.h" +#include "lwip/timeouts.h" const char kPingCommands[] PROGMEM = "|" // no prefix D_CMND_PING @@ -31,119 +34,291 @@ void (* const PingCommand[])(void) PROGMEM = { &CmndPing, }; -// inspired by https://github.com/dancol90/ESP8266Ping - -typedef struct Ping_t { - uint16_t total_count; // total count if packets sent - uint16_t timeout_count; // time-outs (no responses) - uint32_t min_time; // minimum time in ms for a successful response - uint32_t max_time; // maximum time in ms for a successful response - uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average) - bool busy; // is ping on-going - bool done; // indicates the ping campaign is finished -} Ping_t; - -ping_option ping_opt; -Ping_t ping; - extern "C" { - // callbacks for ping + + extern uint32 system_relative_time(uint32 time); + extern void ets_bzero(void *s, size_t n); - // called after a ping response is received or time-out - void ICACHE_RAM_ATTR ping_recv_cb(ping_option *popt, struct ping_resp *p_resp) { - // If successful - if (p_resp->ping_err >= 0) { - uint32_t resp_time = p_resp->resp_time; - ping.sum_time += resp_time; - if (resp_time < ping.min_time) { ping.min_time = resp_time; } - if (resp_time > ping.max_time) { ping.max_time = resp_time; } + const uint16_t Ping_ID = 0xAFAF; // PING packet ID + const size_t Ping_data_size = 32; // default packet size + const uint32_t Ping_timeout_ms = 1000; // default time-out of 1 second, which is enough for LAN/WIFI + const uint32_t Ping_coarse = 1000; // interval between sending packets, 1 packet every second + + typedef struct Ping_t { + uint32 ip; // target IPv4 address + Ping_t *next; // next object in linked list + uint16_t seq_num; // next sequence number + uint16_t seqno; // reject a packet already received + uint8_t success_count; // sucessful responses received + uint8_t timeout_count; // time-outs (no responses) + uint8_t to_send_count; // number of packets remaining to send + uint32_t ping_time_sent; // timestamp when the packet was sent + uint32_t min_time; // minimum time in ms for a successful response + uint32_t max_time; // maximum time in ms for a successful response + uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average) + bool done; // indicates the ping campaign is finished + bool fast; // fast mode, i.e. stop pings when first successful response + } Ping_t; + + // globals + Ping_t *ping_head = nullptr; // head of the Linked List for ping objects + struct raw_pcb *t_ping_pcb = nullptr; // registered with first ping, deregistered after last ping, the same pcb is used for all packets + + // ================================================================================ + // Find the Ping object indexed by IP address + // ================================================================================ + // + // find the ping structure corresponding to the specified IP, or nullptr if not found + // + Ping_t ICACHE_FLASH_ATTR * t_ping_find(uint32_t ip) { + Ping_t *ping = ping_head; + while (ping != nullptr) { + if (ping->ip == ip) { + return ping; + } + ping = ping->next; + } + return nullptr; + } + + // ================================================================================ + // Timer called a packet response is in time-out + // ================================================================================ + // + // called after the ICMP timeout occured + // we never received the packet, increase the timeout count + // + void ICACHE_FLASH_ATTR t_ping_timeout(void* arg) { + Ping_t *ping = (Ping_t*) arg; + ping->timeout_count++; + } + + // ================================================================================ + // Send ICMP packet + // ================================================================================ + // Prepare a echo ICMP request + // + void ICACHE_FLASH_ATTR t_ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_t len, Ping_t *ping) { + size_t data_len = len - sizeof(struct icmp_echo_hdr); + + ICMPH_TYPE_SET(iecho, ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = Ping_ID; + ping->seq_num++; + if (ping->seq_num == 0x7fff) { ping->seq_num = 0; } + + iecho->seqno = htons(ping->seq_num); // TODO + + /* fill the additional data buffer with some data */ + for (uint32_t i = 0; i < data_len; i++) { + ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; + } + + iecho->chksum = inet_chksum(iecho, len); + } + // + // send the ICMP packet + // + void ICACHE_FLASH_ATTR t_ping_send(struct raw_pcb *raw, Ping_t *ping) { + struct pbuf *p; + uint16_t ping_size = sizeof(struct icmp_echo_hdr) + Ping_data_size; + + ping->ping_time_sent = system_get_time(); + p = pbuf_alloc(PBUF_IP, ping_size, PBUF_RAM); + if (!p) { return; } + if ((p->len == p->tot_len) && (p->next == nullptr)) { + ip_addr_t ping_target; + struct icmp_echo_hdr *iecho; + + ping_target.addr = ping->ip; + iecho = (struct icmp_echo_hdr *) p->payload; + + t_ping_prepare_echo(iecho, ping_size, ping); + raw_sendto(raw, p, &ping_target); + } + pbuf_free(p); + } + + // ================================================================================ + // Timer called when it's time to send next packet, of when finished + // ================================================================================ + // this timer is called every x seconds to send a new packet, whatever happened to the previous packet + static void ICACHE_FLASH_ATTR t_ping_coarse_tmr(void *arg) { + Ping_t *ping = (Ping_t*) arg; + if (ping->to_send_count > 0) { + ping->to_send_count--; + // have we sent all packets? + t_ping_send(t_ping_pcb, ping); + + sys_timeout(Ping_timeout_ms, t_ping_timeout, ping); + sys_timeout(Ping_coarse, t_ping_coarse_tmr, ping); + } else { + sys_untimeout(t_ping_coarse_tmr, ping); + ping->done = true; } } - // called after the ping campaign is finished - void ICACHE_RAM_ATTR ping_sent_cb(ping_option *popt, struct ping_resp *p_resp) { - // copy counters to build the MQTT response - ping.total_count = p_resp->total_count; - ping.timeout_count = p_resp->timeout_count; - ping.done = true; + // ================================================================================ + // Callback: a packet response was received + // ================================================================================ + // + // Reveived packet + // + static uint8_t ICACHE_FLASH_ATTR t_ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) { + Ping_t *ping = t_ping_find(addr->addr); + + if (nullptr == ping) { // unknown source address + return 0; // don't eat the packet and ignore it + } + + if (pbuf_header( p, -PBUF_IP_HLEN)==0) { + struct icmp_echo_hdr *iecho; + iecho = (struct icmp_echo_hdr *)p->payload; + + if ((iecho->id == Ping_ID) && (iecho->seqno == htons(ping->seq_num)) && iecho->type == ICMP_ER) { + + if (iecho->seqno != ping->seqno){ // debounce already received packet + /* do some ping result processing */ + sys_untimeout(t_ping_timeout, ping); // remove time-out handler + uint32_t delay = system_relative_time(ping->ping_time_sent); + delay /= 1000; + + ping->sum_time += delay; + if (delay < ping->min_time) { ping->min_time = delay; } + if (delay > ping->max_time) { ping->max_time = delay; } + + ping->success_count++; + ping->seqno = iecho->seqno; + if (ping->fast) { // if fast mode, abort further pings when first successful response is received + sys_untimeout(t_ping_coarse_tmr, ping); + ping->done = true; + ping->to_send_count = 0; + } + } + + pbuf_free(p); + return 1; /* eat the packet */ + } + } + + return 0; /* don't eat the packet */ } + + // ================================================================================ + // Internal structure PCB management + // ================================================================================ + // we are going to send a packet, make sure pcb is initialized + void t_ping_register_pcb(void) { + if (nullptr == t_ping_pcb) { + t_ping_pcb = raw_new(IP_PROTO_ICMP); + + raw_recv(t_ping_pcb, t_ping_recv, nullptr); // we cannot register data structure here as we can only register one + raw_bind(t_ping_pcb, IP_ADDR_ANY); + } + } + + // we have finsihed a ping series, deallocated if no more ongoing + void t_ping_deregister_pcb(void) { + if (nullptr == ping_head) { // deregister only if no ping is flying + raw_remove(t_ping_pcb); + t_ping_pcb = nullptr; + } + } + + // ================================================================================ + // Start pings + // ================================================================================ + bool t_ping_start(uint32_t ip, uint32_t count) { + // check if pings are already ongoing for this IP + if (t_ping_find(ip)) { + return false; + } + + Ping_t *ping = new Ping_t(); + if (0 == count) { + count = 4; + ping->fast = true; + } + ping->min_time = UINT32_MAX; + ping->ip = ip; + ping->to_send_count = count - 1; + + // add to Linked List from head + ping->next = ping_head; + ping_head = ping; // insert at head + + t_ping_register_pcb(); + t_ping_send(t_ping_pcb, ping); + + // set timers for time-out and cadence + sys_timeout(Ping_timeout_ms, t_ping_timeout, ping); + sys_timeout(Ping_coarse, t_ping_coarse_tmr, ping); + } + } // Check if any ping requests is completed, and publish the results void PingResponsePoll(void) { - if (ping.done) { - uint32_t success = ping.total_count - ping.timeout_count; - uint32_t ip = ping_opt.ip; + Ping_t *ping = ping_head; + Ping_t **prev_link = &ping_head; // previous link pointer (used to remove en entry) - // Serial.printf( - // "DEBUG ping_sent_cb: ping reply\n" - // "\tsuccess_count = %d \n" - // "\ttimeout_count = %d \n" - // "\tmin_time = %d \n" - // "\tmax_time = %d \n" - // "\tavg_time = %d \n", - // success, ping.timeout_count, - // ping.min_time, ping.max_time, - // success ? ping.sum_time / success : 0 - // ); + while (ping != nullptr) { + if (ping->done) { + uint32_t success = ping->success_count; + uint32_t ip = ping->ip; - Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{" - "\"Reachable\":%s" - ",\"Success\":%d" - ",\"Timeout\":%d" - ",\"MinTime\":%d" - ",\"MaxTime\":%d" - ",\"AvgTime\":%d" - "}}}"), - ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24, - success ? "true" : "false", - success, ping.timeout_count, - ping.min_time, ping.max_time, - success ? ping.sum_time / success : 0 - ); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); - XdrvRulesProcess(); - ping.done = false; - ping.busy = false; + Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{" + "\"Reachable\":%s" + ",\"Success\":%d" + ",\"Timeout\":%d" + ",\"MinTime\":%d" + ",\"MaxTime\":%d" + ",\"AvgTime\":%d" + "}}}"), + ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24, + success ? "true" : "false", + success, ping->timeout_count, + success ? ping->min_time : 0, ping->max_time, + success ? ping->sum_time / success : 0 + ); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); + XdrvRulesProcess(); + + // remove from linked list + *prev_link = ping->next; + // don't increment prev_link + Ping_t *ping_to_delete = ping; + ping = ping->next; // move to next before deleting the object + delete ping_to_delete; // free memory allocated + } else { + prev_link = &ping->next; + ping = ping->next; + } } } +/*********************************************************************************************\ + * Ping Command +\*********************************************************************************************/ + void CmndPing(void) { uint32_t count = XdrvMailbox.index; IPAddress ip; RemoveSpace(XdrvMailbox.data); - if (count > 8) { count = 8; } - - if (ping.busy) { - ResponseCmndChar_P(PSTR("Ping busy")); - return; - } + if (count > 10) { count = 8; } // max 8 seconds if (WiFi.hostByName(XdrvMailbox.data, ip)) { - memset(&ping_opt, 0, sizeof(ping_opt)); - memset(&ping, 0, sizeof(ping)); - ping.min_time = UINT32_MAX; - - ping_opt.count = count; - ping_opt.coarse_time = 1; // wait 1 second between messages - ping_opt.ip = ip; - - // callbacks - ping_opt.recv_function = (ping_recv_function) ping_recv_cb; // at each response or time-out - ping_opt.sent_function = (ping_sent_function) ping_sent_cb; // when all packets have been sent and reveived - - ping.busy = true; - if (ping_start(&ping_opt)) { + bool ok = t_ping_start(ip, count); + if (ok) { ResponseCmndDone(); } else { - ResponseCmndChar_P(PSTR("Unable to send Ping")); - ping.busy = false; + ResponseCmndChar_P(PSTR("Ping already ongoing for this IP")); } } else { ResponseCmndChar_P(PSTR("Unable to resolve IP address")); } - } @@ -157,7 +332,7 @@ bool Xdrv38(uint8_t function) switch (function) { case FUNC_EVERY_250_MSECOND: - PingResponsePoll(); + PingResponsePoll(); // TODO break; case FUNC_COMMAND: result = DecodeCommand(kPingCommands, PingCommand); @@ -166,4 +341,4 @@ bool Xdrv38(uint8_t function) return result; } -#endif // USE_PING +#endif // USE_PING \ No newline at end of file From 49ef6598fca07aabbc5e20bd56baed33143cfd0f Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 15 Apr 2020 18:55:04 +0200 Subject: [PATCH 08/34] Update size of Ping --- tasmota/my_user_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 97476820f..6ac041770 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -391,7 +391,7 @@ #define SUNRISE_DAWN_ANGLE DAWN_NORMAL // Select desired Dawn Angle from (DAWN_NORMAL, DAWN_CIVIL, DAWN_NAUTIC, DAWN_ASTRONOMIC) // -- Ping ---------------------------------------- -// #define USE_PING // Enable Ping command (+3k code) +// #define USE_PING // Enable Ping command (+2k code) // -- Rules or Script ---------------------------- // Select none or only one of the below defines From ba20008cd91a2984549244eee55cd15a89ec3b7b Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 15 Apr 2020 19:42:50 +0200 Subject: [PATCH 09/34] Don't apply DimmerRange to CT PWM --- tasmota/xdrv_04_light.ino | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index eda02eafb..a636fdeb0 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1985,6 +1985,15 @@ bool isChannelGammaCorrected(uint32_t channel) { return true; } +// is the channel a regular PWM or ColorTemp control +bool isChannelCT(uint32_t channel) { + if (PHILIPS == my_module_type) { + if ((LST_COLDWARM == Light.subtype) && (1 == channel)) { return true; } // PMW reserved for CT + if ((LST_RGBCW == Light.subtype) && (4 == channel)) { return true; } // PMW reserved for CT + } + return false; +} + // Calculate the Gamma correction, if any, for fading, using the fast Gamma curve (10 bits in+out) uint16_t fadeGamma(uint32_t channel, uint16_t v) { if (isChannelGammaCorrected(channel)) { @@ -2106,7 +2115,9 @@ void LightSetOutputs(const uint16_t *cur_col_10) { if (pin[GPIO_PWM1 +i] < 99) { //AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Cur_Col%d 10 bits %d"), i, cur_col_10[i]); uint16_t cur_col = cur_col_10[i + Light.pwm_offset]; - cur_col = cur_col > 0 ? changeUIntScale(cur_col, 0, Settings.pwm_range, Light.pwm_min, Light.pwm_max) : 0; // shrink to the range of pwm_min..pwm_max + if (!isChannelCT(i)) { // if CT don't use pwm_min and pwm_max + cur_col = cur_col > 0 ? changeUIntScale(cur_col, 0, Settings.pwm_range, Light.pwm_min, Light.pwm_max) : 0; // shrink to the range of pwm_min..pwm_max + } analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col : cur_col); } } From 5c43f4c4c216d7465af440122684753ecea34992 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Apr 2020 11:00:56 +0200 Subject: [PATCH 10/34] Fix ESP32 compile error Fix ESP32 compile error (#8195) --- tasmota/xdrv_04_light.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index a636fdeb0..1c5751829 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1987,10 +1987,12 @@ bool isChannelGammaCorrected(uint32_t channel) { // is the channel a regular PWM or ColorTemp control bool isChannelCT(uint32_t channel) { +#ifdef ESP8266 if (PHILIPS == my_module_type) { if ((LST_COLDWARM == Light.subtype) && (1 == channel)) { return true; } // PMW reserved for CT if ((LST_RGBCW == Light.subtype) && (4 == channel)) { return true; } // PMW reserved for CT } +#endif // ESP8266 return false; } From d2b7b4012f6692cd30e01bc23937adc03d8bc5b2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Apr 2020 14:59:01 +0200 Subject: [PATCH 11/34] More ESP32 compatibility More ESP32 compatibility (breaks current ESP32 configuration again!) --- tasmota/settings.h | 31 +++++++++++++++++++++++++------ tasmota/xdrv_99_debug.ino | 22 ++++++++++++++++++++-- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 3f8827636..01f0cf174 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -86,7 +86,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t energy_weekend : 1; // bit 20 (v6.6.0.8) - CMND_TARIFF uint32_t dds2382_model : 1; // bit 21 (v6.6.0.14) - SetOption71 - Select different Modbus registers for Active Energy (#6531) uint32_t hardware_energy_total : 1; // bit 22 (v6.6.0.15) - SetOption72 - Enable hardware energy total counter as reference (#6561) - uint32_t mqtt_buttons : 1; // bit 23 (v8.2.0.3) - SetOption73 - Detach buttons from relays and enable MQTT action state for multipress + uint32_t mqtt_buttons : 1; // bit 23 (v8.2.0.3) - SetOption73 - Detach buttons from relays and enable MQTT action state for multipress uint32_t ds18x20_internal_pullup : 1; // bit 24 (v7.0.0.1) - SetOption74 - Enable internal pullup for single DS18x20 sensor uint32_t grouptopic_mode : 1; // bit 25 (v7.0.0.1) - SetOption75 - GroupTopic replaces %topic% (0) or fixed topic cmnd/grouptopic (1) uint32_t bootcount_update : 1; // bit 26 (v7.0.0.4) - SetOption76 - Enable incrementing bootcount when deepsleep is enabled @@ -245,7 +245,7 @@ typedef struct { } EnergyUsage; -typedef struct PACKED { +typedef struct { uint8_t fnid = 0; uint8_t dpid = 0; } TuyaFnidDpidMap; @@ -253,7 +253,7 @@ typedef struct PACKED { const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017) const uint8_t MAX_TUYA_FUNCTIONS = 16; -struct PACKED SYSCFG { +struct SYSCFG { uint16_t cfg_holder; // 000 v6 header uint16_t cfg_size; // 002 unsigned long save_flag; // 004 @@ -369,7 +369,13 @@ struct PACKED SYSCFG { uint8_t module; // 474 uint8_t ws_color[4][3]; // 475 uint8_t ws_width[3]; // 481 - myio my_gp; // 484 + +#ifdef ESP8266 + myio my_gp; // 484 - 17 bytes (ESP8266) +#else // ESP32 + uint8_t free_esp32_484[17]; // 484 +#endif // ESP8266 - ESP32 + uint8_t my_adc0; // 495 uint16_t light_pixels; // 496 uint8_t light_color[5]; // 498 @@ -397,7 +403,14 @@ struct PACKED SYSCFG { uint32_t ip_address[4]; // 544 unsigned long energy_kWhtotal; // 554 +#ifdef ESP8266 char ex_mqtt_fulltopic[100]; // 558 +#else // ESP32 + myio my_gp; // 558 - 40 bytes (ESP32) + mytmplt user_template; // 580 - 35 bytes (ESP32) + + uint8_t free_esp32_5a3[25]; // 5A3 +#endif // ESP8266 - ESP32 SysBitfield2 flag2; // 5BC unsigned long pulse_counter[MAX_COUNTERS]; // 5C0 @@ -423,7 +436,12 @@ struct PACKED SYSCFG { char user_template_name[15]; // 720 15 bytes - Backward compatibility since v8.2.0.3 - mytmplt user_template; // 72F 14 bytes +#ifdef ESP8266 + mytmplt user_template; // 72F 14 bytes (ESP8266) +#else // ESP32 + uint8_t free_esp32_72f[14]; // 72F +#endif // ESP8266 - ESP32 + uint8_t novasds_startingoffset; // 73D uint8_t web_color[18][3]; // 73E uint16_t display_width; // 774 @@ -507,8 +525,9 @@ struct PACKED SYSCFG { uint8_t zb_free_byte; // F33 uint16_t pms_wake_interval; // F34 - uint8_t free_f36[130]; // F36 + uint8_t free_f36[130]; // F36 - Decrement if adding new Setting variables just above and below + // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 uint16_t pulse_counter_debounce_high; // FBA uint32_t keeloq_master_msb; // FBC diff --git a/tasmota/xdrv_99_debug.ino b/tasmota/xdrv_99_debug.ino index 538ac7f71..d18ab5833 100644 --- a/tasmota/xdrv_99_debug.ino +++ b/tasmota/xdrv_99_debug.ino @@ -172,11 +172,11 @@ void CpuLoadLoop(void) CPU_loops ++; if ((CPU_last_millis + (CPU_load_check *1000)) <= CPU_last_loop_time) { #if defined(F_CPU) && (F_CPU == 160000000L) - int CPU_load = 100 - ( (CPU_loops*(1 + 30*sleep)) / (CPU_load_check *800) ); + int CPU_load = 100 - ( (CPU_loops*(1 + 30*ssleep)) / (CPU_load_check *800) ); CPU_loops = CPU_loops / CPU_load_check; AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, CPU %d%%(160MHz), Loops/sec %d"), ESP.getFreeHeap(), CPU_load, CPU_loops); #else - int CPU_load = 100 - ( (CPU_loops*(1 + 30*sleep)) / (CPU_load_check *400) ); + int CPU_load = 100 - ( (CPU_loops*(1 + 30*ssleep)) / (CPU_load_check *400) ); CPU_loops = CPU_loops / CPU_load_check; AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, CPU %d%%(80MHz), Loops/sec %d"), ESP.getFreeHeap(), CPU_load, CPU_loops); #endif @@ -188,6 +188,7 @@ void CpuLoadLoop(void) /*******************************************************************************************/ +#ifdef ESP8266 #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) // All version before core 2.4.2 // https://github.com/esp8266/Arduino/issues/2557 @@ -224,10 +225,20 @@ void DebugFreeMem(void) #endif // ARDUINO_ESP8266_RELEASE_2_x_x +#else // ESP32 + +void DebugFreeMem(void) +{ + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d"), ESP.getFreeHeap()); +} + +#endif // ESP8266 - ESP32 + /*******************************************************************************************/ void DebugRtcDump(char* parms) { +#ifdef ESP8266 #define CFG_COLS 16 uint16_t idx; @@ -283,6 +294,7 @@ void DebugRtcDump(char* parms) snprintf_P(log_data, sizeof(log_data), PSTR("%s|"), log_data); AddLog(LOG_LEVEL_INFO); } +#endif // ESP8266 } /*******************************************************************************************/ @@ -385,6 +397,7 @@ void DebugCfgPoke(char* parms) void SetFlashMode(uint8_t mode) { +#ifdef ESP8266 uint8_t *_buffer; uint32_t address; @@ -400,6 +413,7 @@ void SetFlashMode(uint8_t mode) } } delete[] _buffer; +#endif // ESP8266 } /*********************************************************************************************\ @@ -503,6 +517,7 @@ uint32_t DebugSwap32(uint32_t x) { void CmndFlashDump(void) { +#ifdef ESP8266 // FlashDump // FlashDump 0xFF000 // FlashDump 0xFC000 10 @@ -533,6 +548,7 @@ void CmndFlashDump(void) DebugSwap32(values[4]), DebugSwap32(values[5]), DebugSwap32(values[6]), DebugSwap32(values[7])); } ResponseCmndDone(); +#endif // ESP8266 } #ifdef USE_I2C @@ -600,10 +616,12 @@ void CmndI2cRead(void) void CmndI2cStretch(void) { +#ifdef ESP8266 if (i2c_flg && (XdrvMailbox.payload > 0)) { Wire.setClockStretchLimit(XdrvMailbox.payload); } ResponseCmndDone(); +#endif // ESP8266 } void CmndI2cClock(void) From 538dfbef2e2f31a6754b816da8d28c9a881ef993 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Apr 2020 16:29:33 +0200 Subject: [PATCH 12/34] More ESP32 compatibility --- tasmota/xdrv_01_webserver.ino | 15 +++++++++++++-- tasmota/xdrv_99_debug.ino | 4 +++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 5d286bf2e..008310cf6 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1675,17 +1675,28 @@ void ModuleSaveSettings(void) if (ValidGPIO(i, cmodule.io[i])) { snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), i); WebGetArg(webindex, tmp, sizeof(tmp)); - Settings.my_gp.io[i] = (!strlen(tmp)) ? 0 : atoi(tmp); - gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(Settings.my_gp.io[i]); + uint8_t value = (!strlen(tmp)) ? 0 : atoi(tmp); +#ifdef ESP8266 + Settings.my_gp.io[i] = value; +#else // ESP32 + if (i == ADC0_PIN) { + Settings.my_adc0 = value; + } else { + Settings.my_gp.io[i] = value; + } +#endif // ESP8266 - ESP32 + gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(value); } } } +#ifdef ESP8266 #ifndef USE_ADC_VCC // WebGetArg("g17", tmp, sizeof(tmp)); WebGetArg("g" STR(ADC0_PIN), tmp, sizeof(tmp)); Settings.my_adc0 = (!strlen(tmp)) ? 0 : atoi(tmp); gpios += F(", " D_ADC "0 "); gpios += String(Settings.my_adc0); #endif // USE_ADC_VCC +#endif // ESP8266 AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MODULE "%s " D_CMND_MODULE "%s"), ModuleName().c_str(), gpios.c_str()); } diff --git a/tasmota/xdrv_99_debug.ino b/tasmota/xdrv_99_debug.ino index d18ab5833..feb04cabd 100644 --- a/tasmota/xdrv_99_debug.ino +++ b/tasmota/xdrv_99_debug.ino @@ -229,7 +229,9 @@ void DebugFreeMem(void) void DebugFreeMem(void) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d"), ESP.getFreeHeap()); + register uint8_t *sp asm("a1"); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), ESP.getFreeHeap(), sp - pxTaskGetStackStart(NULL), XdrvMailbox.data); } #endif // ESP8266 - ESP32 From 367658b75be252e21b952b75aaee6ed5b19f5b04 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Apr 2020 18:33:26 +0200 Subject: [PATCH 13/34] More ESP32 compatibility --- .../src/esp8266toEsp32.cpp | 41 ++++++++++++++----- .../src/esp8266toEsp32.h | 19 ++++----- tasmota/support.ino | 6 ++- tasmota/support_command.ino | 2 +- tasmota/tasmota_compat.h | 1 - tasmota/xdrv_01_webserver.ino | 2 +- 6 files changed, 46 insertions(+), 25 deletions(-) diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp index f4a17f368..029d41470 100644 --- a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp +++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp @@ -20,18 +20,44 @@ #include #include #include "esp8266toEsp32.h" + // ESP Stuff -struct rst_info resetInfo; + +String ESP32GetResetReason(uint32_t cpu_no) +{ + // tools\sdk\include\esp32\rom\rtc.h + switch (rtc_get_reset_reason( (RESET_REASON) cpu_no)) { + case POWERON_RESET : return F("Vbat power on reset"); // 1 + case SW_RESET : return F("Software reset digital core"); // 3 + case OWDT_RESET : return F("Legacy watch dog reset digital core"); // 4 + case DEEPSLEEP_RESET : return F("Deep Sleep reset digital core"); // 5 + case SDIO_RESET : return F("Reset by SLC module, reset digital core"); // 6 + case TG0WDT_SYS_RESET : return F("Timer Group0 Watch dog reset digital core"); // 7 + case TG1WDT_SYS_RESET : return F("Timer Group1 Watch dog reset digital core"); // 8 + case RTCWDT_SYS_RESET : return F("RTC Watch dog Reset digital core"); // 9 + case INTRUSION_RESET : return F("Instrusion tested to reset CPU"); // 10 + case TGWDT_CPU_RESET : return F("Time Group reset CPU"); // 11 + case SW_CPU_RESET : return F("Software reset CPU"); // 12 + case RTCWDT_CPU_RESET : return F("RTC Watch dog Reset CPU"); // 13 + case EXT_CPU_RESET : return F("or APP CPU, reseted by PRO CPU"); // 14 + case RTCWDT_BROWN_OUT_RESET : return F("Reset when the vdd voltage is not stable"); // 15 + case RTCWDT_RTC_RESET : return F("RTC Watch dog reset digital core and rtc module"); // 16 + default : return F("NO_MEAN"); // 0 + } +} String ESP_getResetReason(void) { - // CPU 0 - return String(rtc_get_reset_reason(0)); + return ESP32GetResetReason(0); // CPU 0 } -String ESP_getResetInfo(void) +uint32_t ESP_ResetInfoReason(void) { - return String(PSTR("0")); + RESET_REASON reason = rtc_get_reset_reason(0); + if (POWERON_RESET == reason) { return REASON_DEFAULT_RST; } + if (SW_CPU_RESET == reason) { return REASON_SOFT_RESTART; } + if (DEEPSLEEP_RESET == reason) { return REASON_DEEP_SLEEP_AWAKE; } + if (SW_RESET == reason) { return REASON_EXT_SYS_RST; } } uint32_t ESP_getBootVersion(void) @@ -74,11 +100,6 @@ String String_ESP_getChipId() return String(uint32_t(mac >> 32)) + String(uint32_t(mac)); } -uint32_t ESP_getFlashChipRealSize() -{ - return ESP.getFlashChipSize(); -} - uint32_t ESP_getSketchSize(void) { static uint32_t sketchsize = 0; diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index 8a30da55d..28e187d52 100644 --- a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -34,15 +34,14 @@ #define ESP_flashReadHeader(offset, data, size) ESP32_flashRead(offset, data, size) #define ESP_flashRead(offset, data, size) ESP32_flashRead(offset, data, size) String ESP_getResetReason(void); +uint32_t ESP_ResetInfoReason(void); uint32_t ESP_getBootVersion(void); bool ESP_rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size); bool ESP_rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size); void ESP_reset(); -String ESP_getResetInfo(void); uint32_t ESP_getFlashChipId(); uint32_t ESP_getChipId(); String String_ESP_getChipId(); -uint32_t ESP_getFlashChipRealSize(); uint32_t ESP_getSketchSize(); // Analog @@ -67,7 +66,6 @@ typedef double real64_t; #define ETS_UART_INTR_DISABLE() #define ETS_UART_INTR_ENABLE() -#define getChipId() getEfuseMac() #define ESPhttpUpdate httpUpdate #define getFlashChipRealSize() getFlashChipSize() @@ -92,14 +90,13 @@ typedef int SerialConfig; #undef LWIP_IPV6 -struct rst_info -{ - int reason; -}; - -#define REASON_DEFAULT_RST 1 -#define REASON_EXT_SYS_RST 2 -#define REASON_DEEP_SLEEP_AWAKE 3 +#define REASON_DEFAULT_RST 0 // "Power on" normal startup by power on +#define REASON_WDT_RST 1 // "Hardware Watchdog" hardware watch dog reset +#define REASON_EXCEPTION_RST 2 // "Exception" exception reset, GPIO status won’t change +#define REASON_SOFT_WDT_RST 3 // "Software Watchdog" software watch dog reset, GPIO status won’t change +#define REASON_SOFT_RESTART 4 // "Software/System restart" software restart ,system_restart , GPIO status won’t change +#define REASON_DEEP_SLEEP_AWAKE 5 // "Deep-Sleep Wake" wake up from deep-sleep +#define REASON_EXT_SYS_RST 6 // "External System" external system reset // memmove ... #define memcpy_P memcpy diff --git a/tasmota/support.ino b/tasmota/support.ino index 9c720c996..0435293e6 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -99,7 +99,11 @@ uint32_t ResetReason(void) REASON_DEEP_SLEEP_AWAKE = 5, // "Deep-Sleep Wake" wake up from deep-sleep REASON_EXT_SYS_RST = 6 // "External System" external system reset */ - return resetInfo.reason; +#ifdef ESP8266 + return resetInfo.reason; // Returns Tasmota reason codes +#else + return ESP_ResetInfoReason(); +#endif } String GetResetReason(void) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 6897384d0..0d4e12236 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -448,7 +448,7 @@ void CmndStatus(void) D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d,\"" D_JSON_FLASHCHIPID "\":\"%06X\",\"" D_JSON_FLASHMODE "\":%d,\"" D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"), ESP_getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, - ESP.getFlashChipSize()/1024, ESP_getFlashChipRealSize()/1024, ESP_getFlashChipId(), ESP.getFlashChipMode(), + ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP_getFlashChipId(), ESP.getFlashChipMode(), LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6); XsnsDriverState(); ResponseAppend_P(PSTR(",\"Sensors\":")); diff --git a/tasmota/tasmota_compat.h b/tasmota/tasmota_compat.h index 6571d0f34..839f5cef8 100644 --- a/tasmota/tasmota_compat.h +++ b/tasmota/tasmota_compat.h @@ -17,7 +17,6 @@ #define ESP_reset() ESP.reset() #define ESP_getBootVersion() ESP.getBootVersion() #define ESP_getFlashChipId() ESP.getFlashChipId() -#define ESP_getFlashChipRealSize() ESP.getFlashChipRealSize() #define ESP_getSketchSize() ESP.getSketchSize() #define ESP_getChipId() ESP.getChipId() // diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 008310cf6..8b5806938 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2213,7 +2213,7 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1}2 ")); // Empty line WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d"), ESP_getChipId()); WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP_getFlashChipId()); - WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP_getFlashChipRealSize() / 1024); + WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP.getFlashChipRealSize() / 1024); WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%dkB"), ESP.getFlashChipSize() / 1024); WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%dkB"), ESP_getSketchSize() / 1024); WSContentSend_P(PSTR("}1" D_FREE_PROGRAM_SPACE "}2%dkB"), ESP.getFreeSketchSpace() / 1024); From 618ac9ab14a907ec141fbb02e2f7246f8f438907 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 16 Apr 2020 19:36:14 +0200 Subject: [PATCH 14/34] Added Zigbee attribute types --- tasmota/xdrv_23_zigbee_5_converters.ino | 854 +++++++++++++----------- 1 file changed, 467 insertions(+), 387 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 7a8ea4806..5e39771c5 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -23,6 +23,72 @@ * ZCL \*********************************************************************************************/ + +enum Z_DataTypes { + Znodata = 0x00, + Zdata8 = 0x08, Zdata16, Zdata24, Zdata32, Zdata40, Zdata48, Zdata56, Zdata64, + Zbool = 0x10, + Zmap8 = 0x18, Zmap16, Zmap24, Zmap32, Zmap40, Zmap48, Zmap56, Zmap64, + Zuint8 = 0x20, Zuint16, Zuint24, Zuint32, Zuint40, Zuint48, Zuint56, Zuint64, + Zint8 = 0x28, Zint16, Zint24, Zint32, Zint40, Zint48, Zint56, Zint64, + Zenum8 = 0x30, Zenum16 = 0x31, + Zsemi = 0x38, Zsingle = 0x39, Zdouble = 0x3A, + Zoctstr = 0x41, Zstring = 0x42, Zoctstr16 = 0x43, Zstring16 = 0x44, + Arrray = 0x48, + Zstruct = 0x4C, + Zset = 0x50, Zbag = 0x51, + ZToD = 0xE0, Zdate = 0xE1, ZUTC = 0xE2, + ZclusterId = 0xE8, ZattribId = 0xE9, ZbacOID = 0xEA, + ZEUI64 = 0xF0, Zkey128 = 0xF1, + Zunk = 0xFF +}; + +// +// get the lenth in bytes for a data-type +// return 0 if unknown of type specific +// +// Note: this code is smaller than a static array +uint8_t Z_getDatatypeLen(uint8_t t) { + if ( ((t >= 0x08) && (t <= 0x0F)) || // data8 - data64 + ((t >= 0x18) && (t <= 0x2F)) ) { // map/uint/int + return (t & 0x07) + 1; + } + switch (t) { + case Zbool: + case Zenum8: + return 1; + case Zenum16: + case Zsemi: + case ZclusterId: + case ZattribId: + return 2; + case Zsingle: + case ZToD: + case Zdate: + case ZUTC: + case ZbacOID: + return 4; + case Zdouble: + case ZEUI64: + return 8; + case Zkey128: + return 16; + case Znodata: + default: + return 0; + } +} + +// typedef struct Z_DataTypeMapping { +// uint8_t datatype; +// uint8_t len; // len in bytes and add 0x80 if DISCRETE +// } + +// const Z_DataTypeMapping Z_types[] PROGMEM = { +// { Znodata, 0 }, +// { Zdata8, 0 }, +// }; + typedef union ZCLHeaderFrameControl_t { struct { uint8_t frame_type : 2; // 00 = across entire profile, 01 = cluster specific @@ -188,7 +254,7 @@ uint8_t toPercentageCR2032(uint32_t voltage) { uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer &buf, - uint32_t offset, uint32_t len) { + uint32_t offset, uint32_t buflen) { uint32_t i = offset; uint32_t attrtype = buf.get8(i++); @@ -196,105 +262,98 @@ uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer // fallback - enter a null value json[attrid_str] = (char*) nullptr; + uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute lenght, overloaded for variable length attributes + // now parse accordingly to attr type switch (attrtype) { - case 0x00: // nodata - case 0xFF: // unk - break; - case 0x10: // bool - case 0x20: // uint8 - case 0x30: // enum8 + // case Znodata: // nodata + // case Zunk: // unk + // break; + case Zbool: // bool + case Zuint8: // uint8 + case Zenum8: // enum8 { uint8_t uint8_val = buf.get8(i); - i += 1; + // i += 1; if (0xFF != uint8_val) { json[attrid_str] = uint8_val; } } break; - case 0x21: // uint16 - case 0x31: // enum16 + case Zuint16: // uint16 + case Zenum16: // enum16 { uint16_t uint16_val = buf.get16(i); - i += 2; + // i += 2; if (0xFFFF != uint16_val) { json[attrid_str] = uint16_val; } } break; - case 0x23: // uint32 + case Zuint32: // uint32 { uint32_t uint32_val = buf.get32(i); - i += 4; + // i += 4; if (0xFFFFFFFF != uint32_val) { json[attrid_str] = uint32_val; } } break; - // Note: uint40, uint48, uint56, uint64 are stored as Hex - case 0x24: // uint40 - case 0x25: // uint48 - case 0x26: // uint56 - case 0x27: // uint64 + // Note: uint40, uint48, uint56, uint64 are displayed as Hex + // Note: int40, int48, int56, int64 are displayed as Hex + case Zuint40: // uint40 + case Zuint48: // uint48 + case Zuint56: // uint56 + case Zuint64: // uint64 + case Zint40: // int40 + case Zint48: // int48 + case Zint56: // int56 + case Zint64: // int64 { - uint8_t len = attrtype - 0x1F; // 5 - 8 + // uint8_t len = attrtype - 0x27; // 5 - 8 // print as HEX char hex[2*len+1]; ToHex_P(buf.buf(i), len, hex, sizeof(hex)); json[attrid_str] = hex; - i += len; + // i += len; } break; - case 0x28: // uint8 + case Zint8: // int8 { int8_t int8_val = buf.get8(i); - i += 1; + // i += 1; if (0x80 != int8_val) { json[attrid_str] = int8_val; } } break; - case 0x29: // uint16 + case Zint16: // int16 { int16_t int16_val = buf.get16(i); - i += 2; + // i += 2; if (0x8000 != int16_val) { json[attrid_str] = int16_val; } } break; - case 0x2B: // uint16 + case Zint32: // int32 { int32_t int32_val = buf.get32(i); - i += 4; + // i += 4; if (0x80000000 != int32_val) { json[attrid_str] = int32_val; } } break; - // Note: int40, int48, int56, int64 are not stored as Hex - case 0x2C: // int40 - case 0x2D: // int48 - case 0x2E: // int56 - case 0x2F: // int64 - { - uint8_t len = attrtype - 0x27; // 5 - 8 - // print as HEX - char hex[2*len+1]; - ToHex_P(buf.buf(i), len, hex, sizeof(hex)); - json[attrid_str] = hex; - i += len; - } - break; - case 0x41: // octet string, 1 byte len - case 0x42: // char string, 1 byte len - case 0x43: // octet string, 2 bytes len - case 0x44: // char string, 2 bytes len + case Zoctstr: // octet string, 1 byte len + case Zstring: // char string, 1 byte len + case Zoctstr16: // octet string, 2 bytes len + case Zstring16: // char string, 2 bytes len // For strings, default is to try to do a real string, but reverts to octet stream if null char is present or on some exceptions { bool parse_as_string = true; - uint32_t len = (attrtype <= 0x42) ? buf.get8(i) : buf.get16(i); // len is 8 or 16 bits + len = (attrtype <= 0x42) ? buf.get8(i) : buf.get16(i); // len is 8 or 16 bits i += (attrtype <= 0x42) ? 1 : 2; // increment pointer if (i + len > buf.len()) { // make sure we don't get past the buffer len = buf.len() - i; @@ -302,14 +361,6 @@ uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer // check if we can safely use a string if ((0x41 == attrtype) || (0x43 == attrtype)) { parse_as_string = false; } - // else { - // for (uint32_t j = 0; j < len; j++) { - // if (0x00 == buf.get8(i+j)) { - // parse_as_string = false; - // break; - // } - // } - // } if (parse_as_string) { char str[len+1]; @@ -323,97 +374,82 @@ uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer json[attrid_str] = hex; } - i += len; - break; + // i += len; + // break; } - i += buf.get8(i) + 1; + // i += buf.get8(i) + 1; break; - case 0x08: // data8 - case 0x18: // map8 + case Zdata8: // data8 + case Zmap8: // map8 { uint8_t uint8_val = buf.get8(i); - i += 1; + // i += 1; json[attrid_str] = uint8_val; } break; - case 0x09: // data16 - case 0x19: // map16 + case Zdata16: // data16 + case Zmap16: // map16 { uint16_t uint16_val = buf.get16(i); - i += 2; + // i += 2; json[attrid_str] = uint16_val; } break; - case 0x0B: // data32 - case 0x1B: // map32 + case Zdata32: // data32 + case Zmap32: // map32 { uint32_t uint32_val = buf.get32(i); - i += 4; + // i += 4; json[attrid_str] = uint32_val; } break; - // TODO - case 0x39: // float + case Zsingle: // float { uint32_t uint32_val = buf.get32(i); float * float_val = (float*) &uint32_val; - i += 4; + // i += 4; json[attrid_str] = *float_val; } break; - case 0xE0: // ToD - case 0xE1: // date - case 0xE2: // UTC - i += 4; - break; - - case 0xE8: // clusterId - case 0xE9: // attribId - i += 2; - break; - case 0xEA: // bacOID - i += 4; - break; - - case 0xF0: // EUI64 - i += 8; - break; - case 0xF1: // key128 - i += 16; + // TODO + case ZToD: // ToD + case Zdate: // date + case ZUTC: // UTC + case ZclusterId: // clusterId + case ZattribId: // attribId + case ZbacOID: // bacOID + case ZEUI64: // EUI64 + case Zkey128: // key128 + case Zsemi: // semi (float on 2 bytes) break; // Other un-implemented data types - case 0x0A: // data24 - case 0x0C: // data40 - case 0x0D: // data48 - case 0x0E: // data56 - case 0x0F: // data64 - i += attrtype - 0x07; // 2-8 + case Zdata24: // data24 + case Zdata40: // data40 + case Zdata48: // data48 + case Zdata56: // data56 + case Zdata64: // data64 break; // map - case 0x1A: // map24 - case 0x1C: // map40 - case 0x1D: // map48 - case 0x1E: // map56 - case 0x1F: // map64 - i += attrtype - 0x17; + case Zmap24: // map24 + case Zmap40: // map40 + case Zmap48: // map48 + case Zmap56: // map56 + case Zmap64: // map64 break; - // semi - case 0x38: // semi (float on 2 bytes) - i += 2; - break; - case 0x3A: // double precision + case Zdouble: // double precision { uint64_t uint64_val = buf.get64(i); double * double_val = (double*) &uint64_val; - i += 8; + // i += 8; json[attrid_str] = *double_val; } break; } + i += len; // String pp; // pretty print // json[attrid_str].prettyPrintTo(pp); @@ -529,12 +565,36 @@ void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { // 1 = remove initial value typedef int32_t (*Z_AttrConverter)(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr); typedef struct Z_AttributeConverter { - uint16_t cluster; + uint8_t type; + uint8_t cluster_short; uint16_t attribute; const char * name; Z_AttrConverter func; } Z_AttributeConverter; +enum Cx_cluster_short { + Cx0000, Cx0001, Cx0002, Cx0003, Cx0004, Cx0005, Cx0006, Cx0007, + Cx0008, Cx0009, Cx000A, Cx000B, Cx000C, Cx000D, Cx000E, Cx000F, + Cx0010, Cx0011, Cx0012, Cx0013, Cx0014, Cx001A, Cx0020, Cx0100, + Cx0101, Cx0102, Cx0300, Cx0400, Cx0401, Cx0402, Cx0403, Cx0404, + Cx0405, Cx0406, Cx0B01, Cx0B05, +}; + +const uint16_t Cx_cluster[] PROGMEM = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x001A, 0x0020, 0x0100, + 0x0101, 0x0102, 0x0300, 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, + 0x0405, 0x0406, 0x0B01, 0x0B05, +}; + +uint16_t CxToCluster(uint8_t cx) { + if (cx < sizeof(Cx_cluster)/sizeof(Cx_cluster[0])) { + return pgm_read_word(&Cx_cluster[cx]); + } + return 0xFFFF; +} + ZF(ZCLVersion) ZF(AppVersion) ZF(StackVersion) ZF(HWVersion) ZF(Manufacturer) ZF(ModelId) ZF(DateCode) ZF(PowerSource) ZF(SWBuildID) ZF(Power) ZF(SwitchType) ZF(Dimmer) ZF(MainsVoltage) ZF(MainsFrequency) ZF(BatteryVoltage) ZF(BatteryPercentage) @@ -606,7 +666,7 @@ ZF(WhitePointY) ZF(ColorPointRX) ZF(ColorPointRY) ZF(ColorPointRIntensity) ZF(Co ZF(ColorPointGIntensity) ZF(ColorPointBX) ZF(ColorPointBY) ZF(ColorPointBIntensity) ZF(Illuminance) ZF(IlluminanceMinMeasuredValue) ZF(IlluminanceMaxMeasuredValue) ZF(IlluminanceTolerance) -ZF(IlluminanceLightSensorType) ZF(IlluminanceLevelStatus) +ZF(IlluminanceLightSensorType) ZF(IlluminanceLevelStatus) ZF(IlluminanceTargetLevel) ZF(Temperature) ZF(TemperatureMinMeasuredValue) ZF(TemperatureMaxMeasuredValue) ZF(TemperatureTolerance) @@ -621,341 +681,361 @@ ZF(Humidity) ZF(HumidityMinMeasuredValue) ZF(HumidityMaxMeasuredValue) ZF(Humidi ZF(Occupancy) ZF(OccupancySensorType) ZF(CompanyName) ZF(MeterTypeID) ZF(DataQualityID) ZF(CustomerName) ZF(Model) ZF(PartNumber) -ZF(SoftwareRevision) ZF(POD) ZF(AvailablePower) ZF(PowerThreshold) +ZF(SoftwareRevision) ZF(POD) ZF(AvailablePower) ZF(PowerThreshold) ZF(ProductRevision) ZF(UtilityName) ZF(NumberOfResets) ZF(PersistentMemoryWrites) ZF(LastMessageLQI) ZF(LastMessageRSSI) // list of post-processing directives const Z_AttributeConverter Z_PostProcess[] PROGMEM = { - { 0x0000, 0x0000, Z(ZCLVersion), &Z_Copy }, - { 0x0000, 0x0001, Z(AppVersion), &Z_Copy }, - { 0x0000, 0x0002, Z(StackVersion), &Z_Copy }, - { 0x0000, 0x0003, Z(HWVersion), &Z_Copy }, - { 0x0000, 0x0004, Z(Manufacturer), &Z_ManufKeep }, // record Manufacturer - { 0x0000, 0x0005, Z(ModelId), &Z_ModelKeep }, // record Model - { 0x0000, 0x0006, Z(DateCode), &Z_Copy }, - { 0x0000, 0x0007, Z(PowerSource), &Z_Copy }, - { 0x0000, 0x4000, Z(SWBuildID), &Z_Copy }, - { 0x0000, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint8, Cx0000, 0x0000, Z(ZCLVersion), &Z_Copy }, + { Zuint8, Cx0000, 0x0001, Z(AppVersion), &Z_Copy }, + { Zuint8, Cx0000, 0x0002, Z(StackVersion), &Z_Copy }, + { Zuint8, Cx0000, 0x0003, Z(HWVersion), &Z_Copy }, + { Zstring, Cx0000, 0x0004, Z(Manufacturer), &Z_ManufKeep }, // record Manufacturer + { Zstring, Cx0000, 0x0005, Z(ModelId), &Z_ModelKeep }, // record Model + { Zstring, Cx0000, 0x0006, Z(DateCode), &Z_Copy }, + { Zenum8, Cx0000, 0x0007, Z(PowerSource), &Z_Copy }, + { Zstring, Cx0000, 0x4000, Z(SWBuildID), &Z_Copy }, + { Zunk, Cx0000, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Cmd 0x0A - Cluster 0x0000, attribute 0xFF01 - proprietary - { 0x0000, 0xFF01, nullptr, &Z_AqaraSensor }, // Occupancy (map8) + { Zmap8, Cx0000, 0xFF01, nullptr, &Z_AqaraSensor }, // Occupancy (map8) // Power Configuration cluster - { 0x0001, 0x0000, Z(MainsVoltage), &Z_Copy }, - { 0x0001, 0x0001, Z(MainsFrequency), &Z_Copy }, - { 0x0001, 0x0020, Z(BatteryVoltage), &Z_FloatDiv10 }, - { 0x0001, 0x0021, Z(BatteryPercentage), &Z_Copy }, + { Zuint16, Cx0001, 0x0000, Z(MainsVoltage), &Z_Copy }, + { Zuint8, Cx0001, 0x0001, Z(MainsFrequency), &Z_Copy }, + { Zuint8, Cx0001, 0x0020, Z(BatteryVoltage), &Z_FloatDiv10 }, + { Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), &Z_Copy }, // Device Temperature Configuration cluster - { 0x0002, 0x0000, Z(CurrentTemperature), &Z_Copy }, - { 0x0002, 0x0001, Z(MinTempExperienced), &Z_Copy }, - { 0x0002, 0x0002, Z(MaxTempExperienced), &Z_Copy }, - { 0x0002, 0x0003, Z(OverTempTotalDwell), &Z_Copy }, + { Zint16, Cx0002, 0x0000, Z(CurrentTemperature), &Z_Copy }, + { Zint16, Cx0002, 0x0001, Z(MinTempExperienced), &Z_Copy }, + { Zint16, Cx0002, 0x0002, Z(MaxTempExperienced), &Z_Copy }, + { Zuint16, Cx0002, 0x0003, Z(OverTempTotalDwell), &Z_Copy }, // Scenes cluster - { 0x0005, 0x0000, Z(SceneCount), &Z_Copy }, - { 0x0005, 0x0001, Z(CurrentScene), &Z_Copy }, - { 0x0005, 0x0002, Z(CurrentGroup), &Z_Copy }, - { 0x0005, 0x0003, Z(SceneValid), &Z_Copy }, - //{ 0x0005, 0x0004, Z(NameSupport), &Z_Copy }, + { Zuint8, Cx0005, 0x0000, Z(SceneCount), &Z_Copy }, + { Zuint8, Cx0005, 0x0001, Z(CurrentScene), &Z_Copy }, + { Zuint16, Cx0005, 0x0002, Z(CurrentGroup), &Z_Copy }, + { Zbool, Cx0005, 0x0003, Z(SceneValid), &Z_Copy }, + //{ Zmap8, Cx0005, 0x0004, Z(NameSupport), &Z_Copy }, // On/off cluster - { 0x0006, 0x0000, Z(Power), &Z_Copy }, - { 0x0006, 0x8000, Z(Power), &Z_Copy }, // See 7280 + { Zbool, Cx0006, 0x0000, Z(Power), &Z_Copy }, + { Zbool, Cx0006, 0x8000, Z(Power), &Z_Copy }, // See 7280 // On/Off Switch Configuration cluster - { 0x0007, 0x0000, Z(SwitchType), &Z_Copy }, + { Zenum8, Cx0007, 0x0000, Z(SwitchType), &Z_Copy }, // Level Control cluster - { 0x0008, 0x0000, Z(Dimmer), &Z_Copy }, - // { 0x0008, 0x0001, Z(RemainingTime", &Z_Copy }, - // { 0x0008, 0x0010, Z(OnOffTransitionTime", &Z_Copy }, - // { 0x0008, 0x0011, Z(OnLevel", &Z_Copy }, - // { 0x0008, 0x0012, Z(OnTransitionTime", &Z_Copy }, - // { 0x0008, 0x0013, Z(OffTransitionTime", &Z_Copy }, - // { 0x0008, 0x0014, Z(DefaultMoveRate", &Z_Copy }, + { Zuint8, Cx0008, 0x0000, Z(Dimmer), &Z_Copy }, + // { Zuint16, Cx0008, 0x0001, Z(RemainingTime", &Z_Copy }, + // { Zuint16, Cx0008, 0x0010, Z(OnOffTransitionTime", &Z_Copy }, + // { Zuint8, Cx0008, 0x0011, Z(OnLevel", &Z_Copy }, + // { Zuint16, Cx0008, 0x0012, Z(OnTransitionTime", &Z_Copy }, + // { Zuint16, Cx0008, 0x0013, Z(OffTransitionTime", &Z_Copy }, + // { Zuint16, Cx0008, 0x0014, Z(DefaultMoveRate", &Z_Copy }, // Alarms cluster - { 0x0009, 0x0000, Z(AlarmCount), &Z_Copy }, + { Zuint16, Cx0009, 0x0000, Z(AlarmCount), &Z_Copy }, + // Time cluster - { 0x000A, 0x0000, Z(Time), &Z_Copy }, - { 0x000A, 0x0001, Z(TimeStatus), &Z_Copy }, - { 0x000A, 0x0002, Z(TimeZone), &Z_Copy }, - { 0x000A, 0x0003, Z(DstStart), &Z_Copy }, - { 0x000A, 0x0004, Z(DstEnd), &Z_Copy }, - { 0x000A, 0x0005, Z(DstShift), &Z_Copy }, - { 0x000A, 0x0006, Z(StandardTime), &Z_Copy }, - { 0x000A, 0x0007, Z(LocalTime), &Z_Copy }, - { 0x000A, 0x0008, Z(LastSetTime), &Z_Copy }, - { 0x000A, 0x0009, Z(ValidUntilTime), &Z_Copy }, + { ZUTC, Cx000A, 0x0000, Z(Time), &Z_Copy }, + { Zmap8, Cx000A, 0x0001, Z(TimeStatus), &Z_Copy }, + { Zint32, Cx000A, 0x0002, Z(TimeZone), &Z_Copy }, + { Zuint32, Cx000A, 0x0003, Z(DstStart), &Z_Copy }, + { Zuint32, Cx000A, 0x0004, Z(DstEnd), &Z_Copy }, + { Zint32, Cx000A, 0x0005, Z(DstShift), &Z_Copy }, + { Zuint32, Cx000A, 0x0006, Z(StandardTime), &Z_Copy }, + { Zuint32, Cx000A, 0x0007, Z(LocalTime), &Z_Copy }, + { ZUTC, Cx000A, 0x0008, Z(LastSetTime), &Z_Copy }, + { ZUTC, Cx000A, 0x0009, Z(ValidUntilTime), &Z_Copy }, + // RSSI Location cluster - { 0x000B, 0x0000, Z(LocationType), &Z_Copy }, - { 0x000B, 0x0000, Z(LocationMethod), &Z_Copy }, - { 0x000B, 0x0000, Z(LocationAge), &Z_Copy }, - { 0x000B, 0x0000, Z(QualityMeasure), &Z_Copy }, - { 0x000B, 0x0000, Z(NumberOfDevices), &Z_Copy }, + { Zdata8, Cx000B, 0x0000, Z(LocationType), &Z_Copy }, + { Zenum8, Cx000B, 0x0001, Z(LocationMethod), &Z_Copy }, + { Zuint16, Cx000B, 0x0002, Z(LocationAge), &Z_Copy }, + { Zuint8, Cx000B, 0x0003, Z(QualityMeasure), &Z_Copy }, + { Zuint8, Cx000B, 0x0004, Z(NumberOfDevices), &Z_Copy }, + // Analog Input cluster - { 0x000C, 0x0004, Z(AnalogInActiveText), &Z_Copy }, - { 0x000C, 0x001C, Z(AnalogInDescription), &Z_Copy }, - { 0x000C, 0x002E, Z(AnalogInInactiveText), &Z_Copy }, - { 0x000C, 0x0041, Z(AnalogInMaxValue), &Z_Copy }, - { 0x000C, 0x0045, Z(AnalogInMinValue), &Z_Copy }, - { 0x000C, 0x0051, Z(AnalogInOutOfService), &Z_Copy }, - { 0x000C, 0x0055, Z(AqaraRotate), &Z_Copy }, - { 0x000C, 0x0057, Z(AnalogInPriorityArray),&Z_Copy }, - { 0x000C, 0x0067, Z(AnalogInReliability), &Z_Copy }, - { 0x000C, 0x0068, Z(AnalogInRelinquishDefault),&Z_Copy }, - { 0x000C, 0x006A, Z(AnalogInResolution), &Z_Copy }, - { 0x000C, 0x006F, Z(AnalogInStatusFlags), &Z_Copy }, - { 0x000C, 0x0075, Z(AnalogInEngineeringUnits),&Z_Copy }, - { 0x000C, 0x0100, Z(AnalogInApplicationType),&Z_Copy }, - { 0x000C, 0xFF05, Z(Aqara_FF05), &Z_Copy }, + // { 0xFF, Cx000C, 0x0004, Z(AnalogInActiveText), &Z_Copy }, + { Zstring, Cx000C, 0x001C, Z(AnalogInDescription), &Z_Copy }, + // { 0xFF, Cx000C, 0x002E, Z(AnalogInInactiveText), &Z_Copy }, + { Zsingle, Cx000C, 0x0041, Z(AnalogInMaxValue), &Z_Copy }, + { Zsingle, Cx000C, 0x0045, Z(AnalogInMinValue), &Z_Copy }, + { Zbool, Cx000C, 0x0051, Z(AnalogInOutOfService), &Z_Copy }, + { Zsingle, Cx000C, 0x0055, Z(AqaraRotate), &Z_Copy }, + // { 0xFF, Cx000C, 0x0057, Z(AnalogInPriorityArray),&Z_Copy }, + { Zenum8, Cx000C, 0x0067, Z(AnalogInReliability), &Z_Copy }, + // { 0xFF, Cx000C, 0x0068, Z(AnalogInRelinquishDefault),&Z_Copy }, + { Zsingle, Cx000C, 0x006A, Z(AnalogInResolution), &Z_Copy }, + { Zmap8, Cx000C, 0x006F, Z(AnalogInStatusFlags), &Z_Copy }, + { Zenum16, Cx000C, 0x0075, Z(AnalogInEngineeringUnits),&Z_Copy }, + { Zuint32, Cx000C, 0x0100, Z(AnalogInApplicationType),&Z_Copy }, + { Zunk, Cx000C, 0xFF05, Z(Aqara_FF05), &Z_Copy }, + // Analog Output cluster - { 0x000D, 0x001C, Z(AnalogOutDescription), &Z_Copy }, - { 0x000D, 0x0041, Z(AnalogOutMaxValue), &Z_Copy }, - { 0x000D, 0x0045, Z(AnalogOutMinValue), &Z_Copy }, - { 0x000D, 0x0051, Z(AnalogOutOutOfService),&Z_Copy }, - { 0x000D, 0x0055, Z(AnalogOutValue), &Z_Copy }, - { 0x000D, 0x0057, Z(AnalogOutPriorityArray),&Z_Copy }, - { 0x000D, 0x0067, Z(AnalogOutReliability), &Z_Copy }, - { 0x000D, 0x0068, Z(AnalogOutRelinquishDefault),&Z_Copy }, - { 0x000D, 0x006A, Z(AnalogOutResolution), &Z_Copy }, - { 0x000D, 0x006F, Z(AnalogOutStatusFlags), &Z_Copy }, - { 0x000D, 0x0075, Z(AnalogOutEngineeringUnits),&Z_Copy }, - { 0x000D, 0x0100, Z(AnalogOutApplicationType),&Z_Copy }, + { Zstring, Cx000D, 0x001C, Z(AnalogOutDescription), &Z_Copy }, + { Zsingle, Cx000D, 0x0041, Z(AnalogOutMaxValue), &Z_Copy }, + { Zsingle, Cx000D, 0x0045, Z(AnalogOutMinValue), &Z_Copy }, + { Zbool, Cx000D, 0x0051, Z(AnalogOutOutOfService),&Z_Copy }, + { Zsingle, Cx000D, 0x0055, Z(AnalogOutValue), &Z_Copy }, + { Zunk, Cx000D, 0x0057, Z(AnalogOutPriorityArray),&Z_Copy }, + { Zenum8, Cx000D, 0x0067, Z(AnalogOutReliability), &Z_Copy }, + { Zsingle, Cx000D, 0x0068, Z(AnalogOutRelinquishDefault),&Z_Copy }, + { Zsingle, Cx000D, 0x006A, Z(AnalogOutResolution), &Z_Copy }, + { Zmap8, Cx000D, 0x006F, Z(AnalogOutStatusFlags), &Z_Copy }, + { Zenum16, Cx000D, 0x0075, Z(AnalogOutEngineeringUnits),&Z_Copy }, + { Zuint32, Cx000D, 0x0100, Z(AnalogOutApplicationType),&Z_Copy }, + // Analog Value cluster - { 0x000E, 0x001C, Z(AnalogDescription), &Z_Copy }, - { 0x000E, 0x0051, Z(AnalogOutOfService), &Z_Copy }, - { 0x000E, 0x0055, Z(AnalogValue), &Z_Copy }, - { 0x000E, 0x0057, Z(AnalogPriorityArray), &Z_Copy }, - { 0x000E, 0x0067, Z(AnalogReliability), &Z_Copy }, - { 0x000E, 0x0068, Z(AnalogRelinquishDefault),&Z_Copy }, - { 0x000E, 0x006F, Z(AnalogStatusFlags), &Z_Copy }, - { 0x000E, 0x0075, Z(AnalogEngineeringUnits),&Z_Copy }, - { 0x000E, 0x0100, Z(AnalogApplicationType),&Z_Copy }, + { Zstring, Cx000E, 0x001C, Z(AnalogDescription), &Z_Copy }, + { Zbool, Cx000E, 0x0051, Z(AnalogOutOfService), &Z_Copy }, + { Zsingle, Cx000E, 0x0055, Z(AnalogValue), &Z_Copy }, + { Zunk, Cx000E, 0x0057, Z(AnalogPriorityArray), &Z_Copy }, + { Zenum8, Cx000E, 0x0067, Z(AnalogReliability), &Z_Copy }, + { Zsingle, Cx000E, 0x0068, Z(AnalogRelinquishDefault),&Z_Copy }, + { Zmap8, Cx000E, 0x006F, Z(AnalogStatusFlags), &Z_Copy }, + { Zenum16, Cx000E, 0x0075, Z(AnalogEngineeringUnits),&Z_Copy }, + { Zuint32, Cx000E, 0x0100, Z(AnalogApplicationType),&Z_Copy }, + // Binary Input cluster - { 0x000F, 0x0004, Z(BinaryInActiveText), &Z_Copy }, - { 0x000F, 0x001C, Z(BinaryInDescription), &Z_Copy }, - { 0x000F, 0x002E, Z(BinaryInInactiveText),&Z_Copy }, - { 0x000F, 0x0051, Z(BinaryInOutOfService),&Z_Copy }, - { 0x000F, 0x0054, Z(BinaryInPolarity), &Z_Copy }, - { 0x000F, 0x0055, Z(BinaryInValue), &Z_Copy }, - { 0x000F, 0x0057, Z(BinaryInPriorityArray),&Z_Copy }, - { 0x000F, 0x0067, Z(BinaryInReliability), &Z_Copy }, - { 0x000F, 0x006F, Z(BinaryInStatusFlags), &Z_Copy }, - { 0x000F, 0x0100, Z(BinaryInApplicationType),&Z_Copy }, + { Zstring, Cx000F, 0x0004, Z(BinaryInActiveText), &Z_Copy }, + { Zstring, Cx000F, 0x001C, Z(BinaryInDescription), &Z_Copy }, + { Zstring, Cx000F, 0x002E, Z(BinaryInInactiveText),&Z_Copy }, + { Zbool, Cx000F, 0x0051, Z(BinaryInOutOfService),&Z_Copy }, + { Zenum8, Cx000F, 0x0054, Z(BinaryInPolarity), &Z_Copy }, + { Zstring, Cx000F, 0x0055, Z(BinaryInValue), &Z_Copy }, + // { 0xFF, Cx000F, 0x0057, Z(BinaryInPriorityArray),&Z_Copy }, + { Zenum8, Cx000F, 0x0067, Z(BinaryInReliability), &Z_Copy }, + { Zmap8, Cx000F, 0x006F, Z(BinaryInStatusFlags), &Z_Copy }, + { Zuint32, Cx000F, 0x0100, Z(BinaryInApplicationType),&Z_Copy }, + // Binary Output cluster - { 0x0010, 0x0004, Z(BinaryOutActiveText), &Z_Copy }, - { 0x0010, 0x001C, Z(BinaryOutDescription), &Z_Copy }, - { 0x0010, 0x002E, Z(BinaryOutInactiveText),&Z_Copy }, - { 0x0010, 0x0042, Z(BinaryOutMinimumOffTime),&Z_Copy }, - { 0x0010, 0x0043, Z(BinaryOutMinimumOnTime),&Z_Copy }, - { 0x0010, 0x0051, Z(BinaryOutOutOfService),&Z_Copy }, - { 0x0010, 0x0054, Z(BinaryOutPolarity), &Z_Copy }, - { 0x0010, 0x0055, Z(BinaryOutValue), &Z_Copy }, - { 0x0010, 0x0057, Z(BinaryOutPriorityArray),&Z_Copy }, - { 0x0010, 0x0067, Z(BinaryOutReliability), &Z_Copy }, - { 0x0010, 0x0068, Z(BinaryOutRelinquishDefault),&Z_Copy }, - { 0x0010, 0x006F, Z(BinaryOutStatusFlags), &Z_Copy }, - { 0x0010, 0x0100, Z(BinaryOutApplicationType),&Z_Copy }, + { Zstring, Cx0010, 0x0004, Z(BinaryOutActiveText), &Z_Copy }, + { Zstring, Cx0010, 0x001C, Z(BinaryOutDescription), &Z_Copy }, + { Zstring, Cx0010, 0x002E, Z(BinaryOutInactiveText),&Z_Copy }, + { Zuint32, Cx0010, 0x0042, Z(BinaryOutMinimumOffTime),&Z_Copy }, + { Zuint32, Cx0010, 0x0043, Z(BinaryOutMinimumOnTime),&Z_Copy }, + { Zbool, Cx0010, 0x0051, Z(BinaryOutOutOfService),&Z_Copy }, + { Zenum8, Cx0010, 0x0054, Z(BinaryOutPolarity), &Z_Copy }, + { Zbool, Cx0010, 0x0055, Z(BinaryOutValue), &Z_Copy }, + { Zunk, Cx0010, 0x0057, Z(BinaryOutPriorityArray),&Z_Copy }, + { Zenum8, Cx0010, 0x0067, Z(BinaryOutReliability), &Z_Copy }, + { Zbool, Cx0010, 0x0068, Z(BinaryOutRelinquishDefault),&Z_Copy }, + { Zmap8, Cx0010, 0x006F, Z(BinaryOutStatusFlags), &Z_Copy }, + { Zuint32, Cx0010, 0x0100, Z(BinaryOutApplicationType),&Z_Copy }, + // Binary Value cluster - { 0x0011, 0x0004, Z(BinaryActiveText), &Z_Copy }, - { 0x0011, 0x001C, Z(BinaryDescription), &Z_Copy }, - { 0x0011, 0x002E, Z(BinaryInactiveText), &Z_Copy }, - { 0x0011, 0x0042, Z(BinaryMinimumOffTime), &Z_Copy }, - { 0x0011, 0x0043, Z(BinaryMinimumOnTime), &Z_Copy }, - { 0x0011, 0x0051, Z(BinaryOutOfService), &Z_Copy }, - { 0x0011, 0x0055, Z(BinaryValue), &Z_Copy }, - { 0x0011, 0x0057, Z(BinaryPriorityArray), &Z_Copy }, - { 0x0011, 0x0067, Z(BinaryReliability), &Z_Copy }, - { 0x0011, 0x0068, Z(BinaryRelinquishDefault),&Z_Copy }, - { 0x0011, 0x006F, Z(BinaryStatusFlags), &Z_Copy }, - { 0x0011, 0x0100, Z(BinaryApplicationType),&Z_Copy }, + { Zstring, Cx0011, 0x0004, Z(BinaryActiveText), &Z_Copy }, + { Zstring, Cx0011, 0x001C, Z(BinaryDescription), &Z_Copy }, + { Zstring, Cx0011, 0x002E, Z(BinaryInactiveText), &Z_Copy }, + { Zuint32, Cx0011, 0x0042, Z(BinaryMinimumOffTime), &Z_Copy }, + { Zuint32, Cx0011, 0x0043, Z(BinaryMinimumOnTime), &Z_Copy }, + { Zbool, Cx0011, 0x0051, Z(BinaryOutOfService), &Z_Copy }, + { Zbool, Cx0011, 0x0055, Z(BinaryValue), &Z_Copy }, + { Zunk, Cx0011, 0x0057, Z(BinaryPriorityArray), &Z_Copy }, + { Zenum8, Cx0011, 0x0067, Z(BinaryReliability), &Z_Copy }, + { Zbool, Cx0011, 0x0068, Z(BinaryRelinquishDefault),&Z_Copy }, + { Zmap8, Cx0011, 0x006F, Z(BinaryStatusFlags), &Z_Copy }, + { Zuint32, Cx0011, 0x0100, Z(BinaryApplicationType),&Z_Copy }, + // Multistate Input cluster - { 0x0012, 0x000E, Z(MultiInStateText), &Z_Copy }, - { 0x0012, 0x001C, Z(MultiInDescription), &Z_Copy }, - { 0x0012, 0x004A, Z(MultiInNumberOfStates),&Z_Copy }, - { 0x0012, 0x0051, Z(MultiInOutOfService), &Z_Copy }, - { 0x0012, 0x0055, Z(MultiInValue), &Z_AqaraCube }, - { 0x0012, 0x0067, Z(MultiInReliability), &Z_Copy }, - { 0x0012, 0x006F, Z(MultiInStatusFlags), &Z_Copy }, - { 0x0012, 0x0100, Z(MultiInApplicationType),&Z_Copy }, + { Zunk, Cx0012, 0x000E, Z(MultiInStateText), &Z_Copy }, + { Zstring, Cx0012, 0x001C, Z(MultiInDescription), &Z_Copy }, + { Zuint16, Cx0012, 0x004A, Z(MultiInNumberOfStates),&Z_Copy }, + { Zbool, Cx0012, 0x0051, Z(MultiInOutOfService), &Z_Copy }, + { Zuint16, Cx0012, 0x0055, Z(MultiInValue), &Z_AqaraCube }, + { Zenum8, Cx0012, 0x0067, Z(MultiInReliability), &Z_Copy }, + { Zmap8, Cx0012, 0x006F, Z(MultiInStatusFlags), &Z_Copy }, + { Zuint32, Cx0012, 0x0100, Z(MultiInApplicationType),&Z_Copy }, + // Multistate output - { 0x0013, 0x000E, Z(MultiOutStateText), &Z_Copy }, - { 0x0013, 0x001C, Z(MultiOutDescription), &Z_Copy }, - { 0x0013, 0x004A, Z(MultiOutNumberOfStates),&Z_Copy }, - { 0x0013, 0x0051, Z(MultiOutOutOfService), &Z_Copy }, - { 0x0013, 0x0055, Z(MultiOutValue), &Z_Copy }, - { 0x0013, 0x0057, Z(MultiOutPriorityArray),&Z_Copy }, - { 0x0013, 0x0067, Z(MultiOutReliability), &Z_Copy }, - { 0x0013, 0x0068, Z(MultiOutRelinquishDefault),&Z_Copy }, - { 0x0013, 0x006F, Z(MultiOutStatusFlags), &Z_Copy }, - { 0x0013, 0x0100, Z(MultiOutApplicationType),&Z_Copy }, + { Zunk, Cx0013, 0x000E, Z(MultiOutStateText), &Z_Copy }, + { Zstring, Cx0013, 0x001C, Z(MultiOutDescription), &Z_Copy }, + { Zuint16, Cx0013, 0x004A, Z(MultiOutNumberOfStates),&Z_Copy }, + { Zbool, Cx0013, 0x0051, Z(MultiOutOutOfService), &Z_Copy }, + { Zuint16, Cx0013, 0x0055, Z(MultiOutValue), &Z_Copy }, + // { Zunk, Cx0013, 0x0057, Z(MultiOutPriorityArray),&Z_Copy }, + { Zenum8, Cx0013, 0x0067, Z(MultiOutReliability), &Z_Copy }, + { Zuint16, Cx0013, 0x0068, Z(MultiOutRelinquishDefault),&Z_Copy }, + { Zmap8, Cx0013, 0x006F, Z(MultiOutStatusFlags), &Z_Copy }, + { Zuint32, Cx0013, 0x0100, Z(MultiOutApplicationType),&Z_Copy }, + // Multistate Value cluster - { 0x0014, 0x000E, Z(MultiStateText), &Z_Copy }, - { 0x0014, 0x001C, Z(MultiDescription), &Z_Copy }, - { 0x0014, 0x004A, Z(MultiNumberOfStates), &Z_Copy }, - { 0x0014, 0x0051, Z(MultiOutOfService), &Z_Copy }, - { 0x0014, 0x0055, Z(MultiValue), &Z_Copy }, - { 0x0014, 0x0067, Z(MultiReliability), &Z_Copy }, - { 0x0014, 0x0068, Z(MultiRelinquishDefault),&Z_Copy }, - { 0x0014, 0x006F, Z(MultiStatusFlags), &Z_Copy }, - { 0x0014, 0x0100, Z(MultiApplicationType), &Z_Copy }, + { Zunk, Cx0014, 0x000E, Z(MultiStateText), &Z_Copy }, + { Zstring, Cx0014, 0x001C, Z(MultiDescription), &Z_Copy }, + { Zuint16, Cx0014, 0x004A, Z(MultiNumberOfStates), &Z_Copy }, + { Zbool, Cx0014, 0x0051, Z(MultiOutOfService), &Z_Copy }, + { Zuint16, Cx0014, 0x0055, Z(MultiValue), &Z_Copy }, + { Zenum8, Cx0014, 0x0067, Z(MultiReliability), &Z_Copy }, + { Zuint16, Cx0014, 0x0068, Z(MultiRelinquishDefault),&Z_Copy }, + { Zmap8, Cx0014, 0x006F, Z(MultiStatusFlags), &Z_Copy }, + { Zuint32, Cx0014, 0x0100, Z(MultiApplicationType), &Z_Copy }, + // Power Profile cluster - { 0x001A, 0x0000, Z(TotalProfileNum), &Z_Copy }, - { 0x001A, 0x0001, Z(MultipleScheduling), &Z_Copy }, - { 0x001A, 0x0002, Z(EnergyFormatting), &Z_Copy }, - { 0x001A, 0x0003, Z(EnergyRemote), &Z_Copy }, - { 0x001A, 0x0004, Z(ScheduleMode), &Z_Copy }, + { Zuint8, Cx001A, 0x0000, Z(TotalProfileNum), &Z_Copy }, + { Zbool, Cx001A, 0x0001, Z(MultipleScheduling), &Z_Copy }, + { Zmap8, Cx001A, 0x0002, Z(EnergyFormatting), &Z_Copy }, + { Zbool, Cx001A, 0x0003, Z(EnergyRemote), &Z_Copy }, + { Zmap8, Cx001A, 0x0004, Z(ScheduleMode), &Z_Copy }, + // Poll Control cluster - { 0x0020, 0x0000, Z(CheckinInterval), &Z_Copy }, - { 0x0020, 0x0001, Z(LongPollInterval), &Z_Copy }, - { 0x0020, 0x0002, Z(ShortPollInterval), &Z_Copy }, - { 0x0020, 0x0003, Z(FastPollTimeout), &Z_Copy }, - { 0x0020, 0x0004, Z(CheckinIntervalMin), &Z_Copy }, - { 0x0020, 0x0005, Z(LongPollIntervalMin), &Z_Copy }, - { 0x0020, 0x0006, Z(FastPollTimeoutMax), &Z_Copy }, + { Zuint32, Cx0020, 0x0000, Z(CheckinInterval), &Z_Copy }, + { Zuint32, Cx0020, 0x0001, Z(LongPollInterval), &Z_Copy }, + { Zuint16, Cx0020, 0x0002, Z(ShortPollInterval), &Z_Copy }, + { Zuint16, Cx0020, 0x0003, Z(FastPollTimeout), &Z_Copy }, + { Zuint32, Cx0020, 0x0004, Z(CheckinIntervalMin), &Z_Copy }, + { Zuint32, Cx0020, 0x0005, Z(LongPollIntervalMin), &Z_Copy }, + { Zuint16, Cx0020, 0x0006, Z(FastPollTimeoutMax), &Z_Copy }, + // Shade Configuration cluster - { 0x0100, 0x0000, Z(PhysicalClosedLimit), &Z_Copy }, - { 0x0100, 0x0001, Z(MotorStepSize), &Z_Copy }, - { 0x0100, 0x0002, Z(Status), &Z_Copy }, - { 0x0100, 0x0010, Z(ClosedLimit), &Z_Copy }, - { 0x0100, 0x0011, Z(Mode), &Z_Copy }, + { Zuint16, Cx0100, 0x0000, Z(PhysicalClosedLimit), &Z_Copy }, + { Zuint8, Cx0100, 0x0001, Z(MotorStepSize), &Z_Copy }, + { Zmap8, Cx0100, 0x0002, Z(Status), &Z_Copy }, + { Zuint16, Cx0100, 0x0010, Z(ClosedLimit), &Z_Copy }, + { Zenum8, Cx0100, 0x0011, Z(Mode), &Z_Copy }, + // Door Lock cluster - { 0x0101, 0x0000, Z(LockState), &Z_Copy }, - { 0x0101, 0x0001, Z(LockType), &Z_Copy }, - { 0x0101, 0x0002, Z(ActuatorEnabled), &Z_Copy }, - { 0x0101, 0x0003, Z(DoorState), &Z_Copy }, - { 0x0101, 0x0004, Z(DoorOpenEvents), &Z_Copy }, - { 0x0101, 0x0005, Z(DoorClosedEvents), &Z_Copy }, - { 0x0101, 0x0006, Z(OpenPeriod), &Z_Copy }, + { Zenum8, Cx0101, 0x0000, Z(LockState), &Z_Copy }, + { Zenum8, Cx0101, 0x0001, Z(LockType), &Z_Copy }, + { Zbool, Cx0101, 0x0002, Z(ActuatorEnabled), &Z_Copy }, + { Zenum8, Cx0101, 0x0003, Z(DoorState), &Z_Copy }, + { Zuint32, Cx0101, 0x0004, Z(DoorOpenEvents), &Z_Copy }, + { Zuint32, Cx0101, 0x0005, Z(DoorClosedEvents), &Z_Copy }, + { Zuint16, Cx0101, 0x0006, Z(OpenPeriod), &Z_Copy }, + // Aqara Lumi Vibration Sensor - { 0x0101, 0x0055, Z(AqaraVibrationMode), &Z_AqaraVibration }, - { 0x0101, 0x0503, Z(AqaraVibrationsOrAngle), &Z_Copy }, - { 0x0101, 0x0505, Z(AqaraVibration505), &Z_Copy }, - { 0x0101, 0x0508, Z(AqaraAccelerometer), &Z_AqaraVibration }, + { Zunk, Cx0101, 0x0055, Z(AqaraVibrationMode), &Z_AqaraVibration }, + { Zunk, Cx0101, 0x0503, Z(AqaraVibrationsOrAngle), &Z_Copy }, + { Zunk, Cx0101, 0x0505, Z(AqaraVibration505), &Z_Copy }, + { Zunk, Cx0101, 0x0508, Z(AqaraAccelerometer), &Z_AqaraVibration }, + // Window Covering cluster - { 0x0102, 0x0000, Z(WindowCoveringType), &Z_Copy }, - { 0x0102, 0x0001, Z(PhysicalClosedLimitLift),&Z_Copy }, - { 0x0102, 0x0002, Z(PhysicalClosedLimitTilt),&Z_Copy }, - { 0x0102, 0x0003, Z(CurrentPositionLift), &Z_Copy }, - { 0x0102, 0x0004, Z(CurrentPositionTilt), &Z_Copy }, - { 0x0102, 0x0005, Z(NumberofActuationsLift),&Z_Copy }, - { 0x0102, 0x0006, Z(NumberofActuationsTilt),&Z_Copy }, - { 0x0102, 0x0007, Z(ConfigStatus), &Z_Copy }, - { 0x0102, 0x0008, Z(CurrentPositionLiftPercentage),&Z_Copy }, - { 0x0102, 0x0009, Z(CurrentPositionTiltPercentage),&Z_Copy }, - { 0x0102, 0x0010, Z(InstalledOpenLimitLift),&Z_Copy }, - { 0x0102, 0x0011, Z(InstalledClosedLimitLift),&Z_Copy }, - { 0x0102, 0x0012, Z(InstalledOpenLimitTilt),&Z_Copy }, - { 0x0102, 0x0013, Z(InstalledClosedLimitTilt),&Z_Copy }, - { 0x0102, 0x0014, Z(VelocityLift), &Z_Copy }, - { 0x0102, 0x0015, Z(AccelerationTimeLift),&Z_Copy }, - { 0x0102, 0x0016, Z(DecelerationTimeLift), &Z_Copy }, - { 0x0102, 0x0017, Z(Mode), &Z_Copy }, - { 0x0102, 0x0018, Z(IntermediateSetpointsLift),&Z_Copy }, - { 0x0102, 0x0019, Z(IntermediateSetpointsTilt),&Z_Copy }, + { Zenum8, Cx0102, 0x0000, Z(WindowCoveringType), &Z_Copy }, + { Zuint16, Cx0102, 0x0001, Z(PhysicalClosedLimitLift),&Z_Copy }, + { Zuint16, Cx0102, 0x0002, Z(PhysicalClosedLimitTilt),&Z_Copy }, + { Zuint16, Cx0102, 0x0003, Z(CurrentPositionLift), &Z_Copy }, + { Zuint16, Cx0102, 0x0004, Z(CurrentPositionTilt), &Z_Copy }, + { Zuint16, Cx0102, 0x0005, Z(NumberofActuationsLift),&Z_Copy }, + { Zuint16, Cx0102, 0x0006, Z(NumberofActuationsTilt),&Z_Copy }, + { Zmap8, Cx0102, 0x0007, Z(ConfigStatus), &Z_Copy }, + { Zuint8, Cx0102, 0x0008, Z(CurrentPositionLiftPercentage),&Z_Copy }, + { Zuint8, Cx0102, 0x0009, Z(CurrentPositionTiltPercentage),&Z_Copy }, + { Zuint16, Cx0102, 0x0010, Z(InstalledOpenLimitLift),&Z_Copy }, + { Zuint16, Cx0102, 0x0011, Z(InstalledClosedLimitLift),&Z_Copy }, + { Zuint16, Cx0102, 0x0012, Z(InstalledOpenLimitTilt),&Z_Copy }, + { Zuint16, Cx0102, 0x0013, Z(InstalledClosedLimitTilt),&Z_Copy }, + { Zuint16, Cx0102, 0x0014, Z(VelocityLift), &Z_Copy }, + { Zuint16, Cx0102, 0x0015, Z(AccelerationTimeLift),&Z_Copy }, + { Zuint16, Cx0102, 0x0016, Z(DecelerationTimeLift), &Z_Copy }, + { Zmap8, Cx0102, 0x0017, Z(Mode), &Z_Copy }, + { Zoctstr, Cx0102, 0x0018, Z(IntermediateSetpointsLift),&Z_Copy }, + { Zoctstr, Cx0102, 0x0019, Z(IntermediateSetpointsTilt),&Z_Copy }, // Color Control cluster - { 0x0300, 0x0000, Z(Hue), &Z_Copy }, - { 0x0300, 0x0001, Z(Sat), &Z_Copy }, - { 0x0300, 0x0002, Z(RemainingTime), &Z_Copy }, - { 0x0300, 0x0003, Z(X), &Z_Copy }, - { 0x0300, 0x0004, Z(Y), &Z_Copy }, - { 0x0300, 0x0005, Z(DriftCompensation), &Z_Copy }, - { 0x0300, 0x0006, Z(CompensationText), &Z_Copy }, - { 0x0300, 0x0007, Z(CT), &Z_Copy }, - { 0x0300, 0x0008, Z(ColorMode), &Z_Copy }, - { 0x0300, 0x0010, Z(NumberOfPrimaries), &Z_Copy }, - { 0x0300, 0x0011, Z(Primary1X), &Z_Copy }, - { 0x0300, 0x0012, Z(Primary1Y), &Z_Copy }, - { 0x0300, 0x0013, Z(Primary1Intensity), &Z_Copy }, - { 0x0300, 0x0015, Z(Primary2X), &Z_Copy }, - { 0x0300, 0x0016, Z(Primary2Y), &Z_Copy }, - { 0x0300, 0x0017, Z(Primary2Intensity), &Z_Copy }, - { 0x0300, 0x0019, Z(Primary3X), &Z_Copy }, - { 0x0300, 0x001A, Z(Primary3Y), &Z_Copy }, - { 0x0300, 0x001B, Z(Primary3Intensity), &Z_Copy }, - { 0x0300, 0x0030, Z(WhitePointX), &Z_Copy }, - { 0x0300, 0x0031, Z(WhitePointY), &Z_Copy }, - { 0x0300, 0x0032, Z(ColorPointRX), &Z_Copy }, - { 0x0300, 0x0033, Z(ColorPointRY), &Z_Copy }, - { 0x0300, 0x0034, Z(ColorPointRIntensity), &Z_Copy }, - { 0x0300, 0x0036, Z(ColorPointGX), &Z_Copy }, - { 0x0300, 0x0037, Z(ColorPointGY), &Z_Copy }, - { 0x0300, 0x0038, Z(ColorPointGIntensity), &Z_Copy }, - { 0x0300, 0x003A, Z(ColorPointBX), &Z_Copy }, - { 0x0300, 0x003B, Z(ColorPointBY), &Z_Copy }, - { 0x0300, 0x003C, Z(ColorPointBIntensity), &Z_Copy }, + { Zuint8, Cx0300, 0x0000, Z(Hue), &Z_Copy }, + { Zuint8, Cx0300, 0x0001, Z(Sat), &Z_Copy }, + { Zuint16, Cx0300, 0x0002, Z(RemainingTime), &Z_Copy }, + { Zuint16, Cx0300, 0x0003, Z(X), &Z_Copy }, + { Zuint16, Cx0300, 0x0004, Z(Y), &Z_Copy }, + { Zenum8, Cx0300, 0x0005, Z(DriftCompensation), &Z_Copy }, + { Zstring, Cx0300, 0x0006, Z(CompensationText), &Z_Copy }, + { Zuint16, Cx0300, 0x0007, Z(CT), &Z_Copy }, + { Zenum8, Cx0300, 0x0008, Z(ColorMode), &Z_Copy }, + { Zuint8, Cx0300, 0x0010, Z(NumberOfPrimaries), &Z_Copy }, + { Zuint16, Cx0300, 0x0011, Z(Primary1X), &Z_Copy }, + { Zuint16, Cx0300, 0x0012, Z(Primary1Y), &Z_Copy }, + { Zuint8, Cx0300, 0x0013, Z(Primary1Intensity), &Z_Copy }, + { Zuint16, Cx0300, 0x0015, Z(Primary2X), &Z_Copy }, + { Zuint16, Cx0300, 0x0016, Z(Primary2Y), &Z_Copy }, + { Zuint8, Cx0300, 0x0017, Z(Primary2Intensity), &Z_Copy }, + { Zuint16, Cx0300, 0x0019, Z(Primary3X), &Z_Copy }, + { Zuint16, Cx0300, 0x001A, Z(Primary3Y), &Z_Copy }, + { Zuint8, Cx0300, 0x001B, Z(Primary3Intensity), &Z_Copy }, + { Zuint16, Cx0300, 0x0030, Z(WhitePointX), &Z_Copy }, + { Zuint16, Cx0300, 0x0031, Z(WhitePointY), &Z_Copy }, + { Zuint16, Cx0300, 0x0032, Z(ColorPointRX), &Z_Copy }, + { Zuint16, Cx0300, 0x0033, Z(ColorPointRY), &Z_Copy }, + { Zuint8, Cx0300, 0x0034, Z(ColorPointRIntensity), &Z_Copy }, + { Zuint16, Cx0300, 0x0036, Z(ColorPointGX), &Z_Copy }, + { Zuint16, Cx0300, 0x0037, Z(ColorPointGY), &Z_Copy }, + { Zuint8, Cx0300, 0x0038, Z(ColorPointGIntensity), &Z_Copy }, + { Zuint16, Cx0300, 0x003A, Z(ColorPointBX), &Z_Copy }, + { Zuint16, Cx0300, 0x003B, Z(ColorPointBY), &Z_Copy }, + { Zuint8, Cx0300, 0x003C, Z(ColorPointBIntensity), &Z_Copy }, // Illuminance Measurement cluster - { 0x0400, 0x0000, Z(Illuminance), &Z_Copy }, // Illuminance (in Lux) - { 0x0400, 0x0001, Z(IlluminanceMinMeasuredValue), &Z_Copy }, // - { 0x0400, 0x0002, Z(IlluminanceMaxMeasuredValue), &Z_Copy }, // - { 0x0400, 0x0003, Z(IlluminanceTolerance), &Z_Copy }, // - { 0x0400, 0x0004, Z(IlluminanceLightSensorType), &Z_Copy }, // - { 0x0400, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0400, 0x0000, Z(Illuminance), &Z_Copy }, // Illuminance (in Lux) + { Zuint16, Cx0400, 0x0001, Z(IlluminanceMinMeasuredValue), &Z_Copy }, // + { Zuint16, Cx0400, 0x0002, Z(IlluminanceMaxMeasuredValue), &Z_Copy }, // + { Zuint16, Cx0400, 0x0003, Z(IlluminanceTolerance), &Z_Copy }, // + { Zenum8, Cx0400, 0x0004, Z(IlluminanceLightSensorType), &Z_Copy }, // + { Zunk, Cx0400, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Illuminance Level Sensing cluster - { 0x0401, 0x0000, Z(IlluminanceLevelStatus), &Z_Copy }, // Illuminance (in Lux) - { 0x0401, 0x0001, Z(IlluminanceLightSensorType), &Z_Copy }, // LightSensorType - { 0x0401, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zenum8, Cx0401, 0x0000, Z(IlluminanceLevelStatus), &Z_Copy }, // Illuminance (in Lux) + { Zenum8, Cx0401, 0x0001, Z(IlluminanceLightSensorType), &Z_Copy }, // LightSensorType + { Zuint16, Cx0401, 0x0010, Z(IlluminanceTargetLevel), &Z_Copy }, // + { Zunk, Cx0401, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Temperature Measurement cluster - { 0x0402, 0x0000, Z(Temperature), &Z_FloatDiv100 }, // Temperature - { 0x0402, 0x0001, Z(TemperatureMinMeasuredValue), &Z_FloatDiv100 }, // - { 0x0402, 0x0002, Z(TemperatureMaxMeasuredValue), &Z_FloatDiv100 }, // - { 0x0402, 0x0003, Z(TemperatureTolerance), &Z_FloatDiv100 }, // - { 0x0402, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zint16, Cx0402, 0x0000, Z(Temperature), &Z_FloatDiv100 }, // Temperature + { Zint16, Cx0402, 0x0001, Z(TemperatureMinMeasuredValue), &Z_FloatDiv100 }, // + { Zint16, Cx0402, 0x0002, Z(TemperatureMaxMeasuredValue), &Z_FloatDiv100 }, // + { Zuint16, Cx0402, 0x0003, Z(TemperatureTolerance), &Z_FloatDiv100 }, // + { Zunk, Cx0402, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Pressure Measurement cluster - { 0x0403, 0x0000, Z(PressureUnit), &Z_AddPressureUnit }, // Pressure Unit - { 0x0403, 0x0000, Z(Pressure), &Z_Copy }, // Pressure - { 0x0403, 0x0001, Z(PressureMinMeasuredValue), &Z_Copy }, // - { 0x0403, 0x0002, Z(PressureMaxMeasuredValue), &Z_Copy }, // - { 0x0403, 0x0003, Z(PressureTolerance), &Z_Copy }, // - { 0x0403, 0x0010, Z(PressureScaledValue), &Z_Copy }, // - { 0x0403, 0x0011, Z(PressureMinScaledValue), &Z_Copy }, // - { 0x0403, 0x0012, Z(PressureMaxScaledValue), &Z_Copy }, // - { 0x0403, 0x0013, Z(PressureScaledTolerance), &Z_Copy }, // - { 0x0403, 0x0014, Z(PressureScale), &Z_Copy }, // - { 0x0403, 0xFFFF, nullptr, &Z_Remove }, // Remove all other Pressure values + { Zunk, Cx0403, 0x0000, Z(PressureUnit), &Z_AddPressureUnit }, // Pressure Unit + { Zint16, Cx0403, 0x0000, Z(Pressure), &Z_Copy }, // Pressure + { Zint16, Cx0403, 0x0001, Z(PressureMinMeasuredValue), &Z_Copy }, // + { Zint16, Cx0403, 0x0002, Z(PressureMaxMeasuredValue), &Z_Copy }, // + { Zuint16, Cx0403, 0x0003, Z(PressureTolerance), &Z_Copy }, // + { Zint16, Cx0403, 0x0010, Z(PressureScaledValue), &Z_Copy }, // + { Zint16, Cx0403, 0x0011, Z(PressureMinScaledValue), &Z_Copy }, // + { Zint16, Cx0403, 0x0012, Z(PressureMaxScaledValue), &Z_Copy }, // + { Zuint16, Cx0403, 0x0013, Z(PressureScaledTolerance), &Z_Copy }, // + { Zint8, Cx0403, 0x0014, Z(PressureScale), &Z_Copy }, // + { Zunk, Cx0403, 0xFFFF, nullptr, &Z_Remove }, // Remove all other Pressure values // Flow Measurement cluster - { 0x0404, 0x0000, Z(FlowRate), &Z_FloatDiv10 }, // Flow (in m3/h) - { 0x0404, 0x0001, Z(FlowMinMeasuredValue), &Z_Copy }, // - { 0x0404, 0x0002, Z(FlowMaxMeasuredValue), &Z_Copy }, // - { 0x0404, 0x0003, Z(FlowTolerance), &Z_Copy }, // - { 0x0404, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0404, 0x0000, Z(FlowRate), &Z_FloatDiv10 }, // Flow (in m3/h) + { Zuint16, Cx0404, 0x0001, Z(FlowMinMeasuredValue), &Z_Copy }, // + { Zuint16, Cx0404, 0x0002, Z(FlowMaxMeasuredValue), &Z_Copy }, // + { Zuint16, Cx0404, 0x0003, Z(FlowTolerance), &Z_Copy }, // + { Zunk, Cx0404, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Relative Humidity Measurement cluster - { 0x0405, 0x0000, Z(Humidity), &Z_FloatDiv100 }, // Humidity - { 0x0405, 0x0001, Z(HumidityMinMeasuredValue), &Z_Copy }, // - { 0x0405, 0x0002, Z(HumidityMaxMeasuredValue), &Z_Copy }, // - { 0x0405, 0x0003, "HumidityTolerance", &Z_Copy }, // - { 0x0405, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0405, 0x0000, Z(Humidity), &Z_FloatDiv100 }, // Humidity + { Zuint16, Cx0405, 0x0001, Z(HumidityMinMeasuredValue), &Z_Copy }, // + { Zuint16, Cx0405, 0x0002, Z(HumidityMaxMeasuredValue), &Z_Copy }, // + { Zuint16, Cx0405, 0x0003, Z(HumidityTolerance), &Z_Copy }, // + { Zunk, Cx0405, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Occupancy Sensing cluster - { 0x0406, 0x0000, Z(Occupancy), &Z_Copy }, // Occupancy (map8) - { 0x0406, 0x0001, Z(OccupancySensorType), &Z_Copy }, // OccupancySensorType - { 0x0406, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zmap8, Cx0406, 0x0000, Z(Occupancy), &Z_Copy }, // Occupancy (map8) + { Zenum8, Cx0406, 0x0001, Z(OccupancySensorType), &Z_Copy }, // OccupancySensorType + { Zunk, Cx0406, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Meter Identification cluster - { 0x0B01, 0x0000, Z(CompanyName), &Z_Copy }, - { 0x0B01, 0x0001, Z(MeterTypeID), &Z_Copy }, - { 0x0B01, 0x0004, Z(DataQualityID), &Z_Copy }, - { 0x0B01, 0x0005, Z(CustomerName), &Z_Copy }, - { 0x0B01, 0x0006, Z(Model), &Z_Copy }, - { 0x0B01, 0x0007, Z(PartNumber), &Z_Copy }, - { 0x0B01, 0x000A, Z(SoftwareRevision), &Z_Copy }, - { 0x0B01, 0x000C, Z(POD), &Z_Copy }, - { 0x0B01, 0x000D, Z(AvailablePower), &Z_Copy }, - { 0x0B01, 0x000E, Z(PowerThreshold), &Z_Copy }, + { Zstring, Cx0B01, 0x0000, Z(CompanyName), &Z_Copy }, + { Zuint16, Cx0B01, 0x0001, Z(MeterTypeID), &Z_Copy }, + { Zuint16, Cx0B01, 0x0004, Z(DataQualityID), &Z_Copy }, + { Zstring, Cx0B01, 0x0005, Z(CustomerName), &Z_Copy }, + { Zoctstr, Cx0B01, 0x0006, Z(Model), &Z_Copy }, + { Zoctstr, Cx0B01, 0x0007, Z(PartNumber), &Z_Copy }, + { Zoctstr, Cx0B01, 0x0008, Z(ProductRevision), &Z_Copy }, + { Zoctstr, Cx0B01, 0x000A, Z(SoftwareRevision), &Z_Copy }, + { Zstring, Cx0B01, 0x000B, Z(UtilityName), &Z_Copy }, + { Zstring, Cx0B01, 0x000C, Z(POD), &Z_Copy }, + { Zint24, Cx0B01, 0x000D, Z(AvailablePower), &Z_Copy }, + { Zint24, Cx0B01, 0x000E, Z(PowerThreshold), &Z_Copy }, // Diagnostics cluster - { 0x0B05, 0x0000, Z(NumberOfResets), &Z_Copy }, - { 0x0B05, 0x0001, Z(PersistentMemoryWrites),&Z_Copy }, - { 0x0B05, 0x011C, Z(LastMessageLQI), &Z_Copy }, - { 0x0B05, 0x011D, Z(LastMessageRSSI), &Z_Copy }, + { Zuint16, Cx0B05, 0x0000, Z(NumberOfResets), &Z_Copy }, + { Zuint16, Cx0B05, 0x0001, Z(PersistentMemoryWrites),&Z_Copy }, + { Zuint8, Cx0B05, 0x011C, Z(LastMessageLQI), &Z_Copy }, + { Zuint8, Cx0B05, 0x011D, Z(LastMessageRSSI), &Z_Copy }, }; @@ -1245,7 +1325,7 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { // Iterate on filter for (uint32_t i = 0; i < sizeof(Z_PostProcess) / sizeof(Z_PostProcess[0]); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; - uint16_t conv_cluster = pgm_read_word(&converter->cluster); + uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint16_t conv_attribute = pgm_read_word(&converter->attribute); if ((conv_cluster == cluster) && From 85d04dbc53f9e52f3e87b4b0073c55693a64749a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Apr 2020 19:44:13 +0200 Subject: [PATCH 15/34] Fix minor errors --- platformio_override_sample.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 11c0d7ee0..8fdb61495 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -54,7 +54,7 @@ build_flags = ${core_active.build_flags} upload_port = COM5 extra_scripts = ${scripts_defaults.extra_scripts} - pio/obj-dump.py +; pio/obj-dump.py ; *** Upload file to OTA server using SCP ;upload_port = user@host:/path @@ -240,7 +240,7 @@ upload_resetmethod = ${common.upload_resetmethod} upload_speed = 921600 extra_scripts = ${common.extra_scripts} -build_flags = +build_flags = ${esp_defaults.build_flags} -D BUFFER_LENGTH=128 -D MQTT_MAX_PACKET_SIZE=1200 -D uint32=uint32_t From 8035590e95270e4536b40bc0927ef147ecff9295 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Apr 2020 19:46:26 +0200 Subject: [PATCH 16/34] Defaults for ESP82xx and ESP32 --- platformio.ini | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/platformio.ini b/platformio.ini index 6a3820d02..f29d5f363 100755 --- a/platformio.ini +++ b/platformio.ini @@ -87,17 +87,21 @@ extra_scripts = pio/strip-floats.py pio/name-firmware.py pio/gzip-firmware.py -[esp82xx_defaults] -build_flags = -D NDEBUG - -mtarget-align - -Wl,-Map,firmware.map - -DFP_IN_IROM -; new mechanism to set the IRremoteESP8266 supported protocols: none except HASH, NEC, RC5, RC6 - -D_IR_ENABLE_DEFAULT_=false +[esp_defaults] +build_flags = -D_IR_ENABLE_DEFAULT_=false -DDECODE_HASH=true -DDECODE_NEC=true -DSEND_NEC=true -DDECODE_RC5=true -DSEND_RC5=true -DDECODE_RC6=true -DSEND_RC6=true +; new mechanism to set the IRremoteESP8266 supported protocols: none except HASH, NEC, RC5, RC6 -[irremoteesp8266_full] +[esp82xx_defaults] +build_flags = ${esp_defaults.build_flags} + -Wl,-Map,firmware.map + -D NDEBUG + -mtarget-align + -DFP_IN_IROM + + +[irremoteesp_full] build_flags = -DUSE_IR_REMOTE_FULL -U_IR_ENABLE_DEFAULT_ -DDECODE_PRONTO=false -DSEND_PRONTO=false From bfead88b7dd302c31489233da20fb5bd423eabdd Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Apr 2020 19:48:01 +0200 Subject: [PATCH 17/34] irremote full for esp8266 and esp32 --- platformio_tasmota_env32.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 4f6661c17..71bef8558 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -129,7 +129,7 @@ extra_scripts = ${common32.extra_scripts} lib_extra_dirs = ${common32.lib_extra_dirs} lib_ignore = ${common32.lib_ignore} build_unflags = ${common32.build_unflags} -build_flags = ${common32.build_flags} ${irremoteesp8266_full.build_flags} -DFIRMWARE_IR +build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR [env:tasmota32-ircustom] framework = ${common.framework} @@ -148,7 +148,7 @@ extra_scripts = ${common32.extra_scripts} lib_extra_dirs = ${common32.lib_extra_dirs} lib_ignore = ${common32.lib_ignore} build_unflags = ${common32.build_unflags} -build_flags = ${common32.build_flags} ${irremoteesp8266_full.build_flags} +build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags} [env:tasmota32-BG] framework = ${common.framework} From fa51c6147b5b1495352676c0b0482375bf463e7c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Apr 2020 19:52:57 +0200 Subject: [PATCH 18/34] Update platformio_tasmota_env.ini --- platformio_tasmota_env.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini index a09f01ecd..f122eae1b 100644 --- a/platformio_tasmota_env.ini +++ b/platformio_tasmota_env.ini @@ -32,10 +32,10 @@ build_flags = ${common.build_flags} -DFIRMWARE_SENSORS build_flags = ${common.build_flags} -DFIRMWARE_DISPLAYS [env:tasmota-ir] -build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags} -DFIRMWARE_IR +build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR [env:tasmota-ircustom] -build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags} +build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} [env:tasmota-BG] build_flags = ${common.build_flags} -DMY_LANGUAGE=bg-BG From f6863484c36b2ec6a390efeca6cead4411669708 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Apr 2020 20:54:35 +0200 Subject: [PATCH 19/34] Install only one and latest esptool ESP32 still uses as default the outdated esptool 2.6. Since esptool 2.8 is already used for ESP8266 use it for ESP32 too and prevent install of version 2.6 --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 8fdb61495..701f9c119 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -227,7 +227,7 @@ build_type = debug [common32] platform = espressif32@1.12.0 -platform_packages = +platform_packages = tool-esptoolpy@1.20800.0 board = wemos_d1_mini32 board_build.ldscript = esp32_out.ld board_build.partitions = esp32_partition_app1984k_spiffs64k.csv From 5507ad889a01886432d24d9225546075959124f6 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 17 Apr 2020 09:11:27 +0200 Subject: [PATCH 20/34] Added types for AqaraVibration sensor --- tasmota/xdrv_23_zigbee_5_converters.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 5e39771c5..e8c4e4ab0 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -905,10 +905,10 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint16, Cx0101, 0x0006, Z(OpenPeriod), &Z_Copy }, // Aqara Lumi Vibration Sensor - { Zunk, Cx0101, 0x0055, Z(AqaraVibrationMode), &Z_AqaraVibration }, - { Zunk, Cx0101, 0x0503, Z(AqaraVibrationsOrAngle), &Z_Copy }, - { Zunk, Cx0101, 0x0505, Z(AqaraVibration505), &Z_Copy }, - { Zunk, Cx0101, 0x0508, Z(AqaraAccelerometer), &Z_AqaraVibration }, + { Zuint16, Cx0101, 0x0055, Z(AqaraVibrationMode), &Z_AqaraVibration }, + { Zuint16, Cx0101, 0x0503, Z(AqaraVibrationsOrAngle), &Z_Copy }, + { Zuint32, Cx0101, 0x0505, Z(AqaraVibration505), &Z_Copy }, + { Zuint48, Cx0101, 0x0508, Z(AqaraAccelerometer), &Z_AqaraVibration }, // Window Covering cluster { Zenum8, Cx0102, 0x0000, Z(WindowCoveringType), &Z_Copy }, From e43f0e36a206ea25513a5b1c1eb914d523313f4f Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 17 Apr 2020 09:16:08 +0200 Subject: [PATCH 21/34] Removed unsupported types --- tasmota/xdrv_23_zigbee_5_converters.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index e8c4e4ab0..5cfb5c05f 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -779,7 +779,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zsingle, Cx000D, 0x0045, Z(AnalogOutMinValue), &Z_Copy }, { Zbool, Cx000D, 0x0051, Z(AnalogOutOutOfService),&Z_Copy }, { Zsingle, Cx000D, 0x0055, Z(AnalogOutValue), &Z_Copy }, - { Zunk, Cx000D, 0x0057, Z(AnalogOutPriorityArray),&Z_Copy }, + // { Zunk, Cx000D, 0x0057, Z(AnalogOutPriorityArray),&Z_Copy }, { Zenum8, Cx000D, 0x0067, Z(AnalogOutReliability), &Z_Copy }, { Zsingle, Cx000D, 0x0068, Z(AnalogOutRelinquishDefault),&Z_Copy }, { Zsingle, Cx000D, 0x006A, Z(AnalogOutResolution), &Z_Copy }, @@ -819,7 +819,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zbool, Cx0010, 0x0051, Z(BinaryOutOutOfService),&Z_Copy }, { Zenum8, Cx0010, 0x0054, Z(BinaryOutPolarity), &Z_Copy }, { Zbool, Cx0010, 0x0055, Z(BinaryOutValue), &Z_Copy }, - { Zunk, Cx0010, 0x0057, Z(BinaryOutPriorityArray),&Z_Copy }, + // { Zunk, Cx0010, 0x0057, Z(BinaryOutPriorityArray),&Z_Copy }, { Zenum8, Cx0010, 0x0067, Z(BinaryOutReliability), &Z_Copy }, { Zbool, Cx0010, 0x0068, Z(BinaryOutRelinquishDefault),&Z_Copy }, { Zmap8, Cx0010, 0x006F, Z(BinaryOutStatusFlags), &Z_Copy }, @@ -833,14 +833,14 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint32, Cx0011, 0x0043, Z(BinaryMinimumOnTime), &Z_Copy }, { Zbool, Cx0011, 0x0051, Z(BinaryOutOfService), &Z_Copy }, { Zbool, Cx0011, 0x0055, Z(BinaryValue), &Z_Copy }, - { Zunk, Cx0011, 0x0057, Z(BinaryPriorityArray), &Z_Copy }, + // { Zunk, Cx0011, 0x0057, Z(BinaryPriorityArray), &Z_Copy }, { Zenum8, Cx0011, 0x0067, Z(BinaryReliability), &Z_Copy }, { Zbool, Cx0011, 0x0068, Z(BinaryRelinquishDefault),&Z_Copy }, { Zmap8, Cx0011, 0x006F, Z(BinaryStatusFlags), &Z_Copy }, { Zuint32, Cx0011, 0x0100, Z(BinaryApplicationType),&Z_Copy }, // Multistate Input cluster - { Zunk, Cx0012, 0x000E, Z(MultiInStateText), &Z_Copy }, + // { Zunk, Cx0012, 0x000E, Z(MultiInStateText), &Z_Copy }, { Zstring, Cx0012, 0x001C, Z(MultiInDescription), &Z_Copy }, { Zuint16, Cx0012, 0x004A, Z(MultiInNumberOfStates),&Z_Copy }, { Zbool, Cx0012, 0x0051, Z(MultiInOutOfService), &Z_Copy }, @@ -862,7 +862,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint32, Cx0013, 0x0100, Z(MultiOutApplicationType),&Z_Copy }, // Multistate Value cluster - { Zunk, Cx0014, 0x000E, Z(MultiStateText), &Z_Copy }, + // { Zunk, Cx0014, 0x000E, Z(MultiStateText), &Z_Copy }, { Zstring, Cx0014, 0x001C, Z(MultiDescription), &Z_Copy }, { Zuint16, Cx0014, 0x004A, Z(MultiNumberOfStates), &Z_Copy }, { Zbool, Cx0014, 0x0051, Z(MultiOutOfService), &Z_Copy }, From 4551c5f91a01b85be6b689f02a085ca3f721e768 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 17 Apr 2020 09:22:47 +0200 Subject: [PATCH 22/34] Adding type for Aqara_FF05 --- tasmota/xdrv_23_zigbee_5_converters.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 5cfb5c05f..1e115d13f 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -771,7 +771,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zmap8, Cx000C, 0x006F, Z(AnalogInStatusFlags), &Z_Copy }, { Zenum16, Cx000C, 0x0075, Z(AnalogInEngineeringUnits),&Z_Copy }, { Zuint32, Cx000C, 0x0100, Z(AnalogInApplicationType),&Z_Copy }, - { Zunk, Cx000C, 0xFF05, Z(Aqara_FF05), &Z_Copy }, + { Zuint16, Cx000C, 0xFF05, Z(Aqara_FF05), &Z_Copy }, // Analog Output cluster { Zstring, Cx000D, 0x001C, Z(AnalogOutDescription), &Z_Copy }, @@ -850,7 +850,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint32, Cx0012, 0x0100, Z(MultiInApplicationType),&Z_Copy }, // Multistate output - { Zunk, Cx0013, 0x000E, Z(MultiOutStateText), &Z_Copy }, + // { Zunk, Cx0013, 0x000E, Z(MultiOutStateText), &Z_Copy }, { Zstring, Cx0013, 0x001C, Z(MultiOutDescription), &Z_Copy }, { Zuint16, Cx0013, 0x004A, Z(MultiOutNumberOfStates),&Z_Copy }, { Zbool, Cx0013, 0x0051, Z(MultiOutOutOfService), &Z_Copy }, From d3b2f8c489b8cbe5197fa2248abb0520d17bc2fd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Apr 2020 11:57:09 +0200 Subject: [PATCH 23/34] Add config version tag - Add config version tag - Bump version 8.2.0.4 --- RELEASENOTES.md | 2 +- tasmota/CHANGELOG.md | 4 ++++ tasmota/settings.h | 3 ++- tasmota/settings.ino | 9 +++++++++ tasmota/tasmota_version.h | 2 +- tasmota/xdrv_01_webserver.ino | 10 ++++++++++ 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 81b066e38..2fcda28f5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,7 +52,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.2.0.3 +### Version 8.2.0.4 - Change HM-10 sensor type detection and add features (#7962) - Change light scheme 2,3,4 cycle time speed from 24,48,72,... seconds to 4,6,12,24,36,48,... seconds (#8034) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index ede692fb4..273c44db5 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased (development) +### 8.2.0.4 20200417 + +- Add config version tag + ### 8.2.0.3 20200329 - Change light scheme 2,3,4 cycle time speed from 24,48,72,... seconds to 4,6,12,24,36,48,... seconds (#8034) diff --git a/tasmota/settings.h b/tasmota/settings.h index 01f0cf174..2c3a22af4 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -524,8 +524,9 @@ struct SYSCFG { uint8_t zb_channel; // F32 uint8_t zb_free_byte; // F33 uint16_t pms_wake_interval; // F34 + uint8_t config_version; // F36 - uint8_t free_f36[130]; // F36 - Decrement if adding new Setting variables just above and below + uint8_t free_f37[129]; // F37 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 53110155f..1769b676d 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1337,6 +1337,15 @@ void SettingsDelta(void) } #endif // ESP8266 + if (Settings.version < 0x08020004) { +#ifdef ESP8266 + Settings.config_version = 0; // ESP8266 (Has been 0 for long time) +#endif // ESP8266 +#ifdef ESP32 + Settings.config_version = 1; // ESP32 +#endif // ESP32 + } + Settings.version = VERSION; SettingsSave(1); } diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 3b8314f65..4014ea4d5 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08020003; +const uint32_t VERSION = 0x08020004; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 8b5806938..5660a231d 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2509,6 +2509,16 @@ void HandleUploadLoop(void) } else { valid_settings = (settings_buffer[0] == CONFIG_FILE_SIGN); } + + if (valid_settings) { +#ifdef ESP8266 + valid_settings = (0 == settings_buffer[0xF36]); // Settings.config_version +#endif // ESP8266 +#ifdef ESP32 + valid_settings = (1 == settings_buffer[0xF36]); // Settings.config_version +#endif // ESP32 + } + if (valid_settings) { SettingsDefaultSet2(); memcpy((char*)&Settings +16, settings_buffer +16, sizeof(Settings) -16); From e5a78deaa3c5c50e269d3b2984b36d7a33e49412 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Apr 2020 12:08:43 +0200 Subject: [PATCH 24/34] Fix compile warning --- tasmota/xdrv_20_hue.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index f9e21c3a3..201491d09 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -542,6 +542,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { } } else { #endif +/* switch(on) { case false : ExecuteCommandPower(device, POWER_OFF, SRC_HUE); @@ -549,6 +550,8 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { case true : ExecuteCommandPower(device, POWER_ON, SRC_HUE); break; } +*/ + ExecuteCommandPower(device, (on) ? POWER_ON : POWER_OFF, SRC_HUE); response += buf; resp = true; #ifdef USE_SHUTTER From 318cfe2681c09fa9a2b090d215a3f0dc6464a381 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 17 Apr 2020 12:27:36 +0200 Subject: [PATCH 25/34] Disarm timer for Occupancy:0 --- tasmota/xdrv_23_zigbee_2_devices.ino | 2 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 9f5ef60a9..23970042e 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -65,7 +65,7 @@ typedef int32_t (*Z_DeviceTimer)(uint16_t shortaddr, uint16_t groupaddr, uint16_ typedef enum Z_Def_Category { Z_CAT_NONE = 0, // no category, it will happen anyways Z_CAT_READ_ATTR, // Attribute reporting, either READ_ATTRIBUTE or REPORT_ATTRIBUTE, we coalesce all attributes reported if we can - Z_CAT_VIRTUAL_ATTR, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor + Z_CAT_VIRTUAL_OCCUPANCY, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor Z_CAT_REACHABILITY, // timer set to measure reachability of device, i.e. if we don't get an answer after 1s, it is marked as unreachable (for Alexa) Z_CAT_READ_0006, // Read 0x0006 cluster Z_CAT_READ_0008, // Read 0x0008 cluster diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index aa9505bd7..acccbb8fe 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -534,7 +534,9 @@ void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, co uint32_t occupancy = strToUInt(val_endpoint); if (occupancy) { - zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_ATTR, 0, &Z_OccupancyCallback); + zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback); + } else { + zigbee_devices.resetTimersForDevice(shortaddr, 0 /* groupaddr */, Z_CAT_VIRTUAL_OCCUPANCY); } } } From 39440e56c236bb274395828a1efa2cbf72abe7a7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Apr 2020 14:40:09 +0200 Subject: [PATCH 26/34] Prep ESP32 template --- tasmota/tasmota_template_ESP32.h | 68 +++++--------------------------- 1 file changed, 10 insertions(+), 58 deletions(-) diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index b2d7a5846..59820893f 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -46,34 +46,28 @@ // Supported hardware modules enum SupportedModules { WEMOS, - ESP32_CAM, MAXMODULE }; -const char kModuleNames[] PROGMEM = - "WeMos D1 ESP32|ESP32 CAM|" - ; +const char kModuleNames[] PROGMEM = "ESP32-DevKit"; // Default module settings -const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { - WEMOS, - ESP32_CAM -}; +const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS }; const mytmplt kModules[MAXMODULE] PROGMEM = { - { // "WeMos D1 ESP32", // Any ESP32 device like WeMos and NodeMCU hardware (ESP32) + { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK -// 0, //6 -// 0, //7 -// 0, //8 -// 0, //9 -// 0, //10 -// 0, //11 + //6 IO GPIO6, Flash CLK + //7 IO GPIO7, Flash D0 + //8 IO GPIO8, Flash D1 + //9 IO GPIO9, Flash D2 + //10 IO GPIO10, Flash D3 + //11 IO GPIO11, Flash CMD GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 @@ -83,49 +77,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7 GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 0, //20 - 0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN - GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE - 0, //24 - GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - 0, //28 - 0, //29 - 0, //30 - 0, //31 - GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 - GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 - GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 - GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 - GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 - 0, //37 NO PULLUP - 0, //38 NO PULLUP - GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 - }, - { //"ESP32 CAM", - GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 - GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 - GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK -// 0, //6 -// 0, //7 -// 0, //8 -// 0, //9 -// 0, //10 -// 0, //11 - GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) - GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) - GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT - GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 - GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7 - GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - 0, //20 - 0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN + GPIO_USER, //21 IO GPIO21, VSPIHD, EMAC_TX_EN GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE 0, //24 From dfa20994060538b39670a23f8a39cec94beffa21 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 17 Apr 2020 16:15:41 +0200 Subject: [PATCH 27/34] No Map file is generated for ESP32 Fix error for ESP32. Scripts checks if exists and generates only in target folder if there --- pio/name-firmware.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pio/name-firmware.py b/pio/name-firmware.py index dfb9b7f85..1490ecc5c 100644 --- a/pio/name-firmware.py +++ b/pio/name-firmware.py @@ -28,6 +28,7 @@ def bin_map_copy(source, target, env): shutil.copy(str(target[0]), bin_file) # copy firmware.map to map/.map - shutil.copy("firmware.map", map_file) + if os.path.isfile("firmware.map"): + shutil.move("firmware.map", map_file) env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_map_copy]) From 09599bb4a17d640cd0aaf5d991565783f2954693 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Apr 2020 16:17:01 +0200 Subject: [PATCH 28/34] Provide ESP32 base module support --- tasmota/support.ino | 28 +++++++-- tasmota/support_command.ino | 5 +- tasmota/tasmota_template_ESP32.h | 99 ++++++++++++++++---------------- tasmota/xdrv_01_webserver.ino | 16 ++---- 4 files changed, 81 insertions(+), 67 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 0435293e6..65605abd3 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -100,7 +100,7 @@ uint32_t ResetReason(void) REASON_EXT_SYS_RST = 6 // "External System" external system reset */ #ifdef ESP8266 - return resetInfo.reason; // Returns Tasmota reason codes + return resetInfo.reason; #else return ESP_ResetInfoReason(); #endif @@ -1131,7 +1131,11 @@ void ModuleGpios(myio *gp) if (USER_MODULE == Settings.module) { memcpy(&src, &Settings.user_template.gp, sizeof(mycfgio)); } else { +#ifdef ESP8266 memcpy_P(&src, &kModules[Settings.module].gp, sizeof(mycfgio)); +#else // ESP32 + memcpy_P(&src, &kModules.gp, sizeof(mycfgio)); +#endif // ESP8266 - ESP32 } // 11 85 00 85 85 00 00 00 15 38 85 00 00 81 @@ -1142,10 +1146,9 @@ void ModuleGpios(myio *gp) #ifdef ESP8266 if (6 == i) { j = 9; } if (8 == i) { j = 12; } -#endif // ESP8266 -#ifdef ESP32 +#else // ESP32 if (6 == i) { j = 12; } -#endif // ESP32 +#endif // ESP8266 - ESP32 dest[j] = src[i]; j++; } @@ -1158,11 +1161,24 @@ gpio_flag ModuleFlag(void) { gpio_flag flag; +#ifdef ESP8266 if (USER_MODULE == Settings.module) { flag = Settings.user_template.flag; } else { memcpy_P(&flag, &kModules[Settings.module].flag, sizeof(gpio_flag)); } +#else // ESP32 + if (USER_MODULE == Settings.module) { +/* + gpio_flag gpio_adc0; + memcpy_P(&gpio_adc0, &Settings.user_template.gp + ADC0_PIN - MIN_FLASH_PINS, sizeof(gpio_flag)); + flag = Settings.user_template.flag.data + gpio_adc0.data; +*/ + memcpy_P(&flag, &Settings.user_template.gp + ADC0_PIN - MIN_FLASH_PINS, sizeof(gpio_flag)); + } else { + memcpy_P(&flag, &kModules.gp + ADC0_PIN - MIN_FLASH_PINS, sizeof(gpio_flag)); + } +#endif // ESP8266 - ESP32 return flag; } @@ -1173,7 +1189,11 @@ void ModuleDefault(uint32_t module) Settings.user_template_base = module; char name[TOPSZ]; SettingsUpdateText(SET_TEMPLATE_NAME, GetTextIndexed(name, sizeof(name), module, kModuleNames)); +#ifdef ESP8266 memcpy_P(&Settings.user_template, &kModules[module], sizeof(mytmplt)); +#else // ESP32 + memcpy_P(&Settings.user_template, &kModules, sizeof(mytmplt)); +#endif // ESP8266 - ESP32 } void SetModuleType(void) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 0d4e12236..28eae87f1 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1117,10 +1117,9 @@ void CmndTemplate(void) #ifdef ESP8266 if (6 == i) { j = 9; } if (8 == i) { j = 12; } -#endif // ESP8266 -#ifdef ESP32 +#else // ESP32 if (6 == i) { j = 12; } -#endif // ESP32 +#endif // ESP8266 - ESP32 if (my_module.io[j] > GPIO_NONE) { Settings.user_template.gp.io[i] = my_module.io[j]; } diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 59820893f..967da9400 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -45,58 +45,61 @@ /********************************************************************************************/ // Supported hardware modules enum SupportedModules { - WEMOS, - MAXMODULE -}; + WEMOS, ESP32_CAM_AITHINKER, + MAXMODULE}; -const char kModuleNames[] PROGMEM = "ESP32-DevKit"; +const char kModuleNames[] PROGMEM = + "ESP32-DevKit|ESP32 Cam AiThinker"; // Default module settings -const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS }; +const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { + WEMOS, + ESP32_CAM_AITHINKER +}; -const mytmplt kModules[MAXMODULE] PROGMEM = { - { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) - GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 - GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 - GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK - //6 IO GPIO6, Flash CLK - //7 IO GPIO7, Flash D0 - //8 IO GPIO8, Flash D1 - //9 IO GPIO9, Flash D2 - //10 IO GPIO10, Flash D3 - //11 IO GPIO11, Flash CMD - GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) - GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) - GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT - GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 - GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7 - GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - 0, //20 - GPIO_USER, //21 IO GPIO21, VSPIHD, EMAC_TX_EN - GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE - 0, //24 - GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - 0, //28 - 0, //29 - 0, //30 - 0, //31 - GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 - GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 - GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 - GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 - GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 - 0, //37 NO PULLUP - 0, //38 NO PULLUP - GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 - } +const mytmplt kModules PROGMEM = +{ // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) + GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK + GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 + GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 + GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER + GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK + //6 IO GPIO6, Flash CLK + //7 IO GPIO7, Flash D0 + //8 IO GPIO8, Flash D1 + //9 IO GPIO9, Flash D2 + //10 IO GPIO10, Flash D3 + //11 IO GPIO11, Flash CMD + GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) + GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER + GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) + GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT + GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 + GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7 + GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 + 0, //20 + GPIO_USER, //21 IO GPIO21, VSPIHD, EMAC_TX_EN + GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 + GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE + 0, //24 + GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 + GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 + GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV + 0, //28 + 0, //29 + 0, //30 + 0, //31 + GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 + GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 + GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 + GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 + GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 + 0, //37 NO PULLUP + 0, //38 NO PULLUP + GPIO_USER, //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 + 0 // Flag }; #endif // ESP32 diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 5660a231d..d2e2e1813 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -261,21 +261,18 @@ const char HTTP_SCRIPT_TEMPLATE[] PROGMEM = "as=o.shift();" // Complete ADC0 list "g=o.shift().split(',');" // Array separator "j=0;" -// "for(i=0;i<13;i++){" // Supports 13 GPIOs "for(i=0;i<" STR(MAX_USER_PINS) ";i++){" // Supports 13 GPIOs #ifdef ESP8266 "if(6==i){j=9;}" "if(8==i){j=12;}" -#endif -#ifdef ESP32 +#else // ESP32 "if(6==i){j=12;}" -#endif +#endif // ESP8266 - ESP32 "sk(g[i],j);" // Set GPIO "j++;" "}" "g=o.shift();" // FLAG "os=as;" -// "sk(g&15,17);" // Set ADC0 "sk(g&15," STR(ADC0_PIN) ");" // Set ADC0 "g>>=4;" "for(i=0;i<" STR(GPIO_FLAG_USED) ";i++){" @@ -295,7 +292,6 @@ const char HTTP_SCRIPT_TEMPLATE[] PROGMEM = "function x2(a){" "os=a.responseText;" -// "sk(17,99);" // 17 = WEMOS "sk(" STR(WEMOS_MODULE) ",99);" // 17 = WEMOS "st(" STR(USER_MODULE) ");" "}" @@ -321,13 +317,11 @@ const char HTTP_SCRIPT_MODULE2[] PROGMEM = "}" "function x3(a){" // ADC0 "os=a.responseText;" -// "sk(%d,17);" "sk(%d," STR(ADC0_PIN) ");" "}" "function sl(){" "ld('md?m=1',x1);" // ?m related to Webserver->hasArg("m") "ld('md?g=1',x2);" // ?g related to Webserver->hasArg("g") -// "if(eb('g17')){" "if(eb('g" STR(ADC0_PIN) "')){" "ld('md?a=1',x3);" // ?a related to Webserver->hasArg("a") "}" @@ -1532,10 +1526,9 @@ void TemplateSaveSettings(void) #ifdef ESP8266 if (6 == i) { j = 9; } if (8 == i) { j = 12; } -#endif // ESP8266 -#ifdef ESP32 +#else // ESP32 if (6 == i) { j = 12; } -#endif // ESP32 +#endif // ESP8266 - ESP32 snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), j); WebGetArg(webindex, tmp, sizeof(tmp)); // GPIO uint8_t gpio = atoi(tmp); @@ -1543,7 +1536,6 @@ void TemplateSaveSettings(void) j++; } -// WebGetArg("g17", tmp, sizeof(tmp)); // FLAG - ADC0 WebGetArg("g" STR(ADC0_PIN), tmp, sizeof(tmp)); // FLAG - ADC0 uint32_t flag = atoi(tmp); for (uint32_t i = 0; i < GPIO_FLAG_USED; i++) { From bd38f72ce7f20cc13077d0546aa04d6aa7296961 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 17 Apr 2020 17:14:06 +0200 Subject: [PATCH 29/34] Fix Zigbee DimmerUp/DimmerDown malformed --- tasmota/CHANGELOG.md | 1 + tasmota/xdrv_23_zigbee_6_commands.ino | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 273c44db5..0fb205aff 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,7 @@ ### 8.2.0.4 20200417 - Add config version tag +- Fix Zigbee DimmerUp/DimmerDown malformed ### 8.2.0.3 20200329 diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index 1893925f3..8cb695bd6 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -53,7 +53,7 @@ ZF(DimmerMove) ZF(DimmerStep) ZF(HueMove) ZF(HueStep) ZF(SatMove) ZF(SatStep) ZF(ColorMove) ZF(ColorStep) ZF(ArrowClick) ZF(ArrowHold) ZF(ArrowRelease) ZF(ZoneStatusChange) -ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(001902) ZF(011902) ZF(xxyyyy) ZF(xx) +ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(00190200) ZF(01190200) ZF(xxyyyy) ZF(xx) ZF(xx000A00) ZF(xx0A00) ZF(xxyy0A00) ZF(xxxxyyyy0A00) ZF(xxxx0A00) ZF(xx0A) ZF(xx190A00) ZF(xx19) ZF(xx190A) ZF(xxxxyyyy) ZF(xxxxyyzz) ZF(xxyyzzzz) ZF(xxyyyyzz) @@ -82,8 +82,8 @@ const Z_CommandConverter Z_Commands[] PROGMEM = { // Light & Shutter commands { Z(Power), 0x0006, 0xFF, 0x01, Z() }, // 0=Off, 1=On, 2=Toggle { Z(Dimmer), 0x0008, 0x04, 0x01, Z(xx0A00) }, // Move to Level with On/Off, xx=0..254 (255 is invalid) - { Z(DimmerUp), 0x0008, 0x06, 0x01, Z(001902) }, // Step up by 10%, 0.2 secs - { Z(DimmerDown), 0x0008, 0x06, 0x01, Z(011902) }, // Step down by 10%, 0.2 secs + { Z(DimmerUp), 0x0008, 0x06, 0x01, Z(00190200) }, // Step up by 10%, 0.2 secs + { Z(DimmerDown), 0x0008, 0x06, 0x01, Z(01190200) }, // Step down by 10%, 0.2 secs { Z(DimmerStop), 0x0008, 0x03, 0x01, Z() }, // Stop any Dimmer animation { Z(ResetAlarm), 0x0009, 0x00, 0x01, Z(xxyyyy) }, // Reset alarm (alarm code + cluster identifier) { Z(ResetAllAlarms), 0x0009, 0x01, 0x01, Z() }, // Reset all alarms From 8765223f75c480813a19dee300b57110567ea0ca Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 17 Apr 2020 17:20:46 +0200 Subject: [PATCH 30/34] Add the possibility to add Custom env to build special Tasmota versions with Compiler switches defined in [env:tasmota-xyz] in `platformio_tasmota_cenv.ini` to control user_config_override.h Example: "[env:tasmota-zigbee] build_flags = ${common.build_flags} -DHANS_CONFIG_ZIGBEE=true" which referrs to in user_config_override.h ```#ifdef HANS_CONFIG_ZIGBEE // ****************************************************************** #undef CODE_IMAGE_STR #define CODE_IMAGE_STR "ZIGBEE" #define USE_WEBSERVER // Enable web server and Wifi Manager (+66k code, +8k mem) #define USE_JAVASCRIPT_ES6 // Enable ECMAScript6 syntax using less JavaScript code bytes (fails on IE11) // #define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code) //#define USE_RULES // Add support for rules (+4k4 code) // #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) // #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem) // #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code) //#define USE_SCRIPT // Add support for script // #define USE_SCRIPT_FATFS 4 // Add support for script storage on SD card (+12k code, +4k mem) // #define USE_SCRIPT_WEB_DISPLAY #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices // -- Zigbee interface ---------------------------- #define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP (+35k code, +3.2k mem) #define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home #define USE_ZIGBEE_EXTPANID 0xCCCCCCCCCCCCCCCCL // arbitrary extended PAN ID #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) #define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices #define USE_ZIGBEE_PERMIT_JOIN false // don't allow joining by default #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) #endif ``` --- platformio_override_sample.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 701f9c119..8e898f6b6 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -12,6 +12,7 @@ [platformio] extra_configs = platformio_tasmota_env32.ini + platformio_tasmota_cenv.ini ; *** Build/upload environment default_envs = From a98b719f82796732b7b91fae3cf155156c736e88 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 17 Apr 2020 17:52:44 +0200 Subject: [PATCH 31/34] Remove warning/errors when compiling Zigbee for ESP32 --- tasmota/xdrv_23_zigbee_1_headers.ino | 8 ++++---- tasmota/xdrv_23_zigbee_3_hue.ino | 10 ++++------ tasmota/xdrv_23_zigbee_5_converters.ino | 4 ++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_1_headers.ino b/tasmota/xdrv_23_zigbee_1_headers.ino index 051858697..5a250c781 100644 --- a/tasmota/xdrv_23_zigbee_1_headers.ino +++ b/tasmota/xdrv_23_zigbee_1_headers.ino @@ -25,15 +25,15 @@ void ZigbeeZCLSend_Raw(uint16_t dtsAddr, uint16_t groupaddr, uint16_t clusterId, // Get an JSON attribute, with case insensitive key search -JsonVariant &getCaseInsensitive(const JsonObject &json, const char *needle) { +const JsonVariant &getCaseInsensitive(const JsonObject &json, const char *needle) { // key can be in PROGMEM if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle))) { return *(JsonVariant*)nullptr; } - for (auto kv : json) { - const char *key = kv.key; - JsonVariant &value = kv.value; + for (JsonObject::const_iterator it=json.begin(); it!=json.end(); ++it) { + const char *key = it->key; + const JsonVariant &value = it->value; if (0 == strcasecmp_P(key, needle)) { return value; diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index e534134dc..87b7d39da 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -201,12 +201,10 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) { PSTR("{\"success\":{\"/lights/%d/state/on\":%s}}"), device_id, on ? "true" : "false"); - switch(on) - { - case false : ZigbeeHuePower(shortaddr, 0x00); - break; - case true : ZigbeeHuePower(shortaddr, 0x01); - break; + if (on) { + ZigbeeHuePower(shortaddr, 0x01); + } else { + ZigbeeHuePower(shortaddr, 0x00); } response += buf; resp = true; diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 1e115d13f..67ff8993f 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -109,7 +109,7 @@ public: uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, uint32_t timestamp): - _cmd_id(cmd_id), _manuf_code(manuf_code), _transact_seq(transact_seq), + _manuf_code(manuf_code), _transact_seq(transact_seq), _cmd_id(cmd_id), _payload(buf_len ? buf_len : 250), // allocate the data frame from source or preallocate big enough _cluster_id(clusterid), _groupaddr(groupaddr), _srcaddr(srcaddr), _srcendpoint(srcendpoint), _dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast), @@ -215,9 +215,9 @@ private: uint16_t _manuf_code = 0; // optional uint8_t _transact_seq = 0; // transaction sequence number uint8_t _cmd_id = 0; + SBuffer _payload; uint16_t _cluster_id = 0; uint16_t _groupaddr = 0; - SBuffer _payload; // information from decoded ZCL frame uint16_t _srcaddr; uint8_t _srcendpoint; From b70ca01231b9fc54d5ab23d458f3e124ce78acad Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Apr 2020 18:27:31 +0200 Subject: [PATCH 32/34] Add ESP32 optional brownout disable Add ESP32 brownout disable for weak onboard LDO's - eventually you'll need to change the LDO to a better one. --- libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp | 9 +++++++++ libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h | 1 + tasmota/tasmota.ino | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp index 029d41470..6635f6d4d 100644 --- a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp +++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp @@ -109,3 +109,12 @@ uint32_t ESP_getSketchSize(void) } return sketchsize; } + +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" + +void DisableBrownout(void) +{ + // https://github.com/espressif/arduino-esp32/issues/863#issuecomment-347179737 + WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector +} diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index 28e187d52..276772b95 100644 --- a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -43,6 +43,7 @@ uint32_t ESP_getFlashChipId(); uint32_t ESP_getChipId(); String String_ESP_getChipId(); uint32_t ESP_getSketchSize(); +void DisableBrownout(void); // Analog inline void analogWrite(uint8_t pin, int val) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 1a7c250ae..a0d684517 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -192,6 +192,12 @@ void setup(void) { global_state.data = 3; // Init global state (wifi_down, mqtt_down) to solve possible network issues +#ifdef ESP32 +#ifdef DISABLE_BROWNOUT + DisableBrownout(); +#endif +#endif + RtcRebootLoad(); if (!RtcRebootValid()) { RtcReboot.fast_reboot_count = 0; From d69b8a158dc32ef596b9b8841758e0ce5258f39c Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Fri, 17 Apr 2020 19:23:41 -0300 Subject: [PATCH 33/34] Inverted buttons V2 --- tasmota/support_button_v2.ino | 44 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/tasmota/support_button_v2.ino b/tasmota/support_button_v2.ino index d345b58d2..9548a2b4f 100644 --- a/tasmota/support_button_v2.ino +++ b/tasmota/support_button_v2.ino @@ -1,7 +1,7 @@ /* - support_button.ino - button support for Tasmota + support_button_v2.ino - button support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2020 Federico Leoni and Theo Arends This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,12 +23,8 @@ * Button support \*********************************************************************************************/ -#define MAX_BUTTON_COMMANDS_V2 3 // Max number of button commands supported #define MAX_RELAY_BUTTON1 4 // Max number of relay controlled by button1 -const char kCommands[] PROGMEM = - D_CMND_WIFICONFIG " 2|" D_CMND_RESTART " 1|" D_CMND_UPGRADE " 1"; - //D_CMND_WIFICONFIG " 2|" D_CMND_WIFICONFIG " 2|" D_CMND_WIFICONFIG " 2|" D_CMND_RESTART " 1|" D_CMND_UPGRADE " 1"; const char kMultiPress[] PROGMEM = "|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|"; @@ -107,7 +103,6 @@ uint8_t ButtonSerial(uint8_t serial_in_byte) * SetOption11 (0) - If set perform single press action on double press and reverse * SetOption13 (0) - If set act on single press only * SetOption32 (40) - Max button hold time in Seconds - * SetOption40 (0) - Number of 0.1 seconds until hold is discarded if SetOption1 1 and SetOption13 0 * SetOption73 (0) - Decouple button from relay and send just mqtt topic \*********************************************************************************************/ @@ -177,16 +172,19 @@ void ButtonHandler(void) if (!Button.hold_timer[button_index]) { button_pressed = true; } // Do not allow within 1 second } if (button_pressed) { - if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set - ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally - - } + if (!Settings.flag3.mqtt_buttons) { + if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally + } else { + MqttButtonTopic(button_index +1, 1, 0); // SetOption73 (0) - Decouple button from relay and send just mqtt topic } + } + } } } #endif // ESP8266 else { - - if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) { + if (((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index]) && !Button.inverted_mask) || + ((NOT_PRESSED == button) && (PRESSED == Button.last_state[button_index]) && Button.inverted_mask)) { if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action, SetOption73 (0) - Decouple button from relay and send just mqtt topic if (!Settings.flag3.mqtt_buttons) { @@ -203,9 +201,9 @@ void ButtonHandler(void) Button.window_timer[button_index] = loops_per_second / 2; // 0.5 second multi press window } blinks = 201; - } + } - if (NOT_PRESSED == button) { + if (((NOT_PRESSED == button) && !Button.inverted_mask) || ((PRESSED == button) && Button.inverted_mask)) { Button.hold_timer[button_index] = 0; } else { Button.hold_timer[button_index]++; @@ -223,11 +221,11 @@ void ButtonHandler(void) SendKey(KEY_BUTTON, button_index +1, POWER_HOLD); // Execute Hold command via MQTT if ButtonTopic is set } } else { - if (Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer + if ((Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10)) { // SetOption32 (40) - Button held for factor times longer Button.press_counter[button_index] = 0; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1")); ExecuteCommand(scmnd, SRC_BUTTON); - } + } } } } @@ -236,7 +234,9 @@ void ButtonHandler(void) if (Button.window_timer[button_index]) { Button.window_timer[button_index]--; } else { - if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < MAX_BUTTON_COMMANDS_V2 +6)) { + // if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < MAX_BUTTON_COMMANDS_V2 +6)) { + if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < 7)) { + bool single_press = false; if (Button.press_counter[button_index] < 3) { // Single or Double press #ifdef ESP8266 @@ -280,8 +280,12 @@ void ButtonHandler(void) } } } - } else { // 6 - 8 press are used to send commands - GetTextIndexed(scmnd, sizeof(scmnd), Button.press_counter[button_index] -6, kCommands); + // } else { // 6 - 8 press are used to send commands + // GetTextIndexed(scmnd, sizeof(scmnd), Button.press_counter[button_index] -6, kCommands); + // ExecuteCommand(scmnd, SRC_BUTTON); + // } + } else { // 6 press start wificonfig 2 + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_WIFICONFIG " 2")); ExecuteCommand(scmnd, SRC_BUTTON); } if (Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic From e0753eeeada909553ed1c186b5ebbb198519a0d3 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Sat, 18 Apr 2020 09:59:25 +0200 Subject: [PATCH 34/34] Update Italian tarnslation Align Italian enw string to the scheme of translation of previous strings (see up/down) --- tasmota/language/it-IT.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/language/it-IT.h b/tasmota/language/it-IT.h index 934fcfc75..4f1cfbe17 100644 --- a/tasmota/language/it-IT.h +++ b/tasmota/language/it-IT.h @@ -567,8 +567,8 @@ #define D_SENSOR_SPI_MOSI "SPI - MOSI" #define D_SENSOR_SPI_CLK "SPI - CLK" #define D_SENSOR_BACKLIGHT "Retroilluminazione" -#define D_SENSOR_PMS5003_TX "PMS5003 Tx" -#define D_SENSOR_PMS5003_RX "PMS5003 Rx" +#define D_SENSOR_PMS5003_TX "PMS5003 - TX" +#define D_SENSOR_PMS5003_RX "PMS5003 - RX" #define D_SENSOR_SDS0X1_RX "SDS0X1 - RX" #define D_SENSOR_SDS0X1_TX "SDS0X1 - TX" #define D_SENSOR_HPMA_RX "HPMA - RX"