From e94b997627e97162a84a0bef95c25b9b192f7413 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 7 Apr 2021 15:22:07 +0200 Subject: [PATCH 01/67] Fix restart Info JSON messages --- tasmota/xdrv_02_mqtt.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 3a630e699..6f689bc70 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -551,28 +551,28 @@ void MqttConnected(void) { if (Mqtt.initial_connection_state) { if (ResetReason() != REASON_DEEP_SLEEP_AWAKE) { char stopic2[TOPSZ]; - Response_P(PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"), + Response_P(PSTR("{\"Info1\":{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}}"), ModuleName().c_str(), TasmotaGlobal.version, TasmotaGlobal.image_name, GetFallbackTopic_P(stopic, ""), GetGroupTopic_P(stopic2, "", SET_MQTT_GRP_TOPIC)); MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_INFO "1"), Settings.flag5.mqtt_info_retain); #ifdef USE_WEBSERVER if (Settings.webserver) { #if LWIP_IPV6 - Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"IPv6Address\":\"%s\"}"), + Response_P(PSTR("{\"Info2\":{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"IPv6Address\":\"%s\"}}"), (2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str(), WifiGetIPv6().c_str(), Settings.flag5.mqtt_info_retain); #else - Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"), + Response_P(PSTR("{\"Info2\":{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}}"), (2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str(), Settings.flag5.mqtt_info_retain); #endif // LWIP_IPV6 = 1 MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_INFO "2"), Settings.flag5.mqtt_info_retain); } #endif // USE_WEBSERVER - Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":")); + Response_P(PSTR("{\"Info3\":{\"" D_JSON_RESTARTREASON "\":")); if (CrashFlag()) { CrashDump(); } else { ResponseAppend_P(PSTR("\"%s\""), GetResetReason().c_str()); } - ResponseJsonEnd(); + ResponseJsonEndEnd(); MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_INFO "3"), Settings.flag5.mqtt_info_retain); } From 403eba7a99b15d48f62f253ecf7adc29b1489131 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 7 Apr 2021 15:44:29 +0200 Subject: [PATCH 02/67] Add rule number to rule command JSON result --- tasmota/xdrv_10_rules.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 01bc88ec0..d356fd598 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -2138,10 +2138,10 @@ void CmndRule(void) rule = rule.substring(0, MAX_RULE_SIZE); rule += F("..."); } - // snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}"), + // snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s%d\":{\"State\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}}"), // XdrvMailbox.command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)), // GetStateText(bitRead(Settings.rule_stop, index -1)), sizeof(Settings.rules[index -1]) - strlen(Settings.rules[index -1]) -1, Settings.rules[index -1]); - snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Length\":%d,\"Free\":%d,\"Rules\":\"%s\"}"), + snprintf_P (TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s%d\":{\"State\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Length\":%d,\"Free\":%d,\"Rules\":\"%s\"}}"), XdrvMailbox.command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)), GetStateText(bitRead(Settings.rule_stop, index -1)), rule_len, MAX_RULE_SIZE - GetRuleLenStorage(index - 1), From ad423d199dede4c5ddb113baadc130c7c8f2f49e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 7 Apr 2021 17:55:33 +0200 Subject: [PATCH 03/67] Add command ``Backlog 1;`` Add command ``Backlog 1;`` to allow execution of following commands without delay --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/support_command.ino | 22 ++++++++++++++-------- tasmota/tasmota.ino | 6 +++++- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6baaaa56..b4994fa0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. - Berry add ``gpio`` module - Berry add ``light`` module - Support for dummy energy monitor using user values set by commands ``VoltageSet``, ``CurrentSet``, ``PowerSet`` and ``FrequencySet``. Enable by selecting any GPIO as ``Option A2`` (#10640) +- Command ``Backlog 1;`` to allow execution of following commands without delay ### Changed - PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 55c397eac..671e21e2f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -83,6 +83,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Command ``Sensor80 1 <0..7>`` to control MFRC522 RFID antenna gain from 18dB (0) to 48dB (7) [#11073](https://github.com/arendst/Tasmota/issues/11073) - Command ``SerialBuffer 256..520`` to change hardware serial receive buffer size from default (256) to max local buffer size (520) [#11448](https://github.com/arendst/Tasmota/issues/11448) - Command ``SetOption126 1`` to enable DS18x20 arithmetic mean over teleperiod for JSON temperature based on [#11472](https://github.com/arendst/Tasmota/issues/11472) +- Command ``Backlog 1;`` to allow execution of following commands without delay - Commands ``MqttKeepAlive 1..100`` to set Mqtt Keep Alive timer (default 30) and ``MqttTimeout 1..100`` to set Mqtt Socket Timeout (default 4) [#5341](https://github.com/arendst/Tasmota/issues/5341) - Commands ``DisplayType`` to select sub-modules where implemented and ``DisplayInvert`` to select inverted display where implemented - Support for SML VBUS [#11125](https://github.com/arendst/Tasmota/issues/11125) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index c8b13f2f0..02a920f7c 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -317,8 +317,10 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) /********************************************************************************************/ -void CmndBacklog(void) -{ +void CmndBacklog(void) { + // Backlog command1;command2;.. Execute commands in sequence with a delay in between set with SetOption34 + // Backlog 1;command1;command2;.. Execute commands in sequence with no delay + if (XdrvMailbox.data_len) { #ifdef SUPPORT_IF_STATEMENT @@ -340,15 +342,19 @@ void CmndBacklog(void) } } if (*blcommand != '\0') { + if (BACKLOG_EMPTY && ('1' == *blcommand)) { + TasmotaGlobal.backlog_nodelay = true; + } else { #ifdef SUPPORT_IF_STATEMENT - if (backlog.size() < MAX_BACKLOG) { - backlog.add(blcommand); - } + if (backlog.size() < MAX_BACKLOG) { + backlog.add(blcommand); + } #else - TasmotaGlobal.backlog[TasmotaGlobal.backlog_index] = blcommand; - TasmotaGlobal.backlog_index++; - if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) TasmotaGlobal.backlog_index = 0; + TasmotaGlobal.backlog[TasmotaGlobal.backlog_index] = blcommand; + TasmotaGlobal.backlog_index++; + if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) TasmotaGlobal.backlog_index = 0; #endif + } } blcommand = strtok(nullptr, ";"); } diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 59735a55f..38aa5a8ef 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -141,6 +141,7 @@ struct { bool rule_teleperiod; // Process rule based on teleperiod data using prefix TELE- bool serial_local; // Handle serial locally bool fallback_topic_flag; // Use Topic or FallbackTopic + bool backlog_nodelay; // Execute all backlog commands with no delay bool backlog_mutex; // Command backlog pending bool stop_flash_rotate; // Allow flash configuration rotation bool blinkstate; // LED state @@ -398,11 +399,14 @@ void BacklogLoop(void) { if (!nodelay_detected) { ExecuteCommand((char*)cmd.c_str(), SRC_BACKLOG); } - if (nodelay) { + if (nodelay || TasmotaGlobal.backlog_nodelay) { TasmotaGlobal.backlog_timer = millis(); // Reset backlog_timer which has been set by ExecuteCommand (CommandHandler) } TasmotaGlobal.backlog_mutex = false; } + if (BACKLOG_EMPTY) { + TasmotaGlobal.backlog_nodelay = false; + } } } From d08f9bc3158f993e5fa2dfc4d8dd8edce041b5f6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 7 Apr 2021 18:10:34 +0200 Subject: [PATCH 04/67] Refactor GUI save parameters (Prt1) --- tasmota/xdrv_01_webserver.ino | 84 +++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 5b6797f57..85fc8ced8 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -403,13 +403,16 @@ void ShowWebSource(uint32_t source) } } -void ExecuteWebCommand(char* svalue, uint32_t source) -{ +void ExecuteWebCommand(char* svalue, uint32_t source) { ShowWebSource(source); TasmotaGlobal.last_source = source; ExecuteCommand(svalue, SRC_IGNORE); } +void ExecuteWebCommand(char* svalue) { + ExecuteWebCommand(svalue, SRC_WEBGUI); +} + // replace the series of `Webserver->on()` with a table in PROGMEM typedef struct WebServerDispatch_t { char uri[3]; // the prefix "/" is added automatically @@ -1168,7 +1171,7 @@ bool HandleRootStatusRefresh(void) int32_t ShutterWebButton; if (ShutterWebButton = IsShutterWebButton(device)) { snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %s"), abs(ShutterWebButton), (ShutterWebButton>0) ? PSTR(D_CMND_SHUTTER_STOPOPEN) : PSTR(D_CMND_SHUTTER_STOPCLOSE)); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } else { #endif // USE_SHUTTER ExecuteCommandPower(device, POWER_TOGGLE, SRC_IGNORE); @@ -1186,12 +1189,12 @@ bool HandleRootStatusRefresh(void) WebGetArg(PSTR("d0"), tmp, sizeof(tmp)); // 0 - 100 Dimmer value if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_DIMMER " %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } WebGetArg(PSTR("w0"), tmp, sizeof(tmp)); // 0 - 100 White value if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_WHITE " %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } uint32_t light_device = LightDevice(); // Channel number offset uint32_t pwm_channels = (TasmotaGlobal.light_type & 7) > LST_MAX ? LST_MAX : (TasmotaGlobal.light_type & 7); @@ -1200,23 +1203,23 @@ bool HandleRootStatusRefresh(void) WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_CHANNEL "%d %s"), j +light_device, tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } } WebGetArg(PSTR("t0"), tmp, sizeof(tmp)); // 153 - 500 Color temperature if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_COLORTEMPERATURE " %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } WebGetArg(PSTR("h0"), tmp, sizeof(tmp)); // 0 - 359 Hue value if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_HSBCOLOR "1 %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } WebGetArg(PSTR("n0"), tmp, sizeof(tmp)); // 0 - 99 Saturation value if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_HSBCOLOR "2 %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } #endif // USE_LIGHT #ifdef USE_SHUTTER @@ -1225,7 +1228,7 @@ bool HandleRootStatusRefresh(void) WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %s"), j, tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } } #endif // USE_SHUTTER @@ -1233,19 +1236,19 @@ bool HandleRootStatusRefresh(void) WebGetArg(PSTR("k"), tmp, sizeof(tmp)); // 1 - 16 Pre defined RF keys if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RFKEY "%s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } #endif // USE_SONOFF_RF #ifdef USE_ZIGBEE WebGetArg(PSTR("zbj"), tmp, sizeof(tmp)); if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR("ZbPermitJoin")); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } WebGetArg(PSTR("zbr"), tmp, sizeof(tmp)); if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR("ZbMap")); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } #endif // USE_ZIGBEE @@ -1528,7 +1531,7 @@ void TemplateSaveSettings(void) uint32_t base = atoi(tmp) +1; snprintf_P(svalue, sizeof(svalue), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), svalue, flag, base); - ExecuteWebCommand(svalue, SRC_WEBGUI); + ExecuteWebCommand(svalue); } /*-------------------------------------------------------------------------------------------*/ @@ -1868,27 +1871,30 @@ void HandleLoggingConfiguration(void) void LoggingSaveSettings(void) { - char tmp[TOPSZ]; // Max length is currently 33 - - WebGetArg(PSTR("l0"), tmp, sizeof(tmp)); - SetSeriallog((!strlen(tmp)) ? SERIAL_LOG_LEVEL : atoi(tmp)); - WebGetArg(PSTR("l1"), tmp, sizeof(tmp)); - Settings.weblog_level = (!strlen(tmp)) ? WEB_LOG_LEVEL : atoi(tmp); - WebGetArg(PSTR("l2"), tmp, sizeof(tmp)); - Settings.mqttlog_level = (!strlen(tmp)) ? MQTT_LOG_LEVEL : atoi(tmp); - WebGetArg(PSTR("l3"), tmp, sizeof(tmp)); - SetSyslog((!strlen(tmp)) ? SYS_LOG_LEVEL : atoi(tmp)); - WebGetArg(PSTR("lh"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_SYSLOG_HOST, (!strlen(tmp)) ? SYS_LOG_HOST : tmp); - WebGetArg(PSTR("lp"), tmp, sizeof(tmp)); - Settings.syslog_port = (!strlen(tmp)) ? SYS_LOG_PORT : atoi(tmp); - WebGetArg(PSTR("lt"), tmp, sizeof(tmp)); - Settings.tele_period = (!strlen(tmp)) ? TELE_PERIOD : atoi(tmp); - if ((Settings.tele_period > 0) && (Settings.tele_period < 10)) { - Settings.tele_period = 10; // Do not allow periods < 10 seconds - } - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D_CMND_WEBLOG " %d, " D_CMND_MQTTLOG " %d, " D_CMND_SYSLOG " %d, " D_CMND_LOGHOST " %s, " D_CMND_LOGPORT " %d, " D_CMND_TELEPERIOD " %d"), - Settings.seriallog_level, Settings.weblog_level, Settings.mqttlog_level, Settings.syslog_level, SettingsText(SET_SYSLOG_HOST), Settings.syslog_port, Settings.tele_period); + char tmp1[CMDSZ]; + WebGetArg(PSTR("l0"), tmp1, sizeof(tmp1)); + char tmp2[CMDSZ]; + WebGetArg(PSTR("l1"), tmp2, sizeof(tmp2)); + char tmp3[CMDSZ]; + WebGetArg(PSTR("l2"), tmp3, sizeof(tmp3)); + char tmp4[CMDSZ]; + WebGetArg(PSTR("l3"), tmp4, sizeof(tmp4)); + char tmp5[CMDSZ]; + WebGetArg(PSTR("lh"), tmp5, sizeof(tmp5)); + char tmp6[CMDSZ]; + WebGetArg(PSTR("lp"), tmp6, sizeof(tmp6)); + char tmp7[CMDSZ]; + WebGetArg(PSTR("lt"), tmp7, sizeof(tmp7)); + char command[200]; + snprintf_P(command, sizeof(command),PSTR(D_CMND_BACKLOG " 1;" D_CMND_SERIALLOG " %s;" D_CMND_WEBLOG " %s;" D_CMND_MQTTLOG " %s;" D_CMND_SYSLOG " %s;" D_CMND_LOGHOST " %s;" D_CMND_LOGPORT " %s;" D_CMND_TELEPERIOD " %s"), + (!strlen(tmp1)) ? STR(SERIAL_LOG_LEVEL) : tmp1, + (!strlen(tmp2)) ? STR(WEB_LOG_LEVEL) : tmp2, + (!strlen(tmp3)) ? STR(MQTT_LOG_LEVEL) : tmp3, + (!strlen(tmp4)) ? STR(SYS_LOG_LEVEL) : tmp4, + (!strlen(tmp5)) ? SYS_LOG_HOST : tmp5, + (!strlen(tmp6)) ? STR(SYS_LOG_PORT) : tmp6, + (!strlen(tmp7)) ? STR(TELE_PERIOD) : tmp7); + ExecuteWebCommand(command); } /*-------------------------------------------------------------------------------------------*/ @@ -1990,7 +1996,7 @@ void OtherSaveSettings(void) WebGetArg(PSTR("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(F("t2"))) ? PSTR("; " D_CMND_MODULE " 0") : ""); - ExecuteWebCommand(message, SRC_WEBGUI); + ExecuteWebCommand(message); } } @@ -2053,7 +2059,7 @@ void HandleResetConfiguration(void) char command[CMDSZ]; snprintf_P(command, sizeof(command), PSTR(D_CMND_RESET " 1")); - ExecuteWebCommand(command, SRC_WEBGUI); + ExecuteWebCommand(command); } void HandleRestoreConfiguration(void) @@ -2298,7 +2304,7 @@ void HandleUpgradeFirmwareStart(void) { WebGetArg(PSTR("o"), otaurl, sizeof(otaurl)); if (strlen(otaurl)) { snprintf_P(command, sizeof(command), PSTR(D_CMND_OTAURL " %s"), otaurl); - ExecuteWebCommand(command, SRC_WEBGUI); + ExecuteWebCommand(command); } WSContentStart_P(PSTR(D_INFORMATION)); @@ -2310,7 +2316,7 @@ void HandleUpgradeFirmwareStart(void) { WSContentStop(); snprintf_P(command, sizeof(command), PSTR(D_CMND_UPGRADE " 1")); - ExecuteWebCommand(command, SRC_WEBGUI); + ExecuteWebCommand(command); } void HandleUploadDone(void) { From b6e77cd3d7058f1d6214f6c823b0f2c2b1ee8637 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 7 Apr 2021 18:22:20 +0200 Subject: [PATCH 05/67] Change ``Backlog 1;`` into ``Backlog0`` --- CHANGELOG.md | 2 +- RELEASENOTES.md | 2 +- tasmota/support_command.ino | 25 ++++++++++++------------- tasmota/xdrv_01_webserver.ino | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4994fa0e..5020417d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ All notable changes to this project will be documented in this file. - Berry add ``gpio`` module - Berry add ``light`` module - Support for dummy energy monitor using user values set by commands ``VoltageSet``, ``CurrentSet``, ``PowerSet`` and ``FrequencySet``. Enable by selecting any GPIO as ``Option A2`` (#10640) -- Command ``Backlog 1;`` to allow execution of following commands without delay +- Command ``Backlog0`` to allow execution of following commands without delay ### Changed - PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 671e21e2f..4a490aa04 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -83,7 +83,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Command ``Sensor80 1 <0..7>`` to control MFRC522 RFID antenna gain from 18dB (0) to 48dB (7) [#11073](https://github.com/arendst/Tasmota/issues/11073) - Command ``SerialBuffer 256..520`` to change hardware serial receive buffer size from default (256) to max local buffer size (520) [#11448](https://github.com/arendst/Tasmota/issues/11448) - Command ``SetOption126 1`` to enable DS18x20 arithmetic mean over teleperiod for JSON temperature based on [#11472](https://github.com/arendst/Tasmota/issues/11472) -- Command ``Backlog 1;`` to allow execution of following commands without delay +- Command ``Backlog0`` to allow execution of following commands without delay - Commands ``MqttKeepAlive 1..100`` to set Mqtt Keep Alive timer (default 30) and ``MqttTimeout 1..100`` to set Mqtt Socket Timeout (default 4) [#5341](https://github.com/arendst/Tasmota/issues/5341) - Commands ``DisplayType`` to select sub-modules where implemented and ``DisplayInvert`` to select inverted display where implemented - Support for SML VBUS [#11125](https://github.com/arendst/Tasmota/issues/11125) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 02a920f7c..e80dc20fd 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -318,10 +318,13 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) /********************************************************************************************/ void CmndBacklog(void) { - // Backlog command1;command2;.. Execute commands in sequence with a delay in between set with SetOption34 - // Backlog 1;command1;command2;.. Execute commands in sequence with no delay + // Backlog command1;command2;.. Execute commands in sequence with a delay in between set with SetOption34 + // Backlog0 command1;command2;.. Execute commands in sequence with no delay if (XdrvMailbox.data_len) { + if (0 == XdrvMailbox.index) { + TasmotaGlobal.backlog_nodelay = true; + } #ifdef SUPPORT_IF_STATEMENT char *blcommand = strtok(XdrvMailbox.data, ";"); @@ -342,19 +345,15 @@ void CmndBacklog(void) { } } if (*blcommand != '\0') { - if (BACKLOG_EMPTY && ('1' == *blcommand)) { - TasmotaGlobal.backlog_nodelay = true; - } else { #ifdef SUPPORT_IF_STATEMENT - if (backlog.size() < MAX_BACKLOG) { - backlog.add(blcommand); - } -#else - TasmotaGlobal.backlog[TasmotaGlobal.backlog_index] = blcommand; - TasmotaGlobal.backlog_index++; - if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) TasmotaGlobal.backlog_index = 0; -#endif + if (backlog.size() < MAX_BACKLOG) { + backlog.add(blcommand); } +#else + TasmotaGlobal.backlog[TasmotaGlobal.backlog_index] = blcommand; + TasmotaGlobal.backlog_index++; + if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) TasmotaGlobal.backlog_index = 0; +#endif } blcommand = strtok(nullptr, ";"); } diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 85fc8ced8..c17b72706 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1886,7 +1886,7 @@ void LoggingSaveSettings(void) char tmp7[CMDSZ]; WebGetArg(PSTR("lt"), tmp7, sizeof(tmp7)); char command[200]; - snprintf_P(command, sizeof(command),PSTR(D_CMND_BACKLOG " 1;" D_CMND_SERIALLOG " %s;" D_CMND_WEBLOG " %s;" D_CMND_MQTTLOG " %s;" D_CMND_SYSLOG " %s;" D_CMND_LOGHOST " %s;" D_CMND_LOGPORT " %s;" D_CMND_TELEPERIOD " %s"), + snprintf_P(command, sizeof(command),PSTR(D_CMND_BACKLOG "0 " D_CMND_SERIALLOG " %s;" D_CMND_WEBLOG " %s;" D_CMND_MQTTLOG " %s;" D_CMND_SYSLOG " %s;" D_CMND_LOGHOST " %s;" D_CMND_LOGPORT " %s;" D_CMND_TELEPERIOD " %s"), (!strlen(tmp1)) ? STR(SERIAL_LOG_LEVEL) : tmp1, (!strlen(tmp2)) ? STR(WEB_LOG_LEVEL) : tmp2, (!strlen(tmp3)) ? STR(MQTT_LOG_LEVEL) : tmp3, From ea64f7b9c55aa28353c942c8fdf3b025e252a691 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 8 Apr 2021 14:08:20 +0200 Subject: [PATCH 06/67] Refactor timer GUI save result enabling rule trigger (#11612) --- tasmota/xdrv_09_timers.ino | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index af273fa8f..22e38a2e6 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -879,14 +879,12 @@ void HandleTimerConfiguration(void) void TimerSaveSettings(void) { - char tmp[MAX_TIMERS *12]; // Need space for MAX_TIMERS x 10 digit numbers separated by a comma - char message[32 + (MAX_TIMERS *11)]; // MQT: Timers 0,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 Timer timer; Settings.flag3.timers_enable = Webserver->hasArg(F("e0")); // CMND_TIMERS + char tmp[MAX_TIMERS *12]; // Need space for MAX_TIMERS x 10 digit numbers separated by a comma WebGetArg(PSTR("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 for (uint32_t i = 0; i < MAX_TIMERS; i++) { timer.data = strtol(p, &p, 10); p++; // Skip comma @@ -895,9 +893,10 @@ void TimerSaveSettings(void) Settings.timer[i].data = timer.data; if (flag) TimerSetRandomWindow(i); } - snprintf_P(message, sizeof(message), PSTR("%s,0x%08X"), message, Settings.timer[i].data); } - AddLogData(LOG_LEVEL_DEBUG, message); + char command[CMDSZ]; + snprintf_P(command, sizeof(command), PSTR(D_CMND_TIMERS)); + ExecuteWebCommand(command); } #endif // USE_TIMERS_WEB #endif // USE_WEBSERVER From 6d8daef8fa9f6ddd35a4a34671c832816caa70ae Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 8 Apr 2021 15:43:53 +0200 Subject: [PATCH 07/67] prepare teleinfo bit field settings (#11626) --- tasmota/settings.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 7d254e6d3..b48cbe0d5 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -313,6 +313,20 @@ typedef union { }; } As3935Param; +typedef union { + uint32_t data; + struct { + uint32_t raw_skip : 8; // raw frame to skip when sending raw data (set to 2 means send 1 frame, then skip 2, ...) + uint32_t raw_report_changed : 1; // Report only changed values in raw frames (only valid if raw_skip=0) + uint32_t raw_send : 1; // Enable sending also real time raw data over MQTT + uint32_t raw_limit : 1; // Limit raw data to minimal relevant fields (the ones moving quickly) + uint32_t mode_standard : 1; // Set Linky Standard Mode (9600 bps stream) else legacy (1200 bps) + uint32_t spare4_1 : 4; // Keep some spares for future uses + uint32_t spare8_1 : 8; // Keep some spares for future uses + uint32_t spare8_2 : 8; // Keep some spares for future uses + }; +} TeleinfoCfg; + typedef struct { uint32_t usage1_kWhtotal; uint32_t usage2_kWhtotal; @@ -643,10 +657,11 @@ struct { uint16_t shd_warmup_brightness; // F5C uint8_t shd_warmup_time; // F5E - uint8_t free_f5e[72]; // F5E - Decrement if adding new Setting variables just above and below + uint8_t free_f5e[68]; // F5E - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below + TeleinfoCfg teleinfo; // FA4 uint64_t rf_protocol_mask; // FA8 uint8_t device_group_tie[4]; // FB0 SysBitfield5 flag5; // FB4 From bacc07b2de38a13d3945e83d3ce516299f304baf Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 8 Apr 2021 15:51:34 +0200 Subject: [PATCH 08/67] Fix offset --- tasmota/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index b48cbe0d5..b23d6dd0e 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -657,7 +657,7 @@ struct { uint16_t shd_warmup_brightness; // F5C uint8_t shd_warmup_time; // F5E - uint8_t free_f5e[68]; // F5E - Decrement if adding new Setting variables just above and below + uint8_t free_f5f[69]; // F5F - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below From 1a2addfc1698d537a49fe39aa79e098f2973067a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 8 Apr 2021 17:57:37 +0200 Subject: [PATCH 09/67] Refactor GUI save settings (prt2) --- tasmota/i18n.h | 1 + tasmota/support_command.ino | 20 +++- tasmota/xdrv_01_webserver.ino | 167 ++++++++++++++++------------------ 3 files changed, 95 insertions(+), 93 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 05f6d3ca2..0fdcb4473 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -306,6 +306,7 @@ #define D_WCFG_7_WIFIMANAGER_RESET_ONLY "ManagerRst" #define D_CMND_DEVICENAME "DeviceName" #define D_CMND_FRIENDLYNAME "FriendlyName" +#define D_CMND_FN "FN" #define D_CMND_SWITCHMODE "SwitchMode" #define D_CMND_INTERLOCK "Interlock" #define D_CMND_TELEPERIOD "TelePeriod" diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index e80dc20fd..b0f4d7b2d 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -26,7 +26,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_SERIALBUFFER "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALCONFIG "|" D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" - D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" + D_CMND_DEVICENAME "|" D_CMND_FN "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM"|" D_CMND_SWITCHTEXT "|" #ifdef USE_I2C @@ -54,7 +54,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport, &CmndSerialBuffer, &CmndSerialSend, &CmndBaudrate, &CmndSerialConfig, &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, - &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, + &CmndDevicename, &CmndFriendlyname, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSwitchText, #ifdef USE_I2C @@ -237,7 +237,7 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) type[i] = '\0'; } - AddLog(LOG_LEVEL_DEBUG, PSTR("CMD: " D_GROUP " %d, " D_INDEX " %d, " D_COMMAND " \"%s\", " D_DATA " \"%s\""), grpflg, index, type, dataBuf); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("CMD: " D_GROUP " %d, " D_INDEX " %d, " D_COMMAND " \"%s\", " D_DATA " \"%s\""), grpflg, index, type, dataBuf); if (type != nullptr) { Response_P(PSTR("{\"" D_JSON_COMMAND "\":\"" D_JSON_ERROR "\"}")); @@ -1657,14 +1657,23 @@ void CmndSsid(void) void CmndPassword(void) { - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) { + bool show_asterisk = (XdrvMailbox.index > 2); + if (show_asterisk) { + XdrvMailbox.index -= 2; + } if ((XdrvMailbox.data_len > 4) || (SC_CLEAR == Shortcut()) || (SC_DEFAULT == Shortcut())) { SettingsUpdateText(SET_STAPWD1 + XdrvMailbox.index -1, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? STA_PASS1 : STA_PASS2 : XdrvMailbox.data); Settings.sta_active = XdrvMailbox.index -1; TasmotaGlobal.restart_flag = 2; - ResponseCmndIdxChar(SettingsText(SET_STAPWD1 + XdrvMailbox.index -1)); + if (!show_asterisk) { + ResponseCmndIdxChar(SettingsText(SET_STAPWD1 + XdrvMailbox.index -1)); + } } else { + show_asterisk = true; + } + if (show_asterisk) { Response_P(S_JSON_COMMAND_INDEX_ASTERISK, XdrvMailbox.command, XdrvMailbox.index); } } @@ -1708,6 +1717,7 @@ void CmndDevicename(void) void CmndFriendlyname(void) { + snprintf_P(XdrvMailbox.command, CMDSZ, PSTR(D_CMND_FRIENDLYNAME)); // Rename result shortcut command FN to FriendlyName if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_FRIENDLYNAMES)) { if (!XdrvMailbox.usridx && !XdrvMailbox.data_len) { ResponseCmndAll(SET_FRIENDLYNAME1, MAX_FRIENDLYNAMES); diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index c17b72706..b409b25b2 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1403,8 +1403,7 @@ void WSContentSendAdcNiceList(uint32_t option) { /*-------------------------------------------------------------------------------------------*/ -void HandleTemplateConfiguration(void) -{ +void HandleTemplateConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } if (Webserver->hasArg(F("save"))) { @@ -1504,12 +1503,11 @@ uint16_t WebGetGpioArg(uint32_t i) { return gpio; } -void TemplateSaveSettings(void) -{ - char tmp[TOPSZ]; // WebGetArg NAME and GPIO/BASE/FLAG byte value - char svalue[300]; // Template command string +void TemplateSaveSettings(void) { + char tmp[TOPSZ]; // WebGetArg NAME and GPIO/BASE/FLAG byte value + char svalue[300]; // Template command string - WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // NAME + WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // NAME snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp); uint32_t j = 0; @@ -1521,13 +1519,13 @@ void TemplateSaveSettings(void) } uint32_t flag = 0; - char webindex[5]; // WebGetArg name + char webindex[5]; // WebGetArg name 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; // FLAG + uint32_t state = Webserver->hasArg(webindex) << i; // FLAG flag += state; } - WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); // BASE + WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); // BASE uint32_t base = atoi(tmp) +1; snprintf_P(svalue, sizeof(svalue), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), svalue, flag, base); @@ -1536,8 +1534,7 @@ void TemplateSaveSettings(void) /*-------------------------------------------------------------------------------------------*/ -void HandleModuleConfiguration(void) -{ +void HandleModuleConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } if (Webserver->hasArg(F("save"))) { @@ -1603,30 +1600,27 @@ void HandleModuleConfiguration(void) WSContentStop(); } -void ModuleSaveSettings(void) -{ +void ModuleSaveSettings(void) { char tmp[8]; // WebGetArg numbers only - - WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); + WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); // Module uint32_t new_module = (!strlen(tmp)) ? MODULE : atoi(tmp); Settings.last_module = Settings.module; Settings.module = new_module; SetModuleType(); myio template_gp; TemplateGpios(&template_gp); - String gpios = ""; for (uint32_t i = 0; i < nitems(template_gp.io); i++) { if (Settings.last_module != new_module) { Settings.my_gp.io[i] = GPIO_NONE; } else { if (ValidGPIO(i, template_gp.io[i])) { - Settings.my_gp.io[i] = WebGetGpioArg(i); - gpios += F(", IO"); gpios += String(i); gpios += F(" "); gpios += String(Settings.my_gp.io[i]); + Settings.my_gp.io[i] = WebGetGpioArg(i); // Gpio } } } - - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MODULE "%s " D_CMND_MODULE "%s"), ModuleName().c_str(), gpios.c_str()); + char command[32]; + snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_MODULE ";" D_CMND_GPIO)); + ExecuteWebCommand(command); } /*-------------------------------------------------------------------------------------------*/ @@ -1653,8 +1647,7 @@ String HtmlEscape(const String unescaped) { // Indexed by enum wl_enc_type in file wl_definitions.h starting from -1 const char kEncryptionType[] PROGMEM = "|||" D_WPA_PSK "||" D_WPA2_PSK "|" D_WEP "||" D_NONE "|" D_AUTO; -void HandleWifiConfiguration(void) -{ +void HandleWifiConfiguration(void) { if (!HttpCheckPriviledgedAccess(!WifiIsInManagerMode())) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_WIFI)); @@ -1806,33 +1799,33 @@ void HandleWifiConfiguration(void) WSContentStop(); } -void WifiSaveSettings(void) -{ - char tmp[TOPSZ]; // Max length is currently 150 - - WebGetArg(PSTR("h"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_HOSTNAME, (!strlen(tmp)) ? WIFI_HOSTNAME : tmp); - if (strchr(SettingsText(SET_HOSTNAME), '%') != nullptr) { - SettingsUpdateText(SET_HOSTNAME, WIFI_HOSTNAME); - } - WebGetArg(PSTR("c"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_CORS, (!strlen(tmp)) ? CORS_DOMAIN : tmp); - WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_STASSID1, (!strlen(tmp)) ? STA_SSID1 : tmp); - WebGetArg(PSTR("s2"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_STASSID2, (!strlen(tmp)) ? STA_SSID2 : tmp); - WebGetArg(PSTR("p1"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_STAPWD1, (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? SettingsText(SET_STAPWD1) : tmp); - WebGetArg(PSTR("p2"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_STAPWD2, (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? SettingsText(SET_STAPWD2) : tmp); - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_SSID "2 %s, " D_CMND_CORS " %s"), - SettingsText(SET_HOSTNAME), SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), SettingsText(SET_CORS)); +void WifiSaveSettings(void) { + char tmp1[CMDSZ]; + WebGetArg(PSTR("h"), tmp1, sizeof(tmp1)); // Host name + char tmp2[CMDSZ]; + WebGetArg(PSTR("c"), tmp2, sizeof(tmp2)); // Cors domain + char tmp3[CMDSZ]; + WebGetArg(PSTR("s1"), tmp3, sizeof(tmp3)); // Ssid1 + char tmp4[CMDSZ]; + WebGetArg(PSTR("s2"), tmp4, sizeof(tmp4)); // Ssid2 + char tmp5[CMDSZ]; + WebGetArg(PSTR("p1"), tmp5, sizeof(tmp5)); // Password1 + char tmp6[CMDSZ]; + WebGetArg(PSTR("p2"), tmp6, sizeof(tmp6)); // Password2 + char command[300]; + snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_HOSTNAME " %s;" D_CMND_CORS " %s;" D_CMND_SSID "1 %s;" D_CMND_SSID "2 %s;" D_CMND_PASSWORD "3 %s;" D_CMND_PASSWORD "4 %s"), + (!strlen(tmp1)) ? "1" : tmp1, + (!strlen(tmp2)) ? "1" : tmp2, + (!strlen(tmp3)) ? "1" : tmp3, + (!strlen(tmp4)) ? "1" : tmp4, + (!strlen(tmp5)) ? "\"" : (strlen(tmp5) < 5) ? "" : tmp5, + (!strlen(tmp6)) ? "\"" : (strlen(tmp6) < 5) ? "" : tmp6); + ExecuteWebCommand(command); } /*-------------------------------------------------------------------------------------------*/ -void HandleLoggingConfiguration(void) -{ +void HandleLoggingConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_LOGGING)); @@ -1869,22 +1862,21 @@ void HandleLoggingConfiguration(void) WSContentStop(); } -void LoggingSaveSettings(void) -{ +void LoggingSaveSettings(void) { char tmp1[CMDSZ]; - WebGetArg(PSTR("l0"), tmp1, sizeof(tmp1)); + WebGetArg(PSTR("l0"), tmp1, sizeof(tmp1)); // Serial log level char tmp2[CMDSZ]; - WebGetArg(PSTR("l1"), tmp2, sizeof(tmp2)); + WebGetArg(PSTR("l1"), tmp2, sizeof(tmp2)); // Web log level char tmp3[CMDSZ]; - WebGetArg(PSTR("l2"), tmp3, sizeof(tmp3)); + WebGetArg(PSTR("l2"), tmp3, sizeof(tmp3)); // Mqtt log level char tmp4[CMDSZ]; - WebGetArg(PSTR("l3"), tmp4, sizeof(tmp4)); + WebGetArg(PSTR("l3"), tmp4, sizeof(tmp4)); // Syslog level char tmp5[CMDSZ]; - WebGetArg(PSTR("lh"), tmp5, sizeof(tmp5)); + WebGetArg(PSTR("lh"), tmp5, sizeof(tmp5)); // Syslog host name char tmp6[CMDSZ]; - WebGetArg(PSTR("lp"), tmp6, sizeof(tmp6)); + WebGetArg(PSTR("lp"), tmp6, sizeof(tmp6)); // Syslog port number char tmp7[CMDSZ]; - WebGetArg(PSTR("lt"), tmp7, sizeof(tmp7)); + WebGetArg(PSTR("lt"), tmp7, sizeof(tmp7)); // Teleperiod char command[200]; snprintf_P(command, sizeof(command),PSTR(D_CMND_BACKLOG "0 " D_CMND_SERIALLOG " %s;" D_CMND_WEBLOG " %s;" D_CMND_MQTTLOG " %s;" D_CMND_SYSLOG " %s;" D_CMND_LOGHOST " %s;" D_CMND_LOGPORT " %s;" D_CMND_TELEPERIOD " %s"), (!strlen(tmp1)) ? STR(SERIAL_LOG_LEVEL) : tmp1, @@ -1899,8 +1891,7 @@ void LoggingSaveSettings(void) /*-------------------------------------------------------------------------------------------*/ -void HandleOtherConfiguration(void) -{ +void HandleOtherConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_OTHER)); @@ -1962,42 +1953,36 @@ void HandleOtherConfiguration(void) WSContentStop(); } -void OtherSaveSettings(void) -{ - char tmp[300]; // Needs to hold complete ESP32 template of minimal 230 chars - char webindex[5]; - char friendlyname[TOPSZ]; - char message[MAX_LOGSZ]; +void OtherSaveSettings(void) { + char tmp1[300]; // Needs to hold complete ESP32 template of minimal 230 chars + WebGetArg(PSTR("dn"), tmp1, sizeof(tmp1)); // Device name + char tmp2[100]; + WebGetArg(PSTR("wp"), tmp2, sizeof(tmp2)); // Web password + char command[600]; + snprintf_P(command, sizeof(command),PSTR(D_CMND_BACKLOG "0 " D_CMND_WEBPASSWORD "2 %s;" D_CMND_SO "3 %d;" D_CMND_DEVICENAME " %s"), + (!strlen(tmp2)) ? "\"" : (strlen(tmp2) < 5) ? "" : tmp2, + Webserver->hasArg(F("b1")), // SetOption3 - Enable MQTT + (!strlen(tmp1)) ? "\"" : tmp1); + + char webindex[5]; + for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) { + snprintf_P(webindex, sizeof(webindex), PSTR("a%d"), i); + WebGetArg(webindex, tmp1, sizeof(tmp1)); // Friendly name 1 to 8 + snprintf_P(command, sizeof(command), PSTR("%s;" D_CMND_FN"%d %s"), command, i +1, (!strlen(tmp1)) ? "\"" : tmp1); + } - WebGetArg(PSTR("dn"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_DEVICENAME, (!strlen(tmp)) ? "" : (!strcmp(tmp,"1")) ? SettingsText(SET_FRIENDLYNAME1) : tmp); - WebGetArg(PSTR("wp"), tmp, sizeof(tmp)); - SettingsUpdateText(SET_WEBPWD, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? SettingsText(SET_WEBPWD) : tmp); - Settings.flag.mqtt_enabled = Webserver->hasArg(F("b1")); // SetOption3 - Enable MQTT #ifdef USE_EMULATION - UdpDisconnect(); #if defined(USE_EMULATION_WEMO) || defined(USE_EMULATION_HUE) - WebGetArg(PSTR("b2"), tmp, sizeof(tmp)); - Settings.flag2.emulation = (!strlen(tmp)) ? 0 : atoi(tmp); + WebGetArg(PSTR("b2"), tmp1, sizeof(tmp1)); // Emulation + snprintf_P(command, sizeof(command), PSTR("%s;" D_CMND_EMULATION " %s"), command, (!strlen(tmp1)) ? "0" : tmp1); #endif // USE_EMULATION_WEMO || USE_EMULATION_HUE #endif // USE_EMULATION - snprintf_P(message, sizeof(message), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_DEVICENAME " %s, " D_CMND_FRIENDLYNAME), - GetStateText(Settings.flag.mqtt_enabled), Settings.flag2.emulation, SettingsText(SET_DEVICENAME)); - for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) { - snprintf_P(webindex, sizeof(webindex), PSTR("a%d"), i); - WebGetArg(webindex, tmp, sizeof(tmp)); - snprintf_P(friendlyname, sizeof(friendlyname), PSTR(FRIENDLY_NAME"%d"), i +1); - SettingsUpdateText(SET_FRIENDLYNAME1 +i, (!strlen(tmp)) ? (i) ? friendlyname : PSTR(FRIENDLY_NAME) : tmp); - snprintf_P(message, sizeof(message), PSTR("%s%s %s"), message, (i) ? "," : "", SettingsText(SET_FRIENDLYNAME1 +i)); - } - AddLogData(LOG_LEVEL_INFO, message); - - WebGetArg(PSTR("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(F("t2"))) ? PSTR("; " D_CMND_MODULE " 0") : ""); - ExecuteWebCommand(message); + WebGetArg(PSTR("t1"), tmp1, sizeof(tmp1)); // Template + if (strlen(tmp1)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} + snprintf_P(command, sizeof(command), PSTR("%s;" D_CMND_TEMPLATE " %s%s"), command, tmp1, (Webserver->hasArg(F("t2"))) ? PSTR("; " D_CMND_MODULE " 0") : ""); } + ExecuteWebCommand(command); } /*-------------------------------------------------------------------------------------------*/ @@ -3018,10 +3003,16 @@ void CmndWebServer(void) void CmndWebPassword(void) { + bool show_asterisk = (2 == XdrvMailbox.index); if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_WEBPWD, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? WEB_PASSWORD : XdrvMailbox.data); - ResponseCmndChar(SettingsText(SET_WEBPWD)); + if (!show_asterisk) { + ResponseCmndChar(SettingsText(SET_WEBPWD)); + } } else { + show_asterisk = true; + } + if (show_asterisk) { Response_P(S_JSON_COMMAND_ASTERISK, XdrvMailbox.command); } } @@ -3105,7 +3096,7 @@ void CmndWebButton(void) void CmndCors(void) { if (XdrvMailbox.data_len > 0) { - SettingsUpdateText(SET_CORS, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? WEB_PASSWORD : XdrvMailbox.data); + SettingsUpdateText(SET_CORS, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? CORS_DOMAIN : XdrvMailbox.data); } ResponseCmndChar(SettingsText(SET_CORS)); } From 970f4652f5dd11c96b91a9dd35c63dcd710d01e2 Mon Sep 17 00:00:00 2001 From: Simon Hailes Date: Thu, 8 Apr 2021 18:00:14 +0100 Subject: [PATCH 10/67] Update to iBeacon to use only MAC to recognise different beacons - this brings it into line with common use. A further update would be nice to display major & minor in the web ui, not included here. --- tasmota/xsns_52_esp32_ibeacon_ble.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_52_esp32_ibeacon_ble.ino b/tasmota/xsns_52_esp32_ibeacon_ble.ino index 432455924..4ead16697 100644 --- a/tasmota/xsns_52_esp32_ibeacon_ble.ino +++ b/tasmota/xsns_52_esp32_ibeacon_ble.ino @@ -337,7 +337,7 @@ uint32_t ibeacon_add(struct IBEACON *ib) { if (!strncmp(ib->MAC,"FFFF",4) || strncmp(ib->FACID,"00000000",8)) { for (uint32_t cnt=0;cntUID,PSTR("00000000000000000000000000000000"),32)) { +// if (!strncmp_P(ib->UID,PSTR("00000000000000000000000000000000"),32)) { if (!strncmp(ibeacons[cnt].MAC,ib->MAC,12)) { // exists strncpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME)); @@ -350,7 +350,7 @@ uint32_t ibeacon_add(struct IBEACON *ib) { ibeacons[cnt].count++; return 2; } - } else { +/* } else { if (!strncmp(ibeacons[cnt].UID,ib->UID,32)) { // exists strncpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME)); @@ -363,7 +363,7 @@ uint32_t ibeacon_add(struct IBEACON *ib) { ibeacons[cnt].count++; return 2; } - } + }*/ } } for (uint32_t cnt=0;cnt Date: Thu, 8 Apr 2021 20:02:19 +0200 Subject: [PATCH 11/67] first try of command management --- tasmota/xnrg_15_teleinfo.ino | 192 ++++++++++++++++++++++++++++------- 1 file changed, 155 insertions(+), 37 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index c1e0fc9d9..604936a82 100755 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -38,6 +38,28 @@ #define TINFO_READ_TIMEOUT 400 +#define D_NAME_TELEINFO "Teleinfo" + +// Json Command +const char S_JSON_TELEINFO_COMMAND_STRING[] PROGMEM = "{\"" D_NAME_TELEINFO "\":{\"%s\":%s}}"; +const char S_JSON_TELEINFO_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_TELEINFO "\":{\"%s\":%d}}"; +const char S_JSON_TELEINFO_COMMAND_SETTINGS[] PROGMEM = "{\"TIC_Settings\":{\"Mode\":%s,\"Raw\":%s,\"Skip\":%d,\"Limit\":%d}}"; + +#define MAX_TINFO_COMMAND_NAME 17 // Change this if one of the following kTInfo_Commands is higher then 16 char +const char kTInfo_Commands[] PROGMEM = "historique|standard|none|full|changed|skip|limit|config"; + +enum TInfoCommands { // commands for Console + CMND_TELEINFO_HISTORIQUE=0, // Set Legacy mode + CMND_TELEINFO_STANDARD, // Set Standard Mode + CMND_TELEINFO_RAW_DISABLE, // Disable Raw frame sending + CMND_TELEINFO_RAW_FULL, // Enable all RAW frame send + CMND_TELEINFO_RAW_CHANGE, // Enable only changed values RAW frame send + CMND_TELEINFO_SKIP, // Set number of frame to skip when raw mode is enabled + CMND_TELEINFO_LIMIT, // Limit RAW frame to values subject to fast change (Power, Current, ...), TBD + CMND_TELEINFO_CONFIG // Show Teleinfo current settings +}; + + // All contract type for legacy, standard mode has in clear text enum TInfoContrat{ CONTRAT_BAS = 1, // BASE => Option Base. @@ -126,6 +148,7 @@ bool tinfo_found = false; int contrat; int tarif; int isousc; +int raw_skip; /*********************************************************************************************/ @@ -366,10 +389,11 @@ void DataCallback(struct _ValueList * me, uint8_t flags) Function: responseDumpTInfo Purpose : add teleinfo values into JSON response Input : 1st separator space if begining of JSON, else comma + : select if append all data or just changed one Output : - Comments: - ====================================================================== */ -void ResponseAppendTInfo(char sep) +void ResponseAppendTInfo(char sep, bool all) { struct _ValueList * me = tinfo.getList(); @@ -383,32 +407,37 @@ void ResponseAppendTInfo(char sep) me = me->next; if (me->name && me->value && *me->name && *me->value) { - isNumber = true; - p = me->value; - // Specific treatment serial number don't convert to number later - if (strcmp(me->name, "ADCO")==0 || strcmp(me->name, "ADSC")==0) { - isNumber = false; - } else { - // check if value is number - while (*p && isNumber) { - if ( *p < '0' || *p > '9' ) { - isNumber = false; + // Add values only if we want all data or if data has changed + if (all || ( Settings.teleinfo.raw_report_changed && (me->flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED | TINFO_FLAGS_ALERT) ) ) ) { + + isNumber = true; + p = me->value; + + // Specific treatment serial number don't convert to number later + if (strcmp(me->name, "ADCO")==0 || strcmp(me->name, "ADSC")==0) { + isNumber = false; + } else { + // check if value is number + while (*p && isNumber) { + if ( *p < '0' || *p > '9' ) { + isNumber = false; + } + p++; } - p++; } + + ResponseAppend_P( PSTR("%c\"%s\":"), sep, me->name ); + + if (!isNumber) { + ResponseAppend_P( PSTR("\"%s\""), me->value ); + } else { + ResponseAppend_P( PSTR("%d"), atoi(me->value)); + } + + // Now JSON separator is needed + sep =','; } - - ResponseAppend_P( PSTR("%c\"%s\":"), sep, me->name ); - - if (!isNumber) { - ResponseAppend_P( PSTR("\"%s\""), me->value ); - } else { - ResponseAppend_P( PSTR("%d"), atoi(me->value)); - } - - // Now JSON separator is needed - sep =','; } } } @@ -425,15 +454,28 @@ void NewFrameCallback(struct _ValueList * me) // Reset Energy Watchdog Energy.data_valid[0] = 0; - // send teleinfo full frame only if setup like that - // see setOption108 - if (Settings.flag4.teleinfo_rawdata) { - Response_P(PSTR("{")); - ResponseAppendTInfo(' '); - ResponseJsonEnd(); - // Publish adding ADCO serial number into the topic - // Need setOption4 to be enabled - MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, serialNumber, false); + // Deprecated see setOption108 + // send teleinfo raw data only if setup like that + if (Settings.teleinfo.raw_send) { + // Do we need to skip this frame + if (raw_skip>0) { + raw_skip--; + } + + if (raw_skip == 0 ) { + Response_P(PSTR("{")); + // send teleinfo full frame or only changed data + ResponseAppendTInfo(' ', Settings.teleinfo.raw_report_changed ? false : true ); + ResponseJsonEnd(); + // Publish adding ADCO serial number into the topic + // Need setOption4 to be enabled + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, serialNumber, false); + + // Reset frame skip counter (if 0 it's disabled) + raw_skip = Settings.teleinfo.raw_skip; + } else { + AddLog(LOG_LEVEL_INFO, PSTR("TIC: not sending yet, will do in %d frame(s)"), raw_skip); + } } } @@ -463,9 +505,9 @@ void TInfoInit(void) int baudrate; int serial_buffer_size; - - // SetOption102 - Set Baud rate for Teleinfo serial communication (0 = 1200 or 1 = 9600) - if (Settings.flag4.teleinfo_baudrate) { + // Deprecated SetOption102 - Set Baud rate for Teleinfo serial communication (0 = 1200 or 1 = 9600) + // now set in bit field TeleinfoCfg + if (Settings.teleinfo.mode_standard) { baudrate = 9600; tinfo_mode = TINFO_MODE_STANDARD; serial_buffer_size = TELEINFO_SERIAL_BUFFER_STANDARD; @@ -475,6 +517,7 @@ void TInfoInit(void) serial_buffer_size = TELEINFO_SERIAL_BUFFER_HISTORIQUE; } + if (PinUsed(GPIO_TELEINFO_RX)) { int8_t rx_pin = Pin(GPIO_TELEINFO_RX); AddLog(LOG_LEVEL_INFO, PSTR("TIC: RX on GPIO%d, baudrate %d"), rx_pin, baudrate); @@ -533,11 +576,80 @@ void TInfoInit(void) tinfo.attachNewFrame(NewFrameCallback); tinfo_found = true; + if (Settings.teleinfo.raw_send) { + raw_skip = Settings.teleinfo.raw_skip; + AddLog(LOG_LEVEL_INFO, PSTR("TIC: Raw mode enabled")); + if (raw_skip) { + AddLog(LOG_LEVEL_INFO, PSTR("TIC: Sending only one frame over %d "), raw_skip+1); + } + } AddLog(LOG_LEVEL_INFO, PSTR("TIC: Ready")); } } } + +/* ====================================================================== +Function: TInfoCmd +Purpose : Tasmota core command engine for Teleinfo commands +Input : - +Output : - +Comments: - +====================================================================== */ +bool TInfoCmd(void) { + char command[CMDSZ]; + + uint8_t name_len = strlen(D_NAME_TELEINFO); + + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_TELEINFO), name_len)) { + + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kTInfo_Commands); + switch (command_code) { + case CMND_TELEINFO_STANDARD: + case CMND_TELEINFO_HISTORIQUE: { + char mode_name[MAX_TINFO_COMMAND_NAME]; + if (XdrvMailbox.data_len) { + Settings.teleinfo.mode_standard = command_code == CMND_TELEINFO_STANDARD ? 1 : 0; + // Get the mode and raw name + GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, command_code, kTInfo_Commands); + } + Response_P(S_JSON_TELEINFO_COMMAND_STRING, command, mode_name); + } + break; + + case CMND_TELEINFO_CONFIG: { + if (!XdrvMailbox.data_len) { + char mode_name[MAX_TINFO_COMMAND_NAME]; + char raw_name[MAX_TINFO_COMMAND_NAME]; + + int index_mode = Settings.teleinfo.mode_standard ? CMND_TELEINFO_STANDARD : CMND_TELEINFO_HISTORIQUE; + int index_raw = Settings.teleinfo.raw_send ? CMND_TELEINFO_RAW_FULL : CMND_TELEINFO_RAW_DISABLE; + + if (Settings.teleinfo.raw_send && Settings.teleinfo.raw_report_changed) { + index_raw = CMND_TELEINFO_RAW_CHANGE; + } + + // Get the mode and raw name + GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, index_mode, kTInfo_Commands); + GetTextIndexed(raw_name, MAX_TINFO_COMMAND_NAME, index_raw, kTInfo_Commands); + + Response_P(S_JSON_TELEINFO_COMMAND_SETTINGS, mode_name, raw_name, Settings.teleinfo.raw_skip, Settings.teleinfo.raw_limit ); + } + } + break; + + default: + return false; + } + + return true; + + } else { + return false; + } +} + + /* ====================================================================== Function: TInfoProcess Purpose : Tasmota callback executed often enough to read serial @@ -614,7 +726,7 @@ void TInfoShow(bool json) } // add teleinfo full frame - ResponseAppendTInfo(','); + ResponseAppendTInfo(',', true); #ifdef USE_WEBSERVER } @@ -696,11 +808,17 @@ void TInfoShow(bool json) \*********************************************************************************************/ bool Xnrg15(uint8_t function) { + bool result = false; switch (function) { case FUNC_EVERY_250_MSECOND: TInfoProcess(); break; + case FUNC_COMMAND: + AddLog(LOG_LEVEL_INFO, PSTR("TIC: FUNC_COMMAND")); + result = TInfoCmd(); + break; + case FUNC_JSON_APPEND: TInfoShow(1); break; @@ -716,7 +834,7 @@ bool Xnrg15(uint8_t function) TInfoDrvInit(); break; } - return false; + return result; } #endif // USE_TELEINFO From 66ec23d39986a01099bd5a8cf2ec548f5fc34a19 Mon Sep 17 00:00:00 2001 From: Simon Hailes Date: Thu, 8 Apr 2021 19:08:15 +0100 Subject: [PATCH 12/67] remove endian-swap on major & minor for iBeacon - in theroy to match HM10 implementation? --- tasmota/xsns_52_esp32_ibeacon_ble.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_52_esp32_ibeacon_ble.ino b/tasmota/xsns_52_esp32_ibeacon_ble.ino index 4ead16697..464eefe88 100644 --- a/tasmota/xsns_52_esp32_ibeacon_ble.ino +++ b/tasmota/xsns_52_esp32_ibeacon_ble.ino @@ -233,8 +233,10 @@ int advertismentCallback(BLE_ESP32::ble_advertisment_t *pStruct) memcpy(UUID,oBeacon.getProximityUUID().getNative()->u128.value,16); ESP32BLE_ReverseStr(UUID,16); - uint16_t Major = ENDIAN_CHANGE_U16(oBeacon.getMajor()); - uint16_t Minor = ENDIAN_CHANGE_U16(oBeacon.getMinor()); +// uint16_t Major = ENDIAN_CHANGE_U16(oBeacon.getMajor()); +// uint16_t Minor = ENDIAN_CHANGE_U16(oBeacon.getMinor()); + uint16_t Major = oBeacon.getMajor(); + uint16_t Minor = oBeacon.getMinor(); uint8_t PWR = oBeacon.getSignalPower(); DumpHex((const unsigned char*)&UUID,16,ib.UID); From e9e0d3536871d22a9a69eb8644f5dd47adb700f4 Mon Sep 17 00:00:00 2001 From: Barbudor Date: Thu, 8 Apr 2021 22:59:44 +0200 Subject: [PATCH 13/67] command EnergyConfig --- tasmota/xdrv_03_energy.ino | 14 +++++++++++--- tasmota/xnrg_20_dummy.ino | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index c88995590..f09233069 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -43,7 +43,7 @@ enum EnergyCommands { CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL, CMND_FREQUENCYCAL, - CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS }; + CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS, CMND_NRGCONFIG }; const char kEnergyCommands[] PROGMEM = "|" // No prefix D_CMND_POWERCAL "|" D_CMND_VOLTAGECAL "|" D_CMND_CURRENTCAL "|" D_CMND_FREQUENCYCAL "|" @@ -56,7 +56,7 @@ const char kEnergyCommands[] PROGMEM = "|" // No prefix D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW "|" #endif // USE_ENERGY_POWER_LIMIT #endif // USE_ENERGY_MARGIN_DETECTION - D_CMND_ENERGYRESET "|" D_CMND_TARIFF ; + D_CMND_ENERGYRESET "|" D_CMND_TARIFF "|EnergyConfig"; void (* const EnergyCommand[])(void) PROGMEM = { &CmndPowerCal, &CmndVoltageCal, &CmndCurrentCal, &CmndFrequencyCal, @@ -69,7 +69,7 @@ void (* const EnergyCommand[])(void) PROGMEM = { &CmndSafePower, &CmndSafePowerHold, &CmndSafePowerWindow, #endif // USE_ENERGY_POWER_LIMIT #endif // USE_ENERGY_MARGIN_DETECTION - &CmndEnergyReset, &CmndTariff }; + &CmndEnergyReset, &CmndTariff, &CmndEnergyConfig }; const char kEnergyPhases[] PROGMEM = "|%s / %s|%s / %s / %s||[%s,%s]|[%s,%s,%s]"; @@ -761,6 +761,14 @@ void CmndModuleAddress(void) { } } +void CmndEnergyConfig(void) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NRG: xdrv_03 index:%d"), XdrvMailbox.index); + Energy.command_code = CMND_NRGCONFIG; + if (XnrgCall(FUNC_COMMAND)) { + ResponseCmndDone(); + } +} + #ifdef USE_ENERGY_MARGIN_DETECTION void CmndPowerDelta(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= ENERGY_MAX_PHASES)) { diff --git a/tasmota/xnrg_20_dummy.ino b/tasmota/xnrg_20_dummy.ino index 07b4a22ec..059a4ab1f 100644 --- a/tasmota/xnrg_20_dummy.ino +++ b/tasmota/xnrg_20_dummy.ino @@ -99,6 +99,9 @@ bool NrgDummyCommand(void) { } } } + else if (CMND_NRGCONFIG == Energy.command_code) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NRG: Config payload:%d, data:'%s'"), XdrvMailbox.payload, XdrvMailbox.data ? XdrvMailbox.data : "null" ); + } else serviced = false; // Unknown command return serviced; From 142b7d02aa868bd4279f9970da20d66db65bbebb Mon Sep 17 00:00:00 2001 From: Simon Hailes Date: Fri, 9 Apr 2021 08:19:43 +0100 Subject: [PATCH 14/67] iBeacon - detect the same UUID+MAJOR+MINOR as the same beacon even if mac changes. Add :minor:major to web display --- tasmota/xsns_52_esp32_ibeacon_ble.ino | 39 ++++++++++++++++++++------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/tasmota/xsns_52_esp32_ibeacon_ble.ino b/tasmota/xsns_52_esp32_ibeacon_ble.ino index 464eefe88..b18cbcc99 100644 --- a/tasmota/xsns_52_esp32_ibeacon_ble.ino +++ b/tasmota/xsns_52_esp32_ibeacon_ble.ino @@ -42,6 +42,11 @@ // IBEACON.PERSEC - count of adverts per sec. USeful for detecting button press? // IBEACON.MAJOR - some iBeacon related term? - only present for some // IBEACON.MINOR - some iBeacon related term? - only present for some +// +// Note for Apple iBeacons with UUID,MAJOR,MINOR: +// iBeacons are compared using UUID+MAJOR+MINOR as the unique id rather than MAC address. +// so each of your beacons should have unique MAJOR+MINOR. +// it would be 'normal' for UUID to be identical for a set of iBeacons. //////////////////////////////////////// @@ -89,9 +94,13 @@ struct IBEACON { struct IBEACON_UID { char MAC[12]; char RSSI[4]; + ////////////////////////////// + // DON'T CHANGE THE ORDER HERE + // we reference these as a single field in comparing for 'same' beacon char UID[32]; char MAJOR[4]; char MINOR[4]; + ////////////////////////////// uint8_t FLAGS; uint8_t TIME; uint8_t REPORTED; @@ -339,10 +348,10 @@ uint32_t ibeacon_add(struct IBEACON *ib) { if (!strncmp(ib->MAC,"FFFF",4) || strncmp(ib->FACID,"00000000",8)) { for (uint32_t cnt=0;cntUID,PSTR("00000000000000000000000000000000"),32)) { + if (!strncmp_P(ib->UID,PSTR("00000000000000000000000000000000"),32)) { if (!strncmp(ibeacons[cnt].MAC,ib->MAC,12)) { // exists - strncpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME)); + memcpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME)); memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); ibeacons[cnt].TIME=0; if (ibeacons[cnt].REPTIME >= IB_UPDATE_TIME) { @@ -352,10 +361,15 @@ uint32_t ibeacon_add(struct IBEACON *ib) { ibeacons[cnt].count++; return 2; } -/* } else { - if (!strncmp(ibeacons[cnt].UID,ib->UID,32)) { + } else { + // iBeacons from a phone can change thier MAC frequently. + // but it is intended that UUID+MAJOR+MINOR are unique. + // so if we find the SAME UUID+MAJOR+MINOR, then update the MAC and assume the same device. + // NOT: THIS RELIES ON THE STRUCTURE ORDER + if (!strncmp(ibeacons[cnt].UID,ib->UID,sizeof(ib->UID)+sizeof(ib->MAJOR)+sizeof(ib->MINOR))) { // exists - strncpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME)); + memcpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME)); + memcpy(ibeacons[cnt].MAC,ib->MAC,12); memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); ibeacons[cnt].TIME=0; if (ibeacons[cnt].REPTIME >= IB_UPDATE_TIME) { @@ -365,12 +379,12 @@ uint32_t ibeacon_add(struct IBEACON *ib) { ibeacons[cnt].count++; return 2; } - }*/ + } } } for (uint32_t cnt=0;cntNAME,sizeof(ibeacons[cnt].NAME)); + memcpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME)); memcpy(ibeacons[cnt].MAC,ib->MAC,12); memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); memcpy(ibeacons[cnt].UID,ib->UID,32); @@ -378,7 +392,6 @@ uint32_t ibeacon_add(struct IBEACON *ib) { memcpy(ibeacons[cnt].MINOR,ib->MINOR,4); ibeacons[cnt].FLAGS=1; ibeacons[cnt].TIME=0; - memcpy(ibeacons[cnt].NAME,ib->NAME,16); ibeacons[cnt].REPTIME = 0; ibeacons[cnt].REPORTED = 0; ibeacons[cnt].count = 0; @@ -416,13 +429,15 @@ const char HTTP_IBEACON_HL[] PROGMEM = "{s}
{m}
{e}"; const char HTTP_IBEACON_mac[] PROGMEM = "{s}IBEACON-MAC : %s" " {m} RSSI : %s" "{e}"; const char HTTP_IBEACON_uid[] PROGMEM = - "{s}IBEACON-UID : %s" " {m} RSSI : %s" "{e}"; + "{s}IBEACON-UID : %s:%s:%s" " {m} RSSI : %s" "{e}"; const char HTTP_IBEACON_name[] PROGMEM = "{s}IBEACON-NAME : %s (%s)" " {m} RSSI : %s" "{e}"; void IBEACON_Show(void) { char mac[14]; char rssi[6]; char uid[34]; + char major[6]; + char minor[6]; char name[18]; //TasAutoMutex localmutex(&beaconmutex, "iBeacShow"); int total = 0; @@ -436,6 +451,10 @@ void IBEACON_Show(void) { rssi[4]=0; memcpy(uid,ibeacons[cnt].UID,32); uid[32]=0; + memcpy(major,ibeacons[cnt].MAJOR,4); + major[4]=0; + memcpy(minor,ibeacons[cnt].MINOR,4); + minor[4]=0; memcpy(name,ibeacons[cnt].NAME,16); name[16]=0; if (!strncmp_P(uid,PSTR("00000000000000000000000000000000"),32)) { @@ -445,7 +464,7 @@ void IBEACON_Show(void) { WSContentSend_PD(HTTP_IBEACON_mac,mac,rssi); } } else { - WSContentSend_PD(HTTP_IBEACON_uid,uid,rssi); + WSContentSend_PD(HTTP_IBEACON_uid,uid,major,minor,rssi); } } } From 740e4392ef9228127de9d8c78628e16bdc3bff91 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Apr 2021 09:49:33 +0200 Subject: [PATCH 15/67] Add command EnergyConfig for future use --- tasmota/i18n.h | 1 + tasmota/xdrv_03_energy.ino | 13 ++++++------- tasmota/xnrg_20_dummy.ino | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 0fdcb4473..9799fbe90 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -421,6 +421,7 @@ #define D_CMND_VOLTAGESET "VoltageSet" #define D_CMND_CURRENTSET "CurrentSet" #define D_CMND_FREQUENCYSET "FrequencySet" +#define D_CMND_ENERGYCONFIG "EnergyConfig" #define D_CMND_MAXPOWER "MaxPower" #define D_CMND_MAXPOWERHOLD "MaxPowerHold" #define D_CMND_MAXPOWERWINDOW "MaxPowerWindow" diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index f09233069..d15e873cd 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -43,11 +43,11 @@ enum EnergyCommands { CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL, CMND_FREQUENCYCAL, - CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS, CMND_NRGCONFIG }; + CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS, CMND_ENERGYCONFIG }; const char kEnergyCommands[] PROGMEM = "|" // No prefix D_CMND_POWERCAL "|" D_CMND_VOLTAGECAL "|" D_CMND_CURRENTCAL "|" D_CMND_FREQUENCYCAL "|" - D_CMND_POWERSET "|" D_CMND_VOLTAGESET "|" D_CMND_CURRENTSET "|" D_CMND_FREQUENCYSET "|" D_CMND_MODULEADDRESS "|" + D_CMND_POWERSET "|" D_CMND_VOLTAGESET "|" D_CMND_CURRENTSET "|" D_CMND_FREQUENCYSET "|" D_CMND_MODULEADDRESS "|" D_CMND_ENERGYCONFIG "|" #ifdef USE_ENERGY_MARGIN_DETECTION D_CMND_POWERDELTA "|" D_CMND_POWERLOW "|" D_CMND_POWERHIGH "|" D_CMND_VOLTAGELOW "|" D_CMND_VOLTAGEHIGH "|" D_CMND_CURRENTLOW "|" D_CMND_CURRENTHIGH "|" #ifdef USE_ENERGY_POWER_LIMIT @@ -56,11 +56,11 @@ const char kEnergyCommands[] PROGMEM = "|" // No prefix D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW "|" #endif // USE_ENERGY_POWER_LIMIT #endif // USE_ENERGY_MARGIN_DETECTION - D_CMND_ENERGYRESET "|" D_CMND_TARIFF "|EnergyConfig"; + D_CMND_ENERGYRESET "|" D_CMND_TARIFF; void (* const EnergyCommand[])(void) PROGMEM = { &CmndPowerCal, &CmndVoltageCal, &CmndCurrentCal, &CmndFrequencyCal, - &CmndPowerSet, &CmndVoltageSet, &CmndCurrentSet, &CmndFrequencySet, &CmndModuleAddress, + &CmndPowerSet, &CmndVoltageSet, &CmndCurrentSet, &CmndFrequencySet, &CmndModuleAddress, &CmndEnergyConfig, #ifdef USE_ENERGY_MARGIN_DETECTION &CmndPowerDelta, &CmndPowerLow, &CmndPowerHigh, &CmndVoltageLow, &CmndVoltageHigh, &CmndCurrentLow, &CmndCurrentHigh, #ifdef USE_ENERGY_POWER_LIMIT @@ -69,7 +69,7 @@ void (* const EnergyCommand[])(void) PROGMEM = { &CmndSafePower, &CmndSafePowerHold, &CmndSafePowerWindow, #endif // USE_ENERGY_POWER_LIMIT #endif // USE_ENERGY_MARGIN_DETECTION - &CmndEnergyReset, &CmndTariff, &CmndEnergyConfig }; + &CmndEnergyReset, &CmndTariff}; const char kEnergyPhases[] PROGMEM = "|%s / %s|%s / %s / %s||[%s,%s]|[%s,%s,%s]"; @@ -762,8 +762,7 @@ void CmndModuleAddress(void) { } void CmndEnergyConfig(void) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("NRG: xdrv_03 index:%d"), XdrvMailbox.index); - Energy.command_code = CMND_NRGCONFIG; + Energy.command_code = CMND_ENERGYCONFIG; if (XnrgCall(FUNC_COMMAND)) { ResponseCmndDone(); } diff --git a/tasmota/xnrg_20_dummy.ino b/tasmota/xnrg_20_dummy.ino index 059a4ab1f..0c70d6998 100644 --- a/tasmota/xnrg_20_dummy.ino +++ b/tasmota/xnrg_20_dummy.ino @@ -99,8 +99,9 @@ bool NrgDummyCommand(void) { } } } - else if (CMND_NRGCONFIG == Energy.command_code) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("NRG: Config payload:%d, data:'%s'"), XdrvMailbox.payload, XdrvMailbox.data ? XdrvMailbox.data : "null" ); + else if (CMND_ENERGYCONFIG == Energy.command_code) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NRG: Config index %d, payload %d, data '%s'"), + XdrvMailbox.index, XdrvMailbox.payload, XdrvMailbox.data ? XdrvMailbox.data : "null" ); } else serviced = false; // Unknown command From 0650744ac27108931a070918f08173d71ddfd68d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Apr 2021 10:04:37 +0200 Subject: [PATCH 16/67] Remove overtemp detection on external energy monitoring devices Removed overtemp detection on external energy monitoring devices (#11628) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/xdrv_03_energy.ino | 3 ++- tasmota/xnrg_01_hlw8012.ino | 3 ++- tasmota/xnrg_02_cse7766.ino | 3 ++- tasmota/xnrg_04_mcp39f501.ino | 1 + tasmota/xnrg_07_ade7953.ino | 1 + tasmota/xnrg_14_bl0940.ino | 1 + tasmota/xnrg_19_cse7761.ino | 1 + tasmota/xnrg_20_dummy.ino | 2 ++ 10 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5020417d5..543d6f1f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ All notable changes to this project will be documented in this file. - Limit number of relay/button columns in GUI to 8 (#11546) - ADC range result from int to float using command ``FreqRes`` for decimal resolution selection (#11545) - Teleinfo, if raw mode selected also return telemety values in SENSOR data +- Removed overtemp detection on external energy monitoring devices (#11628) ### Fixed - HC-SR04 on ESP32 release serial interface if not used (#11507) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4a490aa04..713e7fb19 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -115,6 +115,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - DeepSleep announcement topic [#11223](https://github.com/arendst/Tasmota/issues/11223) - Limit number of relay/button columns in GUI to 8 [#11546](https://github.com/arendst/Tasmota/issues/11546) - ADC range result from int to float using command ``FreqRes`` for decimal resolution selection [#11545](https://github.com/arendst/Tasmota/issues/11545) +- Removed overtemp detection on external energy monitoring devices [#11628](https://github.com/arendst/Tasmota/issues/11628) ### Fixed - PN532 on ESP32 Serial flush both Tx and Rx buffers [#10910](https://github.com/arendst/Tasmota/issues/10910) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index d15e873cd..9351ceb9b 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -102,6 +102,7 @@ struct ENERGY { uint8_t phase_count; // Number of phases active bool voltage_common; // Use single voltage bool frequency_common; // Use single frequency + bool use_overtemp; // Use global temperature as overtemp trigger on internal energy monitor hardware bool kWhtoday_offset_init; bool voltage_available; // Enable if voltage is measured @@ -501,7 +502,7 @@ void EnergyMqttShow(void) void EnergyEverySecond(void) { // Overtemp check - if (TasmotaGlobal.global_update) { + if (Energy.use_overtemp && TasmotaGlobal.global_update) { if (TasmotaGlobal.power && !isnan(TasmotaGlobal.temperature_celsius) && (TasmotaGlobal.temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // SetOption42 Device overtemp, turn off relays AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Temperature %1_f"), &TasmotaGlobal.temperature_celsius); diff --git a/tasmota/xnrg_01_hlw8012.ino b/tasmota/xnrg_01_hlw8012.ino index 4f83c8e19..0c04e0e80 100644 --- a/tasmota/xnrg_01_hlw8012.ino +++ b/tasmota/xnrg_01_hlw8012.ino @@ -269,7 +269,8 @@ void HlwDrvInit(void) Energy.current_available = false; Energy.voltage_available = false; } - + Energy.use_overtemp = true; // Use global temperature for overtemp detection + TasmotaGlobal.energy_driver = XNRG_01; } } diff --git a/tasmota/xnrg_02_cse7766.ino b/tasmota/xnrg_02_cse7766.ino index 24c7fcc09..e925d9b6b 100644 --- a/tasmota/xnrg_02_cse7766.ino +++ b/tasmota/xnrg_02_cse7766.ino @@ -221,7 +221,7 @@ void CseSnsInit(void) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions // CseSerial = new TasmotaSerial(Pin(GPIO_CSE7766_RX), Pin(GPIO_CSE7766_TX), 1); CseSerial = new TasmotaSerial(Pin(GPIO_CSE7766_RX), -1, 1); - if (CseSerial->begin(4800, 2)) { // Fake Software Serial 8E1 by using two stop bits + if (CseSerial->begin(4800, SERIAL_8E1)) { if (CseSerial->hardwareSerial()) { SetSerial(4800, TS_SERIAL_8E1); ClaimSerial(); @@ -230,6 +230,7 @@ void CseSnsInit(void) { Settings.param[P_CSE7766_INVALID_POWER] = CSE_MAX_INVALID_POWER; // SetOption39 1..255 } Cse.power_invalid = Settings.param[P_CSE7766_INVALID_POWER]; + Energy.use_overtemp = true; // Use global temperature for overtemp detection } else { TasmotaGlobal.energy_driver = ENERGY_NONE; } diff --git a/tasmota/xnrg_04_mcp39f501.ino b/tasmota/xnrg_04_mcp39f501.ino index d71402dfa..395f66852 100644 --- a/tasmota/xnrg_04_mcp39f501.ino +++ b/tasmota/xnrg_04_mcp39f501.ino @@ -573,6 +573,7 @@ void McpSnsInit(void) mcp_buffer = (char*)(malloc(MCP_BUFFER_SIZE)); } DigitalWrite(GPIO_MCP39F5_RST, 0, 1); // MCP enable + Energy.use_overtemp = true; // Use global temperature for overtemp detection } else { TasmotaGlobal.energy_driver = ENERGY_NONE; } diff --git a/tasmota/xnrg_07_ade7953.ino b/tasmota/xnrg_07_ade7953.ino index f2c5802a2..5da3ec952 100644 --- a/tasmota/xnrg_07_ade7953.ino +++ b/tasmota/xnrg_07_ade7953.ino @@ -215,6 +215,7 @@ void Ade7953DrvInit(void) Energy.phase_count = 2; // Handle two channels as two phases Energy.voltage_common = true; // Use common voltage Energy.frequency_common = true; // Use common frequency + Energy.use_overtemp = true; // Use global temperature for overtemp detection TasmotaGlobal.energy_driver = XNRG_07; } } diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index 81a9d4791..00a69c323 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -219,6 +219,7 @@ void Bl0940SnsInit(void) { Settings.energy_current_calibration = BL0940_IREF; Settings.energy_power_calibration = BL0940_PREF; } + Energy.use_overtemp = true; // Use global temperature for overtemp detection for (uint32_t i = 0; i < 5; i++) { for (uint32_t j = 0; j < 6; j++) { diff --git a/tasmota/xnrg_19_cse7761.ino b/tasmota/xnrg_19_cse7761.ino index a644c48f4..478d5db62 100644 --- a/tasmota/xnrg_19_cse7761.ino +++ b/tasmota/xnrg_19_cse7761.ino @@ -600,6 +600,7 @@ void Cse7761DrvInit(void) { #ifdef CSE7761_FREQUENCY Energy.frequency_common = true; // Use common frequency #endif + Energy.use_overtemp = true; // Use global temperature for overtemp detection TasmotaGlobal.energy_driver = XNRG_19; } } diff --git a/tasmota/xnrg_20_dummy.ino b/tasmota/xnrg_20_dummy.ino index 0c70d6998..f1bac903b 100644 --- a/tasmota/xnrg_20_dummy.ino +++ b/tasmota/xnrg_20_dummy.ino @@ -33,6 +33,7 @@ #define NRG_DUMMY_U_COMMON true // Phase voltage = false, Common voltage = true #define NRG_DUMMY_F_COMMON true // Phase frequency = false, Common frequency = true #define NRG_DUMMY_DC false // AC = false, DC = true; +#define NRG_DUMMY_OVERTEMP true // Use global temperature for overtemp detection #define NRG_DUMMY_UREF 24000 // Voltage 240.00 V (= P / I) #define NRG_DUMMY_IREF 41666 // Current 0.417 A (= P / U) @@ -121,6 +122,7 @@ void NrgDummyDrvInit(void) { Energy.voltage_common = NRG_DUMMY_U_COMMON; // Phase voltage = false, Common voltage = true Energy.frequency_common = NRG_DUMMY_F_COMMON; // Phase frequency = false, Common frequency = true Energy.type_dc = NRG_DUMMY_DC; // AC = false, DC = true; + Energy.use_overtemp = NRG_DUMMY_OVERTEMP; // Use global temperature for overtemp detection TasmotaGlobal.energy_driver = XNRG_20; } From b8f2c97fbef35f04ac9a0f37aa0d4564e1d3c2f8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Apr 2021 12:18:26 +0200 Subject: [PATCH 17/67] Refactor GUI save settings (prt3) --- tasmota/xdrv_01_webserver.ino | 16 +++++------ tasmota/xdrv_07_domoticz.ino | 51 ++++++++++++++++------------------- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index b409b25b2..e61df582f 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1505,16 +1505,16 @@ uint16_t WebGetGpioArg(uint32_t i) { void TemplateSaveSettings(void) { char tmp[TOPSZ]; // WebGetArg NAME and GPIO/BASE/FLAG byte value - char svalue[300]; // Template command string + char command[300]; // Template command string WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // NAME - snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp); + snprintf_P(command, sizeof(command), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp); uint32_t j = 0; for (uint32_t i = 0; i < nitems(Settings.user_template.gp.io); i++) { if (6 == i) { j = 9; } if (8 == i) { j = 12; } - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s%d"), svalue, (i>0)?",":"", WebGetGpioArg(j)); + snprintf_P(command, sizeof(command), PSTR("%s%s%d"), command, (i>0)?",":"", WebGetGpioArg(j)); j++; } @@ -1528,8 +1528,8 @@ void TemplateSaveSettings(void) { WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); // BASE uint32_t base = atoi(tmp) +1; - snprintf_P(svalue, sizeof(svalue), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), svalue, flag, base); - ExecuteWebCommand(svalue); + snprintf_P(command, sizeof(command), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), command, flag, base); + ExecuteWebCommand(command); } /*-------------------------------------------------------------------------------------------*/ @@ -1878,7 +1878,7 @@ void LoggingSaveSettings(void) { char tmp7[CMDSZ]; WebGetArg(PSTR("lt"), tmp7, sizeof(tmp7)); // Teleperiod char command[200]; - snprintf_P(command, sizeof(command),PSTR(D_CMND_BACKLOG "0 " D_CMND_SERIALLOG " %s;" D_CMND_WEBLOG " %s;" D_CMND_MQTTLOG " %s;" D_CMND_SYSLOG " %s;" D_CMND_LOGHOST " %s;" D_CMND_LOGPORT " %s;" D_CMND_TELEPERIOD " %s"), + snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_SERIALLOG " %s;" D_CMND_WEBLOG " %s;" D_CMND_MQTTLOG " %s;" D_CMND_SYSLOG " %s;" D_CMND_LOGHOST " %s;" D_CMND_LOGPORT " %s;" D_CMND_TELEPERIOD " %s"), (!strlen(tmp1)) ? STR(SERIAL_LOG_LEVEL) : tmp1, (!strlen(tmp2)) ? STR(WEB_LOG_LEVEL) : tmp2, (!strlen(tmp3)) ? STR(MQTT_LOG_LEVEL) : tmp3, @@ -1958,8 +1958,8 @@ void OtherSaveSettings(void) { WebGetArg(PSTR("dn"), tmp1, sizeof(tmp1)); // Device name char tmp2[100]; WebGetArg(PSTR("wp"), tmp2, sizeof(tmp2)); // Web password - char command[600]; - snprintf_P(command, sizeof(command),PSTR(D_CMND_BACKLOG "0 " D_CMND_WEBPASSWORD "2 %s;" D_CMND_SO "3 %d;" D_CMND_DEVICENAME " %s"), + char command[500]; + snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_WEBPASSWORD "2 %s;" D_CMND_SO "3 %d;" D_CMND_DEVICENAME " %s"), (!strlen(tmp2)) ? "\"" : (strlen(tmp2) < 5) ? "" : tmp2, Webserver->hasArg(F("b1")), // SetOption3 - Enable MQTT (!strlen(tmp1)) ? "\"" : tmp1); diff --git a/tasmota/xdrv_07_domoticz.ino b/tasmota/xdrv_07_domoticz.ino index 5542288dd..f2289aa68 100644 --- a/tasmota/xdrv_07_domoticz.ino +++ b/tasmota/xdrv_07_domoticz.ino @@ -602,36 +602,31 @@ void HandleDomoticzConfiguration(void) { } void DomoticzSaveSettings(void) { - char stemp[20]; - char ssensor_indices[6 * MAX_DOMOTICZ_SNS_IDX]; - char tmp[100]; - - for (uint32_t i = 0; i < MAX_DOMOTICZ_IDX; i++) { - snprintf_P(stemp, sizeof(stemp), PSTR("r%d"), i); - WebGetArg(stemp, tmp, sizeof(tmp)); - Settings.domoticz_relay_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); - snprintf_P(stemp, sizeof(stemp), PSTR("k%d"), i); - WebGetArg(stemp, tmp, sizeof(tmp)); - Settings.domoticz_key_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); - snprintf_P(stemp, sizeof(stemp), PSTR("s%d"), i); - WebGetArg(stemp, tmp, sizeof(tmp)); - Settings.domoticz_switch_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); + char tmp1[CMDSZ]; + WebGetArg(PSTR("ut"), tmp1, sizeof(tmp1)); + char command[500]; + snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_PRFX_DOMOTICZ D_CMND_UPDATETIMER " %s"), + (!strlen(tmp1)) ? STR(DOMOTICZ_UPDATE_TIMER) : tmp1); + char arg_idx[8]; + char tmp2[CMDSZ]; + char tmp3[CMDSZ]; + for (uint32_t i = 1; i <= MAX_DOMOTICZ_IDX; i++) { + snprintf_P(arg_idx, sizeof(arg_idx), PSTR("r%d"), i -1); + WebGetArg(arg_idx, tmp1, sizeof(tmp1)); + arg_idx[0] = 'k'; + WebGetArg(arg_idx, tmp2, sizeof(tmp2)); + arg_idx[0] = 's'; + WebGetArg(arg_idx, tmp3, sizeof(tmp3)); + snprintf_P(command, sizeof(command),PSTR("%s;" D_PRFX_DOMOTICZ D_CMND_IDX "%d %s;" D_PRFX_DOMOTICZ D_CMND_KEYIDX "%d %s;" D_PRFX_DOMOTICZ D_CMND_SWITCHIDX "%d %s"), + command, i, (!strlen(tmp1)) ? "0" : tmp1, i, (!strlen(tmp2)) ? "0" : tmp2, i, (!strlen(tmp3)) ? "0" : tmp3); } - ssensor_indices[0] = '\0'; - for (uint32_t i = 0; i < DZ_MAX_SENSORS; i++) { - snprintf_P(stemp, sizeof(stemp), PSTR("l%d"), i); - WebGetArg(stemp, tmp, sizeof(tmp)); - Settings.domoticz_sensor_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); - snprintf_P(ssensor_indices, sizeof(ssensor_indices), PSTR("%s%s%d"), ssensor_indices, (strlen(ssensor_indices)) ? "," : "", Settings.domoticz_sensor_idx[i]); + for (uint32_t i = 1; i <= DZ_MAX_SENSORS; i++) { + snprintf_P(arg_idx, sizeof(arg_idx), PSTR("l%d"), i -1); + WebGetArg(arg_idx, tmp1, sizeof(tmp1)); + snprintf_P(command, sizeof(command),PSTR("%s;" D_PRFX_DOMOTICZ D_CMND_SENSORIDX "%d %s"), + command, i, (!strlen(tmp1)) ? "0" : tmp1); } - WebGetArg(PSTR("ut"), tmp, sizeof(tmp)); - Settings.domoticz_update_timer = (!strlen(tmp)) ? DOMOTICZ_UPDATE_TIMER : atoi(tmp); - - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_DOMOTICZ D_CMND_IDX " %d,%d,%d,%d, " D_CMND_KEYIDX " %d,%d,%d,%d, " D_CMND_SWITCHIDX " %d,%d,%d,%d, " D_CMND_SENSORIDX " %s, " D_CMND_UPDATETIMER " %d"), - Settings.domoticz_relay_idx[0], Settings.domoticz_relay_idx[1], Settings.domoticz_relay_idx[2], Settings.domoticz_relay_idx[3], - Settings.domoticz_key_idx[0], Settings.domoticz_key_idx[1], Settings.domoticz_key_idx[2], Settings.domoticz_key_idx[3], - Settings.domoticz_switch_idx[0], Settings.domoticz_switch_idx[1], Settings.domoticz_switch_idx[2], Settings.domoticz_switch_idx[3], - ssensor_indices, Settings.domoticz_update_timer); + ExecuteWebCommand(command); // Note: beware of max number of commands in backlog currently 30 (MAX_BACKLOG) } #endif // USE_WEBSERVER From dd7cecc064193f02a66843d0607ede52c463ea9b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Apr 2021 12:49:57 +0200 Subject: [PATCH 18/67] Fix backlog nodelay when sleep is active --- tasmota/support_command.ino | 4 ++++ tasmota/tasmota.ino | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b0f4d7b2d..b81a86b10 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -323,7 +323,11 @@ void CmndBacklog(void) { if (XdrvMailbox.data_len) { if (0 == XdrvMailbox.index) { + if (!TasmotaGlobal.backlog_nodelay) { + TasmotaGlobal.backlog_sleep = TasmotaGlobal.sleep; + } TasmotaGlobal.backlog_nodelay = true; + TasmotaGlobal.sleep = 0; } #ifdef SUPPORT_IF_STATEMENT diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 38aa5a8ef..94bda17b7 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -170,6 +170,7 @@ struct { uint8_t latching_relay_pulse; // Latching relay pulse timer uint8_t active_device; // Active device in ExecuteCommandPower uint8_t sleep; // Current copy of Settings.sleep + uint8_t backlog_sleep; // Copy of sleep uint8_t leds_present; // Max number of LED supported uint8_t led_inverted; // LED inverted flag (1 = (0 = On, 1 = Off)) uint8_t led_power; // LED power state @@ -404,8 +405,9 @@ void BacklogLoop(void) { } TasmotaGlobal.backlog_mutex = false; } - if (BACKLOG_EMPTY) { + if (BACKLOG_EMPTY && TasmotaGlobal.backlog_nodelay) { TasmotaGlobal.backlog_nodelay = false; + TasmotaGlobal.sleep = TasmotaGlobal.backlog_sleep; } } } From 60de9696d88e813fec21a9b88c4c5bb70251993c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Apr 2021 14:00:09 +0200 Subject: [PATCH 19/67] Refactor backlog nodelay in relation to sleep --- tasmota/support_command.ino | 4 ---- tasmota/tasmota.ino | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b81a86b10..b0f4d7b2d 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -323,11 +323,7 @@ void CmndBacklog(void) { if (XdrvMailbox.data_len) { if (0 == XdrvMailbox.index) { - if (!TasmotaGlobal.backlog_nodelay) { - TasmotaGlobal.backlog_sleep = TasmotaGlobal.sleep; - } TasmotaGlobal.backlog_nodelay = true; - TasmotaGlobal.sleep = 0; } #ifdef SUPPORT_IF_STATEMENT diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 94bda17b7..b9e94829a 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -170,7 +170,6 @@ struct { uint8_t latching_relay_pulse; // Latching relay pulse timer uint8_t active_device; // Active device in ExecuteCommandPower uint8_t sleep; // Current copy of Settings.sleep - uint8_t backlog_sleep; // Copy of sleep uint8_t leds_present; // Max number of LED supported uint8_t led_inverted; // LED inverted flag (1 = (0 = On, 1 = Off)) uint8_t led_power; // LED power state @@ -405,15 +404,14 @@ void BacklogLoop(void) { } TasmotaGlobal.backlog_mutex = false; } - if (BACKLOG_EMPTY && TasmotaGlobal.backlog_nodelay) { + if (BACKLOG_EMPTY) { TasmotaGlobal.backlog_nodelay = false; - TasmotaGlobal.sleep = TasmotaGlobal.backlog_sleep; } } } void SleepDelay(uint32_t mseconds) { - if (mseconds) { + if (!TasmotaGlobal.backlog_nodelay && mseconds) { uint32_t wait = millis() + mseconds; while (!TimeReached(wait) && !Serial.available()) { // We need to service serial buffer ASAP as otherwise we get uart buffer overrun delay(1); From 77cd07ab8be53a60f5e6eb009e503f4811109aa1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Apr 2021 16:42:51 +0200 Subject: [PATCH 20/67] Fix display driver 16 support --- tasmota/tasmota_template.h | 5 +++++ ...xdsp_16_epaper_47.ino => xdsp_16_esp32_epaper_47.ino} | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) rename tasmota/{xdsp_16_epaper_47.ino => xdsp_16_esp32_epaper_47.ino} (94%) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index ae4741ff8..70bcff270 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -160,6 +160,7 @@ enum UserSelectablePins { GPIO_ZEROCROSS, #ifdef ESP32 GPIO_HALLEFFECT, + GPIO_EPD_DATA, // Base connection EPD driver #endif GPIO_SENSOR_END }; @@ -341,6 +342,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_ZEROCROSS "|" #ifdef ESP32 D_SENSOR_HALLEFFECT "|" + D_SENSOR_EPD_DATA "|" #endif ; @@ -470,6 +472,9 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_DISPLAY_TM1637 AGPIO(GPIO_BACKLIGHT), // Display backlight control AGPIO(GPIO_OLED_RESET), // OLED Display Reset +#ifdef ESP32 + AGPIO(GPIO_EPD_DATA), // Base connection EPD driver +#endif #endif // USE_DISPLAY #ifdef USE_MAX31865 diff --git a/tasmota/xdsp_16_epaper_47.ino b/tasmota/xdsp_16_esp32_epaper_47.ino similarity index 94% rename from tasmota/xdsp_16_epaper_47.ino rename to tasmota/xdsp_16_esp32_epaper_47.ino index d56651a6f..63605c42a 100644 --- a/tasmota/xdsp_16_epaper_47.ino +++ b/tasmota/xdsp_16_esp32_epaper_47.ino @@ -1,5 +1,5 @@ /* - xdsp_16_epaper_47.ino - LILIGO47 e-paper support for Tasmota + xdsp_16_esp32_epaper_47.ino - LILIGO47 e-paper support for Tasmota Copyright (C) 2021 Theo Arends, Gerhard Mutz and LILIGO @@ -17,7 +17,7 @@ along with this program. If not, see . */ - +#ifdef ESP32 #ifdef USE_DISPLAY #ifdef USE_LILYGO47 @@ -37,8 +37,8 @@ extern uint16_t bg_color; /*********************************************************************************************/ void EpdInitDriver47(void) { + if (PinUsed(GPIO_EPD_DATA)) { - if (1) { Settings.display_model = XDSP_16; if (Settings.display_width != EPD47_WIDTH) { @@ -96,5 +96,6 @@ bool Xdsp16(uint8_t function) return result; } -#endif // USE_DISPLAY_EPAPER +#endif // USE_LILYGO47 #endif // USE_DISPLAY +#endif // ESP32 \ No newline at end of file From eb3fe9c5eb5fdd82becb74ff4bdf7717cfae7cb5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Apr 2021 17:05:22 +0200 Subject: [PATCH 21/67] Oops. Fix compile --- tasmota/language/af_AF.h | 2 +- tasmota/language/bg_BG.h | 2 +- tasmota/language/cs_CZ.h | 2 +- tasmota/language/de_DE.h | 2 +- tasmota/language/el_GR.h | 2 +- tasmota/language/en_GB.h | 2 +- tasmota/language/es_ES.h | 2 +- tasmota/language/fr_FR.h | 2 +- tasmota/language/fy_NL.h | 2 +- tasmota/language/he_HE.h | 2 +- tasmota/language/hu_HU.h | 2 +- tasmota/language/it_IT.h | 2 +- tasmota/language/ko_KO.h | 2 +- tasmota/language/nl_NL.h | 2 +- tasmota/language/pl_PL.h | 2 +- tasmota/language/pt_BR.h | 2 +- tasmota/language/pt_PT.h | 2 +- tasmota/language/ro_RO.h | 2 +- tasmota/language/ru_RU.h | 2 +- tasmota/language/sk_SK.h | 2 +- tasmota/language/sv_SE.h | 2 +- tasmota/language/tr_TR.h | 2 +- tasmota/language/uk_UA.h | 2 +- tasmota/language/vi_VN.h | 2 +- tasmota/language/zh_CN.h | 2 +- tasmota/language/zh_TW.h | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 989e5636d..6d4500990 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 0dfbe2b13..d37361752 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -809,7 +809,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 91929e163..a4405b404 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index a6bb7e8a6..f8831c5ad 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Puls" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 9b694ad22..969718b10 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 54c33fec0..52dadf8d9 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 74ec56458..8487e5e6d 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "Cruce por cero" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 8d5772871..545341bfb 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 594a67785..a3aa1c6fa 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index ce16e050f..60c37d543 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 905bb4cb4..195172128 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index e35a9a2e8..2ae9b97cb 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ - RX" #define D_SENSOR_ZEROCROSS "Impulsi ZC" #define D_SENSOR_HALLEFFECT "Effetto hall" - +#define D_SENSOR_EPD_DATA "EPD - Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 74e3caddc..ca33d2207 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 618990ea2..e90b2db19 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 8db1978fa..af6185933 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index e95c48a9b..cc05a5552 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index fbc55ab05..23cd2a44d 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 19d1c59e8..0bcf7674b 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 7549ce1bb..f8a33be61 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index ab6bf0649..1510a1546 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 5ebdfcd4b..7166c6687 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 2b1660f05..51b297bb8 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 816ea4381..2d3de8097 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 993dce616..9b8fce166 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index c7f21781f..aced421f3 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 3af05b2cd..2c83e5dc0 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" #define D_SENSOR_ZEROCROSS "ZC Pulse" #define D_SENSOR_HALLEFFECT "HallEffect" - +#define D_SENSOR_EPD_DATA "EPD Data" // Units #define D_UNIT_AMPERE "安培" From 19ddda132c998cba0bda82dfd78ddcdc65e378ca Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 9 Apr 2021 19:45:06 +0200 Subject: [PATCH 22/67] now settings are done with command Moved config to bit field added some config option --- tasmota/xnrg_15_teleinfo.ino | 189 +++++++++++++++++++++++++---------- 1 file changed, 138 insertions(+), 51 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 604936a82..394a57060 100755 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -41,12 +41,12 @@ #define D_NAME_TELEINFO "Teleinfo" // Json Command -const char S_JSON_TELEINFO_COMMAND_STRING[] PROGMEM = "{\"" D_NAME_TELEINFO "\":{\"%s\":%s}}"; -const char S_JSON_TELEINFO_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_TELEINFO "\":{\"%s\":%d}}"; -const char S_JSON_TELEINFO_COMMAND_SETTINGS[] PROGMEM = "{\"TIC_Settings\":{\"Mode\":%s,\"Raw\":%s,\"Skip\":%d,\"Limit\":%d}}"; +//const char S_JSON_TELEINFO_COMMAND_STRING[] PROGMEM = "{\"" D_NAME_TELEINFO "\":{\"%s\":%s}}"; +//const char S_JSON_TELEINFO_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_TELEINFO "\":{\"%s\":%d}}"; +const char TELEINFO_COMMAND_SETTINGS[] PROGMEM = "TIC: Settings Mode:%s, Raw:%s, Skip:%d, Limit:%d"; -#define MAX_TINFO_COMMAND_NAME 17 // Change this if one of the following kTInfo_Commands is higher then 16 char -const char kTInfo_Commands[] PROGMEM = "historique|standard|none|full|changed|skip|limit|config"; +#define MAX_TINFO_COMMAND_NAME 16+1 // Change this if one of the following kTInfo_Commands is higher then 16 char +const char kTInfo_Commands[] PROGMEM = "historique|standard|noraw|full|changed|skip|limit"; enum TInfoCommands { // commands for Console CMND_TELEINFO_HISTORIQUE=0, // Set Legacy mode @@ -55,8 +55,7 @@ enum TInfoCommands { // commands for Console CMND_TELEINFO_RAW_FULL, // Enable all RAW frame send CMND_TELEINFO_RAW_CHANGE, // Enable only changed values RAW frame send CMND_TELEINFO_SKIP, // Set number of frame to skip when raw mode is enabled - CMND_TELEINFO_LIMIT, // Limit RAW frame to values subject to fast change (Power, Current, ...), TBD - CMND_TELEINFO_CONFIG // Show Teleinfo current settings + CMND_TELEINFO_LIMIT // Limit RAW frame to values subject to fast change (Power, Current, ...), TBD }; @@ -458,10 +457,6 @@ void NewFrameCallback(struct _ValueList * me) // send teleinfo raw data only if setup like that if (Settings.teleinfo.raw_send) { // Do we need to skip this frame - if (raw_skip>0) { - raw_skip--; - } - if (raw_skip == 0 ) { Response_P(PSTR("{")); // send teleinfo full frame or only changed data @@ -474,7 +469,8 @@ void NewFrameCallback(struct _ValueList * me) // Reset frame skip counter (if 0 it's disabled) raw_skip = Settings.teleinfo.raw_skip; } else { - AddLog(LOG_LEVEL_INFO, PSTR("TIC: not sending yet, will do in %d frame(s)"), raw_skip); + AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: not sending yet, will do in %d frame(s)"), raw_skip); + raw_skip--; } } } @@ -597,58 +593,150 @@ Output : - Comments: - ====================================================================== */ bool TInfoCmd(void) { + bool serviced = false; char command[CMDSZ]; - uint8_t name_len = strlen(D_NAME_TELEINFO); - if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_TELEINFO), name_len)) { + // At least "EnergyConfig Teleinfo" + if (CMND_ENERGYCONFIG == Energy.command_code && XdrvMailbox.data_len >= name_len && !strncasecmp_P(XdrvMailbox.data, PSTR(D_NAME_TELEINFO), name_len) ) { + // Just "EnergyConfig Teleinfo" no more parameter + // Show Teleinfo configuration + if (XdrvMailbox.data_len == name_len) { - uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kTInfo_Commands); - switch (command_code) { - case CMND_TELEINFO_STANDARD: - case CMND_TELEINFO_HISTORIQUE: { - char mode_name[MAX_TINFO_COMMAND_NAME]; - if (XdrvMailbox.data_len) { - Settings.teleinfo.mode_standard = command_code == CMND_TELEINFO_STANDARD ? 1 : 0; - // Get the mode and raw name - GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, command_code, kTInfo_Commands); + char mode_name[MAX_TINFO_COMMAND_NAME]; + char raw_name[MAX_TINFO_COMMAND_NAME]; + int index_mode = Settings.teleinfo.mode_standard ? CMND_TELEINFO_STANDARD : CMND_TELEINFO_HISTORIQUE; + int index_raw = Settings.teleinfo.raw_send ? CMND_TELEINFO_RAW_FULL : CMND_TELEINFO_RAW_DISABLE; + if (Settings.teleinfo.raw_send && Settings.teleinfo.raw_report_changed) { + index_raw = CMND_TELEINFO_RAW_CHANGE; + } + // Get the mode and raw name + GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, index_mode, kTInfo_Commands); + GetTextIndexed(raw_name, MAX_TINFO_COMMAND_NAME, index_raw, kTInfo_Commands); + + AddLog_P(LOG_LEVEL_INFO, TELEINFO_COMMAND_SETTINGS, mode_name, raw_name, Settings.teleinfo.raw_skip, Settings.teleinfo.raw_limit); + + serviced = true; + + // At least "EnergyConfig Teleinfo xyz" plus one space and one (or more) char + // so "EnergyConfig Teleinfo 0" or "EnergyConfig Teleinfo Standard" + } else if (XdrvMailbox.data_len > name_len + 1 && XdrvMailbox.data[name_len] == ' ' ) { + // Now point on parameter + char *pParam = XdrvMailbox.data + name_len + 1; + char *p = pParam; + char *pValue = nullptr; + // Check for sub parameter ie : EnergyConfig Teleinfo Skip value + while(*p) { + if (*p == ' ') { + if (*(p+1)) { + // Skip parameter by emptying th string so below getcommandcode works + *p++ = 0x00; + // Save parameter value for later + pValue = p; + } + break; } - Response_P(S_JSON_TELEINFO_COMMAND_STRING, command, mode_name); + p++; } - break; - case CMND_TELEINFO_CONFIG: { - if (!XdrvMailbox.data_len) { + int command_code = GetCommandCode(command, sizeof(command), pParam, kTInfo_Commands); + + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TIC: EnergyConfig " D_NAME_TELEINFO " parameter '%s' => cmnd %d"), pParam, command_code); + + switch (command_code) { + case CMND_TELEINFO_STANDARD: + case CMND_TELEINFO_HISTORIQUE: { char mode_name[MAX_TINFO_COMMAND_NAME]; - char raw_name[MAX_TINFO_COMMAND_NAME]; - int index_mode = Settings.teleinfo.mode_standard ? CMND_TELEINFO_STANDARD : CMND_TELEINFO_HISTORIQUE; - int index_raw = Settings.teleinfo.raw_send ? CMND_TELEINFO_RAW_FULL : CMND_TELEINFO_RAW_DISABLE; + // Get the mode name + GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, command_code, kTInfo_Commands); - if (Settings.teleinfo.raw_send && Settings.teleinfo.raw_report_changed) { - index_raw = CMND_TELEINFO_RAW_CHANGE; - } + // Only if current settings is different than previous + if ( (tinfo_mode==TINFO_MODE_STANDARD && command_code==CMND_TELEINFO_HISTORIQUE) || + (tinfo_mode==TINFO_MODE_HISTORIQUE && command_code==CMND_TELEINFO_STANDARD) ) { - // Get the mode and raw name - GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, index_mode, kTInfo_Commands); - GetTextIndexed(raw_name, MAX_TINFO_COMMAND_NAME, index_raw, kTInfo_Commands); + // Cleanup Serial not sure it will works since + // there is no end() or close() on tasmotaserial class + if (TInfoSerial) { + TInfoSerial->flush(); + //TInfoSerial->end(); + free(TInfoSerial); + } - Response_P(S_JSON_TELEINFO_COMMAND_SETTINGS, mode_name, raw_name, Settings.teleinfo.raw_skip, Settings.teleinfo.raw_limit ); + // Change mode + Settings.teleinfo.mode_standard = command_code == CMND_TELEINFO_STANDARD ? 1 : 0; + + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Configured to '%s' mode"), mode_name); + + // Re init teleinfo (LibTeleinfo always free linked list on init) + TInfoInit(); + + serviced = true; + + } else { + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Already configured to '%s' mode"), mode_name); + } } - } - break; - - default: - return false; - } - - return true; - - } else { - return false; - } -} + break; + case CMND_TELEINFO_RAW_DISABLE: + case CMND_TELEINFO_RAW_FULL: + case CMND_TELEINFO_RAW_CHANGE: { + + // Enable all RAW frame send + char raw_name[MAX_TINFO_COMMAND_NAME]; + + // Get the raw name + GetTextIndexed(raw_name, MAX_TINFO_COMMAND_NAME, command_code, kTInfo_Commands); + + if (command_code == CMND_TELEINFO_RAW_DISABLE) { + // disable raw mode + Settings.teleinfo.raw_send = 0; + } else { + // enable raw mode + Settings.teleinfo.raw_send = 1; + Settings.teleinfo.raw_report_changed = command_code == CMND_TELEINFO_RAW_CHANGE ? 1 : 0; + } + + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode set to '%s'"), raw_name); + serviced = true; + } + break; + + case CMND_TELEINFO_SKIP: { + // Set Raw mode skip frame number + char skip_name[MAX_TINFO_COMMAND_NAME]; + // Get the raw name + GetTextIndexed(skip_name, MAX_TINFO_COMMAND_NAME, command_code, kTInfo_Commands); + int l = strlen(skip_name); + + // At least "EnergyConfig Teleinfo skip" plus one space and one (or more) digit + // so "EnergyConfig Teleinfo Skip 0" or "EnergyConfig Teleinfo Skip 123" + if ( pValue ) { + raw_skip = atoi(pValue); + Settings.teleinfo.raw_skip = raw_skip; + + if (raw_skip ==0) { + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode set with no skiping frame")); + } else { + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode sending one frame over %d"), raw_skip+1); + } + serviced = true; + } else { + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode no skip value")); + } + } + break; + + default: + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: incorrect command parameter '%s'"), pParam); + break; + + } + } + } + return serviced ; +} /* ====================================================================== Function: TInfoProcess @@ -815,7 +903,6 @@ bool Xnrg15(uint8_t function) TInfoProcess(); break; case FUNC_COMMAND: - AddLog(LOG_LEVEL_INFO, PSTR("TIC: FUNC_COMMAND")); result = TInfoCmd(); break; From b2d2742df177496e14546edbee8a1e4eb13611a1 Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 10 Apr 2021 00:49:38 +0200 Subject: [PATCH 23/67] removed unneeded teleinfo from command --- tasmota/xnrg_15_teleinfo.ino | 69 ++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 394a57060..75ff81cef 100755 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -389,15 +389,16 @@ Function: responseDumpTInfo Purpose : add teleinfo values into JSON response Input : 1st separator space if begining of JSON, else comma : select if append all data or just changed one -Output : - +Output : false if asked for changed value and none has changed else true Comments: - ====================================================================== */ -void ResponseAppendTInfo(char sep, bool all) +bool ResponseAppendTInfo(char sep, bool all) { struct _ValueList * me = tinfo.getList(); char * p ; - boolean isNumber ; + bool isNumber ; + bool hasValue = false; // Loop thru all the teleinfo frame but // always check we don't buffer overflow of MQTT data @@ -411,6 +412,7 @@ void ResponseAppendTInfo(char sep, bool all) if (all || ( Settings.teleinfo.raw_report_changed && (me->flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED | TINFO_FLAGS_ALERT) ) ) ) { isNumber = true; + hasValue = true; p = me->value; // Specific treatment serial number don't convert to number later @@ -439,6 +441,7 @@ void ResponseAppendTInfo(char sep, bool all) } } } + return hasValue; } /* ====================================================================== @@ -460,11 +463,15 @@ void NewFrameCallback(struct _ValueList * me) if (raw_skip == 0 ) { Response_P(PSTR("{")); // send teleinfo full frame or only changed data - ResponseAppendTInfo(' ', Settings.teleinfo.raw_report_changed ? false : true ); + bool hasData = ResponseAppendTInfo(' ', Settings.teleinfo.raw_report_changed ? false : true ); ResponseJsonEnd(); + // Publish adding ADCO serial number into the topic // Need setOption4 to be enabled - MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, serialNumber, false); + // No need to send empty payload + if (hasData) { + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, serialNumber, false); + } // Reset frame skip counter (if 0 it's disabled) raw_skip = Settings.teleinfo.raw_skip; @@ -595,13 +602,16 @@ Comments: - bool TInfoCmd(void) { bool serviced = false; char command[CMDSZ]; - uint8_t name_len = strlen(D_NAME_TELEINFO); + //uint8_t name_len = strlen(D_NAME_TELEINFO); - // At least "EnergyConfig Teleinfo" - if (CMND_ENERGYCONFIG == Energy.command_code && XdrvMailbox.data_len >= name_len && !strncasecmp_P(XdrvMailbox.data, PSTR(D_NAME_TELEINFO), name_len) ) { - // Just "EnergyConfig Teleinfo" no more parameter + // At least "EnergyConfig" + if (CMND_ENERGYCONFIG == Energy.command_code) { + + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TIC: len %d, data '%s'"), XdrvMailbox.data_len, XdrvMailbox.data ? XdrvMailbox.data : "null" ); + + // Just "EnergyConfig" no more parameter // Show Teleinfo configuration - if (XdrvMailbox.data_len == name_len) { + if (XdrvMailbox.data_len == 0) { char mode_name[MAX_TINFO_COMMAND_NAME]; char raw_name[MAX_TINFO_COMMAND_NAME]; @@ -618,11 +628,11 @@ bool TInfoCmd(void) { serviced = true; - // At least "EnergyConfig Teleinfo xyz" plus one space and one (or more) char - // so "EnergyConfig Teleinfo 0" or "EnergyConfig Teleinfo Standard" - } else if (XdrvMailbox.data_len > name_len + 1 && XdrvMailbox.data[name_len] == ' ' ) { + // At least "EnergyConfig xyz" plus one space and one (or more) char + // so "EnergyConfig 0" or "EnergyConfig Teleinfo Standard" + } else if (XdrvMailbox.data_len) { // Now point on parameter - char *pParam = XdrvMailbox.data + name_len + 1; + char *pParam = XdrvMailbox.data; char *p = pParam; char *pValue = nullptr; // Check for sub parameter ie : EnergyConfig Teleinfo Skip value @@ -641,7 +651,7 @@ bool TInfoCmd(void) { int command_code = GetCommandCode(command, sizeof(command), pParam, kTInfo_Commands); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TIC: EnergyConfig " D_NAME_TELEINFO " parameter '%s' => cmnd %d"), pParam, command_code); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TIC: param '%s' cmnd %d"), pParam, command_code); switch (command_code) { case CMND_TELEINFO_STANDARD: @@ -666,7 +676,7 @@ bool TInfoCmd(void) { // Change mode Settings.teleinfo.mode_standard = command_code == CMND_TELEINFO_STANDARD ? 1 : 0; - AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Configured to '%s' mode"), mode_name); + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: '%s' mode"), mode_name); // Re init teleinfo (LibTeleinfo always free linked list on init) TInfoInit(); @@ -674,7 +684,7 @@ bool TInfoCmd(void) { serviced = true; } else { - AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Already configured to '%s' mode"), mode_name); + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: No change to '%s' mode"), mode_name); } } break; @@ -698,7 +708,7 @@ bool TInfoCmd(void) { Settings.teleinfo.raw_report_changed = command_code == CMND_TELEINFO_RAW_CHANGE ? 1 : 0; } - AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode set to '%s'"), raw_name); + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw to '%s'"), raw_name); serviced = true; } break; @@ -711,25 +721,30 @@ bool TInfoCmd(void) { int l = strlen(skip_name); // At least "EnergyConfig Teleinfo skip" plus one space and one (or more) digit - // so "EnergyConfig Teleinfo Skip 0" or "EnergyConfig Teleinfo Skip 123" + // so "EnergyConfig Skip 0" or "EnergyConfig Skip 123" if ( pValue ) { - raw_skip = atoi(pValue); - Settings.teleinfo.raw_skip = raw_skip; + int value = atoi(pValue); + if (value >= 0 && value <= 255) { + raw_skip = value; + Settings.teleinfo.raw_skip = raw_skip; - if (raw_skip ==0) { - AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode set with no skiping frame")); + if (raw_skip ==0) { + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw no skip")); + } else { + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw each %d frame(s)"), raw_skip+1); + } + serviced = true; } else { - AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode sending one frame over %d"), raw_skip+1); + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: skip can be 0 to 255")); } - serviced = true; } else { - AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: Raw mode no skip value")); + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: no skip value")); } } break; default: - AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: incorrect command parameter '%s'"), pParam); + AddLog_P(LOG_LEVEL_INFO, PSTR("TIC: bad cmd param '%s'"), pParam); break; } From 3cab37ed80e32a71d4b3c23acec97ffaaa9ca72e Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 10 Apr 2021 00:58:42 +0200 Subject: [PATCH 24/67] obsolated SetOption102 and SetOption108 now teleinfo has it own bit field configuration --- tasmota/settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index b23d6dd0e..9e8b31d26 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -121,13 +121,13 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t zerocross_dimmer : 1; // bit 17 (v8.3.1.4) - SetOption99 - (PWM Dimmer) Enable zerocross dimmer (1) uint32_t remove_zbreceived : 1; // bit 18 (v8.3.1.7) - SetOption100 - (Zigbee) Remove ZbReceived form JSON message (1) uint32_t zb_index_ep : 1; // bit 19 (v8.3.1.7) - SetOption101 - (Zigbee) Add the source endpoint as suffix to attributes, ex `Power3` (1) instead of `Power` (0) if sent from endpoint 3 - uint32_t teleinfo_baudrate : 1; // bit 20 (v8.4.0.1) - SetOption102 - (Teleinfo) Set Baud rate for Teleinfo communication to 1200 (0) or 9600 (1) + uint32_t obsolete1 : 1; // bit 20 (v9.3.1.3) - SetOption102 - teleinfo_baudrate Obsolete Teleinfo config has now a dedicated bit field uint32_t mqtt_tls : 1; // bit 21 (v8.4.0.1) - SetOption103 - (MQTT TLS) Enable TLS mode (1) (requires TLS version) uint32_t mqtt_no_retain : 1; // bit 22 (v8.4.0.1) - SetOption104 - (MQTT) No Retain (1) - disable all MQTT retained messages, some brokers don't support it: AWS IoT, Losant uint32_t white_blend_mode : 1; // bit 23 (v8.4.0.1) - SetOption105 - (Light) White Blend Mode (1) - used to be `RGBWWTable` last value `0`, now deprecated in favor of this option uint32_t virtual_ct : 1; // bit 24 (v8.4.0.1) - SetOption106 - (Light) Virtual CT (1) - Creates a virtual White ColorTemp for RGBW lights uint32_t virtual_ct_cw : 1; // bit 25 (v8.4.0.1) - SetOption107 - (Light) Virtual CT Channel (1) - signals whether the hardware white is cold CW (true) or warm WW (false) - uint32_t teleinfo_rawdata : 1; // bit 26 (v8.4.0.2) - SetOption108 - (Teleinfo) Enable Teleinfo + Tasmota Energy device (0) or Teleinfo raw data only (1) + uint32_t obsolete2 : 1; // bit 26 (v9.3.1.3) - SetOption108 - teleinfo_rawdata Obsolete Teleinfo config has now a dedicated bit field uint32_t alexa_gen_1 : 1; // bit 27 (v8.4.0.3) - SetOption109 - (Alexa) Gen1 mode (1) - if you only have Echo Dot 2nd gen devices uint32_t zb_disable_autobind : 1; // bit 28 (v8.5.0.1) - SetOption110 - (Zigbee) Disable auto-config (1) when pairing new devices uint32_t buzzer_freq_mode : 1; // bit 29 (v8.5.0.1) - SetOption111 - (Buzzer) Use frequency output (1) for buzzer pin instead of on/off signal (0) From ec1065f442802ebb0464dcbfe94110c671be0a52 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Sat, 10 Apr 2021 09:54:35 +0200 Subject: [PATCH 25/67] Update Italian language --- tasmota/language/it_IT.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 2ae9b97cb..b59fb78a3 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -1,7 +1,7 @@ /* it-IT.h - localization for Italian - Italy for Tasmota - Copyright (C) 2021 Gennaro Tortone, Antonio Fragola, Bovirus and Adrian Scillato + Copyright (C) 2021 Gennaro Tortone, Antonio Fragola, bovirus and Adrian Scillato 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 @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Last update - 9.3.1.2 (27.03.2021) + * Updated until v9.3.1.1 - Last update 10.04.2021 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -810,7 +810,7 @@ #define D_SENSOR_TFMINIPLUS_RX "TFmini+ - RX" #define D_SENSOR_ZEROCROSS "Impulsi ZC" #define D_SENSOR_HALLEFFECT "Effetto hall" -#define D_SENSOR_EPD_DATA "EPD - Data" +#define D_SENSOR_EPD_DATA "EPD - Dati" // Units #define D_UNIT_AMPERE "A" From fe4d314d6d6933ff1bf2b5432bd63057c4c13fe7 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 10 Apr 2021 15:00:46 +0200 Subject: [PATCH 26/67] Use Arduino core 2..0..0.pre for S2 it is based on IDF4.4 and Arduino branch master commit https://github.com/espressif/arduino-esp32/commit/371f382db7dd36c470bb2669b222adf0a497600d --- 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 05814bc69..7ea2d58e0 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -175,7 +175,7 @@ build_flags = ${common32.build_flags} extends = env:tasmota32_base board = esp32s2 board_build.flash_mode = qio -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/s2-1.0.5-rc6/esp32-s2-1.0.5-rc6.zip +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/esp32-2.0.0-pre/esp32-2.0.0-pre.zip platformio/tool-mklittlefs @ ~1.203.200522 platformio/tool-esptoolpy @ ~1.30000.0 build_unflags = ${esp32_defaults.build_unflags} From 059904176046a59a84935afe0ecf62ae641c2e26 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 10 Apr 2021 15:04:50 +0200 Subject: [PATCH 27/67] Change telegram chatid from int32 to string Change telegram chatid from int32 to string (#11649) --- tasmota/xdrv_40_telegram.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index d73f39341..8d1099fc1 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -62,11 +62,11 @@ static const uint8_t Telegram_Fingerprint[] PROGMEM = USE_TELEGRAM_FINGERPRINT; typedef struct { String text; + String chat_id; // String from_first_name; // String from_last_name; // uint32_t from_id = 0; uint32_t update_id = 0; - int32_t chat_id = 0; } TelegramMessage; struct { @@ -233,12 +233,12 @@ void TelegramGetUpdates(uint32_t offset) { // Telegram.message[i].from_id = result["message"].getObject()["from"].getObject()["id"].getUInt(); // Telegram.message[i].from_first_name = result["message"].getObject()["from"].getObject()["first_name"].getStr(); // Telegram.message[i].from_last_name = result["message"].getObject()["from"].getObject()["last_name"].getStr(); - Telegram.message[i].chat_id = result["message"].getObject()["chat"].getObject()["id"].getUInt(); + Telegram.message[i].chat_id = result["message"].getObject()["chat"].getObject()["id"].getStr(); Telegram.message[i].text = result["message"].getObject()["text"].getStr(); } Telegram.next_update_id = Telegram.message[i].update_id +1; // Write id of last read message - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Parsed update_id %d, chat_id %d, text \"%s\""), Telegram.message[i].update_id, Telegram.message[i].chat_id, Telegram.message[i].text.c_str()); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Parsed update_id %d, chat_id %s, text \"%s\""), Telegram.message[i].update_id, Telegram.message[i].chat_id.c_str(), Telegram.message[i].text.c_str()); } } else { // AddLog(LOG_LEVEL_DEBUG, PSTR("TGM: No new messages")); @@ -248,7 +248,7 @@ void TelegramGetUpdates(uint32_t offset) { } } -bool TelegramSendMessage(int32_t chat_id, String text) { +bool TelegramSendMessage(String chat_id, String text) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: sendMessage")); if (!TelegramInit()) { return false; } @@ -256,7 +256,7 @@ bool TelegramSendMessage(int32_t chat_id, String text) { bool sent = false; if (text != "") { String _token = SettingsText(SET_TELEGRAM_TOKEN); - String command = "bot" + _token + "/sendMessage?chat_id=" + String(chat_id) + "&text=" + UrlEncode(text); + String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + "&text=" + UrlEncode(text); String response = TelegramConnectToTelegram(command); // AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); @@ -440,7 +440,7 @@ void CmndTmSend(void) { if (XdrvMailbox.data_len > 0) { String message = XdrvMailbox.data; String chat_id = SettingsText(SET_TELEGRAM_CHATID); - if (!TelegramSendMessage(chat_id.toInt(), message)) { + if (!TelegramSendMessage(chat_id, message)) { ResponseCmndFailed(); return; } From 915f2e2cef29157b07cfec2b7dc203e1dbf759a3 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Sat, 10 Apr 2021 11:16:49 -0300 Subject: [PATCH 28/67] Update it_IT.h --- tasmota/language/it_IT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index b59fb78a3..3a5230d0e 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.3.1.1 - Last update 10.04.2021 + * Updated until v9.3.1.2 - Last update 10.04.2021 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) From be236472fefe5819b36d4f789131e5cb7a4e3aef Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 10 Apr 2021 18:20:15 +0200 Subject: [PATCH 29/67] Add Tasmota discovery as alternative to Home Assistant discovery using define ``USE_TASMOTA_DISCOVERY`` --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/my_user_config.h | 5 +- tasmota/support_command.ino | 9 +- tasmota/xdrv_12_discovery.ino | 223 +++++++++++++++++++++++++++++ tasmota/xdrv_12_home_assistant.ino | 1 + 6 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 tasmota/xdrv_12_discovery.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index 543d6f1f2..1608a6987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - Berry add ``light`` module - Support for dummy energy monitor using user values set by commands ``VoltageSet``, ``CurrentSet``, ``PowerSet`` and ``FrequencySet``. Enable by selecting any GPIO as ``Option A2`` (#10640) - Command ``Backlog0`` to allow execution of following commands without delay +- Tasmota discovery as alternative to Home Assistant discovery using define ``USE_TASMOTA_DISCOVERY`` ### Changed - PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 713e7fb19..f61d91dcb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -104,6 +104,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - ESP32 support for WS2812 hardware driver via RMT or I2S - ESP32 support for secondary I2C controller - ESP32 support for internal Hall Effect sensor connected to both GPIO36 and GPIO39 only +- Tasmota discovery as alternative to Home Assistant discovery using define ``USE_TASMOTA_DISCOVERY`` ### Changed - TasmotaSerial library from v3.2.0 to v3.3.0 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index f2af992f8..1a6da9982 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -396,11 +396,14 @@ #define DOMOTICZ_OUT_TOPIC "domoticz/out" // Domoticz Output Topic // -- MQTT - Home Assistant Discovery ------------- -#define USE_HOME_ASSISTANT // Enable Home Assistant Discovery Support (+4.1k code, +6 bytes mem) +#define USE_HOME_ASSISTANT // Enable Home Assistant Discovery Support (+12k code, +6 bytes mem) #define HOME_ASSISTANT_DISCOVERY_PREFIX "homeassistant" // Home Assistant discovery prefix #define HOME_ASSISTANT_LWT_TOPIC "homeassistant/status" // home Assistant Birth and Last Will Topic (default = homeassistant/status) #define HOME_ASSISTANT_LWT_SUBSCRIBE true // Subscribe to Home Assistant Birth and Last Will Topic (default = true) +// -- MQTT - Tasmota Discovery --------------------- +//#define USE_TASMOTA_DISCOVERY // Enable Tasmota Discovery support (+2k code) + // -- MQTT - TLS - AWS IoT ------------------------ // Using TLS starting with version v6.5.0.16 compilation will only work using Core 2.4.2 and 2.5.2. No longer supported: 2.3.0 //#define USE_MQTT_TLS // Use TLS for MQTT connection (+34.5k code, +7.0k mem and +4.8k additional during connection handshake) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b0f4d7b2d..a701203de 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -975,11 +975,16 @@ void CmndSetoptionBase(bool indexed) { TasmotaGlobal.stop_flash_rotate = XdrvMailbox.payload; SettingsSave(2); } - #ifdef USE_HOME_ASSISTANT +#ifdef USE_HOME_ASSISTANT if ((19 == pindex) || (30 == pindex)) { HAssDiscover(); // Delayed execution to provide enough resources during hass_discovery or hass_light } - #endif // USE_HOME_ASSISTANT +#endif // USE_HOME_ASSISTANT +#ifdef USE_TASMOTA_DISCOVERY + if (19 == pindex) { + TasRediscover(); + } +#endif // USE_TASMOTA_DISCOVERY } else if (3 == ptype) { // SetOption50 .. 81 bitWrite(Settings.flag3.data, pindex, XdrvMailbox.payload); diff --git a/tasmota/xdrv_12_discovery.ino b/tasmota/xdrv_12_discovery.ino new file mode 100644 index 000000000..0b16945f0 --- /dev/null +++ b/tasmota/xdrv_12_discovery.ino @@ -0,0 +1,223 @@ +/* + xdrv_12_discovery.ino - Discovery support for Tasmota + + Copyright (C) 2021 Erik Montnemery, 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_TASMOTA_DISCOVERY +#undef USE_HOME_ASSISTANT +/*********************************************************************************************\ + * Tasmota discovery + * + * A stripped down version of xdrv_12_home_assistant to be used as alternative for TasmoManager + * + * SetOption19 0 - Enables discovery + * SetOption19 1 - Disables discovery and removes retained message from MQTT server + * SetOption73 1 - Enable discovery for buttons + * SetOption114 1 - Enable discovery for switches +\*********************************************************************************************/ + +#define XDRV_12 12 + +const char TASMOTA_DISCOVER_DEVICE[] PROGMEM = // Basic parameters for Discovery + "{\"ip\":\"%_I\"," // IP Address + "\"dn\":\"%s\"," // Device Name + "\"fn\":[%s]," // Friendly Names + "\"hn\":\"%s\"," // Host Name + "\"mac\":\"%s\"," // Full MAC as Device id + "\"md\":\"%s\"," // Module or Template Name + "\"ty\":%d,\"if\":%d," // Flag for TuyaMCU and Ifan devices + "\"ofln\":\"" MQTT_LWT_OFFLINE "\"," // Payload Offline + "\"onln\":\"" MQTT_LWT_ONLINE "\"," // Payload Online + "\"state\":[\"%s\",\"%s\",\"%s\",\"%s\"]," // State text for "OFF","ON","TOGGLE","HOLD" + "\"sw\":\"%s\"," // Software Version + "\"t\":\"%s\"," // Topic + "\"ft\":\"%s\"," // Full Topic + "\"tp\":[\"%s\",\"%s\",\"%s\"]," // Topics for command, stat and tele + "\"rl\":[%s],\"swc\":[%s],\"swn\":[%s],\"btn\":[%s]," // Inputs / Outputs + "\"so\":{\"4\":%d,\"11\":%d,\"13\":%d,\"17\":%d,\"20\":%d," // SetOptions + "\"30\":%d,\"68\":%d,\"73\":%d,\"82\":%d,\"114\":%d,\"117\":%d}," + "\"lk\":%d,\"lt_st\":%d,\"sho\":[%s],\"ver\":1}"; // Light SubType, Shutter Options and Discovery version + +struct { + uint8_t init_step; +} TasDiscoverData; + +void TasDiscovery(void) { + bool iFan = false; +#ifdef ESP8266 + if ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)) { iFan = true; } +#endif // ESP8266 + + uint8_t lightidx = MAX_RELAYS + 1; // Will store the starting position of the lights + if (Light.subtype > LST_NONE) { + if (!light_controller.isCTRGBLinked()) { // One or two lights present + lightidx = TasmotaGlobal.devices_present - 2; + } else { + lightidx = TasmotaGlobal.devices_present - 1; + } + } + + if ((Light.device > 0) && Settings.flag3.pwm_multi_channels) { // How many relays are light devices? + lightidx = TasmotaGlobal.devices_present - Light.subtype; + } + + uint16_t Relay[MAX_RELAYS] = { 0 }; // Base array to store the relay type + uint16_t Shutter[MAX_RELAYS] = { 0 }; // Array to store a temp list for shutters + char RelLst[MAX_RELAYS*2] = { 0 }; // Relay as a char list, "0,0,0,0,0,0,0,0" + for (uint32_t i = 0; i < MAX_RELAYS; i++) { + if (i < TasmotaGlobal.devices_present) { + +#ifdef USE_SHUTTER + if (Settings.flag3.shutter_mode) { + for (uint32_t k = 0; k < MAX_SHUTTERS; k++) { + if (0 == Settings.shutter_startrelay[k]) { + break; + } else { + if (Settings.shutter_startrelay[k] > 0 && Settings.shutter_startrelay[k] <= MAX_SHUTTER_RELAYS) { + Shutter[Settings.shutter_startrelay[k]-1] = Shutter[Settings.shutter_startrelay[k]] = 1; + } + } + } + } +#endif // USE_SHUTTER + + if (Shutter[i] != 0) { // Check if there are shutters present + Relay[i] = 3; // Relay is a shutter + } else { + if (i >= lightidx || (iFan && i == 0)) { // First relay on Ifan controls the light + Relay[i] = 2; // Relay is a light + } else { + if (!iFan) { // Relays 2-4 for ifan are controlled by FANSPEED and don't need to be present if TasmotaGlobal.module_type = SONOFF_IFAN02 or SONOFF_IFAN03 + Relay[i] = 1; // Simple Relay + } + } + } + } + snprintf_P(RelLst, sizeof(RelLst), PSTR("%s%s%d"), RelLst, (i > 0 ? "," : ""), Relay[i]); // Vector for the Official Integration + } + + bool TuyaMod = false; + bool iFanMod = false; +#ifdef ESP8266 + if ((TUYA_DIMMER == TasmotaGlobal.module_type) || (SK03_TUYA == TasmotaGlobal.module_type)) { TuyaMod = true; }; + if ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)) { iFanMod = true; }; +#endif // ESP8266 + + char friendly_name[200]; + friendly_name[0] = '\0'; + uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present; + for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) { + char fname[TOPSZ]; + snprintf_P(fname, sizeof(fname), PSTR("\"%s\""), EscapeJSONString(SettingsText(SET_FRIENDLYNAME1 +i)).c_str()); + snprintf_P(friendly_name, sizeof(friendly_name), PSTR("%s%s%s"), friendly_name, (i > 0 ? "," : ""), (i < maxfn) ? fname : PSTR("null")); + } + + char switch_mode[90]; + switch_mode[0] = '\0'; + char switch_name[300]; + switch_name[0] = '\0'; + // Enable Discovery for Switches only if SetOption114 is enabled + for (uint32_t i = 0; i < MAX_SWITCHES; i++) { + char sname[TOPSZ]; + snprintf_P(sname, sizeof(sname), PSTR("\"%s\""), GetSwitchText(i).c_str()); + snprintf_P(switch_mode, sizeof(switch_mode), PSTR("%s%s%d"), switch_mode, (i > 0 ? "," : ""), (PinUsed(GPIO_SWT1, i) & Settings.flag5.mqtt_switches) ? Settings.switchmode[i] : -1); + snprintf_P(switch_name, sizeof(switch_name), PSTR("%s%s%s"), switch_name, (i > 0 ? "," : ""), (PinUsed(GPIO_SWT1, i) & Settings.flag5.mqtt_switches) ? sname : PSTR("null")); + } + + bool SerialButton = false; + char button_flag[90]; + button_flag[0] = '\0'; + // Enable Discovery for Buttons only if SetOption73 is enabled + for (uint32_t i = 0; i < MAX_KEYS; i++) { +#ifdef ESP8266 + SerialButton = ((0 == i) && (SONOFF_DUAL == TasmotaGlobal.module_type )); +#endif // ESP8266 + snprintf_P(button_flag, sizeof(button_flag), PSTR("%s%s%d"), button_flag, (i > 0 ? "," : ""), (SerialButton ? 1 : (PinUsed(GPIO_KEY1, i)) & Settings.flag3.mqtt_buttons)); + } + + char shutter_option[90]; + shutter_option[0] = '\0'; + for (uint32_t i = 0; i < MAX_SHUTTERS; i++) { +#ifdef USE_SHUTTER + snprintf_P(shutter_option, sizeof(shutter_option), PSTR("%s%s%d"), shutter_option, (i > 0 ? "," : ""), Settings.shutter_options[i]); +#else + snprintf_P(shutter_option, sizeof(shutter_option), PSTR("%s%s0"), shutter_option, (i > 0 ? "," : "")); +#endif // USE_SHUTTER + } + + // Full 12 chars MAC address as ID + String mac_address = WiFi.macAddress(); + mac_address.replace(":", ""); + char unique_id[30]; + snprintf_P(unique_id, sizeof(unique_id), PSTR("%s"), mac_address.c_str()); + + TasmotaGlobal.masterlog_level = LOG_LEVEL_DEBUG_MORE; // Hide topic on clean and remove use weblog 4 to show it + + ResponseClear(); // Clear retained message + if (!Settings.flag.hass_discovery) { // SetOption19 - Clear retained message + Response_P(TASMOTA_DISCOVER_DEVICE, (uint32_t)WiFi.localIP(), SettingsText(SET_DEVICENAME), + friendly_name, TasmotaGlobal.hostname, unique_id, ModuleName().c_str(), TuyaMod, iFanMod, GetStateText(0), GetStateText(1), GetStateText(2), GetStateText(3), + TasmotaGlobal.version, TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_FULLTOPIC), PSTR(SUB_PREFIX), PSTR(PUB_PREFIX), PSTR(PUB_PREFIX2), RelLst, switch_mode, switch_name, + button_flag, Settings.flag.mqtt_response, Settings.flag.button_swap, Settings.flag.button_single, Settings.flag.decimal_text, Settings.flag.not_power_linked, + Settings.flag.hass_light, Settings.flag3.pwm_multi_channels, Settings.flag3.mqtt_buttons, Settings.flag4.alexa_ct_range, Settings.flag5.mqtt_switches, + Settings.flag5.fade_fixed_duration, light_controller.isCTRGBLinked(), Light.subtype, shutter_option); + } + char stopic[TOPSZ]; + snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/config"), unique_id); + MqttPublish(stopic, true); + + if (!Settings.flag.hass_discovery) { // SetOption19 - Clear retained message + Response_P(PSTR("{\"sn\":")); + MqttShowSensor(); + ResponseAppend_P(PSTR(",\"ver\":1}")); + } + snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/sensors"), unique_id); + MqttPublish(stopic, true); + + TasmotaGlobal.masterlog_level = LOG_LEVEL_NONE; // Restore WebLog state +} + +void TasRediscover(void) { + TasDiscoverData.init_step = 1; // Delayed discovery or clear retained messages +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv12(uint8_t function) { + bool result = false; + + if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT + switch (function) { + case FUNC_EVERY_SECOND: + if (TasDiscoverData.init_step) { + TasDiscoverData.init_step--; + if (!TasDiscoverData.init_step) { + TasDiscovery(); // Send the topics for discovery + } + } + break; + case FUNC_MQTT_INIT: + TasDiscoverData.init_step = 10; // Delayed discovery + break; + } + } + return result; +} + +#endif // USE_TASMOTA_DISCOVERY \ No newline at end of file diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 617ec2e39..8f0f75941 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -18,6 +18,7 @@ */ #ifdef USE_HOME_ASSISTANT +#undef USE_TASMOTA_DISCOVERY #define XDRV_12 12 From b9110f602fcd28ead0ed01b39a6a807a6b8c8235 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 11 Apr 2021 07:49:13 +0200 Subject: [PATCH 30/67] add full partial and full refresh --- lib/libesp32_epdiy/src/epd4in7.cpp | 34 +++++++++++++++++++++++------ lib/libesp32_epdiy/src/epd4in7.h | 1 + tasmota/xdsp_16_esp32_epaper_47.ino | 4 ++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/libesp32_epdiy/src/epd4in7.cpp b/lib/libesp32_epdiy/src/epd4in7.cpp index 93a9f859d..4f041b473 100644 --- a/lib/libesp32_epdiy/src/epd4in7.cpp +++ b/lib/libesp32_epdiy/src/epd4in7.cpp @@ -44,10 +44,14 @@ extern uint8_t *buffer; -int temperature; +int temperature = 25; EpdiyHighlevelState hl; +uint16_t Epd47::GetColorFromIndex(uint8_t index) { + return index & 0xf; +} + Epd47::Epd47(int16_t dwidth, int16_t dheight) : Renderer(dwidth, dheight) { width = dwidth; height = dheight; @@ -63,11 +67,27 @@ int32_t Epd47::Init(void) { void Epd47::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) { - if (p == DISPLAY_INIT_FULL) { + + if (p == DISPLAY_INIT_MODE) { epd_poweron(); epd_clear(); epd_poweroff(); } + if (p == DISPLAY_INIT_FULL) { + memset(hl.back_fb, 0xff, width * height / 2); + epd_poweron(); + epd_clear(); + epd_hl_update_screen(&hl, MODE_GC16, temperature); + epd_poweroff(); + return; + } + if (p == DISPLAY_INIT_PARTIAL) { + memset(hl.back_fb, 0xff, width * height / 2); + epd_poweron(); + epd_hl_update_screen(&hl, MODE_GL16, temperature); + epd_poweroff(); + return; + } setRotation(rot); setTextWrap(false); cp437(true); @@ -94,6 +114,7 @@ void Epd47::fillScreen(uint16_t color) { void Epd47::drawPixel(int16_t x, int16_t y, uint16_t color) { uint16_t xp = x; uint16_t yp = y; +uint8_t *buf_ptr; switch (getRotation()) { case 1: @@ -107,14 +128,13 @@ uint16_t yp = y; case 3: _swap(xp, yp); yp = height - yp - 1; + break; } - uint32_t maxsize = width * height / 2; - uint8_t *buf_ptr = &buffer[yp * width / 2 + xp / 2]; - if ((uint32_t)buf_ptr >= (uint32_t)buffer + maxsize) { - return; - } + if (xp >= width) return; + if (yp >= height) return; + buf_ptr = &buffer[yp * width / 2 + xp / 2]; if (xp % 2) { *buf_ptr = (*buf_ptr & 0x0F) | (color << 4); diff --git a/lib/libesp32_epdiy/src/epd4in7.h b/lib/libesp32_epdiy/src/epd4in7.h index 86717e7f3..79a3081bb 100644 --- a/lib/libesp32_epdiy/src/epd4in7.h +++ b/lib/libesp32_epdiy/src/epd4in7.h @@ -51,6 +51,7 @@ public: void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); void pushColors(uint16_t *data, uint16_t len, boolean first); + uint16_t GetColorFromIndex(uint8_t index); private: uint16_t width; uint16_t height; diff --git a/tasmota/xdsp_16_esp32_epaper_47.ino b/tasmota/xdsp_16_esp32_epaper_47.ino index 63605c42a..990c92fdf 100644 --- a/tasmota/xdsp_16_esp32_epaper_47.ino +++ b/tasmota/xdsp_16_esp32_epaper_47.ino @@ -53,7 +53,7 @@ void EpdInitDriver47(void) { epd47->Init(); renderer = epd47; - renderer->DisplayInit(DISPLAY_INIT_FULL, Settings.display_size, Settings.display_rotate, Settings.display_font); + renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font); renderer->setTextColor(EPD47_BLACK, EPD47_WHITE); #ifdef SHOW_SPLASH @@ -98,4 +98,4 @@ bool Xdsp16(uint8_t function) #endif // USE_LILYGO47 #endif // USE_DISPLAY -#endif // ESP32 \ No newline at end of file +#endif // ESP32 From 16e397dbd74ee1007ee2b91781f1d5b71ee90307 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 11 Apr 2021 12:30:50 +0200 Subject: [PATCH 31/67] udisplay lib --- .../Adafruit_GFX.cpp | 10 + .../Adafruit_GFX.h | 4 + lib/lib_display/UDisplay/keywords.txt | 30 + lib/lib_display/UDisplay/library.properties | 9 + lib/lib_display/UDisplay/uDisplay.cpp | 607 ++++++++++++++++++ lib/lib_display/UDisplay/uDisplay.h | 114 ++++ 6 files changed, 774 insertions(+) create mode 100644 lib/lib_display/UDisplay/keywords.txt create mode 100644 lib/lib_display/UDisplay/library.properties create mode 100644 lib/lib_display/UDisplay/uDisplay.cpp create mode 100644 lib/lib_display/UDisplay/uDisplay.h diff --git a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp index dbfd00e2d..5e88150cc 100644 --- a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp +++ b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp @@ -1243,6 +1243,16 @@ void Adafruit_GFX::setTextSize(uint8_t s_x, uint8_t s_y) { textsize_y = (s_y > 0) ? s_y : 1; } +void Adafruit_GFX::setwidth(uint16_t w) { + WIDTH = w; + _width = w; +} + +void Adafruit_GFX::setheight(uint16_t h) { + HEIGHT = h; + _height = h; +} + /**************************************************************************/ /*! @brief Set rotation setting for display diff --git a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h index dc970b26d..8af31324e 100644 --- a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h +++ b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h @@ -187,6 +187,10 @@ virtual void /************************************************************************/ int16_t height(void) const { return _height; } + void setwidth(uint16_t w); + + void setheight(uint16_t h); + /************************************************************************/ /*! @brief Get rotation setting for display diff --git a/lib/lib_display/UDisplay/keywords.txt b/lib/lib_display/UDisplay/keywords.txt new file mode 100644 index 000000000..bb1efcdcc --- /dev/null +++ b/lib/lib_display/UDisplay/keywords.txt @@ -0,0 +1,30 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +ST7789 KEYWORD1 + + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +setRotation KEYWORD2 +setAddrWindow KEYWORD2 +pushColor KEYWORD2 +drawPixel KEYWORD2 +drawFastVLine KEYWORD2 +drawFastHLine KEYWORD2 +fillRect KEYWORD2 +setRotation KEYWORD2 +setRotation KEYWORD2 +height KEYWORD2 +width KEYWORD2 +invertDisplay KEYWORD2 +drawImage KEYWORD2 +setScrollArea KEYWORD2 +scroll KEYWORD2 diff --git a/lib/lib_display/UDisplay/library.properties b/lib/lib_display/UDisplay/library.properties new file mode 100644 index 000000000..c7dd23a3a --- /dev/null +++ b/lib/lib_display/UDisplay/library.properties @@ -0,0 +1,9 @@ +name=universal display Library +version=0.1 +author=Gerhard Mutz +maintainer=Gerhard Mutz +sentence=This is a library a couple of displays. +paragraph=This is a library a couple of displays. +category=Display +url=https://github.com/arendst/Tasmota +architectures=* diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp new file mode 100644 index 000000000..0c15c8712 --- /dev/null +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -0,0 +1,607 @@ +/* + uDisplay.cpp - universal display driver support for Tasmota + + Copyright (C) 2021 Gerhard Mutz 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include "uDisplay.h" + + +const uint16_t udisp_colors[]={UDISP_BLACK,UDISP_WHITE,UDISP_RED,UDISP_GREEN,UDISP_BLUE,UDISP_CYAN,UDISP_MAGENTA,\ + UDISP_YELLOW,UDISP_NAVY,UDISP_DARKGREEN,UDISP_DARKCYAN,UDISP_MAROON,UDISP_PURPLE,UDISP_OLIVE,\ +UDISP_LIGHTGREY,UDISP_DARKGREY,UDISP_ORANGE,UDISP_GREENYELLOW,UDISP_PINK}; + +uint16_t uDisplay::GetColorFromIndex(uint8_t index) { + if (index >= sizeof(udisp_colors) / 2) index = 0; + return udisp_colors[index]; +} + +extern uint8_t *buffer; + +uDisplay::uDisplay(char *lp) : Renderer(800, 600) { + // analyse decriptor + uint8_t section = 0; + dsp_ncmds = 0; + char linebuff[128]; + while (*lp) { + + uint16_t llen = strlen_ln(lp); + strncpy(linebuff, lp, llen); + linebuff[llen] = 0; + lp += llen; + char *lp1 = linebuff; + + if (*lp1 == '#') break; + if (*lp1 == '\n') lp1++; + while (*lp1 == ' ') lp1++; + //Serial.printf(">> %s\n",lp1); + if (*lp1 != ';') { + // check ids: + if (*lp1 == ':') { + // id line + lp1++; + section = *lp1++; + } else { + switch (section) { + case 'H': + // header line + // SD1306,128,64,1,I2C,5a,*,*,* + str2c(&lp1, dname, sizeof(dname)); + char ibuff[16]; + gxs = next_val(&lp1); + setwidth(gxs); + gys = next_val(&lp1); + setheight(gys); + bpp = next_val(&lp1); + str2c(&lp1, ibuff, sizeof(ibuff)); + if (!strncmp(ibuff, "I2C", 3)) { + interface = _UDSP_I2C; + i2caddr = next_hex(&lp1); + i2c_scl = next_val(&lp1); + i2c_sda = next_val(&lp1); + reset = next_val(&lp1); + section = 0; + } else if (!strncmp(ibuff, "SPI", 3)) { + interface = _UDSP_SPI; + spi_nr = next_val(&lp1); + spi_cs = next_val(&lp1); + spi_clk = next_val(&lp1); + spi_mosi = next_val(&lp1); + spi_dc = next_val(&lp1); + bpanel = next_val(&lp1); + reset = next_val(&lp1); + spi_miso = next_val(&lp1); + spi_speed = next_val(&lp1); + + section = 0; + Serial.printf("%d %d %d %d %d %d %d %d\n", spi_cs, spi_clk, spi_mosi, spi_dc, bpanel, reset, spi_miso, spi_speed); + } + break; + case 'S': + splash_font = next_val(&lp1); + splash_size = next_val(&lp1); + fg_col = next_val(&lp1); + if (bpp == 16) { + fg_col = GetColorFromIndex(fg_col); + } + bg_col = next_val(&lp1); + if (bpp == 16) { + bg_col = GetColorFromIndex(bg_col); + } + splash_xp = next_val(&lp1); + splash_yp = next_val(&lp1); + break; + case 'I': + // init data + if (interface == _UDSP_I2C) { + dsp_cmds[dsp_ncmds++] = next_hex(&lp1); + if (!str2c(&lp1, ibuff, sizeof(ibuff))) { + dsp_cmds[dsp_ncmds++] = strtol(ibuff, 0, 16); + } + } else { + while (1) { + if (!str2c(&lp1, ibuff, sizeof(ibuff))) { + dsp_cmds[dsp_ncmds++] = strtol(ibuff, 0, 16); + } else { + break; + } + if (dsp_ncmds >= sizeof(dsp_cmds)) break; + + } + } + break; + case 'o': + str2c(&lp1, ibuff, sizeof(ibuff)); + dsp_off = strtol(ibuff, 0, 16); + break; + case 'O': + str2c(&lp1, ibuff, sizeof(ibuff)); + dsp_on = strtol(ibuff, 0, 16); + break; + case '0': + rot_0 = next_hex(&lp1); + break; + case '1': + rot_1 = next_hex(&lp1); + break; + case '2': + rot_2 = next_hex(&lp1); + break; + case '3': + rot_3 = next_hex(&lp1); + break; + case 'A': + saw_1 = next_hex(&lp1); + saw_2 = next_hex(&lp1); + saw_3 = next_hex(&lp1); + break; + } + } + } + if (*lp == '\n') { + lp++; + } else { + lp = strchr(lp, '\n'); + if (!lp) break; + lp++; + } + } +} + + +Renderer *uDisplay::Init(void) { + + + if (reset >= 0) { + pinMode(reset, OUTPUT); + digitalWrite(reset, HIGH); + delay(50); + digitalWrite(reset, LOW); + delay(50); + digitalWrite(reset, HIGH); + delay(200); + } + + if (interface == _UDSP_I2C) { + Wire.begin(i2c_sda, i2c_scl); + if (bpp < 16) { + if (buffer) free(buffer); + buffer = (uint8_t*)calloc((width()*height()*bpp)/8, 1); + + for (uint32_t cnt = 0; cnt < dsp_ncmds; cnt++) { + i2c_command(dsp_cmds[cnt]); + } + } + } + if (interface == _UDSP_SPI) { + if (bpanel >= 0) { +#ifdef ESP32 + ledcSetup(ESP32_PWM_CHANNEL, 4000, 8); + ledcAttachPin(bpanel, ESP32_PWM_CHANNEL); + ledcWrite(ESP32_PWM_CHANNEL, 128); +#else + pinMode(bpanel, OUTPUT); + digitalWrite(bpanel, HIGH); +#endif // ESP32 + } + if (spi_dc >= 0) { + pinMode(spi_dc, OUTPUT); + digitalWrite(spi_dc, HIGH); + } + if (spi_cs >= 0) { + pinMode(spi_cs, OUTPUT); + digitalWrite(spi_cs, HIGH); + } + + spiSettings = SPISettings(spi_speed, MSBFIRST, SPI_MODE3); + +#ifdef ESP8266 + SPI.begin(); + uspi = &SPI; +#else + if (spi_nr != 1) { + uspi = new SPIClass(HSPI); + } else { + uspi = &SPI; + } + uspi->begin(spi_clk, spi_miso, spi_mosi, -1); +#endif + + uint16_t index = 0; + + SPI_BEGIN_TRANSACTION + while (1) { + uint8_t iob; + SPI_CS_LOW + SPI_DC_LOW + iob = dsp_cmds[index++]; + uspi->write(iob); + SPI_DC_HIGH + uint8_t args = dsp_cmds[index++]; + //Serial.printf("cmd, args %x, %d ", iob, args&0x7f); + for (uint32_t cnt = 0; cnt < (args & 0x7f); cnt++) { + iob = dsp_cmds[index++]; + //Serial.printf("%02x ", iob ); + uspi->write(iob); + } + SPI_CS_HIGH + //Serial.printf("\n"); + if (args & 0x80) delay(120); + if (index >= dsp_ncmds) break; + } + SPI_END_TRANSACTION + + } + return this; +} + +void uDisplay::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { + setRotation(rot); + invertDisplay(false); + setTextWrap(false); + cp437(true); + setTextFont(font); + setTextSize(size); + setTextColor(fg_col, bg_col); + setCursor(0,0); + fillScreen(bg_col); + Updateframe(); +} + +void uDisplay::spi_command(uint8_t val) { + SPI_BEGIN_TRANSACTION + SPI_DC_LOW + SPI_CS_LOW + uspi->write(val); + SPI_CS_HIGH + SPI_DC_HIGH + SPI_END_TRANSACTION +} + +void uDisplay::i2c_command(uint8_t val) { + //Serial.printf("%02x\n",val ); + Wire.beginTransmission(i2caddr); + Wire.write(0); + Wire.write(val); + Wire.endTransmission(); +} + +#define SH1106_SETLOWCOLUMN 0 +#define SH1106_SETHIGHCOLUMN 0x10 +#define SH1106_SETSTARTLINE 0x40 + + +void uDisplay::Updateframe(void) { + + if (interface == _UDSP_I2C) { + i2c_command(SH1106_SETLOWCOLUMN | 0x0); // low col = 0 + i2c_command(SH1106_SETHIGHCOLUMN | 0x0); // hi col = 0 + i2c_command(SH1106_SETSTARTLINE | 0x0); // line #0 + + uint8_t ys = gys >> 3; + uint8_t xs = gxs >> 3; + //uint8_t xs = 132 >> 3; + uint8_t m_row = 0; + uint8_t m_col = 2; + + uint16_t p = 0; + + uint8_t i, j, k = 0; + + for ( i = 0; i < ys; i++) { + // send a bunch of data in one xmission + i2c_command(0xB0 + i + m_row);//set page address + i2c_command(m_col & 0xf);//set lower column address + i2c_command(0x10 | (m_col >> 4));//set higher column address + + for( j = 0; j < 8; j++){ + Wire.beginTransmission(i2caddr); + Wire.write(0x40); + for ( k = 0; k < xs; k++, p++) { + Wire.write(buffer[p]); + } + Wire.endTransmission(); + } + } + } +} + +void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::drawFastVLine(x, y, h, color); + return; + } + // Rudimentary clipping + if ((x >= _width) || (y >= _height)) return; + if ((y + h - 1) >= _height) h = _height - y; + + SPI_BEGIN_TRANSACTION + + SPI_CS_LOW + + setAddrWindow_int(x, y, 1, h); + + while (h--) { + uspi->write16(color); + } + + SPI_CS_HIGH + + SPI_END_TRANSACTION +} + +void uDisplay::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::drawFastHLine(x, y, w, color); + return; + } + + // Rudimentary clipping + if((x >= _width) || (y >= _height)) return; + if((x+w-1) >= _width) w = _width-x; + + + SPI_BEGIN_TRANSACTION + + SPI_CS_LOW + + setAddrWindow_int(x, y, w, 1); + + + while (w--) { + uspi->write16(color); + } + + SPI_CS_HIGH + + SPI_END_TRANSACTION +} + +void uDisplay::fillScreen(uint16_t color) { + fillRect(0, 0, gxs, gys, color); +} + +// fill a rectangle +void uDisplay::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::fillRect(x, y, w, h, color); + return; + } + + // rudimentary clipping (drawChar w/big text requires this) + if((x >= gxs) || (y >= gys)) return; + if((x + w - 1) >= gxs) w = gxs - x; + if((y + h - 1) >= gys) h = gys - y; + + + SPI_BEGIN_TRANSACTION + SPI_CS_LOW + + setAddrWindow_int(x, y, w, h); + + for (y = h; y > 0; y--) { + for (x = w; x > 0; x--) { + uspi->write16(color); + } + } + SPI_CS_HIGH + SPI_END_TRANSACTION +} + + +void uDisplay::Splash(void) { + setTextFont(splash_font); + setTextSize(splash_size); + DrawStringAt(splash_xp, splash_yp, dname, fg_col, 0); + Updateframe(); +} + +void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { + + if (!x0 && !y0 && !x1 && !y1) { + SPI_CS_HIGH + SPI_END_TRANSACTION + } else { + SPI_CS_LOW + SPI_BEGIN_TRANSACTION + setAddrWindow_int(x0, y0, x1 - x0, y1 - y0 ); + } +} + +void uDisplay::setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { + uint32_t xa = ((uint32_t)x << 16) | (x+w-1); + uint32_t ya = ((uint32_t)y << 16) | (y+h-1); + + SPI_DC_LOW + uspi->write(saw_1); + SPI_DC_HIGH + + uspi->write32(xa); + + SPI_DC_LOW + uspi->write(saw_2); + SPI_DC_HIGH + + uspi->write32(ya); + + SPI_DC_LOW + uspi->write(saw_3); // write to RAM + SPI_DC_HIGH + +} + +void uDisplay::pushColors(uint16_t *data, uint16_t len, boolean first) { + uint16_t color; + + while (len--) { + color = *data++; + uspi->write16(color); + } + +} + +void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::drawPixel(x, y, color); + return; + } + + if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; + + + SPI_BEGIN_TRANSACTION + + SPI_CS_LOW + + setAddrWindow_int(x, y, 1, 1); + + uspi->write16(color); + + SPI_CS_HIGH + + SPI_END_TRANSACTION +} + +void uDisplay::setRotation(uint8_t m) { + if (interface != _UDSP_SPI) { + Renderer::setRotation(m); + return; + } + switch (rotation) { + case 0: + if (interface == _UDSP_SPI) spi_command(rot_0); + _width = gxs; + _height = gys; + break; + case 1: + if (interface == _UDSP_SPI) spi_command(rot_1); + _width = gys; + _height = gxs; + break; + case 2: + if (interface == _UDSP_SPI) spi_command(rot_2); + _width = gxs; + _height = gys; + break; + case 3: + if (interface == _UDSP_SPI) spi_command(rot_3); + _width = gys; + _height = gxs; + break; + } +} + +void uDisplay::DisplayOnff(int8_t on) { + + if (interface == _UDSP_I2C) { + if (on) { + i2c_command(dsp_on); + } else { + i2c_command(dsp_off); + } + } else { + if (on) { + spi_command(dsp_on); + if (bpanel >= 0) { +#ifdef ESP32 + ledcWrite(ESP32_PWM_CHANNEL, dimmer); +#else + digitalWrite(bpanel, HIGH); +#endif + } + + } else { + spi_command(dsp_off); + if (bpanel >= 0) { +#ifdef ESP32 + ledcWrite(ESP32_PWM_CHANNEL, 0); +#else + digitalWrite(bpanel, LOW); +#endif + } + } + } +} + +void uDisplay::dim(uint8_t dim) { + dimmer = dim; + if (dimmer > 15) dimmer = 15; + dimmer = ((float)dimmer / 15.0) * 255.0; +#ifdef ESP32 + ledcWrite(ESP32_PWM_CHANNEL, dimmer); +#endif +} + + + +uint8_t uDisplay::strlen_ln(char *str) { + for (uint32_t cnt = 0; cnt < 256; cnt++) { + if (!str[cnt] || str[cnt] == '\n') return cnt; + } + return 0; +} + +char *uDisplay::devname(void) { + return dname; +} + +uint32_t uDisplay::str2c(char **sp, char *vp, uint32_t len) { + char *lp = *sp; + if (len) len--; + char *cp = strchr(lp, ','); + if (cp) { + while (1) { + if (*lp == ',') { + *vp = 0; + *sp = lp + 1; + return 0; + } + if (len) { + *vp++ = *lp++; + len--; + } else { + lp++; + } + } + } else { + uint8_t slen = strlen(lp); + if (slen) { + strlcpy(vp, *sp, len); + *sp = lp + slen; + return 0; + } + } + return 1; +} + +int32_t uDisplay::next_val(char **sp) { + char ibuff[16]; + str2c(sp, ibuff, sizeof(ibuff)); + return atoi(ibuff); +} + +uint32_t uDisplay::next_hex(char **sp) { + char ibuff[16]; + str2c(sp, ibuff, sizeof(ibuff)); + return strtol(ibuff, 0, 16); +} diff --git a/lib/lib_display/UDisplay/uDisplay.h b/lib/lib_display/UDisplay/uDisplay.h new file mode 100644 index 000000000..f5f3c789d --- /dev/null +++ b/lib/lib_display/UDisplay/uDisplay.h @@ -0,0 +1,114 @@ +#ifndef _UDISP_ +#define _UDISP_ + +#include +#include + +#define _UDSP_I2C 1 +#define _UDSP_SPI 2 + +#define UDISP1_WHITE 1 +#define UDISP1_BLACK 0 + + +// Color definitions +#define UDISP_BLACK 0x0000 /* 0, 0, 0 */ +#define UDISP_NAVY 0x000F /* 0, 0, 128 */ +#define UDISP_DARKGREEN 0x03E0 /* 0, 128, 0 */ +#define UDISP_DARKCYAN 0x03EF /* 0, 128, 128 */ +#define UDISP_MAROON 0x7800 /* 128, 0, 0 */ +#define UDISP_PURPLE 0x780F /* 128, 0, 128 */ +#define UDISP_OLIVE 0x7BE0 /* 128, 128, 0 */ +#define UDISP_LIGHTGREY 0xC618 /* 192, 192, 192 */ +#define UDISP_DARKGREY 0x7BEF /* 128, 128, 128 */ +#define UDISP_BLUE 0x001F /* 0, 0, 255 */ +#define UDISP_GREEN 0x07E0 /* 0, 255, 0 */ +#define UDISP_CYAN 0x07FF /* 0, 255, 255 */ +#define UDISP_RED 0xF800 /* 255, 0, 0 */ +#define UDISP_MAGENTA 0xF81F /* 255, 0, 255 */ +#define UDISP_YELLOW 0xFFE0 /* 255, 255, 0 */ +#define UDISP_WHITE 0xFFFF /* 255, 255, 255 */ +#define UDISP_ORANGE 0xFD20 /* 255, 165, 0 */ +#define UDISP_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ +#define UDISP_PINK 0xF81F + +#define SPI_BEGIN_TRANSACTION uspi->beginTransaction(spiSettings); +#define SPI_END_TRANSACTION uspi->endTransaction(); +#define SPI_CS_LOW if (spi_cs >= 0) digitalWrite(spi_cs, LOW); +#define SPI_CS_HIGH if (spi_cs >= 0) digitalWrite(spi_cs, HIGH); +#define SPI_DC_LOW if (spi_dc >= 0) digitalWrite(spi_dc, LOW); +#define SPI_DC_HIGH if (spi_dc >= 0) digitalWrite(spi_dc, HIGH); + +#define ESP32_PWM_CHANNEL 1 + +class uDisplay : public Renderer { + public: + uDisplay(char *); + Renderer *Init(void); + void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); + void Updateframe(); + void DisplayOnff(int8_t on); + void Splash(void); + char *devname(void); + uint16_t fgcol(void) const { return fg_col; }; + uint16_t bgcol(void) const { return bg_col; }; + void dim(uint8_t dim); + uint16_t GetColorFromIndex(uint8_t index); + void setRotation(uint8_t m); + void fillScreen(uint16_t color); + void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + void pushColors(uint16_t *data, uint16_t len, boolean first); + + private: + void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + void drawPixel(int16_t x, int16_t y, uint16_t color); + void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); + uint32_t str2c(char **sp, char *vp, uint32_t len); + void i2c_command(uint8_t val); + void spi_command(uint8_t val); + uint8_t strlen_ln(char *str); + int32_t next_val(char **sp); + uint32_t next_hex(char **sp); + void setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h); + char dname[16]; + int8_t bpp; + uint8_t interface; + uint8_t i2caddr; + int8_t i2c_scl; + int8_t i2c_sda; + int8_t reset; + uint8_t dsp_cmds[128]; + uint8_t dsp_ncmds; + uint8_t dsp_on; + uint8_t dsp_off; + uint16_t splash_font; + uint16_t splash_size; + uint16_t splash_xp; + uint16_t splash_yp; + uint16_t fg_col; + uint16_t bg_col; + uint16_t gxs; + uint16_t gys; + int8_t spi_cs; + int8_t spi_clk; + int8_t spi_mosi; + int8_t spi_dc; + int8_t bpanel; + int8_t spi_miso; + uint8_t dimmer; + SPIClass *uspi; + SPISettings spiSettings; + uint32_t spi_speed; + uint8_t spi_nr = 1; + uint8_t rot_0; + uint8_t rot_1; + uint8_t rot_2; + uint8_t rot_3; + uint8_t saw_1; + uint8_t saw_2; + uint8_t saw_3; + uint8_t flags; +}; + +#endif // _UDISP_ From 0e7e956a7b8ce296926d37a744116091157e5e64 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 11 Apr 2021 12:32:02 +0200 Subject: [PATCH 32/67] universal display driver --- tasmota/xdrv_10_scripter.ino | 53 ++++-- tasmota/xdrv_13_display.ino | 14 +- tasmota/xdsp_17_universal.ino | 332 ++++++++++++++++++++++++++++++++++ 3 files changed, 384 insertions(+), 15 deletions(-) create mode 100644 tasmota/xdsp_17_universal.ino diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 7731237bd..5e920afba 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -65,7 +65,9 @@ keywords if then else endif, or, and are better readable for beginners (others m #define SCRIPT_MAXPERM (PMEM_SIZE)-4/sizeof(float) #define MAX_SCRIPT_SIZE MAX_RULE_SIZE*MAX_RULE_SETS +#ifndef MAX_SARRAY_NUM #define MAX_SARRAY_NUM 32 +#endif uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); @@ -1413,38 +1415,42 @@ uint32_t match_vars(char *dvnam, float **fp, char **sp, uint32_t *ind) { } #endif //USE_SCRIPT_GLOBVARS +#ifndef SCRIPT_IS_STRING_MAXSIZE +#define SCRIPT_IS_STRING_MAXSIZE 256 +#endif + char *isargs(char *lp, uint32_t isind) { float fvar; lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0); SCRIPT_SKIP_SPACES - if (*lp!='"') { + if (*lp != '"') { return lp; } lp++; - if (glob_script_mem.si_num[isind]>0 && glob_script_mem.last_index_string[isind]) { + if (glob_script_mem.si_num[isind] > 0 && glob_script_mem.last_index_string[isind]) { free(glob_script_mem.last_index_string[isind]); } char *sstart = lp; uint8_t slen = 0; - for (uint32_t cnt = 0; cnt<256; cnt++) { - if (*lp=='\n' || *lp=='"' || *lp==0) { + for (uint32_t cnt = 0; cnt < SCRIPT_IS_STRING_MAXSIZE; cnt++) { + if (*lp == '\n' || *lp == '"' || *lp == 0) { lp++; - if (cnt>0 && !slen) { + if (cnt > 0 && !slen) { slen++; } glob_script_mem.siro_num[isind] = slen; break; } - if (*lp=='|') { + if (*lp == '|') { slen++; } lp++; } glob_script_mem.si_num[isind] = fvar; - if (glob_script_mem.si_num[isind]>0) { - if (glob_script_mem.si_num[isind]>MAX_SARRAY_NUM) { + if (glob_script_mem.si_num[isind] > 0) { + if (glob_script_mem.si_num[isind] > MAX_SARRAY_NUM) { glob_script_mem.si_num[isind] = MAX_SARRAY_NUM; } @@ -1468,17 +1474,17 @@ float fvar; char str[SCRIPT_MAXSSIZE]; str[0] = 0; uint8_t index = fvar; - if (index<1) index = 1; + if (index < 1) index = 1; index--; if (gv) gv->strind = index; glob_script_mem.sind_num = isind; if (glob_script_mem.last_index_string[isind]) { if (!glob_script_mem.si_num[isind]) { - if (index<=glob_script_mem.siro_num[isind]) { + if (index <= glob_script_mem.siro_num[isind]) { GetTextIndexed(str, sizeof(str), index , glob_script_mem.last_index_string[isind]); } } else { - if (index>glob_script_mem.si_num[isind]) { + if (index > glob_script_mem.si_num[isind]) { index = glob_script_mem.si_num[isind]; } strlcpy(str,glob_script_mem.last_index_string[isind] + (index * glob_script_mem.max_ssize), glob_script_mem.max_ssize); @@ -1866,6 +1872,15 @@ chknext: } #endif //USE_SCRIPT_TASK #endif //ESP32 +#ifdef USE_ANGLE_FUNC + if (!strncmp(vname, "cos(", 4)) { + lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); + fvar = cosf(fvar); + lp++; + len = 0; + goto exit; + } +#endif break; case 'd': if (!strncmp(vname, "day", 3)) { @@ -2196,6 +2211,22 @@ chknext: len = 0; goto exit; } + if (!strncmp(vname, "fmt(", 4)) { + lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); + if (!fvar) { +#ifdef ESP8266 + LittleFS.format(); +#endif +#ifdef ESP32 + LITTLEFS.format(); +#endif + } else { + //SD.format(); + } + lp++; + len = 0; + goto exit; + } if (!strncmp(vname, "frd(", 4)) { char str[glob_script_mem.max_ssize + 1]; lp = GetStringArgument(lp + 4, OPER_EQU, str, 0); diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index fe599d7a7..1b8a19df9 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -80,6 +80,7 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log #define D_CMND_DISP_CLOCK "Clock" #define D_CMND_DISP_TEXTNC "TextNC" // NC - "No Clear" #define D_CMND_DISP_SCROLLTEXT "ScrollText" +#define D_CMND_DISP_REINIT "reinit" enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND, FUNC_DISPLAY_MODEL, FUNC_DISPLAY_MODE, FUNC_DISPLAY_POWER, @@ -108,7 +109,7 @@ const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix #endif D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|" - D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|" D_CMND_DISP_SCROLLTEXT + D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|" D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_REINIT ; void (* const DisplayCommand[])(void) PROGMEM = { @@ -120,7 +121,7 @@ void (* const DisplayCommand[])(void) PROGMEM = { #endif &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC, &CmndDisplayRaw, &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, - &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC, &CmndDisplayScrollText + &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC, &CmndDisplayScrollText,&DisplayReInitDriver }; #ifdef USE_GRAPH @@ -989,7 +990,7 @@ void Display_Text_From_File(const char *file) { File fp; if (!ufsp) return; fp = ufsp->open(file, FS_FILE_READ); - if (fp >= 0) { + if (fp > 0) { char *savptr = XdrvMailbox.data; char linebuff[128]; while (fp.available()) { @@ -1021,7 +1022,7 @@ void Display_Text_From_File(const char *file) { fp.close(); } } -#endif +#endif // USE_UFILESYS #ifdef USE_DT_VARS @@ -2001,6 +2002,11 @@ void CmndDisplayScrollText(void) { if(result) ResponseCmndChar(XdrvMailbox.data); } +void DisplayReInitDriver(void) { + XdspCall(FUNC_DISPLAY_INIT_DRIVER); + ResponseCmndDone(); +} + /*********************************************************************************************\ * Optional drivers \*********************************************************************************************/ diff --git a/tasmota/xdsp_17_universal.ino b/tasmota/xdsp_17_universal.ino new file mode 100644 index 000000000..eb4a9dbd8 --- /dev/null +++ b/tasmota/xdsp_17_universal.ino @@ -0,0 +1,332 @@ +/* + xdsp_17_universal.ino - universal display driver support for Tasmota + + Copyright (C) 2021 Gerhard Mutz 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifdef USE_DISPLAY +#ifdef USE_UNIVERSAL_DISPLAY + +#define XDSP_17 17 + +#include + +uDisplay *udisp; +bool udisp_init_done = false; +extern uint8_t color_type; +extern uint16_t fg_color; +extern uint16_t bg_color; + +#ifdef USE_UFILESYS +extern FS *ufsp; +#endif + +#define DISPDESC_SIZE 1000 + +#define DSP_ROM_DESC + +/*********************************************************************************************/ +#ifdef DSP_ROM_DESC +/* sample descriptor */ +const char DSP_SAMPLE_DESC[] PROGMEM = +// name,xs,ys,bpp,interface, (HEX) address, scl,sda,reset +// '*' means take pin number from tasmota +":H\n" +"SH1106,128,64,1,I2C,3c,*,*,*\n" +// splash settings, font, size, fgcol, bgcol, x,y +":S\n" +"0,1,1,0,40,20\n" +// init register settings, must be in HEX +":I\n" +"AE\n" +"D5,80\n" +"A8,3f\n" +"D3,00\n" +"40\n" +"8D,14\n" +"20,00\n" +"A1\n" +"C8\n" +"DA,12\n" +"81,CF\n" +"D9F1\n" +"DB,40\n" +"A4\n" +"A6\n" +"AF\n" +// switch display off +":o\n" +"AE\n" +// switch display on +":O\n" +"AF\n" +"#\n"; + +#endif // DSP_ROM_DESC +/*********************************************************************************************/ + +void Init_uDisp(void) { +char *ddesc = 0; +char *fbuff; + + if (1) { + Settings.display_model = XDSP_17; + + fg_color = 1; + bg_color = 0; + color_type = COLOR_BW; + + fbuff = (char*)calloc(DISPDESC_SIZE, 1); + if (!fbuff) return; + +#ifdef USE_UFILESYS + if (ufsp && !TasmotaGlobal.no_autoexec) { + File fp; + fp = ufsp->open("/dispdesc.txt", "r"); + if (fp > 0) { + uint32_t size = fp.size(); + fp.read((uint8_t*)fbuff, size); + fp.close(); + ddesc = fbuff; + AddLog(LOG_LEVEL_INFO, PSTR("DSP: File descriptor used")); + } + } +#endif + + +#ifdef USE_SCRIPT + if (bitRead(Settings.rule_enabled, 0) && !ddesc) { + uint8_t dfound = Run_Scripter(">d",-2,0); + if (dfound == 99) { + char *lp = glob_script_mem.section_ptr + 2; + while (*lp != '\n') lp++; + memcpy(fbuff, lp + 1, DISPDESC_SIZE - 1); + ddesc = fbuff; + AddLog(LOG_LEVEL_INFO, PSTR("DSP: Script descriptor used")); + } + } +#endif // USE_SCRIPT + + +#ifdef DSP_ROM_DESC + if (!ddesc) { + memcpy_P(fbuff, DSP_SAMPLE_DESC, sizeof(DSP_SAMPLE_DESC)); + ddesc = fbuff; + AddLog(LOG_LEVEL_INFO, PSTR("DSP: Flash descriptor used")); + } +#endif // DSP_ROM_DESC + + if (!ddesc) { + AddLog(LOG_LEVEL_INFO, PSTR("DSP: No valid descriptor found")); + if (fbuff) free(fbuff); + return; + } + // now replace tasmota vars before passing to driver + char *cp = strstr(ddesc, "I2C"); + if (cp) { + cp += 4; + //,3c,22,21,-1 + // i2c addr + //if (*cp == '*') { + // Settings.display_address + //} + uint8_t i2caddr = strtol(cp, 0, 16); + if (I2cSetDevice(i2caddr)) { + I2cSetActiveFound(i2caddr, "DSP-I2C"); + } + cp+=3; + //replacepin(&cp, Settings.display_address); + replacepin(&cp, Pin(GPIO_I2C_SCL)); + replacepin(&cp, Pin(GPIO_I2C_SDA)); + replacepin(&cp, Pin(GPIO_OLED_RESET)); + } + + cp = strstr(ddesc, "SPI"); + if (cp) { + cp += 4; + //; 7 params nr,cs,sclk,mosi,dc,bl,reset,miso + //SPI,*,*,*,*,*,*,* + if (*cp == '1') { + cp+=2; + replacepin(&cp, Pin(GPIO_SPI_CS)); + replacepin(&cp, Pin(GPIO_SPI_CLK)); + replacepin(&cp, Pin(GPIO_SPI_MOSI)); + replacepin(&cp, Pin(GPIO_SPI_DC)); + replacepin(&cp, Pin(GPIO_BACKLIGHT)); + replacepin(&cp, Pin(GPIO_OLED_RESET)); + replacepin(&cp, Pin(GPIO_SPI_MISO)); + } else { + // soft spi pins + cp+=2; + replacepin(&cp, Pin(GPIO_SSPI_CS)); + replacepin(&cp, Pin(GPIO_SSPI_SCLK)); + replacepin(&cp, Pin(GPIO_SSPI_MOSI)); + replacepin(&cp, Pin(GPIO_SSPI_DC)); + replacepin(&cp, Pin(GPIO_BACKLIGHT)); + replacepin(&cp, Pin(GPIO_OLED_RESET)); + replacepin(&cp, Pin(GPIO_SSPI_MISO)); + } + } + + // init renderer + if (udisp) delete udisp; + udisp = new uDisplay(ddesc); + +/* + File fp; + fp = ufsp->open("/dump.txt", "w"); + fp.write(ddesc, DISPDESC_SIZE); + fp.close(); +*/ + // release desc buffer + if (fbuff) free(fbuff); + + renderer = udisp->Init(); + if (!renderer) return; + + Settings.display_width = renderer->width(); + Settings.display_height = renderer->height(); + fg_color = udisp->fgcol(); + bg_color = udisp->bgcol(); + + renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font); + + +#ifdef SHOW_SPLASH + udisp->Splash(); +#endif + + udisp_init_done = true; + AddLog(LOG_LEVEL_INFO, PSTR("DSP: %s!"), udisp->devname()); + } +} + + +/*********************************************************************************************/ + +void replacepin(char **cp, uint16_t pin) { + char *lp = *cp; + if (*lp == ',') lp++; + if (*lp == '*') { + char val[8]; + itoa(pin, val, 10); + uint16_t slen = strlen(val); + //AddLog(LOG_LEVEL_INFO, PSTR("replace pin: %d"), pin); + memmove(lp + slen, lp + 1, strlen(lp)); + memmove(lp, val, slen); + } + char *np = strchr(lp, ','); + if (np) { + *cp = np + 1; + } +} + +#ifdef USE_DISPLAY_MODES1TO5 + +void UDISP_PrintLog(void) +{ + disp_refresh--; + if (!disp_refresh) { + disp_refresh = Settings.display_refresh; + if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); } + + char* txt = DisplayLogBuffer('\370'); + if (txt != NULL) { + uint8_t last_row = Settings.display_rows -1; + + renderer->clearDisplay(); + renderer->setTextSize(Settings.display_size); + renderer->setCursor(0,0); + for (byte i = 0; i < last_row; i++) { + strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); + renderer->println(disp_screen_buffer[i]); + } + strlcpy(disp_screen_buffer[last_row], txt, disp_screen_buffer_cols); + DisplayFillScreen(last_row); + + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "[%s]"), disp_screen_buffer[last_row]); + + renderer->println(disp_screen_buffer[last_row]); + renderer->Updateframe(); + } + } +} + +void UDISP_Time(void) +{ + char line[12]; + + renderer->clearDisplay(); + renderer->setTextSize(Settings.display_size); + renderer->setTextFont(Settings.display_font); + renderer->setCursor(0, 0); + snprintf_P(line, sizeof(line), PSTR(" %02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); // [ 12:34:56 ] + renderer->println(line); + renderer->println(); + snprintf_P(line, sizeof(line), PSTR("%02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year); // [01-02-2018] + renderer->println(line); + renderer->Updateframe(); +} + +void UDISP_Refresh(void) // Every second +{ + if (!renderer) return; + if (Settings.display_mode) { // Mode 0 is User text + switch (Settings.display_mode) { + case 1: // Time + UDISP_Time(); + break; + case 2: // Local + case 3: // Local + case 4: // Mqtt + case 5: // Mqtt + UDISP_PrintLog(); + break; + } + } +} + +#endif // USE_DISPLAY_MODES1TO5 + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdsp17(uint8_t function) +{ + bool result = false; + + if (FUNC_DISPLAY_INIT_DRIVER == function) { + Init_uDisp(); + } + else if (udisp_init_done && (XDSP_17 == Settings.display_model)) { + switch (function) { + case FUNC_DISPLAY_MODEL: + result = true; + break; +#ifdef USE_DISPLAY_MODES1TO5 + case FUNC_DISPLAY_EVERY_SECOND: + UDISP_Refresh(); + break; +#endif // USE_DISPLAY_MODES1TO5 + } + } + return result; +} + +#endif // USE_UNIVERSAL_DISPLAY +#endif // USE_DISPLAY From 835e7ab2e3115814b55c2d323cf2bc26a853dfe0 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 11 Apr 2021 12:38:45 +0200 Subject: [PATCH 33/67] add sample descriptors --- tasmota/displaydesc/ILI9341_desc.txt | 50 ++++++++++++++++++++++++++++ tasmota/displaydesc/SH1106_desc.txt | 31 +++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tasmota/displaydesc/ILI9341_desc.txt create mode 100644 tasmota/displaydesc/SH1106_desc.txt diff --git a/tasmota/displaydesc/ILI9341_desc.txt b/tasmota/displaydesc/ILI9341_desc.txt new file mode 100644 index 000000000..6aab1b1c5 --- /dev/null +++ b/tasmota/displaydesc/ILI9341_desc.txt @@ -0,0 +1,50 @@ +; name,xs,ys,bpp,interface, spi_nr cs, sclk,mosi,dc, bp ,reset,miso,spi_speed +:H +ILI9341,240,320,16,SPI,1,*,*,*,*,*,*,*,40000000 +; splash settings, font, size, fgcol, bgcol, x,y +:S +2,1,1,0,40,20 +; initialyze +:I +EF,3,03,80,02 +CF,3,00,C1,30 +ED,4,64,03,12,81 +E8,3,85,00,78 +CB,5,39,2C,00,34,02 +F7,1,20 +EA,2,00,00 +C0,1,23 +C1,1,10 +C5,2,3e,28 +C7,1,86 +36,1,48 +37,1,00 +3A,1,55 +B1,2,00,18 +B6,3,08,82,27 +F2,1,00 +26,1,01 +E0,0F,0F,31,2B,0C,0E,08,4E,F1,37,07,10,03,0E,09,00 +E1,0F,00,0E,14,03,11,07,31,C1,48,08,0F,0C,31,36,0F +11,80 +29,80 +; off +:o +28 +; on +:O +29 +; set adress window +:A +2A,2B,2C +; rotation +:0 +48 +:1 +28 +:2 +88 +:3 +E8 +# + diff --git a/tasmota/displaydesc/SH1106_desc.txt b/tasmota/displaydesc/SH1106_desc.txt new file mode 100644 index 000000000..954cb3740 --- /dev/null +++ b/tasmota/displaydesc/SH1106_desc.txt @@ -0,0 +1,31 @@ +; name,xs,ys,bpp,interface, address, scl,sda,reset +:H +SH1106,128,64,1,I2C,3c,*,*,* +; splash settings, font, size, fgcol, bgcol, x,y +:S +0,1,1,0,40,20 +; init register settings +:I +AE +D5,80 +A8,3f +D3,00 +40 +8D,14 +20,00 +A1 +C8 +DA,12 +81,CF +D9F1 +DB,40 +A4 +A6 +AF +; switch display off +:o +AE +; switch display on +:O +AF +# \ No newline at end of file From c2cde43a54acbc00e233e3d36a55d29391668f67 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 11 Apr 2021 13:29:33 +0200 Subject: [PATCH 34/67] Refactor Tasmota Discovery --- tasmota/support_network.ino | 6 + tasmota/support_tasmota.ino | 7 +- tasmota/xdrv_10_rules.ino | 4 +- tasmota/xdrv_12_discovery.ino | 209 ++++++++++++++++------------- tasmota/xdrv_12_home_assistant.ino | 4 +- tasmota/xdrv_20_hue.ino | 6 +- 6 files changed, 131 insertions(+), 105 deletions(-) diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino index 242c03121..c033b0fdc 100644 --- a/tasmota/support_network.ino +++ b/tasmota/support_network.ino @@ -127,3 +127,9 @@ String NetworkMacAddress(void) { #endif return WiFi.macAddress(); } + +String NetworkUniqueId(void) { + String unique_id = WiFi.macAddress(); + unique_id.replace(":", ""); // Full 12 chars MAC address as ID + return unique_id; +} diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 078d32b8c..05e6e3974 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -43,8 +43,7 @@ char* Format(char* output, const char* input_p, int size) snprintf_P(tmp, size, PSTR("%s%c0%dd"), output, '%', digits); snprintf_P(output, size, tmp, ESP_getChipId() & 0x1fff); // %04d - short chip ID in dec, like in hostname } else { - String mac_address = WiFi.macAddress(); - mac_address.replace(":", ""); + String mac_address = NetworkUniqueId(); if (digits > 12) { digits = 12; } String mac_part = mac_address.substring(12 - digits); snprintf_P(output, size, PSTR("%s%s"), output, mac_part.c_str()); // %01X .. %12X - mac address in hex @@ -122,9 +121,7 @@ char* GetTopic_P(char *stopic, uint32_t prefix, char *topic, const char* subtopi fulltopic.replace(FPSTR(MQTT_TOKEN_TOPIC), (const __FlashStringHelper *)topic); fulltopic.replace(F("%hostname%"), TasmotaGlobal.hostname); - String token_id = WiFi.macAddress(); - token_id.replace(":", ""); - fulltopic.replace(F("%id%"), token_id); + fulltopic.replace(F("%id%"), NetworkUniqueId()); } fulltopic.replace(F("#"), ""); fulltopic.replace(F("//"), "/"); diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index d356fd598..cf539ec6b 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -759,9 +759,7 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved) RulesVarReplace(commands, F("%TOPIC%"), TasmotaGlobal.mqtt_topic); snprintf_P(stemp, sizeof(stemp), PSTR("%06X"), ESP_getChipId()); RulesVarReplace(commands, F("%DEVICEID%"), stemp); - String mac_address = WiFi.macAddress(); - mac_address.replace(":", ""); - RulesVarReplace(commands, F("%MACADDR%"), mac_address); + RulesVarReplace(commands, F("%MACADDR%"), NetworkUniqueId()); #if defined(USE_TIMERS) && defined(USE_SUNRISE) RulesVarReplace(commands, F("%SUNRISE%"), String(SunMinutes(0))); RulesVarReplace(commands, F("%SUNSET%"), String(SunMinutes(1))); diff --git a/tasmota/xdrv_12_discovery.ino b/tasmota/xdrv_12_discovery.ino index 0b16945f0..bdc31e4cc 100644 --- a/tasmota/xdrv_12_discovery.ino +++ b/tasmota/xdrv_12_discovery.ino @@ -32,52 +32,69 @@ #define XDRV_12 12 -const char TASMOTA_DISCOVER_DEVICE[] PROGMEM = // Basic parameters for Discovery - "{\"ip\":\"%_I\"," // IP Address - "\"dn\":\"%s\"," // Device Name - "\"fn\":[%s]," // Friendly Names - "\"hn\":\"%s\"," // Host Name - "\"mac\":\"%s\"," // Full MAC as Device id - "\"md\":\"%s\"," // Module or Template Name - "\"ty\":%d,\"if\":%d," // Flag for TuyaMCU and Ifan devices - "\"ofln\":\"" MQTT_LWT_OFFLINE "\"," // Payload Offline - "\"onln\":\"" MQTT_LWT_ONLINE "\"," // Payload Online - "\"state\":[\"%s\",\"%s\",\"%s\",\"%s\"]," // State text for "OFF","ON","TOGGLE","HOLD" - "\"sw\":\"%s\"," // Software Version - "\"t\":\"%s\"," // Topic - "\"ft\":\"%s\"," // Full Topic - "\"tp\":[\"%s\",\"%s\",\"%s\"]," // Topics for command, stat and tele - "\"rl\":[%s],\"swc\":[%s],\"swn\":[%s],\"btn\":[%s]," // Inputs / Outputs - "\"so\":{\"4\":%d,\"11\":%d,\"13\":%d,\"17\":%d,\"20\":%d," // SetOptions - "\"30\":%d,\"68\":%d,\"73\":%d,\"82\":%d,\"114\":%d,\"117\":%d}," - "\"lk\":%d,\"lt_st\":%d,\"sho\":[%s],\"ver\":1}"; // Light SubType, Shutter Options and Discovery version +uint8_t TasDiscoverData_init_step; -struct { - uint8_t init_step; -} TasDiscoverData; +void TasDiscoverMessage(void) { + Response_P(PSTR("{\"ip\":\"%_I\"," // IP Address + "\"dn\":\"%s\"," // Device Name + "\"fn\":["), // Friendly Names (start) + (uint32_t)WiFi.localIP(), + SettingsText(SET_DEVICENAME)); -void TasDiscovery(void) { - bool iFan = false; + uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present; + for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) { + char fname[TOPSZ]; + snprintf_P(fname, sizeof(fname), PSTR("\"%s\""), EscapeJSONString(SettingsText(SET_FRIENDLYNAME1 +i)).c_str()); + ResponseAppend_P(PSTR("%s%s"), (i > 0 ? "," : ""), (i < maxfn) ? fname : PSTR("null")); + } + + bool TuyaMod = false; + bool iFanMod = false; #ifdef ESP8266 - if ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)) { iFan = true; } + if ((TUYA_DIMMER == TasmotaGlobal.module_type) || (SK03_TUYA == TasmotaGlobal.module_type)) { TuyaMod = true; }; + if ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)) { iFanMod = true; }; #endif // ESP8266 - uint8_t lightidx = MAX_RELAYS + 1; // Will store the starting position of the lights + ResponseAppend_P(PSTR("]," // Friendly Names (end) + "\"hn\":\"%s\"," // Host Name + "\"mac\":\"%s\"," // Full MAC as Device id + "\"md\":\"%s\"," // Module or Template Name + "\"ty\":%d,\"if\":%d," // Flag for TuyaMCU and Ifan devices + "\"ofln\":\"" MQTT_LWT_OFFLINE "\"," // Payload Offline + "\"onln\":\"" MQTT_LWT_ONLINE "\"," // Payload Online + "\"state\":[\"%s\",\"%s\",\"%s\",\"%s\"]," // State text for "OFF","ON","TOGGLE","HOLD" + "\"sw\":\"%s\"," // Software Version + "\"t\":\"%s\"," // Topic + "\"ft\":\"%s\"," // Full Topic + "\"tp\":[\"%s\",\"%s\",\"%s\"]," // Topics for command, stat and tele + "\"rl\":["), // Relays (start) + TasmotaGlobal.hostname, + NetworkUniqueId().c_str(), + ModuleName().c_str(), + TuyaMod, iFanMod, + GetStateText(0), GetStateText(1), GetStateText(2), GetStateText(3), + TasmotaGlobal.version, + TasmotaGlobal.mqtt_topic, + SettingsText(SET_MQTT_FULLTOPIC), + PSTR(SUB_PREFIX), + PSTR(PUB_PREFIX), + PSTR(PUB_PREFIX2)); + + uint8_t lightidx = MAX_RELAYS + 1; // Will store the starting position of the lights if (Light.subtype > LST_NONE) { - if (!light_controller.isCTRGBLinked()) { // One or two lights present + if (!light_controller.isCTRGBLinked()) { // One or two lights present lightidx = TasmotaGlobal.devices_present - 2; } else { lightidx = TasmotaGlobal.devices_present - 1; } } - if ((Light.device > 0) && Settings.flag3.pwm_multi_channels) { // How many relays are light devices? + if ((Light.device > 0) && Settings.flag3.pwm_multi_channels) { // How many relays are light devices? lightidx = TasmotaGlobal.devices_present - Light.subtype; } - uint16_t Relay[MAX_RELAYS] = { 0 }; // Base array to store the relay type - uint16_t Shutter[MAX_RELAYS] = { 0 }; // Array to store a temp list for shutters - char RelLst[MAX_RELAYS*2] = { 0 }; // Relay as a char list, "0,0,0,0,0,0,0,0" + uint16_t Relay[MAX_RELAYS] = { 0 }; // Base array to store the relay type + uint16_t Shutter[MAX_RELAYS] = { 0 }; // Array to store a temp list for shutters for (uint32_t i = 0; i < MAX_RELAYS; i++) { if (i < TasmotaGlobal.devices_present) { @@ -95,104 +112,116 @@ void TasDiscovery(void) { } #endif // USE_SHUTTER - if (Shutter[i] != 0) { // Check if there are shutters present - Relay[i] = 3; // Relay is a shutter + if (Shutter[i] != 0) { // Check if there are shutters present + Relay[i] = 3; // Relay is a shutter } else { - if (i >= lightidx || (iFan && i == 0)) { // First relay on Ifan controls the light - Relay[i] = 2; // Relay is a light + if (i >= lightidx || (iFanMod && (0 == i))) { // First relay on Ifan controls the light + Relay[i] = 2; // Relay is a light } else { - if (!iFan) { // Relays 2-4 for ifan are controlled by FANSPEED and don't need to be present if TasmotaGlobal.module_type = SONOFF_IFAN02 or SONOFF_IFAN03 - Relay[i] = 1; // Simple Relay + if (!iFanMod) { // Relays 2-4 for ifan are controlled by FANSPEED and don't need to be present if TasmotaGlobal.module_type = SONOFF_IFAN02 or SONOFF_IFAN03 + Relay[i] = 1; // Simple Relay } } } } - snprintf_P(RelLst, sizeof(RelLst), PSTR("%s%s%d"), RelLst, (i > 0 ? "," : ""), Relay[i]); // Vector for the Official Integration + ResponseAppend_P(PSTR("%s%d"), (i > 0 ? "," : ""), Relay[i]); // Vector for the Official Integration } - bool TuyaMod = false; - bool iFanMod = false; -#ifdef ESP8266 - if ((TUYA_DIMMER == TasmotaGlobal.module_type) || (SK03_TUYA == TasmotaGlobal.module_type)) { TuyaMod = true; }; - if ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)) { iFanMod = true; }; -#endif // ESP8266 + ResponseAppend_P(PSTR("]," // Relays (end) + "\"swc\":[")); // Switch modes (start) - char friendly_name[200]; - friendly_name[0] = '\0'; - uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present; - for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) { - char fname[TOPSZ]; - snprintf_P(fname, sizeof(fname), PSTR("\"%s\""), EscapeJSONString(SettingsText(SET_FRIENDLYNAME1 +i)).c_str()); - snprintf_P(friendly_name, sizeof(friendly_name), PSTR("%s%s%s"), friendly_name, (i > 0 ? "," : ""), (i < maxfn) ? fname : PSTR("null")); + // Enable Discovery for Switches only if SetOption114 is enabled + for (uint32_t i = 0; i < MAX_SWITCHES; i++) { + ResponseAppend_P(PSTR("%s%d"), (i > 0 ? "," : ""), (PinUsed(GPIO_SWT1, i) && Settings.flag5.mqtt_switches) ? Settings.switchmode[i] : -1); } - char switch_mode[90]; - switch_mode[0] = '\0'; - char switch_name[300]; - switch_name[0] = '\0'; + ResponseAppend_P(PSTR("]," // Switch modes (end) + "\"swn\":[")); // Switch names (start) + // Enable Discovery for Switches only if SetOption114 is enabled for (uint32_t i = 0; i < MAX_SWITCHES; i++) { char sname[TOPSZ]; snprintf_P(sname, sizeof(sname), PSTR("\"%s\""), GetSwitchText(i).c_str()); - snprintf_P(switch_mode, sizeof(switch_mode), PSTR("%s%s%d"), switch_mode, (i > 0 ? "," : ""), (PinUsed(GPIO_SWT1, i) & Settings.flag5.mqtt_switches) ? Settings.switchmode[i] : -1); - snprintf_P(switch_name, sizeof(switch_name), PSTR("%s%s%s"), switch_name, (i > 0 ? "," : ""), (PinUsed(GPIO_SWT1, i) & Settings.flag5.mqtt_switches) ? sname : PSTR("null")); + ResponseAppend_P(PSTR("%s%s"), (i > 0 ? "," : ""), (PinUsed(GPIO_SWT1, i) && Settings.flag5.mqtt_switches) ? sname : PSTR("null")); } + ResponseAppend_P(PSTR("]," // Switch names (end) + "\"btn\":[")); // Button flag (start) + bool SerialButton = false; - char button_flag[90]; - button_flag[0] = '\0'; // Enable Discovery for Buttons only if SetOption73 is enabled for (uint32_t i = 0; i < MAX_KEYS; i++) { #ifdef ESP8266 SerialButton = ((0 == i) && (SONOFF_DUAL == TasmotaGlobal.module_type )); -#endif // ESP8266 - snprintf_P(button_flag, sizeof(button_flag), PSTR("%s%s%d"), button_flag, (i > 0 ? "," : ""), (SerialButton ? 1 : (PinUsed(GPIO_KEY1, i)) & Settings.flag3.mqtt_buttons)); +#endif // ESP8266 + ResponseAppend_P(PSTR("%s%d"), (i > 0 ? "," : ""), (SerialButton ? 1 : (PinUsed(GPIO_KEY1, i)) && Settings.flag3.mqtt_buttons)); } - char shutter_option[90]; - shutter_option[0] = '\0'; + ResponseAppend_P(PSTR("]," // Button flag (end) + "\"so\":{\"4\":%d," // SetOptions + "\"11\":%d," + "\"13\":%d," + "\"17\":%d," + "\"20\":%d," + "\"30\":%d," + "\"68\":%d," + "\"73\":%d," + "\"82\":%d," + "\"114\":%d," + "\"117\":%d}," + "\"lk\":%d," // Light CTRGB linked + "\"lt_st\":%d," // Light SubType + "\"sho\":["), // Shutter Options (start) + Settings.flag.mqtt_response, + Settings.flag.button_swap, + Settings.flag.button_single, + Settings.flag.decimal_text, + Settings.flag.not_power_linked, + Settings.flag.hass_light, + Settings.flag3.pwm_multi_channels, + Settings.flag3.mqtt_buttons, + Settings.flag4.alexa_ct_range, + Settings.flag5.mqtt_switches, + Settings.flag5.fade_fixed_duration, + light_controller.isCTRGBLinked(), + Light.subtype); + for (uint32_t i = 0; i < MAX_SHUTTERS; i++) { #ifdef USE_SHUTTER - snprintf_P(shutter_option, sizeof(shutter_option), PSTR("%s%s%d"), shutter_option, (i > 0 ? "," : ""), Settings.shutter_options[i]); + ResponseAppend_P(PSTR("%s%d"), (i > 0 ? "," : ""), Settings.shutter_options[i]); #else - snprintf_P(shutter_option, sizeof(shutter_option), PSTR("%s%s0"), shutter_option, (i > 0 ? "," : "")); + ResponseAppend_P(PSTR("%s0"), (i > 0 ? "," : "")); #endif // USE_SHUTTER } - // Full 12 chars MAC address as ID - String mac_address = WiFi.macAddress(); - mac_address.replace(":", ""); - char unique_id[30]; - snprintf_P(unique_id, sizeof(unique_id), PSTR("%s"), mac_address.c_str()); + ResponseAppend_P(PSTR("]," // Shutter Options (end) + "\"ver\":1}")); // Discovery version +} - TasmotaGlobal.masterlog_level = LOG_LEVEL_DEBUG_MORE; // Hide topic on clean and remove use weblog 4 to show it +void TasDiscovery(void) { + TasmotaGlobal.masterlog_level = LOG_LEVEL_DEBUG_MORE; // Hide topic on clean and remove use weblog 4 to show it - ResponseClear(); // Clear retained message - if (!Settings.flag.hass_discovery) { // SetOption19 - Clear retained message - Response_P(TASMOTA_DISCOVER_DEVICE, (uint32_t)WiFi.localIP(), SettingsText(SET_DEVICENAME), - friendly_name, TasmotaGlobal.hostname, unique_id, ModuleName().c_str(), TuyaMod, iFanMod, GetStateText(0), GetStateText(1), GetStateText(2), GetStateText(3), - TasmotaGlobal.version, TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_FULLTOPIC), PSTR(SUB_PREFIX), PSTR(PUB_PREFIX), PSTR(PUB_PREFIX2), RelLst, switch_mode, switch_name, - button_flag, Settings.flag.mqtt_response, Settings.flag.button_swap, Settings.flag.button_single, Settings.flag.decimal_text, Settings.flag.not_power_linked, - Settings.flag.hass_light, Settings.flag3.pwm_multi_channels, Settings.flag3.mqtt_buttons, Settings.flag4.alexa_ct_range, Settings.flag5.mqtt_switches, - Settings.flag5.fade_fixed_duration, light_controller.isCTRGBLinked(), Light.subtype, shutter_option); + ResponseClear(); // Clear retained message + if (!Settings.flag.hass_discovery) { // SetOption19 - Clear retained message + TasDiscoverMessage(); // Build discovery message } char stopic[TOPSZ]; - snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/config"), unique_id); + snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/config"), NetworkUniqueId().c_str()); MqttPublish(stopic, true); - if (!Settings.flag.hass_discovery) { // SetOption19 - Clear retained message + if (!Settings.flag.hass_discovery) { // SetOption19 - Clear retained message Response_P(PSTR("{\"sn\":")); MqttShowSensor(); ResponseAppend_P(PSTR(",\"ver\":1}")); } - snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/sensors"), unique_id); + snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/sensors"), NetworkUniqueId().c_str()); MqttPublish(stopic, true); - TasmotaGlobal.masterlog_level = LOG_LEVEL_NONE; // Restore WebLog state + TasmotaGlobal.masterlog_level = LOG_LEVEL_NONE; // Restore WebLog state } void TasRediscover(void) { - TasDiscoverData.init_step = 1; // Delayed discovery or clear retained messages + TasDiscoverData_init_step = 1; // Delayed discovery or clear retained messages } /*********************************************************************************************\ @@ -202,18 +231,18 @@ void TasRediscover(void) { bool Xdrv12(uint8_t function) { bool result = false; - if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT + if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT switch (function) { case FUNC_EVERY_SECOND: - if (TasDiscoverData.init_step) { - TasDiscoverData.init_step--; - if (!TasDiscoverData.init_step) { - TasDiscovery(); // Send the topics for discovery + if (TasDiscoverData_init_step) { + TasDiscoverData_init_step--; + if (!TasDiscoverData_init_step) { + TasDiscovery(); // Send the topics for discovery } } break; case FUNC_MQTT_INIT: - TasDiscoverData.init_step = 10; // Delayed discovery + TasDiscoverData_init_step = 10; // Delayed discovery break; } } diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 8f0f75941..b4d1a945a 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -329,9 +329,7 @@ void NewHAssDiscovery(void) ResponseClear(); // Clear retained message // Full 12 chars MAC address as ID - String mac_address = WiFi.macAddress(); - mac_address.replace(":", ""); - snprintf_P(unique_id, sizeof(unique_id), PSTR("%s"), mac_address.c_str()); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%s"), NetworkUniqueId().c_str()); snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/config"), unique_id); // Send empty message if new discovery is disabled diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index db20ef24c..e41233b9c 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -172,8 +172,7 @@ const char HUE_API[] PROGMEM = "\x00\x06\x3B\x37\x8C\xEC\x2D\x10\xEC\x9C\x2F\x9D String HueBridgeId(void) { - String temp = WiFi.macAddress(); - temp.replace(":", ""); + String temp = NetworkUniqueId(); String bridgeid = temp.substring(0, 6); bridgeid += F("FFFE"); bridgeid += temp.substring(6); @@ -182,8 +181,7 @@ String HueBridgeId(void) String HueSerialnumber(void) { - String serial = WiFi.macAddress(); - serial.replace(":", ""); + String serial = NetworkUniqueId(); serial.toLowerCase(); return serial; // 5ccf7f139f3d } From 9e0300031a45b8e41ef3e1837c5e915381765922 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 11 Apr 2021 15:14:10 +0200 Subject: [PATCH 35/67] Berry driver.add_cmd() --- .../Berry-0.1.10/src/be_solidifylib.c | 171 ++++++++---------- lib/libesp32/Berry-0.1.10/src/berry.h | 66 ++++++- .../Berry-0.1.10/src/port/be_driverlib.c | 76 ++++++++ tasmota/xdrv_52_3_berry_tasmota.ino | 17 ++ tasmota/xdrv_52_7_berry_embedded.ino | 13 ++ 5 files changed, 241 insertions(+), 102 deletions(-) diff --git a/lib/libesp32/Berry-0.1.10/src/be_solidifylib.c b/lib/libesp32/Berry-0.1.10/src/be_solidifylib.c index cd355bc3d..56304bea3 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_solidifylib.c +++ b/lib/libesp32/Berry-0.1.10/src/be_solidifylib.c @@ -45,46 +45,39 @@ static const char * m_type_ktab(int type) } } -static void m_solidify_closure(bvm *vm, bclosure *cl, int builtins) -{ - bproto *pr = cl->proto; - const char * func_name = str(pr->name); +static void m_solidify_proto(bvm *vm, bproto *pr, const char * func_name, int builtins) +{ + // const char * func_name = str(pr->name); const char * func_source = str(pr->source); - // logfmt("// == builtin_count %i\n", builtins); - // logfmt("// type %i, ", cl->type); - // logfmt("// marked %i, ", cl->marked); - // logfmt("// nupvals %i\n", cl->nupvals); + if (pr->nproto > 0) { + for (int32_t i = 0; i < pr->nproto; i++) { + size_t sub_len = strlen(func_name) + 10; + char sub_name[sub_len]; + snprintf(sub_name, sizeof(sub_name), "%s_%d", func_name, i); + m_solidify_proto(vm, pr->ptab[i], sub_name, builtins); + } + } - // logfmt("// PROTO:\n"); - // logfmt("// type %i, ", pr->type); - // logfmt("// marked %i, ", pr->marked); - // logfmt("// nstack %i, ", pr->nstack); - // logfmt("// argcs %i, ", pr->argc); - // // logfmt("// varg %i\n", pr->varg); + logfmt("\n/********** Solidified proto: %s */\n", func_name); - // logfmt("// gray %p\n", (void*)pr->gray); - // logfmt("// upvals %p\n", (void*)pr->upvals); - // logfmt("// proto_tab %p (%i)\n", (void*)pr->ptab, pr->nproto); + if (pr->nproto > 0) { + logfmt("static const bproto *%s_subproto[%i] = {\n", func_name, pr->nproto); + for (int32_t i = 0; i < pr->nproto; i++) { + logfmt(" &%s_%d_proto,\n", func_name, i); + // logfmt(" be_local_const_upval(%i, %i),\n", pr->upvals[i].instack, pr->upvals[i].idx); TODO + } + logfmt("};\n\n"); + } - // logfmt("// name %s\n", str(pr->name)); - // logfmt("// source %s\n", str(pr->source)); - - // logfmt("\n"); - - // logfmt("// ktab %p (%i)\n", (void*)pr->ktab, pr->nconst); - // for (int i = 0; i < pr->nconst; i++) { - // logfmt("// const[%i] type %i (%s) %p", i, pr->ktab[i].type, be_vtype2str(&pr->ktab[i]), pr->ktab[i].v.p); - // if (pr->ktab[i].type == BE_STRING) { - // logfmt(" = '%s'", str(pr->ktab[i].v.s)); - // } - // logfmt("\n"); - // } - - logfmt("\n"); - logfmt("/********************************************************************\n"); - logfmt("** Solidified function: %s\n", func_name); - logfmt("********************************************************************/\n\n"); + if (pr->nupvals > 0) { + logfmt("static const bupvaldesc %s_upvals[%i] = {\n", func_name, pr->nupvals); + for (int32_t i = 0; i < pr->nupvals; i++) { + logfmt(" be_local_const_upval(%i, %i),\n", pr->upvals[i].instack, pr->upvals[i].idx); + // logfmt("// upval[%d] = { .instack = %i, .idx = %i }\n", i, pr->upvals[i].instack, pr->upvals[i].idx); + } + logfmt("};\n\n"); + } /* create static strings for name and source */ logfmt("be_define_local_const_str(%s_str_name, \"%s\", %i, 0, %u, 0);\n", @@ -107,30 +100,32 @@ static void m_solidify_closure(bvm *vm, bclosure *cl, int builtins) } logfmt("\n"); - logfmt("static const bvalue %s_ktab[%i] = {\n", func_name, pr->nconst); - for (int k = 0; k < pr->nconst; k++) { - int type = pr->ktab[k].type; - const char *type_name = m_type_ktab(type); - if (type_name == NULL) { - char error[64]; - snprintf(error, sizeof(error), "Unsupported type in function constants: %i", type); - be_raise(vm, "internal_error", error); - } - if (type == BE_STRING) { - logfmt(" { { .s=be_local_const_str(%s_str_%i) }, %s},\n", func_name, k, type_name); - } else if (type == BE_INT) { - logfmt(" { { .i=%" BE_INT_FMTLEN "i }, %s},\n", pr->ktab[k].v.i, type_name); - } else if (type == BE_REAL) { -#if BE_USE_SINGLE_FLOAT - logfmt(" { { .p=(void*)0x%08X }, %s},\n", (uint32_t) pr->ktab[k].v.p, type_name); -#else - logfmt(" { { .p=(void*)0x%016llX }, %s},\n", (uint64_t) pr->ktab[k].v.p, type_name); -#endif - } else if (type == BE_BOOL) { - logfmt(" { { .b=%i }, %s},\n", pr->ktab[k].v.b, type_name); + if (pr->nconst > 0) { + logfmt("static const bvalue %s_ktab[%i] = {\n", func_name, pr->nconst); + for (int k = 0; k < pr->nconst; k++) { + int type = pr->ktab[k].type; + const char *type_name = m_type_ktab(type); + if (type_name == NULL) { + char error[64]; + snprintf(error, sizeof(error), "Unsupported type in function constants: %i", type); + be_raise(vm, "internal_error", error); + } + if (type == BE_STRING) { + logfmt(" { { .s=be_local_const_str(%s_str_%i) }, %s},\n", func_name, k, type_name); + } else if (type == BE_INT) { + logfmt(" { { .i=%" BE_INT_FMTLEN "i }, %s},\n", pr->ktab[k].v.i, type_name); + } else if (type == BE_REAL) { + #if BE_USE_SINGLE_FLOAT + logfmt(" { { .p=(void*)0x%08X }, %s},\n", (uint32_t) pr->ktab[k].v.p, type_name); + #else + logfmt(" { { .p=(void*)0x%016llX }, %s},\n", (uint64_t) pr->ktab[k].v.p, type_name); + #endif + } else if (type == BE_BOOL) { + logfmt(" { { .b=%i }, %s},\n", pr->ktab[k].v.b, type_name); + } } + logfmt("};\n\n"); } - logfmt("};\n\n"); logfmt("static const uint32_t %s_code[%i] = {\n", func_name, pr->codesize); for (int pc = 0; pc < pr->codesize; pc++) { @@ -150,52 +145,28 @@ static void m_solidify_closure(bvm *vm, bclosure *cl, int builtins) } logfmt("};\n\n"); - logfmt("static const bproto %s_proto = {\n", func_name); - // bcommon_header - logfmt(" NULL, // bgcobject *next\n"); - logfmt(" %i, // type\n", pr->type); - logfmt(" GC_CONST, // marked\n"); - // - logfmt(" %i, // nstack\n", pr->nstack); - logfmt(" %i, // nupvals\n", pr->nupvals); - logfmt(" %i, // argc\n", pr->argc); - logfmt(" %i, // varg\n", pr->varg); - if (pr->nproto > 0) { - be_raise(vm, "internal_error", "unsupported non-null proto list"); + logfmt("be_define_local_proto(%s, %d, %d, %d, %d, %d);\n", + func_name, pr->nstack, pr->argc, (pr->nconst > 0) ? 1 : 0, (pr->nproto > 0) ? 1 : 0, (pr->nupvals > 0) ? 1 : 0); +} + +static void m_solidify_closure(bvm *vm, bclosure *cl, int builtins) +{ + bproto *pr = cl->proto; + const char * func_name = str(pr->name); + + if (cl->nupvals > 0) { + be_raise(vm, "internal_error", "Unsupported upvals in closure"); } - logfmt(" NULL, // bgcobject *gray\n"); - logfmt(" NULL, // bupvaldesc *upvals\n"); - logfmt(" (bvalue*) &%s_ktab, // ktab\n", func_name); - logfmt(" NULL, // bproto **ptab\n"); - logfmt(" (binstruction*) &%s_code, // code\n", func_name); - logfmt(" be_local_const_str(%s_str_name), // name\n", func_name); - logfmt(" %i, // codesize\n", pr->codesize); - logfmt(" %i, // nconst\n", pr->nconst); - logfmt(" %i, // nproto\n", pr->nproto); - logfmt(" be_local_const_str(%s_str_source), // source\n", func_name); - // - logfmt("#if BE_DEBUG_RUNTIME_INFO /* debug information */\n"); - logfmt(" NULL, // lineinfo\n"); - logfmt(" 0, // nlineinfo\n"); - logfmt("#endif\n"); - logfmt("#if BE_DEBUG_VAR_INFO\n"); - logfmt(" NULL, // varinfo\n"); - logfmt(" 0, // nvarinfo\n"); - logfmt("#endif\n"); - logfmt("};\n\n"); + + logfmt("\n"); + logfmt("/********************************************************************\n"); + logfmt("** Solidified function: %s\n", func_name); + logfmt("********************************************************************/\n"); + + m_solidify_proto(vm, pr, func_name, builtins); // closure - logfmt("static const bclosure %s_closure = {\n", func_name); - // bcommon_header - logfmt(" NULL, // bgcobject *next\n"); - logfmt(" %i, // type\n", cl->type); - logfmt(" GC_CONST, // marked\n"); - // - logfmt(" %i, // nupvals\n", cl->nupvals); - logfmt(" NULL, // bgcobject *gray\n"); - logfmt(" (bproto*) &%s_proto, // proto\n", func_name); - logfmt(" { NULL } // upvals\n"); - logfmt("};\n\n"); + logfmt("be_define_local_closure(%s);\n\n", func_name); logfmt("/*******************************************************************/\n\n"); } diff --git a/lib/libesp32/Berry-0.1.10/src/berry.h b/lib/libesp32/Berry-0.1.10/src/berry.h index 25e9f3c85..760ec2961 100644 --- a/lib/libesp32/Berry-0.1.10/src/berry.h +++ b/lib/libesp32/Berry-0.1.10/src/berry.h @@ -101,7 +101,7 @@ enum berrorcode { #elif defined(__GNUC__) /* in GCC */ #define BERRY_LOCAL __attribute__ ((visibility ("hidden"))) #else /* other platforms */ - #define BERRY_LOCAL static + #define BERRY_LOCAL #endif #ifdef __cplusplus @@ -252,7 +252,7 @@ typedef struct bntvmodule { /* support for solidified berry functions */ /* native const strings outside of global string hash */ #define be_define_local_const_str(_name, _s, _hash, _extra, _len, _next) \ - BERRY_LOCAL const bcstring be_local_const_str_##_name = { \ + static const bcstring be_local_const_str_##_name = { \ .next = (bgcobject *)NULL, \ .type = BE_STRING, \ .marked = GC_CONST, \ @@ -264,6 +264,68 @@ typedef struct bntvmodule { #define be_local_const_str(_name) (bstring*) &be_local_const_str_##_name +/* conditional macro see https://stackoverflow.com/questions/11632219/c-preprocessor-macro-specialisation-based-on-an-argument */ +#define BE_IIF(cond) BE_IIF_ ## cond +#define BE_IIF_0(t, f) f +#define BE_IIF_1(t, f) t + +#if BE_DEBUG_VAR_INFO + #define be_local_const_upval(ins, idx) { "", ins, idx } +#else + #define be_local_const_upval(ins, idx) { ins, idx } +#endif + +/* conditional block in bproto depending on compilation options */ +#if BE_DEBUG_RUNTIME_INFO + #define PROTO_RUNTIME_BLOCK \ + NULL, /* varinfo */ \ + 0, /* nvarinfo */ +#else + #define PROTO_RUNTIME_BLOCK +#endif +#if BE_DEBUG_VAR_INFO + #define PROTO_VAR_INFO_BLOCK\ + NULL, /* varinfo */ \ + 0, /* nvarinfo */ +#else + #define PROTO_VAR_INFO_BLOCK +#endif + +/* define bproto */ +#define be_define_local_proto(_name, _nstack, _argc, _is_const, _is_subproto, _is_upval) \ + static const bproto _name##_proto = { \ + NULL, /* bgcobject *next */ \ + 8, /* type BE_PROTO */ \ + GC_CONST, /* marked outside of GC */ \ + (_nstack), /* nstack */ \ + BE_IIF(_is_upval)(sizeof(_name##_upvals)/sizeof(bupvaldesc),0),/* nupvals */ \ + (_argc), /* argc */ \ + 0, /* varg */ \ + NULL, /* bgcobject *gray */ \ + BE_IIF(_is_upval)((bupvaldesc*)&_name##_upvals,NULL), /* bupvaldesc *upvals */ \ + BE_IIF(_is_const)((bvalue*)&_name##_ktab,NULL), /* ktab */ \ + BE_IIF(_is_subproto)((struct bproto**)&_name##_subproto,NULL),/* bproto **ptab */ \ + (binstruction*) &_name##_code, /* code */ \ + be_local_const_str(_name##_str_name), /* name */ \ + sizeof(_name##_code)/sizeof(uint32_t), /* codesize */ \ + BE_IIF(_is_const)(sizeof(_name##_ktab)/sizeof(bvalue),0),/* nconst */ \ + BE_IIF(_is_subproto)(sizeof(_name##_subproto)/sizeof(bproto*),0),/* proto */ \ + be_local_const_str(_name##_str_source), /* source */ \ + PROTO_RUNTIME_BLOCK \ + PROTO_VAR_INFO_BLOCK \ + } + +#define be_define_local_closure(_name) \ + const bclosure _name##_closure = { \ + NULL, /* bgcobject *next */ \ + 36, /* type BE_CLOSURE */ \ + GC_CONST, /* marked */ \ + 0, /* nupvals */ \ + NULL, /* bgcobject *gray */ \ + (bproto*) &_name##_proto, /* proto */ \ + { NULL } /* upvals */ \ + } + /* debug hook typedefs */ #define BE_HOOK_LINE 1 diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c b/lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c index 4e9b8cce8..fd9c2ccbb 100644 --- a/lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c +++ b/lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c @@ -5,6 +5,77 @@ * *******************************************************************/ #include "be_object.h" +#include "be_string.h" +#include "be_gc.h" + +extern int d_getTasmotaGlob(bvm *vm); + + +/******************************************************************** + "class Driver2 : Driver " + "def add_cmd(c, f) " + "var tasmota = self.get_tasmota() " + "tasmota.add_cmd(c, / cmd, idx, payload, payload_json -> f(self, cmd, idx, payload, payload_json)) " + "end " + "end " + "Driver = Driver2 " +********************************************************************/ +/******************************************************************** +** Solidified function: add_cmd +********************************************************************/ + +/********** Solidified proto: add_cmd_0 */ +static const bupvaldesc add_cmd_0_upvals[2] = { + be_local_const_upval(1, 2), + be_local_const_upval(1, 0), +}; + +be_define_local_const_str(add_cmd_0_str_name, "add_cmd_0", 607256038, 0, 8, 0); +be_define_local_const_str(add_cmd_0_str_source, "input", -103256197, 0, 5, 0); + +static const uint32_t add_cmd_0_code[8] = { + 0x68100000, // 0000 GETUPV R4 U0 + 0x68140001, // 0001 GETUPV R5 U1 + 0x5C180000, // 0002 MOVE R6 R0 + 0x5C1C0200, // 0003 MOVE R7 R1 + 0x5C200400, // 0004 MOVE R8 R2 + 0x5C240600, // 0005 MOVE R9 R3 + 0x7C100A00, // 0006 CALL R4 5 + 0x80040800, // 0007 RET 1 R4 +}; + +be_define_local_proto(add_cmd_0, 10, 4, 0, 0, 1); + +/********** Solidified proto: add_cmd */ +static const bproto *add_cmd_subproto[1] = { + &add_cmd_0_proto, +}; + +be_define_local_const_str(add_cmd_str_name, "add_cmd", -933336417, 0, 7, 0); +be_define_local_const_str(add_cmd_str_source, "input", -103256197, 0, 5, 0); +be_define_local_const_str(add_cmd_str_0, "get_tasmota", 334356779, 0, 11, 0); +be_define_local_const_str(add_cmd_str_1, "add_cmd", -933336417, 0, 7, 0); + +static const bvalue add_cmd_ktab[2] = { + { { .s=be_local_const_str(add_cmd_str_0) }, BE_STRING}, + { { .s=be_local_const_str(add_cmd_str_1) }, BE_STRING}, +}; + +static const uint32_t add_cmd_code[8] = { + 0x8C0C0100, // 0000 GETMET R3 R0 R256 + 0x7C0C0200, // 0001 CALL R3 1 + 0x8C100701, // 0002 GETMET R4 R3 R257 + 0x5C180200, // 0003 MOVE R6 R1 + 0x841C0000, // 0004 CLOSURE R7 P0 + 0x7C100600, // 0005 CALL R4 3 + 0xA0000000, // 0006 CLOSE 0 + 0x80000000, // 0007 RET 0 R0 +}; + +be_define_local_proto(add_cmd, 8, 3, 1, 1, 0); +be_define_local_closure(add_cmd); + +/*******************************************************************/ // #if !BE_USE_PRECOMPILED_OBJECT #if 1 // TODO we will do pre-compiled later @@ -19,6 +90,11 @@ void be_load_driverlib(bvm *vm) { "web_sensor", NULL }, { "json_append", NULL }, { "button_pressed", NULL }, + + { "get_tasmota", d_getTasmotaGlob }, + + { NULL, (bntvfunc) BE_CLOSURE }, /* mark section for berry closures */ + { "add_cmd", (bntvfunc) &add_cmd_closure }, { NULL, NULL } }; diff --git a/tasmota/xdrv_52_3_berry_tasmota.ino b/tasmota/xdrv_52_3_berry_tasmota.ino index 89ea65858..e22330a7e 100644 --- a/tasmota/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/xdrv_52_3_berry_tasmota.ino @@ -361,4 +361,21 @@ void berry_log(const char * berry_buf) { } +/*********************************************************************************************\ + * Helper function for `Driver` class + * + * get_tasmota() -> tasmota instance from globals + * allows to use solidified methods refering to the global object `tasmota` + * +\*********************************************************************************************/ +extern "C" { + + int32_t d_getTasmotaGlob(struct bvm *vm); + int32_t d_getTasmotaGlob(struct bvm *vm) { + be_getglobal(berry.vm, PSTR("tasmota")); + be_return(vm); // Return + } + +} + #endif // USE_BERRY diff --git a/tasmota/xdrv_52_7_berry_embedded.ino b/tasmota/xdrv_52_7_berry_embedded.ino index cfcce38e2..f1d44250a 100644 --- a/tasmota/xdrv_52_7_berry_embedded.ino +++ b/tasmota/xdrv_52_7_berry_embedded.ino @@ -352,6 +352,15 @@ const char berry_prog[] = "end " + // // Monkey patch `Driver` class - To be continued + // "class Driver2 : Driver " + // "def add_cmd(c, f) " + // "var tasmota = self.get_tasmota() " + // "tasmota.add_cmd(c, / cmd, idx, payload, payload_json -> f(self, cmd, idx, payload, payload_json)) " + // "end " + // "end " + // "Driver = Driver2 " + // Instantiate tasmota object "tasmota = Tasmota() " "def log(m,l) tasmota.log(m,l) end " @@ -380,12 +389,16 @@ const char berry_prog[] = // "end " // "end " +#ifdef USE_I2C "tasmota.wire1 = Wire(1) " "tasmota.wire2 = Wire(2) " "wire1 = tasmota.wire1 " "wire2 = tasmota.wire2 " +#endif // USE_I2C + // auto-import gpio "import gpio " + #ifdef USE_LIGHT "import light " #endif // USE_LIGHT From 4805f26649ccb30105fec62de7c0d3835cf0c323 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 11 Apr 2021 15:16:40 +0200 Subject: [PATCH 36/67] udisplay option a3 --- tasmota/tasmota_template.h | 4 ++-- tasmota/xdsp_17_universal.ino | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 70bcff270..9b27c12d9 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -169,14 +169,14 @@ enum ProgramSelectablePins { GPIO_USER, // User configurable needs to be 2047 GPIO_MAX }; -#define MAX_OPTIONS_A 2 // Increase if more bits are used from GpioOptionABits +#define MAX_OPTIONS_A 3 // Increase if more bits are used from GpioOptionABits typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... uint32_t data; // Allow bit manipulation using SetOption struct { // GPIO Option_A1 .. Option_A32 uint32_t pwm1_input : 1; // bit 0 (v9.2.0.1) - Option_A1 - (Light) Change PWM1 to input on power off and no fade running (1) uint32_t dummy_energy : 1; // bit 1 (v9.3.1.2) - Option_A2 - (Energy) Enable dummy values - uint32_t spare02 : 1; // bit 2 + uint32_t udisplay_driver : 1; // bit 2 Universal display driver uint32_t spare03 : 1; // bit 3 uint32_t spare04 : 1; // bit 4 uint32_t spare05 : 1; // bit 5 diff --git a/tasmota/xdsp_17_universal.ino b/tasmota/xdsp_17_universal.ino index eb4a9dbd8..c72b4cb85 100644 --- a/tasmota/xdsp_17_universal.ino +++ b/tasmota/xdsp_17_universal.ino @@ -83,7 +83,7 @@ void Init_uDisp(void) { char *ddesc = 0; char *fbuff; - if (1) { + if (TasmotaGlobal.gpio_optiona.udisplay_driver) { Settings.display_model = XDSP_17; fg_color = 1; From 06a75af1af87705f733a20462187f29017a6471c Mon Sep 17 00:00:00 2001 From: Barbudor Date: Sun, 11 Apr 2021 15:22:57 +0200 Subject: [PATCH 37/67] file system editor GUI_FILE_EDIT --- tasmota/language/af_AF.h | 3 + tasmota/language/bg_BG.h | 3 + tasmota/language/cs_CZ.h | 3 + tasmota/language/de_DE.h | 3 + tasmota/language/el_GR.h | 3 + tasmota/language/en_GB.h | 3 + tasmota/language/es_ES.h | 3 + tasmota/language/fr_FR.h | 3 + tasmota/language/fy_NL.h | 3 + tasmota/language/he_HE.h | 3 + tasmota/language/hu_HU.h | 3 + tasmota/language/it_IT.h | 3 + tasmota/language/ko_KO.h | 3 + tasmota/language/nl_NL.h | 3 + tasmota/language/pl_PL.h | 3 + tasmota/language/pt_BR.h | 3 + tasmota/language/pt_PT.h | 3 + tasmota/language/ro_RO.h | 3 + tasmota/language/ru_RU.h | 3 + tasmota/language/sk_SK.h | 3 + tasmota/language/sv_SE.h | 3 + tasmota/language/tr_TR.h | 3 + tasmota/language/uk_UA.h | 3 + tasmota/language/vi_VN.h | 3 + tasmota/language/zh_CN.h | 3 + tasmota/language/zh_TW.h | 3 + tasmota/xdrv_50_filesystem.ino | 173 ++++++++++++++++++++++++++++++--- 27 files changed, 238 insertions(+), 13 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 6d4500990..76b555acb 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Bestuur lêerstelsel" #define D_FS_SIZE "Grootte" #define D_FS_FREE "Vry" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "versterking:" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index d37361752..145448e04 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -915,6 +915,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "усилване:" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index a4405b404..af7fa2d8b 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index f8831c5ad..a466598c7 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Verwalte Dateisystem" #define D_FS_SIZE "Größe" #define D_FS_FREE "Frei" +#define D_NEW_FILE "neue-datei.txt" +#define D_CREATE_NEW_FILE "Neue Datei erstellen und bearbeiten" +#define D_EDIT_FILE "Datei bearbeiten" //xsns_67_as3935.ino #define D_AS3935_GAIN "Umgebung:" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 969718b10..16ad54b6f 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 52dadf8d9..73dacd8a3 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 8487e5e6d..8bcefba0d 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Explorar Archivos" #define D_FS_SIZE "Tamaño" #define D_FS_FREE "Libre" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "Ganancia:" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 545341bfb..a37dd796d 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -915,6 +915,9 @@ #define D_MANAGE_FILE_SYSTEM "Gestion du Système de Fichier" #define D_FS_SIZE "Taille" #define D_FS_FREE "Libre" +#define D_NEW_FILE "nouveau-fichier.txt" +#define D_CREATE_NEW_FILE "Créer and modifier un nouveau fichier" +#define D_EDIT_FILE "Modification de fichier" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index a3aa1c6fa..5f00102ab 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Bestânbehearder" #define D_FS_SIZE "Grutte" #define D_FS_FREE "Frij" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 60c37d543..f25d847eb 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 195172128..f4d210a5c 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Fájlrendszer kezelése" #define D_FS_SIZE "Méret" #define D_FS_FREE "Szabad" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "nyereség:" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 3a5230d0e..f15d873a7 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Gestione File system" #define D_FS_SIZE "Dimensione" #define D_FS_FREE "Liberi" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "guadagno:" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index ca33d2207..ef341444e 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index e90b2db19..667c7ac91 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Bestandsbeheer" #define D_FS_SIZE "Grootte" #define D_FS_FREE "Vrij" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index af6185933..00840c694 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Menadżer plików" #define D_FS_SIZE "Rozmiar" #define D_FS_FREE "Wolne" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "wejście:" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index cc05a5552..398d49286 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 23cd2a44d..d2aeec758 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 0bcf7674b..d5d9733df 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index f8a33be61..5a4ef6cad 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 1510a1546..2f4d37a99 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 7166c6687..a1a2077a2 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 51b297bb8..dd041c94c 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 2d3de8097..0b6f967ae 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 9b8fce166..e47e52952 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "khuếch đại:" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index aced421f3..6b5a4c301 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 2c83e5dc0..2a36f65b7 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -916,6 +916,9 @@ #define D_MANAGE_FILE_SYSTEM "Manage File system" #define D_FS_SIZE "Size" #define D_FS_FREE "Free" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index 3a5626cfb..c187df02c 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -279,7 +279,7 @@ bool TfsFileExists(const char *fname){ bool yes = ffsp->exists(fname); if (!yes) { - AddLog(LOG_LEVEL_DEBUG, PSTR("TFS: File not found")); + AddLog(LOG_LEVEL_DEBUG, PSTR("TFS: File '%s' not found"), fname); } return yes; } @@ -320,7 +320,7 @@ bool TfsLoadFile(const char *fname, uint8_t *buf, uint32_t len) { File file = ffsp->open(fname, "r"); if (!file) { - AddLog(LOG_LEVEL_INFO, PSTR("TFS: File not found")); + AddLog(LOG_LEVEL_INFO, PSTR("TFS: File '%s' not found"), fname); return false; } @@ -564,21 +564,46 @@ const char UFS_FORM_SDC_DIRa[] PROGMEM = const char UFS_FORM_SDC_DIRc[] PROGMEM = ""; const char UFS_FORM_FILE_UPGb[] PROGMEM = +#ifdef GUI_EDIT_FILE + "
" + "
" +#endif "" "" ""; const char UFS_FORM_SDC_DIRd[] PROGMEM = "
%s
"; const char UFS_FORM_SDC_DIRb[] PROGMEM = - "
%s %s %8d %s
"; + "
%s %s %8d %s %s
"; const char UFS_FORM_SDC_HREF[] PROGMEM = - "http://%_I/ufsd?download=%s/%s"; + "ufsd?download=%s/%s"; + #ifdef GUI_TRASH_FILE const char UFS_FORM_SDC_HREFdel[] PROGMEM = - //"🗑"; - "🔥"; // 🔥 + //"🗑"; // 🗑️ + "🔥"; // 🔥 #endif // GUI_TRASH_FILE +#ifdef GUI_EDIT_FILE + +#define FILE_BUFFER_SIZE 1024 + +const char UFS_FORM_SDC_HREFedit[] PROGMEM = + "📝"; // 📝 + +const char HTTP_EDITOR_FORM_START[] PROGMEM = + "
 " D_EDIT_FILE " " + "
" + "

" + "" + "" + "
"; + +#endif // #ifdef GUI_EDIT_FILE + void UfsDirectory(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -656,7 +681,7 @@ void UfsListDir(char *path, uint8_t depth) { if (dir) { dir.rewindDirectory(); if (strlen(path)>1) { - ext_snprintf_P(npath, sizeof(npath), PSTR("http://%_I/ufsd?download=%s"), (uint32_t)WiFi.localIP(), path); + ext_snprintf_P(npath, sizeof(npath), PSTR("ufsd?download=%s"), path); for (uint32_t cnt = strlen(npath) - 1; cnt > 0; cnt--) { if (npath[cnt] == '/') { if (npath[cnt - 1] == '=') { @@ -698,7 +723,7 @@ void UfsListDir(char *path, uint8_t depth) { sprintf(cp, format, ep); if (entry.isDirectory()) { - ext_snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, (uint32_t)WiFi.localIP(), pp, ep); + ext_snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, pp, ep); WSContentSend_P(UFS_FORM_SDC_DIRd, npath, ep, name); uint8_t plen = strlen(path); if (plen > 1) { @@ -710,13 +735,20 @@ void UfsListDir(char *path, uint8_t depth) { } else { #ifdef GUI_TRASH_FILE char delpath[128]; - ext_snprintf_P(delpath, sizeof(delpath), UFS_FORM_SDC_HREFdel, (uint32_t)WiFi.localIP(), pp, ep); + ext_snprintf_P(delpath, sizeof(delpath), UFS_FORM_SDC_HREFdel, pp, ep); #else char delpath[2]; delpath[0]=0; #endif // GUI_TRASH_FILE - ext_snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, (uint32_t)WiFi.localIP(), pp, ep); - WSContentSend_P(UFS_FORM_SDC_DIRb, npath, ep, name, tstr.c_str(), entry.size(), delpath); +#ifdef GUI_EDIT_FILE + char editpath[128]; + ext_snprintf_P(editpath, sizeof(editpath), UFS_FORM_SDC_HREFedit, pp, ep); +#else + char editpath[2]; + editpath[0]=0; +#endif // GUI_TRASH_FILE + ext_snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, pp, ep); + WSContentSend_P(UFS_FORM_SDC_DIRb, npath, ep, name, tstr.c_str(), entry.size(), delpath, editpath); } } entry.close(); @@ -733,13 +765,13 @@ uint8_t UfsDownloadFile(char *file) { File download_file; if (!dfsp->exists(file)) { - AddLog(LOG_LEVEL_INFO, PSTR("UFS: File not found")); + AddLog(LOG_LEVEL_INFO, PSTR("UFS: File '%s' not found"), file); return 0; } download_file = dfsp->open(file, UFS_FILE_READ); if (!download_file) { - AddLog(LOG_LEVEL_INFO, PSTR("UFS: Could not open file")); + AddLog(LOG_LEVEL_INFO, PSTR("UFS: Could not open file '%s'"), file); return 0; } @@ -877,6 +909,117 @@ void UfsUploadFileClose(void) { ufs_upload_file.close(); } + +//****************************************************************************************** +// File Editor +//****************************************************************************************** + +#ifdef GUI_EDIT_FILE + +void UfsEditor(void) { + if (!HttpCheckPriviledgedAccess()) { return; } + + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor GET")); + + String fname; + if (Webserver->hasArg(F("file"))) { + fname = Webserver->arg(F("file")); + } + else { + fname = D_NEW_FILE; + } + if (fname[0] != '/') fname = "/" +fname; + + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file=%s, ffs_type=%d, TfsFileExist=%d"), fname.c_str(), ffs_type, TfsFileExists(fname.c_str())); + + WSContentStart_P(PSTR(D_EDIT_FILE)); + WSContentSendStyle(); + WSContentSend_P(HTTP_EDITOR_FORM_START, fname.c_str()); + + if (ffs_type && TfsFileExists(fname.c_str())) { + File fp = ffsp->open(fname.c_str(), "r"); + if (!fp) { + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file open failed")); + WSContentSend_P(D_NEW_FILE); + } + else { + uint8_t *buf = (uint8_t*)malloc(FILE_BUFFER_SIZE+1); + size_t filelen = fp.size(); + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file len=%d"), filelen); + while ( filelen > 0 ) { + size_t l = fp.read(buf, FILE_BUFFER_SIZE); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UFS: UfsEditor: read=%d"), l); + if (l < 0) break; + buf[l] = '\0'; + WSContentSend_P((const char*)buf); + filelen -= l; + } + fp.close(); + free(buf); + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: read done")); + } + } + else { + WSContentSend_P(D_NEW_FILE); + } + + WSContentSend_P(HTTP_EDITOR_FORM_END); + WSContentSend_P(UFS_WEB_DIR, PSTR(D_MANAGE_FILE_SYSTEM)); + WSContentStop(); +} + +void UfsEditorUpload(void) { + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file upload")); + + if (!HttpCheckPriviledgedAccess()) { return; } + + if (!Webserver->hasArg("name")) { + AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: file upload - no filename")); + WSSend(400, CT_PLAIN, F("400: Bad request - no filename")); + return; + } + String name = Webserver->arg("name"); + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file '%s'"), name.c_str()); + + if (!Webserver->hasArg("content")) { + AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: file upload - no content")); + WSSend(400, CT_PLAIN, F("400: Bad request - no content")); + return; + } + String content = Webserver->arg("content"); + + if (!ffsp) { + Web.upload_error = 1; + AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: 507: no storage available")); + WSSend(507, CT_PLAIN, F("507: no storage available")); + return; + } + + File fp = ffsp->open(name.c_str(), "w"); + if(!fp) { + Web.upload_error = 1; + AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: 400: invalid file name '%s'"), name.c_str()); + WSSend(400, CT_PLAIN, F("400: bad request - invalid filename")); + return; + } + + if (*content.c_str()) { + content.replace("\r\n", "\n"); + content.replace("\r", "\n"); + } + + if (!fp.print(content)) { + AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: write error on '%s'"), name.c_str()); + } + + fp.close(); + + Webserver->sendHeader(F("Location"),F("/ufsu")); + Webserver->send(303); +} + +#endif // #ifdef GUI_EDIT_FILE + #endif // USE_WEBSERVER /*********************************************************************************************\ @@ -916,6 +1059,10 @@ bool Xdrv50(uint8_t function) { Webserver->on("/ufsd", UfsDirectory); Webserver->on("/ufsu", HTTP_GET, UfsDirectory); Webserver->on("/ufsu", HTTP_POST,[](){Webserver->sendHeader(F("Location"),F("/ufsu"));Webserver->send(303);}, HandleUploadLoop); +#ifdef GUI_EDIT_FILE + Webserver->on("/ufse", HTTP_GET, UfsEditor); + Webserver->on("/ufse", HTTP_POST, UfsEditorUpload); +#endif break; #endif // USE_WEBSERVER } From d4b2a85aff4a9da01229fe5b83c43970a2b72214 Mon Sep 17 00:00:00 2001 From: Barbudor Date: Sun, 11 Apr 2021 15:39:59 +0200 Subject: [PATCH 38/67] Display exception in autoexec.bet --- tasmota/xdrv_52_7_berry_embedded.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/xdrv_52_7_berry_embedded.ino b/tasmota/xdrv_52_7_berry_embedded.ino index cfcce38e2..e704e597f 100644 --- a/tasmota/xdrv_52_7_berry_embedded.ino +++ b/tasmota/xdrv_52_7_berry_embedded.ino @@ -22,7 +22,7 @@ /*********************************************************************************************\ * Handlers for Berry calls and async - * + * \*********************************************************************************************/ const char berry_prog[] = @@ -106,7 +106,7 @@ const char berry_prog[] = // "self._rules.remove(pat) " // "end " // "end " - + // // Rules trigger if match. return true if match, false if not // "def try_rule(event, rule, f) " // "import string " @@ -161,7 +161,7 @@ const char berry_prog[] = // "end " // "return false " // "end " - + // "def set_timer(delay,f) " // "if !self._timers self._timers=[] end " // "self._timers.push([self.millis(delay),f]) " @@ -258,7 +258,7 @@ const char berry_prog[] = // "c() " // "self.log(string.format(\"BRY: sucessfully loaded '%s'\",f)) " // "except .. as e " - // "raise \"io_error\",string.format(\"Could not load file '%s'\",f) " + // "raise \"io_error\",string.format(\"Could not load file '%s'\",f) " // "end " // "end " @@ -395,8 +395,8 @@ const char berry_autoexec[] = // load "autoexec.be" using import, which loads either .be or .bec file "try " "load('autoexec.be') " - "except .. " - "log(\"BRY: No 'autoexec.be' file\") " + "except .. as e,m " + "log(\"BRY: exception in autoexec '\",e,\"':\",m) " "end " ; #endif // USE_BERRY From 173038c12cdfdc30a53f6ccb5afb12a446e64f45 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 11 Apr 2021 17:33:22 +0200 Subject: [PATCH 39/67] Force SO19 0 --- tasmota/xdrv_12_discovery.ino | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_12_discovery.ino b/tasmota/xdrv_12_discovery.ino index bdc31e4cc..f5972ad6b 100644 --- a/tasmota/xdrv_12_discovery.ino +++ b/tasmota/xdrv_12_discovery.ino @@ -22,9 +22,10 @@ /*********************************************************************************************\ * Tasmota discovery * - * A stripped down version of xdrv_12_home_assistant to be used as alternative for TasmoManager + * A version of xdrv_12_home_assistant supporting the new Tasmota Discovery be used by + * latest versions of Home Assistant or TasmoManager. * - * SetOption19 0 - Enables discovery + * SetOption19 0 - Enables discovery (default) * SetOption19 1 - Disables discovery and removes retained message from MQTT server * SetOption73 1 - Enable discovery for buttons * SetOption114 1 - Enable discovery for switches @@ -224,6 +225,11 @@ void TasRediscover(void) { TasDiscoverData_init_step = 1; // Delayed discovery or clear retained messages } +void TasDiscoverInit(void) { + TasDiscoverData_init_step = 10; // Delayed discovery + Settings.flag.hass_discovery = 0; // SetOption19 - Enable Tasmota discovery and Disable legacy Hass discovery +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -242,7 +248,7 @@ bool Xdrv12(uint8_t function) { } break; case FUNC_MQTT_INIT: - TasDiscoverData_init_step = 10; // Delayed discovery + TasDiscoverInit(); break; } } From 30d016ea3f5a442f5573e5fed8c20cedeac29def Mon Sep 17 00:00:00 2001 From: ha0y <30557072+ha0y@users.noreply.github.com> Date: Mon, 12 Apr 2021 00:36:35 +0800 Subject: [PATCH 40/67] Update zh_CN.h --- tasmota/language/zh_CN.h | 116 +++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 6b5a4c301..6451d3107 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -1,7 +1,7 @@ /* zh-CN.h - localization for Chinese (Simplified) - China for Tasmota - Copyright (C) 2021 Killadm + Copyright (C) 2021 Killadm, Haoyu 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 @@ -63,7 +63,7 @@ #define D_BRIGHTLIGHT "亮" #define D_BSSID "BSSId" #define D_BUTTON "按钮" -#define D_BY "汉化: killadm 作者:" // Written by me +#define D_BY "作者:" // Written by me #define D_BYTES "大小:" #define D_CELSIUS "摄氏" #define D_CHANNEL "频道" @@ -187,9 +187,9 @@ #define D_UV_INDEX_2 "中" #define D_UV_INDEX_3 "高" #define D_UV_INDEX_4 "危险" -#define D_UV_INDEX_5 "BurnL1/2" -#define D_UV_INDEX_6 "BurnL3" -#define D_UV_INDEX_7 "OoR" +#define D_UV_INDEX_5 "一/二度烧伤" +#define D_UV_INDEX_6 "三度烧伤" +#define D_UV_INDEX_7 "超出范围" #define D_UV_LEVEL "紫外线水平" #define D_UV_POWER "紫外线功率 " #define D_VERSION "版本" @@ -200,7 +200,7 @@ #define D_WEB_SERVER "Web Server" // tasmota.ino -#define D_WARNING_MINIMAL_VERSION "警告:精简固件不支持配置持久化保存" +#define D_WARNING_MINIMAL_VERSION "警告:精简固件不支持持久保存设置" #define D_LEVEL_10 "level 1-0" #define D_LEVEL_01 "level 0-1" #define D_SERIAL_LOGGING_DISABLED "串口日志已禁用" @@ -238,7 +238,7 @@ #define D_ERASED_SECTOR "擦除扇区" // webserver.ino -#define D_NOSCRIPT "Tasmota要求浏览器支持 JavaScript" +#define D_NOSCRIPT "Tasmota 要求浏览器支持 JavaScript" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "当前是精简版固件
请升级" #define D_WEBSERVER_ACTIVE_ON "Web 服务器地址:" #define D_WITH_IP_ADDRESS "IP 地址:" @@ -247,12 +247,12 @@ #define D_REDIRECTED "重定向到认证页面" #define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager 设置无线操作模式" #define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager 设置接入点" -#define D_TRYING_TO_CONNECT "尝试将设备连接到网络" +#define D_TRYING_TO_CONNECT "设备正在尝试连接网络" -#define D_RESTART_IN "重启需要" +#define D_RESTART_IN "重启倒计时" #define D_SECONDS "秒" -#define D_DEVICE_WILL_RESTART "设备将在几秒钟内重启" -#define D_BUTTON_TOGGLE "状态切换" +#define D_DEVICE_WILL_RESTART "设备将在几秒钟后重启" +#define D_BUTTON_TOGGLE "开/关" #define D_CONFIGURATION "设置" #define D_INFORMATION "信息" #define D_FIRMWARE_UPGRADE "固件升级" @@ -260,9 +260,9 @@ #define D_CONFIRM_RESTART "确认重启" #define D_CONFIGURE_MODULE "模块设置" -#define D_CONFIGURE_WIFI "WiFi设置" -#define D_CONFIGURE_MQTT "MQTT设置" -#define D_CONFIGURE_DOMOTICZ "Domoticz设置" +#define D_CONFIGURE_WIFI "WiFi 设置" +#define D_CONFIGURE_MQTT "MQTT 设置" +#define D_CONFIGURE_DOMOTICZ "Domoticz 设置" #define D_CONFIGURE_LOGGING "日志设置" #define D_CONFIGURE_OTHER "其他设置" #define D_CONFIRM_RESET_CONFIGURATION "确认重置配置" @@ -314,10 +314,10 @@ #define D_ACTIVATE "启用" #define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "WEB 管理密码" -#define D_MQTT_ENABLE "启用MQTT" +#define D_MQTT_ENABLE "启用 MQTT" #define D_MQTT_TLS_ENABLE "MQTT TLS" #define D_FRIENDLY_NAME "昵称" -#define D_BELKIN_WEMO "贝尔金 WeMo" +#define D_BELKIN_WEMO "Belkin WeMo" #define D_HUE_BRIDGE "飞利浦 Hue 网桥" #define D_SINGLE_DEVICE "单设备" #define D_MULTI_DEVICE "多设备" @@ -463,30 +463,30 @@ #define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_23_zigbee -#define D_ZIGBEE_PERMITJOIN_ACTIVE "Devices allowed to join" +#define D_ZIGBEE_PERMITJOIN_ACTIVE "允许设备连入" #define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee Mapping" -#define D_ZIGBEE_NOT_STARTED "Zigbee not started" +#define D_ZIGBEE_NOT_STARTED "Zigbee 未启动" #define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Mapping in progress (%d s. remaining)" #define D_ZIGBEE_MAPPING_NOT_PRESENT "No mapping" #define D_ZIGBEE_MAP_REFRESH "Zigbee Map Refresh" #define D_ZIGBEE_MAP "Zigbee Map" -#define D_ZIGBEE_PERMITJOIN "Zigbee Permit Join" -#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key" -#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device" -#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute" -#define D_ZIGBEE_INVALID_PARAM "Invalid parameter" -#define D_ZIGBEE_MISSING_PARAM "Missing parameters" -#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s" -#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command" -#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload" -#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s" -#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)" -#define D_ZIGBEE_NO_ATTRIBUTE "No attribute in list" -#define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "Unsupported attribute type" -#define D_ZIGBEE_JSON_REQUIRED "Config requires JSON objects" +#define D_ZIGBEE_PERMITJOIN "Zigbee 允许连入" +#define D_ZIGBEE_GENERATE_KEY "正在生成 Zigbee 网络随机秘钥" +#define D_ZIGBEE_UNKNOWN_DEVICE "未知设备" +#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "未知属性" +#define D_ZIGBEE_INVALID_PARAM "参数无效" +#define D_ZIGBEE_MISSING_PARAM "缺失参数" +#define D_ZIGBEE_UNKNWON_ATTRIBUTE "未知属性名称: %s , 忽略" +#define D_ZIGBEE_TOO_MANY_CLUSTERS "每个命令不应有多个簇 ID" +#define D_ZIGBEE_WRONG_DELIMITER "消息体分隔符错误" +#define D_ZIGBEE_UNRECOGNIZED_COMMAND "无法识别的 Zigbee 命令: %s" +#define D_ZIGBEE_TOO_MANY_COMMANDS "只允许一个命令 (%d)" +#define D_ZIGBEE_NO_ATTRIBUTE "列表中没有属性" +#define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "不支持的属性类型" +#define D_ZIGBEE_JSON_REQUIRED "配置需要 JSON 对象" #define D_ZIGBEE_RESET_1_OR_2 "1 or 2 to reset" -#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address" -#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'" +#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "找到 ZBBridge EEPROM, 地址:" +#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "正在随机化 Zigbee 参数, 请通过 'ZbConfig' 检查" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用电量" @@ -551,7 +551,7 @@ #define D_RESET_HX711 "秤重置" #define D_CONFIGURE_HX711 "秤配置" #define D_HX711_PARAMETERS "秤参数" -#define D_ITEM_WEIGHT "物品中粮" +#define D_ITEM_WEIGHT "物品重量" #define D_REFERENCE_WEIGHT "参考重量" #define D_CALIBRATE "校准" #define D_CALIBRATION "校准" @@ -813,50 +813,50 @@ #define D_SENSOR_EPD_DATA "EPD Data" // Units -#define D_UNIT_AMPERE "安" +#define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "厘米" #define D_UNIT_DEGREE "°" #define D_UNIT_FAHRENHEIT "F" -#define D_UNIT_HERTZ "赫兹" -#define D_UNIT_HOUR "时" +#define D_UNIT_HERTZ "Hz" +#define D_UNIT_HOUR "小时" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KELVIN "K" #define D_UNIT_KILOMETER "km" -#define D_UNIT_KILOGRAM "千克" -#define D_UNIT_KILOMETER_PER_HOUR "公里/时" // or "km/h" -#define D_UNIT_KILOOHM "千欧" -#define D_UNIT_KILOWATTHOUR "千瓦时" +#define D_UNIT_KILOGRAM "kg" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" +#define D_UNIT_KILOOHM "kΩ" +#define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LITERS "L" #define D_UNIT_LITERS_PER_MIN "L/m" -#define D_UNIT_LUX "勒克斯" -#define D_UNIT_MICROGRAM_PER_CUBIC_METER "微克/立方米" -#define D_UNIT_MICROMETER "微米" -#define D_UNIT_MICROSECOND "微秒" +#define D_UNIT_LUX "lx" +#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³" +#define D_UNIT_MICROMETER "µm" +#define D_UNIT_MICROSECOND "µs" #define D_UNIT_MICROSIEMENS_PER_CM "µS/cm" -#define D_UNIT_MILLIAMPERE "毫安" +#define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLILITERS "ml" -#define D_UNIT_MILLIMETER "毫米" -#define D_UNIT_MILLIMETER_MERCURY "毫米汞柱" -#define D_UNIT_MILLISECOND "毫秒" +#define D_UNIT_MILLIMETER "mm" +#define D_UNIT_MILLIMETER_MERCURY "mmHg" +#define D_UNIT_MILLISECOND "ms" #define D_UNIT_MILLIVOLT "mV" #define D_UNIT_MINUTE "分" #define D_UNIT_PARTS_PER_BILLION "ppb" -#define D_UNIT_PARTS_PER_DECILITER "每分升" +#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_MILIGRAMS_PER_LITER "mg/L" #define D_UNIT_PERCENT "%%" -#define D_UNIT_PRESSURE "百帕" +#define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "秒" #define D_UNIT_SECTORS "扇区" -#define D_UNIT_VA "伏安" -#define D_UNIT_VAR "无功伏安" -#define D_UNIT_VOLT "伏" -#define D_UNIT_WATT "瓦" -#define D_UNIT_WATTHOUR "瓦时" -#define D_UNIT_WATT_METER_QUADRAT "瓦/平米" +#define D_UNIT_VA "VA" +#define D_UNIT_VAR "VAr" +#define D_UNIT_VOLT "V" +#define D_UNIT_WATT "W" +#define D_UNIT_WATTHOUR "Wh" +#define D_UNIT_WATT_METER_QUADRAT "W/m²" #define D_NEW_ADDRESS "Setting address to" #define D_OUT_OF_RANGE "Out of Range" From 3dab9465cfe8573fee6addbce84c11272a3d73f7 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 11 Apr 2021 18:52:05 +0200 Subject: [PATCH 41/67] Remove default envs --- platformio.ini | 45 ++------------------------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/platformio.ini b/platformio.ini index 2bd850f94..9468f5102 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,49 +6,9 @@ ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/en/stable/projectconf.html - - -; *** Tasmota build variant selection -[build_envs] -default_envs = -; *** Uncomment by deleting ";" in the line(s) below to select version(s) -; tasmota -; tasmota-ircustom -; tasmota-minimal -; tasmota-lite -; tasmota-knx -; tasmota-sensors -; tasmota-display -; tasmota-zbbridge -; tasmota-ir -; tasmota-AF -; tasmota-BG -; tasmota-BR -; tasmota-CN -; tasmota-CZ -; tasmota-DE -; tasmota-ES -; tasmota-FR -; tasmota-FY -; tasmota-GR -; tasmota-HE -; tasmota-HU -; tasmota-IT -; tasmota-KO -; tasmota-NL -; tasmota-PL -; tasmota-PT -; tasmota-RO -; tasmota-RU -; tasmota-SE -; tasmota-SK -; tasmota-TR -; tasmota-TW -; tasmota-UK -; tasmota-VN -; -; *** Selection for Tasmota ESP32 is done in platformio_tasmota32.ini ; +; ********************************************************************* +; *** Selection of Tasmota build variant is done with VSC ; *** alternatively can be done in: platformio_override.ini ; *** See example: platformio_override_sample.ini ; ********************************************************************* @@ -63,7 +23,6 @@ extra_configs = platformio_tasmota32.ini platformio_tasmota_env.ini platformio_tasmota_env32.ini platformio_override.ini -default_envs = ${build_envs.default_envs} [common] framework = arduino From 45d833d3a06f471ceeb59187184b0a236f1c0942 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 11 Apr 2021 19:48:23 +0200 Subject: [PATCH 42/67] No default envs selection --- platformio_tasmota32.ini | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index de1e9f08f..abf1d0199 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -1,45 +1,6 @@ ; *** BETA ESP32 Tasmota version *** ; *** expect the unexpected. Some features not working!!! *** -[platformio] - -; *** Tasmota build variant selection -default_envs = ${build_envs.default_envs} -; *** Uncomment by deleting ";" in the line(s) below to select version(s) -; tasmota32 -; tasmota32-bluetooth -; tasmota32-webcam -; tasmota32-odroidgo -; tasmota32-core2 -; tasmota32-display -; tasmota32-ir -; tasmota32-ircustom -; tasmota32-AF -; tasmota32-BG -; tasmota32-BR -; tasmota32-CN -; tasmota32-CZ -; tasmota32-DE -; tasmota32-ES -; tasmota32-FR -; tasmota32-FY -; tasmota32-GR -; tasmota32-HE -; tasmota32-HU -; tasmota32-IT -; tasmota32-KO -; tasmota32-NL -; tasmota32-PL -; tasmota32-PT -; tasmota32-RO -; tasmota32-RU -; tasmota32-SE -; tasmota32-SK -; tasmota32-TR -; tasmota32-TW -; tasmota32-UK -; tasmota32-VN - [common32] platform = ${core32.platform} platform_packages = ${core32.platform_packages} From 1535e24a55245627204aa93d402e55076aaef579 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 11 Apr 2021 20:01:26 +0200 Subject: [PATCH 43/67] Ignore compilation artefacts --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 503ccf780..53c8da544 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,13 @@ ## OS specific ######## .DS_Store .fuse_hidden* + +## Compilation artefacts ######## *.pyc +*.d +*.o +*.gcno +*.gcda ## Project files ###### .platformio From 26cc711cc8681fc1e54ce24f6239546f89b4fc25 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Mon, 12 Apr 2021 07:32:34 +0200 Subject: [PATCH 44/67] Update Italian language --- tasmota/language/it_IT.h | 216 +++++++++++++++++++-------------------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index f15d873a7..c73ad3d5c 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.3.1.2 - Last update 10.04.2021 + * Updated until v9.3.1.2 - Last update 11.04.2021 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -648,9 +648,9 @@ #define D_SENSOR_TM1638_CLK "TM1638 - CLK" #define D_SENSOR_TM1638_DIO "TM1638 - DIO" #define D_SENSOR_TM1638_STB "TM1638 - STB" -#define D_SENSOR_MAX7219_DIN "MAX7219 - DIN" +#define D_SENSOR_MAX7219_DIN "MAX7219 - DIN" #define D_SENSOR_MAX7219_CS "MAX7219 - CS" -#define D_SENSOR_MAX7219_CLK "MAX7219 - CLK" +#define D_SENSOR_MAX7219_CLK "MAX7219 - CLK" #define D_SENSOR_HX711_SCK "HX711 - SCK" #define D_SENSOR_HX711_DAT "HX711 - DAT" #define D_SENSOR_FTC532 "FTC532" @@ -806,57 +806,57 @@ #define D_SENSOR_NEOPOOL_TX "NeoPool - TX" #define D_SENSOR_NEOPOOL_RX "NeoPool - RX" #define D_SENSOR_VL53L0X_XSHUT "VL53L0X XSHUT" -#define D_SENSOR_TFMINIPLUS_TX "TFmini+ - TX" -#define D_SENSOR_TFMINIPLUS_RX "TFmini+ - RX" +#define D_SENSOR_TFMINIPLUS_TX "TFmini+ - TX" +#define D_SENSOR_TFMINIPLUS_RX "TFmini+ - RX" #define D_SENSOR_ZEROCROSS "Impulsi ZC" #define D_SENSOR_HALLEFFECT "Effetto hall" #define D_SENSOR_EPD_DATA "EPD - Dati" // Units -#define D_UNIT_AMPERE "A" -#define D_UNIT_CELSIUS "C" -#define D_UNIT_CENTIMETER "cm" -#define D_UNIT_DEGREE "°" -#define D_UNIT_FAHRENHEIT "F" -#define D_UNIT_HERTZ "Hz" -#define D_UNIT_HOUR "o" -#define D_UNIT_GALLONS "gal" -#define D_UNIT_GALLONS_PER_MIN "g/m" -#define D_UNIT_INCREMENTS "inc" -#define D_UNIT_KELVIN "K" -#define D_UNIT_KILOMETER "km" -#define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" -#define D_UNIT_KILOOHM "kΩ" -#define D_UNIT_KILOWATTHOUR "kWh" -#define D_UNIT_LITERS "L" -#define D_UNIT_LITERS_PER_MIN "L/m" -#define D_UNIT_LUX "lx" +#define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" +#define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" +#define D_UNIT_HERTZ "Hz" +#define D_UNIT_HOUR "o" +#define D_UNIT_GALLONS "gal" +#define D_UNIT_GALLONS_PER_MIN "g/m" +#define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" +#define D_UNIT_KILOGRAM "kg" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" +#define D_UNIT_KILOOHM "kΩ" +#define D_UNIT_KILOWATTHOUR "kWh" +#define D_UNIT_LITERS "L" +#define D_UNIT_LITERS_PER_MIN "L/m" +#define D_UNIT_LUX "lx" #define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³" -#define D_UNIT_MICROMETER "µm" -#define D_UNIT_MICROSECOND "µs" -#define D_UNIT_MICROSIEMENS_PER_CM "µS/cm" -#define D_UNIT_MILLIAMPERE "mA" -#define D_UNIT_MILLILITERS "ml" -#define D_UNIT_MILLIMETER "mm" -#define D_UNIT_MILLIMETER_MERCURY "mmHg" -#define D_UNIT_MILLISECOND "ms" -#define D_UNIT_MILLIVOLT "mV" -#define D_UNIT_MINUTE "Min" -#define D_UNIT_PARTS_PER_BILLION "ppb" -#define D_UNIT_PARTS_PER_DECILITER "ppd" -#define D_UNIT_PARTS_PER_MILLION "ppm" -#define D_UNIT_MILIGRAMS_PER_LITER "mg/L" -#define D_UNIT_PERCENT "%%" -#define D_UNIT_PRESSURE "hPa" -#define D_UNIT_SECOND "sec" -#define D_UNIT_SECTORS "settori" -#define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" -#define D_UNIT_VOLT "V" -#define D_UNIT_WATT "W" -#define D_UNIT_WATTHOUR "Wh" -#define D_UNIT_WATT_METER_QUADRAT "W/m²" +#define D_UNIT_MICROMETER "µm" +#define D_UNIT_MICROSECOND "µs" +#define D_UNIT_MICROSIEMENS_PER_CM "µS/cm" +#define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLILITERS "ml" +#define D_UNIT_MILLIMETER "mm" +#define D_UNIT_MILLIMETER_MERCURY "mmHg" +#define D_UNIT_MILLISECOND "ms" +#define D_UNIT_MILLIVOLT "mV" +#define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" +#define D_UNIT_PARTS_PER_DECILITER "ppd" +#define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_MILIGRAMS_PER_LITER "mg/L" +#define D_UNIT_PERCENT "%%" +#define D_UNIT_PRESSURE "hPa" +#define D_UNIT_SECOND "sec" +#define D_UNIT_SECTORS "settori" +#define D_UNIT_VA "VA" +#define D_UNIT_VAR "VAr" +#define D_UNIT_VOLT "V" +#define D_UNIT_WATT "W" +#define D_UNIT_WATTHOUR "Wh" +#define D_UNIT_WATT_METER_QUADRAT "W/m²" #define D_NEW_ADDRESS "Imposta indirizzo a" #define D_OUT_OF_RANGE "Fuori intervallo" @@ -916,38 +916,38 @@ #define D_MANAGE_FILE_SYSTEM "Gestione File system" #define D_FS_SIZE "Dimensione" #define D_FS_FREE "Liberi" -#define D_NEW_FILE "newfile.txt" -#define D_CREATE_NEW_FILE "Create and edit new file" -#define D_EDIT_FILE "Edit File" +#define D_NEW_FILE "nuovofile.txt" +#define D_CREATE_NEW_FILE "Crea e modifica nuovo file" +#define D_EDIT_FILE "Modifica file" //xsns_67_as3935.ino -#define D_AS3935_GAIN "guadagno:" -#define D_AS3935_ENERGY "energia:" -#define D_AS3935_DISTANCE "distanza:" +#define D_AS3935_GAIN "guadagno:" +#define D_AS3935_ENERGY "energia:" +#define D_AS3935_DISTANCE "distanza:" #define D_AS3935_DISTURBER "disturbatore:" -#define D_AS3935_VRMS "µVrms:" -#define D_AS3935_APRX "appross.:" -#define D_AS3935_AWAY "lontano" -#define D_AS3935_LIGHT "illuminazione" -#define D_AS3935_OUT "illuminazione fuori intervallo" -#define D_AS3935_NOT "distanza non determinata" -#define D_AS3935_ABOVE "illuminazione ambientale" -#define D_AS3935_NOISE "rilevato rumore" -#define D_AS3935_DISTDET "rilevato disturbatore" -#define D_AS3935_INTNOEV "Interrupt senza evento!" -#define D_AS3935_FLICKER "Flicker PIN IRQ!" -#define D_AS3935_POWEROFF "Spegnimento" -#define D_AS3935_NOMESS "in ascolto..." -#define D_AS3935_ON "ON" -#define D_AS3935_OFF "OFF" -#define D_AS3935_INDOORS "Interno" -#define D_AS3935_OUTDOORS "Esterno" -#define D_AS3935_CAL_FAIL "calibrazione fallita" -#define D_AS3935_CAL_OK "calibrazione impostata a:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "appross.:" +#define D_AS3935_AWAY "lontano" +#define D_AS3935_LIGHT "illuminazione" +#define D_AS3935_OUT "illuminazione fuori intervallo" +#define D_AS3935_NOT "distanza non determinata" +#define D_AS3935_ABOVE "illuminazione ambientale" +#define D_AS3935_NOISE "rilevato rumore" +#define D_AS3935_DISTDET "rilevato disturbatore" +#define D_AS3935_INTNOEV "Interrupt senza evento!" +#define D_AS3935_FLICKER "Flicker PIN IRQ!" +#define D_AS3935_POWEROFF "Spegnimento" +#define D_AS3935_NOMESS "in ascolto..." +#define D_AS3935_ON "ON" +#define D_AS3935_OFF "OFF" +#define D_AS3935_INDOORS "Interno" +#define D_AS3935_OUTDOORS "Esterno" +#define D_AS3935_CAL_FAIL "calibrazione fallita" +#define D_AS3935_CAL_OK "calibrazione impostata a:" //xsns_68_opentherm.ino -#define D_SENSOR_BOILER_OT_RX "OpenTherm - RX" -#define D_SENSOR_BOILER_OT_TX "OpenTherm - TX" +#define D_SENSOR_BOILER_OT_RX "OpenTherm - RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm - TX" // xnrg_15_teleinfo Denky (Teleinfo) #define D_CONTRACT "Contratto" @@ -959,41 +959,41 @@ #define D_MAX_CURRENT "Corrente max" // xsns_79_as608.ino -#define D_FP_ENROLL_PLACEFINGER "Appoggia impronta" -#define D_FP_ENROLL_REMOVEFINGER "Rimuovi impronta" -#define D_FP_ENROLL_PLACESAMEFINGER "Appoggia di nuovo stessa impronta" -#define D_FP_ENROLL_RETRY "Errore quindi riprova" -#define D_FP_ENROLL_RESTART "Riavvia" -#define D_FP_ENROLL_ERROR "Errore" -#define D_FP_ENROLL_RESET "Ripristina" -#define D_FP_ENROLL_ACTIVE "Attivo" -#define D_FP_ENROLL_INACTIVE "Non attivo" +#define D_FP_ENROLL_PLACEFINGER "Appoggia impronta" +#define D_FP_ENROLL_REMOVEFINGER "Rimuovi impronta" +#define D_FP_ENROLL_PLACESAMEFINGER "Appoggia di nuovo stessa impronta" +#define D_FP_ENROLL_RETRY "Errore quindi riprova" +#define D_FP_ENROLL_RESTART "Riavvia" +#define D_FP_ENROLL_ERROR "Errore" +#define D_FP_ENROLL_RESET "Ripristina" +#define D_FP_ENROLL_ACTIVE "Attivo" +#define D_FP_ENROLL_INACTIVE "Non attivo" // Indexed by Adafruit_Fingerprint.h defines -#define D_FP_PACKETRECIEVEERR "Errore comunicazione" // 0x01 Error when receiving data package -#define D_FP_NOFINGER "" // 0x02 No finger on the sensor -#define D_FP_IMAGEFAIL "Errore immagine" // 0x03 Failed to enroll the finger -#define D_FP_IMAGEMESS "Immmagine troppo danneggiata" // 0x06 Failed to generate character file due to overly disorderly fingerprint image -#define D_FP_FEATUREFAIL "Impronta troppo piccola" // 0x07 Failed to generate character file due to the lack of character point or small fingerprint image -#define D_FP_NOMATCH "Nessuna corrispondenza" // 0x08 Finger doesn't match -#define D_FP_NOTFOUND "Corrispondenza non trovata" // 0x09 Failed to find matching finger -#define D_FP_ENROLLMISMATCH "L'impronta non corrisponde" // 0x0A Failed to combine the character files -#define D_FP_BADLOCATION "Locazione errata" // 0x0B Addressed PageID is beyond the finger library -#define D_FP_DBRANGEFAIL "Errore intervallo DB" // 0x0C Error when reading template from library or invalid template -#define D_FP_UPLOADFEATUREFAIL "Errore funzione upload" // 0x0D Error when uploading template -#define D_FP_PACKETRESPONSEFAIL "Errore risposta pacchetto" // 0x0E Module failed to receive the following data packages -#define D_FP_UPLOADFAIL "Errore upload" // 0x0F Error when uploading image -#define D_FP_DELETEFAIL "Errore eliminazione" // 0x10 Failed to delete the template -#define D_FP_DBCLEARFAIL "Errore azzeramento DB" // 0x11 Failed to clear finger library -#define D_FP_PASSFAIL "Errore password" // 0x13 Find whether the fingerprint passed or failed -#define D_FP_INVALIDIMAGE "Immagine non valida" // 0x15 Failed to generate image because of lac of valid primary image -#define D_FP_FLASHERR "Errore scrittura flash" // 0x18 Error when writing flash -#define D_FP_INVALIDREG "Numero non valido" // 0x1A Invalid register number -#define D_FP_ADDRCODE "Codice indirizzo" // 0x20 Address code -#define D_FP_PASSVERIFY "Password verificata" // 0x21 Verify the fingerprint passed -#define D_FP_UNKNOWNERROR "Errore" // Any other error +#define D_FP_PACKETRECIEVEERR "Errore comunicazione" // 0x01 Error when receiving data package +#define D_FP_NOFINGER "" // 0x02 No finger on the sensor +#define D_FP_IMAGEFAIL "Errore immagine" // 0x03 Failed to enroll the finger +#define D_FP_IMAGEMESS "Immmagine troppo danneggiata" // 0x06 Failed to generate character file due to overly disorderly fingerprint image +#define D_FP_FEATUREFAIL "Impronta troppo piccola" // 0x07 Failed to generate character file due to the lack of character point or small fingerprint image +#define D_FP_NOMATCH "Nessuna corrispondenza" // 0x08 Finger doesn't match +#define D_FP_NOTFOUND "Corrispondenza non trovata" // 0x09 Failed to find matching finger +#define D_FP_ENROLLMISMATCH "L'impronta non corrisponde" // 0x0A Failed to combine the character files +#define D_FP_BADLOCATION "Locazione errata" // 0x0B Addressed PageID is beyond the finger library +#define D_FP_DBRANGEFAIL "Errore intervallo DB" // 0x0C Error when reading template from library or invalid template +#define D_FP_UPLOADFEATUREFAIL "Errore funzione upload" // 0x0D Error when uploading template +#define D_FP_PACKETRESPONSEFAIL "Errore risposta pacchetto" // 0x0E Module failed to receive the following data packages +#define D_FP_UPLOADFAIL "Errore upload" // 0x0F Error when uploading image +#define D_FP_DELETEFAIL "Errore eliminazione" // 0x10 Failed to delete the template +#define D_FP_DBCLEARFAIL "Errore azzeramento DB" // 0x11 Failed to clear finger library +#define D_FP_PASSFAIL "Errore password" // 0x13 Find whether the fingerprint passed or failed +#define D_FP_INVALIDIMAGE "Immagine non valida" // 0x15 Failed to generate image because of lac of valid primary image +#define D_FP_FLASHERR "Errore scrittura flash" // 0x18 Error when writing flash +#define D_FP_INVALIDREG "Numero non valido" // 0x1A Invalid register number +#define D_FP_ADDRCODE "Codice indirizzo" // 0x20 Address code +#define D_FP_PASSVERIFY "Password verificata" // 0x21 Verify the fingerprint passed +#define D_FP_UNKNOWNERROR "Errore" // Any other error // xsns_83_neopool.ino -#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names +#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names #define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife (giallo)" #define D_NEOPOOL_MACH_AQUASCENIC "Aquascenic (blu)" #define D_NEOPOOL_MACH_OXILIFE "Oxilife (verde)" @@ -1040,7 +1040,7 @@ #define D_NEOPOOL_LOW "Bassa" #define D_NEOPOOL_FLOW1 "FL1" #define D_NEOPOOL_FLOW2 "FL2" -#define D_NEOPOOL_PH_HIGH "troppo alto" // ph Alarms +#define D_NEOPOOL_PH_HIGH "troppo alto" // ph Alarms #define D_NEOPOOL_PH_LOW "troppo basso" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "tempo pompa superato" From 0025ca4ae488a09c083f59190a3c1f7ff028f5e7 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 12 Apr 2021 10:18:27 +0200 Subject: [PATCH 45/67] Auto copy platformio_override --- pio-tools/override_copy.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pio-tools/override_copy.py b/pio-tools/override_copy.py index 1cb6c991b..5318f9169 100644 --- a/pio-tools/override_copy.py +++ b/pio-tools/override_copy.py @@ -7,3 +7,9 @@ if os.path.isfile("tasmota/user_config_override.h"): print ("*** use provided user_config_override.h as planned ***") else: shutil.copy("tasmota/user_config_override_sample.h", "tasmota/user_config_override.h") + +# copy platformio_override_sample.ini to platformio_override.ini +if os.path.isfile("platformio_override.ini"): + print ("*** use provided platformio_override.ini as planned ***") +else: + shutil.copy("platformio_override_sample.ini", "platformio_override.ini") From 162e60eb3073c4fece15ea2f59bca4e624035009 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 12 Apr 2021 11:49:53 +0200 Subject: [PATCH 46/67] Fix migration to higher version (#11640) --- tasmota/tasmota.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index b9e94829a..55272c584 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -98,6 +98,8 @@ * Global variables \*********************************************************************************************/ +const uint32_t VERSION_MARKER[] PROGMEM = { 0x5AA55AA5, 0xFFFFFFFF, 0xA55AA55A }; + WiFiUDP PortUdp; // UDP Syslog and Alexa struct { @@ -364,6 +366,8 @@ void setup(void) { AddLog(LOG_LEVEL_INFO, PSTR(D_WARNING_MINIMAL_VERSION)); #endif // FIRMWARE_MINIMAL + memcpy_P(TasmotaGlobal.mqtt_data, VERSION_MARKER, 1); // Dummy for compiler saving VERSION_MARKER + #ifdef USE_ARDUINO_OTA ArduinoOTAInit(); #endif // USE_ARDUINO_OTA From ab33b394f2c428cd4abf3b91637ba44c9bc8af66 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 12 Apr 2021 12:20:49 +0200 Subject: [PATCH 47/67] Add commands Add commands ``Discover``, ``DiscoverButton`` and ``DiscoverSwitch`` --- tasmota/support_tasmota.ino | 2 +- tasmota/tasmota_template.h | 2 +- tasmota/xdrv_12_discovery.ino | 48 ++++++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 05e6e3974..eb852ca77 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -886,7 +886,7 @@ void PerformEverySecond(void) Settings.last_module = Settings.module; #ifdef USE_DEEPSLEEP - if (!(DeepSleepEnabled() && !Settings.flag3.bootcount_update)) { + if (!(DeepSleepEnabled() && !Settings.flag3.bootcount_update)) { // SetOption76 - (Deepsleep) Enable incrementing bootcount (1) when deepsleep is enabled #endif Settings.bootcount++; // Moved to here to stop flash writes during start-up AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), Settings.bootcount); diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 9b27c12d9..74940db07 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -176,7 +176,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu struct { // GPIO Option_A1 .. Option_A32 uint32_t pwm1_input : 1; // bit 0 (v9.2.0.1) - Option_A1 - (Light) Change PWM1 to input on power off and no fade running (1) uint32_t dummy_energy : 1; // bit 1 (v9.3.1.2) - Option_A2 - (Energy) Enable dummy values - uint32_t udisplay_driver : 1; // bit 2 Universal display driver + uint32_t udisplay_driver : 1; // bit 2 (v9.3.1.2) - Option_A3 - (Display) Universal display driver uint32_t spare03 : 1; // bit 3 uint32_t spare04 : 1; // bit 4 uint32_t spare05 : 1; // bit 5 diff --git a/tasmota/xdrv_12_discovery.ino b/tasmota/xdrv_12_discovery.ino index f5972ad6b..9a592159a 100644 --- a/tasmota/xdrv_12_discovery.ino +++ b/tasmota/xdrv_12_discovery.ino @@ -25,10 +25,10 @@ * A version of xdrv_12_home_assistant supporting the new Tasmota Discovery be used by * latest versions of Home Assistant or TasmoManager. * - * SetOption19 0 - Enables discovery (default) - * SetOption19 1 - Disables discovery and removes retained message from MQTT server - * SetOption73 1 - Enable discovery for buttons - * SetOption114 1 - Enable discovery for switches + * SetOption19 0 - [DiscoverOff 0] [Discover 1] Enables discovery (default) + * SetOption19 1 - [DiscoverOff 1] [Discover 0] Disables discovery and removes retained message from MQTT server + * SetOption73 1 - [DiscoverButton] Enable discovery for buttons + * SetOption114 1 - [DiscoverSwitch] Enable discovery for switches \*********************************************************************************************/ #define XDRV_12 12 @@ -226,8 +226,41 @@ void TasRediscover(void) { } void TasDiscoverInit(void) { - TasDiscoverData_init_step = 10; // Delayed discovery - Settings.flag.hass_discovery = 0; // SetOption19 - Enable Tasmota discovery and Disable legacy Hass discovery + if (ResetReason() != REASON_DEEP_SLEEP_AWAKE) { + Settings.flag.hass_discovery = 0; // SetOption19 - Enable Tasmota discovery and Disable legacy Hass discovery + TasDiscoverData_init_step = 10; // Delayed discovery + } +} + +/*********************************************************************************************\ + * Commands + * + * Discover 0 - Disables discovery and removes retained message from MQTT server + * Discover 1 - Enables discovery (default) + * DiscoverOff 0 - Enables discovery (default) + * DiscoverOff 1 - Disables discovery and removes retained message from MQTT server + * DiscoverButton 1 - Enable discovery for buttons + * DiscoverSwitch 1 - Enable discovery for switches +\*********************************************************************************************/ + +const char kTasDiscoverCommands[] PROGMEM = "Discover|" // Prefix + // SetOption synonyms + "Off|Button|Switch|" + // Commands + "|"; + +SO_SYNONYMS(kTasDiscoverSynonyms, + 19, 73, 114 ); + +void (* const TasDiscoverCommand[])(void) PROGMEM = { + &CmndTasDiscover }; + +void CmndTasDiscover(void) { + if (XdrvMailbox.payload >= 0) { + Settings.flag.hass_discovery = !(XdrvMailbox.payload & 1); + TasRediscover(); + } + ResponseCmndChar(GetStateText(!Settings.flag.hass_discovery)); } /*********************************************************************************************\ @@ -247,6 +280,9 @@ bool Xdrv12(uint8_t function) { } } break; + case FUNC_COMMAND: + result = DecodeCommand(kTasDiscoverCommands, TasDiscoverCommand, kTasDiscoverSynonyms); + break; case FUNC_MQTT_INIT: TasDiscoverInit(); break; From 591021a5568cf0360c4372f7a9e9a88fa42bc1a8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 12 Apr 2021 14:59:40 +0200 Subject: [PATCH 48/67] Add ESP32 Cpu Temperature --- tasmota/support_esp.ino | 15 ++++++++++++++- tasmota/support_tasmota.ino | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tasmota/support_esp.ino b/tasmota/support_esp.ino index 65dd3871c..19024ee1c 100644 --- a/tasmota/support_esp.ino +++ b/tasmota/support_esp.ino @@ -457,7 +457,6 @@ uint8_t* FlashDirectAccess(void) { return data; } - void *special_malloc(uint32_t size) { if (psramFound()) { return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); @@ -473,6 +472,20 @@ void *special_realloc(void *ptr, size_t size) { } } +#ifdef __cplusplus +extern "C" { +#endif +uint8_t temprature_sens_read(); // librtc.a(rtc_analog.o) +#ifdef __cplusplus +} +#endif + +float CpuTemperature(void) { +// return ConvertTemp(temperatureRead()); + uint8_t tf = temprature_sens_read(); // Fahrenheit + return ConvertTemp(((float)(tf -32) / 1.8)); +} + #endif // ESP32 /*********************************************************************************************\ diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index eb852ca77..17fc84a3f 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -821,6 +821,11 @@ bool MqttShowSensor(void) { ResponseAppendTime(); +#ifdef ESP32 + float t = CpuTemperature(); + ResponseAppend_P(PSTR(",\"Cpu" D_JSON_TEMPERATURE "\":%*_f"), Settings.flag2.temperature_resolution, &t); +#endif + int json_data_start = strlen(TasmotaGlobal.mqtt_data); for (uint32_t i = 0; i < MAX_SWITCHES; i++) { #ifdef USE_TM1638 From 0318f630acd2b6bfdbf62cf4dcfaaa6329cf87af Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 12 Apr 2021 15:55:45 +0200 Subject: [PATCH 49/67] Fix ESP-S2 temperature issue --- tasmota/support_esp.ino | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tasmota/support_esp.ino b/tasmota/support_esp.ino index 19024ee1c..a1a469b96 100644 --- a/tasmota/support_esp.ino +++ b/tasmota/support_esp.ino @@ -472,18 +472,8 @@ void *special_realloc(void *ptr, size_t size) { } } -#ifdef __cplusplus -extern "C" { -#endif -uint8_t temprature_sens_read(); // librtc.a(rtc_analog.o) -#ifdef __cplusplus -} -#endif - float CpuTemperature(void) { -// return ConvertTemp(temperatureRead()); - uint8_t tf = temprature_sens_read(); // Fahrenheit - return ConvertTemp(((float)(tf -32) / 1.8)); + return ConvertTemp(temperatureRead()); } #endif // ESP32 From 7457d0b03cb75a545fa7371f066bd792038c4005 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 12 Apr 2021 16:21:33 +0200 Subject: [PATCH 50/67] Refactor ESP32 Temperature and Hall Effect sensor --- tasmota/my_user_config.h | 1 - tasmota/support_features.ino | 4 +- tasmota/support_tasmota.ino | 5 -- tasmota/tasmota_configurations_ESP32.h | 1 - ...lleffect.ino => xsns_87_esp32_sensors.ino} | 78 +++++++++++++------ 5 files changed, 54 insertions(+), 35 deletions(-) rename tasmota/{xsns_87_esp32_halleffect.ino => xsns_87_esp32_sensors.ino} (64%) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 1a6da9982..f30354df0 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -900,7 +900,6 @@ // #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT #define USE_ADC // Add support for ADC on GPIO32 to GPIO39 -#define USE_HALLEFFECT // Add support for internal Hall Effcet sensor connected to GPIO36 and GPIO39 //#define USE_SPI // Add support for hardware SPI //#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 3cd84d00f..8051e4eb8 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -737,9 +737,7 @@ void ResponseAppendFeatures(void) #ifdef USE_BERRY feature8 |= 0x00000008; // xdrv_52_9_berry.ino #endif -#ifdef USE_HALLEFFECT - feature8 |= 0x00000010; // xsns_87_esp32_halleffect.ino -#endif +// feature8 |= 0x00000010; #if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_DUMMY) feature8 |= 0x00000020; #endif diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 17fc84a3f..eb852ca77 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -821,11 +821,6 @@ bool MqttShowSensor(void) { ResponseAppendTime(); -#ifdef ESP32 - float t = CpuTemperature(); - ResponseAppend_P(PSTR(",\"Cpu" D_JSON_TEMPERATURE "\":%*_f"), Settings.flag2.temperature_resolution, &t); -#endif - int json_data_start = strlen(TasmotaGlobal.mqtt_data); for (uint32_t i = 0; i < MAX_SWITCHES; i++) { #ifdef USE_TM1638 diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index 8d7295ce4..ef568017d 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -187,7 +187,6 @@ #define USE_LIGHT_PALETTE // Add support for color palette (+0k9 code) -#define USE_HALLEFFECT // Add support for internal Hall Effcet sensor connected to GPIO36 and GPIO39 #define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+1k3 code) #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram) diff --git a/tasmota/xsns_87_esp32_halleffect.ino b/tasmota/xsns_87_esp32_sensors.ino similarity index 64% rename from tasmota/xsns_87_esp32_halleffect.ino rename to tasmota/xsns_87_esp32_sensors.ino index 07fdad4bb..6ab5b9820 100644 --- a/tasmota/xsns_87_esp32_halleffect.ino +++ b/tasmota/xsns_87_esp32_sensors.ino @@ -1,5 +1,5 @@ /* - xsns_87_esp32_halleffect.ino - ESP32 Hall Effect sensor for Tasmota + xsns_87_esp32_sensors.ino - ESP32 Temperature and Hall Effect sensor for Tasmota Copyright (C) 2021 Theo Arends @@ -18,9 +18,8 @@ */ #ifdef ESP32 -#if CONFIG_IDF_TARGET_ESP32 -#ifdef USE_HALLEFFECT /*********************************************************************************************\ + * ESP32 CPU Temperature * ESP32 internal Hall Effect sensor connected to both GPIO36 and GPIO39 * * To enable set @@ -30,13 +29,15 @@ #define XSNS_87 87 +#if CONFIG_IDF_TARGET_ESP32 + #define HALLEFFECT_SAMPLE_COUNT 32 // 32 takes about 12 mS at 80MHz CPU frequency struct { bool present = false; } HEData; -void HallEffectInit(void) { +void Esp32SensorInit(void) { if (PinUsed(GPIO_HALLEFFECT) && PinUsed(GPIO_HALLEFFECT, 1)) { if (((36 == Pin(GPIO_HALLEFFECT)) && (39 == Pin(GPIO_HALLEFFECT, 1))) || ((39 == Pin(GPIO_HALLEFFECT)) && (36 == Pin(GPIO_HALLEFFECT, 1)))) { @@ -51,22 +52,52 @@ void HallEffectInit(void) { const char HTTP_SNS_HALL_EFFECT[] PROGMEM = "{s}" D_HALL_EFFECT "{m}%d{e}"; #endif // USE_WEBSERVER -void HallEffectShow(bool json) { +#endif // CONFIG_IDF_TARGET_ESP32 + +void Esp32SensorShow(bool json) { + +#if CONFIG_IDF_TARGET_ESP32 int value = 0; - for (uint32_t i = 0; i < HALLEFFECT_SAMPLE_COUNT; i++) { - value += hallRead(); + if (HEData.present) { + for (uint32_t i = 0; i < HALLEFFECT_SAMPLE_COUNT; i++) { + value += hallRead(); + } + value /= HALLEFFECT_SAMPLE_COUNT; } - value /= HALLEFFECT_SAMPLE_COUNT; +#endif // CONFIG_IDF_TARGET_ESP32 + if (json) { - ResponseAppend_P(PSTR(",\"" D_JSON_HALLEFFECT "\":%d"), value); + float t = CpuTemperature(); + ResponseAppend_P(PSTR(",\"ESP32\":{\"" D_JSON_TEMPERATURE "\":%*_f"), Settings.flag2.temperature_resolution, &t); + +#if CONFIG_IDF_TARGET_ESP32 + if (HEData.present) { + ResponseAppend_P(PSTR(",\"" D_JSON_HALLEFFECT "\":%d"), value); + } +#endif // CONFIG_IDF_TARGET_ESP32 + + ResponseJsonEnd(); + #ifdef USE_DOMOTICZ if (0 == TasmotaGlobal.tele_period) { - DomoticzSensor(DZ_COUNT, value); + +#if CONFIG_IDF_TARGET_ESP32 + if (HEData.present) { + DomoticzSensor(DZ_COUNT, value); + } +#endif // CONFIG_IDF_TARGET_ESP32 + } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { - WSContentSend_P(HTTP_SNS_HALL_EFFECT, value); + +#if CONFIG_IDF_TARGET_ESP32 + if (HEData.present) { + WSContentSend_P(HTTP_SNS_HALL_EFFECT, value); + } +#endif // CONFIG_IDF_TARGET_ESP32 + #endif // USE_WEBSERVER } } @@ -78,24 +109,21 @@ void HallEffectShow(bool json) { bool Xsns87(uint8_t function) { bool result = false; - if (FUNC_INIT == function) { - HallEffectInit(); - } - else if (HEData.present) { - switch (function) { - case FUNC_JSON_APPEND: - HallEffectShow(1); - break; + switch (function) { + case FUNC_JSON_APPEND: + Esp32SensorShow(1); + break; #ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: - HallEffectShow(0); - break; + case FUNC_WEB_SENSOR: + Esp32SensorShow(0); + break; #endif // USE_WEBSERVER - } + case FUNC_INIT: + Esp32SensorInit(); + break; + } return result; } -#endif // USE_HALLEFFECT -#endif // CONFIG_IDF_TARGET_ESP32 #endif // ESP32 From bbb8de3515634d11a996de06ecf252d1af57eca7 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 12 Apr 2021 16:32:46 +0200 Subject: [PATCH 51/67] Add experimental Arduino32 / IDF4.4 --- platformio_override_sample.ini | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 7ea2d58e0..9821e2e97 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -185,6 +185,16 @@ lib_ignore = Micro-RTSP ESP32 Ethernet +; *** EXPERIMENTAL Tasmota version for Arduino ESP32 IDF4.4. Linking not working. +[env:tasmota32idf4] +extends = env:tasmota32_base +platform = https://github.com/Jason2866/platform-espressif32.git#feature/arduino-idf-v4.4 +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/esp32-2.0.0-pre/esp32-2.0.0-pre.zip + platformio/tool-mklittlefs @ ~1.203.200522 +build_unflags = ${esp32_defaults.build_unflags} +build_flags = ${esp32_defaults.build_flags} + ;-DESP32_STAGE=true + ; *** Debug version used for PlatformIO Home Project Inspection [env:tasmota-debug] build_type = debug From 5cdf225fe009fb51c674a18a1cd9bf1d0fb8b87b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 12 Apr 2021 16:50:04 +0200 Subject: [PATCH 52/67] Refactor ESP32 sensors --- tasmota/i18n.h | 3 +-- tasmota/xsns_87_esp32_sensors.ino | 20 +++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 9799fbe90..c435348a8 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -815,8 +815,6 @@ const float kSpeedConversionFactor[] = {1, // none #ifdef USE_WEBSERVER // {s} = , {m} = , {e} = const char HTTP_SNS_F_TEMP[] PROGMEM = "{s}%s " D_TEMPERATURE "{m}%*_f " D_UNIT_DEGREE "%c{e}"; -//const char HTTP_SNS_TEMP[] PROGMEM = "{s}%s " D_TEMPERATURE "{m}%s " D_UNIT_DEGREE "%c{e}"; - const char HTTP_SNS_HUM[] PROGMEM = "{s}%s " D_HUMIDITY "{m}%s " D_UNIT_PERCENT "{e}"; const char HTTP_SNS_DEW[] PROGMEM = "{s}%s " D_DEWPOINT "{m}%s " D_UNIT_DEGREE "%c{e}"; const char HTTP_SNS_PRESSURE[] PROGMEM = "{s}%s " D_PRESSURE "{m}%s " "%s{e}"; @@ -832,6 +830,7 @@ const char HTTP_SNS_RANGE_CHR[] PROGMEM = "{s}%s " D_RANGE "{ const char HTTP_SNS_RANGE[] PROGMEM = "{s}%s " D_RANGE "{m}%d" "{e}"; const char HTTP_SNS_DISTANCE[] PROGMEM = "{s}%s " D_DISTANCE "{m}%d " D_UNIT_MILLIMETER "{e}"; const char HTTP_SNS_DISTANCE_CM[] PROGMEM = "{s}%s " D_DISTANCE "{m}%s " D_UNIT_CENTIMETER "{e}"; +const char HTTP_SNS_HALL_EFFECT[] PROGMEM = "{s}%s " D_HALL_EFFECT "{m}%d" "{e}"; const char HTTP_SNS_VOLTAGE[] PROGMEM = "{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"; const char HTTP_SNS_CURRENT[] PROGMEM = "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"; const char HTTP_SNS_POWER[] PROGMEM = "{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"; diff --git a/tasmota/xsns_87_esp32_sensors.ino b/tasmota/xsns_87_esp32_sensors.ino index 6ab5b9820..c5fc80d52 100644 --- a/tasmota/xsns_87_esp32_sensors.ino +++ b/tasmota/xsns_87_esp32_sensors.ino @@ -19,9 +19,9 @@ #ifdef ESP32 /*********************************************************************************************\ - * ESP32 CPU Temperature - * ESP32 internal Hall Effect sensor connected to both GPIO36 and GPIO39 + * ESP32 CPU Temperature and optional Hall Effect sensor * + * ESP32 internal Hall Effect sensor connected to both GPIO36 and GPIO39 * To enable set * GPIO36 as HallEffect 1 * GPIO39 as HallEffect 2 @@ -47,14 +47,10 @@ void Esp32SensorInit(void) { } } -#ifdef USE_WEBSERVER -// {s} = , {m} = , {e} = -const char HTTP_SNS_HALL_EFFECT[] PROGMEM = "{s}" D_HALL_EFFECT "{m}%d{e}"; -#endif // USE_WEBSERVER - #endif // CONFIG_IDF_TARGET_ESP32 void Esp32SensorShow(bool json) { + float t = CpuTemperature(); #if CONFIG_IDF_TARGET_ESP32 int value = 0; @@ -67,7 +63,7 @@ void Esp32SensorShow(bool json) { #endif // CONFIG_IDF_TARGET_ESP32 if (json) { - float t = CpuTemperature(); + bool temperature_present = (strstr_P(TasmotaGlobal.mqtt_data, PSTR(D_JSON_TEMPERATURE)) != nullptr); ResponseAppend_P(PSTR(",\"ESP32\":{\"" D_JSON_TEMPERATURE "\":%*_f"), Settings.flag2.temperature_resolution, &t); #if CONFIG_IDF_TARGET_ESP32 @@ -77,9 +73,11 @@ void Esp32SensorShow(bool json) { #endif // CONFIG_IDF_TARGET_ESP32 ResponseJsonEnd(); - #ifdef USE_DOMOTICZ if (0 == TasmotaGlobal.tele_period) { + if (!temperature_present) { // Only send if no other sensor already did + DomoticzFloatSensor(DZ_TEMP, t); + } #if CONFIG_IDF_TARGET_ESP32 if (HEData.present) { @@ -91,10 +89,11 @@ void Esp32SensorShow(bool json) { #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { + WSContentSend_Temp("ESP32", t); #if CONFIG_IDF_TARGET_ESP32 if (HEData.present) { - WSContentSend_P(HTTP_SNS_HALL_EFFECT, value); + WSContentSend_P(HTTP_SNS_HALL_EFFECT, "ESP32", value); } #endif // CONFIG_IDF_TARGET_ESP32 @@ -121,7 +120,6 @@ bool Xsns87(uint8_t function) { case FUNC_INIT: Esp32SensorInit(); break; - } return result; } From dcad3c16c68e4fae47bcc6289051b75a35271a12 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Mon, 12 Apr 2021 13:31:31 -0300 Subject: [PATCH 53/67] Move WifiManager Log to Webserver file --- tasmota/support_wifi.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino index 804070103..e85374eda 100644 --- a/tasmota/support_wifi.ino +++ b/tasmota/support_wifi.ino @@ -106,7 +106,6 @@ void WifiConfig(uint8_t type) } #ifdef USE_WEBSERVER else if (WIFI_MANAGER == Wifi.config_type || WIFI_MANAGER_RESET_ONLY == Wifi.config_type) { - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES)); WifiManagerBegin(WIFI_MANAGER_RESET_ONLY == Wifi.config_type); } #endif // USE_WEBSERVER From c63b211009592bed93cf8d8aa5a0d19d4e2a52a5 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Mon, 12 Apr 2021 13:35:34 -0300 Subject: [PATCH 54/67] Fix Double Call of StartWebserver when it is in WiFiManager Mode --- tasmota/support_tasmota.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index eb852ca77..dab8dffc0 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1305,7 +1305,7 @@ void Every250mSeconds(void) if (Settings.webserver) { #ifdef ESP8266 - StartWebserver(Settings.webserver, WiFi.localIP()); + if (!WifiIsInManagerMode()) { StartWebserver(Settings.webserver, WiFi.localIP()); } #endif // ESP8266 #ifdef ESP32 #ifdef USE_ETHERNET From 6a48b1a63d2e92991c1c70def2f207ea7d8573d5 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Mon, 12 Apr 2021 13:36:43 -0300 Subject: [PATCH 55/67] Webserver: Simplify Initial WiFi Configuration --- tasmota/xdrv_01_webserver.ino | 328 ++++++++++++++++++++++++++++------ 1 file changed, 270 insertions(+), 58 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e61df582f..25f8fa68f 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -34,6 +34,19 @@ #define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 11 as used by WifiManager web GUI #endif +#ifndef MAX_WIFI_NETWORKS_TO_SHOW +#define MAX_WIFI_NETWORKS_TO_SHOW 3 // Maximum number of Wifi Networks to show in the Wifi Configuration Menu BEFORE clicking on Show More Networks. +#endif + +#ifndef RESTART_AFTER_INITIAL_WIFI_CONFIG +#define RESTART_AFTER_INITIAL_WIFI_CONFIG true // Restart Tasmota after initial Wifi Config of a blank device +#endif // If disabled, Tasmota will keep both the wifi AP and the wifi connection to the router + // but only until next restart. +#ifndef AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP // If RESTART_AFTER_INITIAL_WIFI_CONFIG and AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP are true, +#define AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP true // the user will be redirected to the new IP of Tasmota (in the new Network). +#endif // If the first is true, but this is false, the device will restart but the user will see + // a window telling that the WiFi Configuration was Ok and that the window can be closed. + const uint16_t CHUNKED_BUFFER_SIZE = (MESSZ / 2) - 100; // Chunk buffer size (should be smaller than half mqtt_data size = MESSZ) const uint16_t HTTP_REFRESH_TIME = 2345; // milliseconds @@ -102,6 +115,17 @@ const char HTTP_SCRIPT_WIFI[] PROGMEM = "eb('p1').focus();" "}"; +const char HTTP_SCRIPT_HIDE[] PROGMEM = + "function hidBtns() {" + "eb('butmo').style.display = 'none';" + "eb('butmod').style.display = 'none';" + "eb('but0').style.display = 'block';" + "eb('but1').style.display = 'block';" + "eb('but13').style.display = 'block';" + "eb('but0d').style.display = 'block';" + "eb('but13d').style.display = 'block';" + "}"; + const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = "setTimeout(function(){location.href='.';},%d);"; @@ -259,13 +283,19 @@ const char HTTP_FORM_MODULE[] PROGMEM = "

" D_MODULE_TYPE " (%s)

" "
"; +const char HTTP_FORM_WIFI_INITIAL[] PROGMEM = + "
 " D_WIFI_PARAMETERS " " + "
" + "

" D_AP1_SSID "

" // Need \" instead of ' to be able to use ' in text (#8489) + "


"; + const char HTTP_FORM_WIFI[] PROGMEM = "
 " D_WIFI_PARAMETERS " " "" - "

" D_AP1_SSID " (" STA_SSID1 ")

" // Need \" instead of ' to be able to use ' in text (#8489) - "


" - "

" D_AP2_SSID " (" STA_SSID2 ")

" - "


" + "

" D_AP1_SSID " (" STA_SSID1 ")

" // Need \" instead of ' to be able to use ' in text (#8489) + "


" + "

" D_AP2_SSID " (" STA_SSID2 ")

" + "


" "

" D_HOSTNAME " (%s)

" "

" D_CORS_DOMAIN "

"; @@ -366,6 +396,7 @@ const char kUploadErrors[] PROGMEM = const uint16_t DNS_PORT = 53; enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY}; +enum WifiTestOptions {WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED_SUCCESSFUL, WIFI_TEST_FINISHED_BAD}; DNSServer *DnsServer; ESP8266WebServer *Webserver; @@ -380,6 +411,11 @@ struct WEB { uint8_t config_xor_on_set = CONFIG_FILE_XOR; bool upload_services_stopped = false; bool reset_web_log_flag = false; // Reset web console log + bool initial_config = false; + uint8_t wifiTest = WIFI_NOT_TESTING; + uint8_t wifi_test_counter = 0; + uint16_t save_data_counter = 0; + uint8_t old_wificonfig = WIFI_MANAGER; } Web; // Helper function to avoid code duplication (saves 4k Flash) @@ -497,8 +533,8 @@ void StartWebserver(int type, IPAddress ipweb) NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", (uint32_t)ipweb); #endif // LWIP_IPV6 = 1 TasmotaGlobal.rules_flag.http_init = 1; + Web.state = type; } - if (type) { Web.state = type; } } void StopWebserver(void) @@ -513,6 +549,7 @@ void StopWebserver(void) void WifiManagerBegin(bool reset_only) { // setup AP + if (!Web.initial_config) { AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES)); } if (!TasmotaGlobal.global_state.wifi_down) { // WiFi.mode(WIFI_AP_STA); WifiSetMode(WIFI_AP_STA); @@ -523,7 +560,7 @@ void WifiManagerBegin(bool reset_only) AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_WIFIMANAGER_SET_ACCESSPOINT)); } - StopWebserver(); + //StopWebserver(); DnsServer = new DNSServer(); @@ -717,7 +754,7 @@ void WSContentStart_P(const char* title) void WSContentSendStyle_P(const char* formatP, ...) { - if (WifiIsInManagerMode()) { + if ( WifiIsInManagerMode() && (!Web.initial_config) ) { if (WifiConfigCounter()) { WSContentSend_P(HTTP_SCRIPT_COUNTER); } @@ -753,8 +790,14 @@ void WSContentSendStyle_P(const char* formatP, ...) WebColor(COL_TEXT_WARNING), #endif WebColor(COL_TITLE), - ModuleName().c_str(), SettingsText(SET_DEVICENAME)); - if (Settings.flag3.gui_hostname_ip) { // SetOption53 - Show hostanme and IP address in GUI main menu + (Web.initial_config) ? "" : ModuleName().c_str(), SettingsText(SET_DEVICENAME)); + + // SetOption53 - Show hostname and IP address in GUI main menu +#if (RESTART_AFTER_INITIAL_WIFI_CONFIG) + if (Settings.flag3.gui_hostname_ip) { +#else + if ( Settings.flag3.gui_hostname_ip || ( (WiFi.getMode() == WIFI_AP_STA) && (!Web.initial_config) ) ) { +#endif bool lip = (static_cast(WiFi.localIP()) != 0); bool sip = (static_cast(WiFi.softAPIP()) != 0); WSContentSend_P(PSTR("

%s%s (%s%s%s)

"), // tasmota.local (192.168.2.12, 192.168.4.1) @@ -772,29 +815,33 @@ void WSContentSendStyle(void) WSContentSendStyle_P(nullptr); } -void WSContentButton(uint32_t title_index) +void WSContentButton(uint32_t title_index, bool show=true) { char action[4]; char title[100]; // Large to accomodate UTF-16 as used by Russian if (title_index <= BUTTON_RESET_CONFIGURATION) { char confirm[100]; - WSContentSend_P(PSTR("

"), + WSContentSend_P(PSTR("

"), + title_index, + show ? "block":"none", GetTextIndexed(action, sizeof(action), title_index, kButtonAction), GetTextIndexed(confirm, sizeof(confirm), title_index, kButtonConfirm), (!title_index) ? PSTR("rst") : PSTR("non"), GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); } else { - WSContentSend_P(PSTR("

"), + WSContentSend_P(PSTR("

"), + title_index, + show ? "block":"none", GetTextIndexed(action, sizeof(action), title_index, kButtonAction), GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); } } -void WSContentSpaceButton(uint32_t title_index) +void WSContentSpaceButton(uint32_t title_index, bool show=true) { - WSContentSend_P(PSTR("
")); // 5px padding - WSContentButton(title_index); + WSContentSend_P(PSTR("
"),title_index, show ? "block":"none"); // 5px padding + WSContentButton(title_index, show); } void WSContentSend_Temp(const char *types, float f_temperature) { @@ -821,7 +868,7 @@ void WSContentEnd(void) void WSContentStop(void) { - if (WifiIsInManagerMode()) { + if ( WifiIsInManagerMode() && (!Web.initial_config) ) { if (WifiConfigCounter()) { WSContentSend_P(HTTP_COUNTER); } @@ -836,31 +883,53 @@ void WebRestart(uint32_t type) { // type 0 = restart // type 1 = restart after config change - // type 2 = restart after config change with possible ip address change too - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTART)); - + // type 2 = Checking WiFi Connection - no restart, only refresh page. + // type 3 = restart after WiFi Connection Test Successful bool reset_only = (HTTP_MANAGER_RESET_ONLY == Web.state); WSContentStart_P((type) ? PSTR(D_SAVE_CONFIGURATION) : PSTR(D_RESTART), !reset_only); - WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); +#if ((RESTART_AFTER_INITIAL_WIFI_CONFIG) && (AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP)) + // In case of type 3 (New network has been configured) go to the new device's IP in the new Network + if (3 == type) { + WSContentSend_P("setTimeout(function(){location.href='http://%_I';},%d);", + (uint32_t)WiFi.localIP(), + HTTP_RESTART_RECONNECT_TIME + ); + } else { + WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); + } +#else + // In case of type 3 (New network has been configured) do not refresh the page. Just halt. + // The IP of the device while was in AP mode, won't be the new IP of the newly configured Network. + if (!(3 == type)) { WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); } +#endif WSContentSendStyle(); if (type) { - WSContentSend_P(PSTR("
" D_CONFIGURATION_SAVED "
")); - if (2 == type) { - WSContentSend_P(PSTR("
" D_TRYING_TO_CONNECT "
")); + if (!(3 == type)) { + WSContentSend_P(PSTR("
%s

"), (type==2) ? PSTR(D_TRYING_TO_CONNECT) : PSTR(D_CONFIGURATION_SAVED) ); + } else { +#if (AFTER_INITIAL_WIFI_CONFIG_GO_TO_NEW_IP) + WSContentSend_P(PSTR("
" D_SUCCESSFUL_WIFI_CONNECTION "

" D_REDIRECTING_TO_NEW_IP "

"), WebColor(COL_TEXT_SUCCESS) ); +#else + WSContentSend_P(PSTR("
" D_SUCCESSFUL_WIFI_CONNECTION "

" D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "

"), WebColor(COL_TEXT_SUCCESS) ); +#endif } - WSContentSend_P(PSTR("
")); } - WSContentSend_P(HTTP_MSG_RSTRT); - if (HTTP_MANAGER == Web.state || reset_only) { - Web.state = HTTP_ADMIN; - } else { - WSContentSpaceButton(BUTTON_MAIN); + if (type<2) { + WSContentSend_P(HTTP_MSG_RSTRT); + if (HTTP_MANAGER == Web.state || reset_only) { + Web.state = HTTP_ADMIN; + } else { + WSContentSpaceButton(BUTTON_MAIN); + } } WSContentStop(); - ShowWebSource(SRC_WEBGUI); - TasmotaGlobal.restart_flag = 2; + if (!(2 == type)) { + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTART)); + ShowWebSource(SRC_WEBGUI); + TasmotaGlobal.restart_flag = 2; + } } /*********************************************************************************************/ @@ -919,6 +988,10 @@ void HandleRoot(void) HandleWifiLogin(); } else { if (!strlen(SettingsText(SET_WEBPWD)) || (((Webserver->arg(F("USER1")) == WEB_USERNAME ) && (Webserver->arg(F("PASS1")) == SettingsText(SET_WEBPWD) )) || HTTP_MANAGER_RESET_ONLY == Web.state)) { + if (!Web.initial_config) { + Web.initial_config = !strlen(SettingsText(SET_STASSID1)); + if (Web.initial_config) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Blank Device - Initial Configuration")); } + } HandleWifiConfiguration(); } else { // wrong user and pass @@ -1648,26 +1721,77 @@ String HtmlEscape(const String unescaped) { const char kEncryptionType[] PROGMEM = "|||" D_WPA_PSK "||" D_WPA2_PSK "|" D_WEP "||" D_NONE "|" D_AUTO; void HandleWifiConfiguration(void) { + char tmp[TOPSZ]; // Max length is currently 150 + if (!HttpCheckPriviledgedAccess(!WifiIsInManagerMode())) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_WIFI)); if (Webserver->hasArg(F("save")) && HTTP_MANAGER_RESET_ONLY != Web.state) { - WifiSaveSettings(); - WebRestart(2); + if ( WifiIsInManagerMode() ) { + // Test WIFI Connection to Router + // As Tasmota is in this case in AP mode, a STA connection can be established too at the same time + Web.wifi_test_counter = 9; // seconds to test user's proposed AP + Web.wifiTest = WIFI_TESTING; + + Web.save_data_counter = TasmotaGlobal.save_data_counter; + TasmotaGlobal.save_data_counter = 0; // Stop auto saving data - Updating Settings + Settings.save_data = 0; + + Web.old_wificonfig = TasmotaGlobal.wifi_state_flag; + Settings.sta_config = WIFI_MANAGER; + TasmotaGlobal.wifi_state_flag = Settings.sta_config; + + TasmotaGlobal.sleep = 0; // Disable sleep + TasmotaGlobal.restart_flag = 0; // No restart + TasmotaGlobal.ota_state_flag = 0; // No OTA +// TasmotaGlobal.blinks = 0; // Disable blinks initiated by WifiManager + + WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // SSID1 + SettingsUpdateText(SET_STASSID1, tmp); + WebGetArg(PSTR("p1"), tmp, sizeof(tmp)); // PASSWORD1 + SettingsUpdateText(SET_STAPWD1, tmp); + + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECTING_TO_AP " %s " D_AS " %s ..."), + SettingsText(SET_STASSID1), TasmotaGlobal.hostname); + + WiFi.begin(SettingsText(SET_STASSID1), SettingsText(SET_STAPWD1)); + + WebRestart(2); + } else { + // STATION MODE or MIXED + // Save the config and restart + WifiSaveSettings(); + WebRestart(1); + } return; } + if ( WIFI_TEST_FINISHED_SUCCESSFUL == Web.wifiTest ) { + Web.wifiTest = WIFI_NOT_TESTING; +#if (RESTART_AFTER_INITIAL_WIFI_CONFIG) + WebRestart(3); +#else + HandleRoot(); +#endif + } + WSContentStart_P(PSTR(D_CONFIGURE_WIFI), !WifiIsInManagerMode()); WSContentSend_P(HTTP_SCRIPT_WIFI); + if (WifiIsInManagerMode()) { WSContentSend_P(HTTP_SCRIPT_HIDE); } + if (WIFI_TESTING == Web.wifiTest) { WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); } #ifdef USE_ENHANCED_GUI_WIFI_SCAN WSContentSendStyle_P(HTTP_HEAD_STYLE_SSI, WebColor(COL_TEXT)); #else WSContentSendStyle(); #endif // USE_ENHANCED_GUI_WIFI_SCAN + bool limitScannedNetworks = true; if (HTTP_MANAGER_RESET_ONLY != Web.state) { - if (Webserver->hasArg(F("scan"))) { + if (WIFI_TESTING == Web.wifiTest) { + limitScannedNetworks = false; + } else { + if (Webserver->hasArg(F("scan"))) { limitScannedNetworks = false; } #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION @@ -1677,7 +1801,7 @@ void HandleWifiConfiguration(void) { if (0 == n) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_NO_NETWORKS_FOUND)); WSContentSend_P(PSTR(D_NO_NETWORKS_FOUND)); - WSContentSend_P(PSTR(". " D_REFRESH_TO_SCAN_AGAIN ".")); + limitScannedNetworks = false; // in order to show D_SCAN_FOR_WIFI_NETWORKS } else { //sort networks int indices[n]; @@ -1685,7 +1809,6 @@ void HandleWifiConfiguration(void) { indices[i] = i; } - // RSSI SORT for (uint32_t i = 0; i < n; i++) { for (uint32_t j = i + 1; j < n; j++) { @@ -1695,9 +1818,16 @@ void HandleWifiConfiguration(void) { } } + uint32_t networksToShow = n; + if ((limitScannedNetworks) && (networksToShow > MAX_WIFI_NETWORKS_TO_SHOW)) { networksToShow = MAX_WIFI_NETWORKS_TO_SHOW; } + + if (WifiIsInManagerMode()) { WSContentSend_P(PSTR("
" D_SELECT_YOUR_WIFI_NETWORK "

"), WebColor(COL_TEXT)); } + #ifdef USE_ENHANCED_GUI_WIFI_SCAN //display networks in page - for (uint32_t i = 0; i < n; i++) { + bool skipduplicated; + int ssid_showed = 0; + for (uint32_t i = 0; i < networksToShow; i++) { if (indices[i] < n) { int32_t rssi = WiFi.RSSI(indices[i]); String ssid = WiFi.SSID(indices[i]); @@ -1705,29 +1835,47 @@ void HandleWifiConfiguration(void) { ssid.c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), rssi); // Print SSID - WSContentSend_P(PSTR("
%s
"), HtmlEscape(ssid).c_str()); + if (!limitScannedNetworks) { + WSContentSend_P(PSTR("
%s
"), HtmlEscape(ssid).c_str()); + } + skipduplicated = false; String nextSSID = ""; // Handle all APs with the same SSID for (uint32_t j = 0; j < n; j++) { if ((indices[j] < n) && ((nextSSID = WiFi.SSID(indices[j])) == ssid)) { - // Update RSSI / quality - rssi = WiFi.RSSI(indices[j]); - uint32_t rssi_as_quality = WifiGetRssiAsQuality(rssi); - uint32_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4); + if (!skipduplicated) { + // Update RSSI / quality + rssi = WiFi.RSSI(indices[j]); + uint32_t rssi_as_quality = WifiGetRssiAsQuality(rssi); + uint32_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4); - // Print item - WSContentSend_P(PSTR("
%s(%d)
"), - rssi, rssi_as_quality, - WiFi.BSSIDstr(indices[j]).c_str(), - WiFi.channel(indices[j]) - ); - // Print signal strength indicator - for (uint32_t k = 0; k < 4; ++k) { - WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + if (limitScannedNetworks) { + // Print SSID and item + WSContentSend_P(PSTR("
%s
"), rssi, rssi_as_quality, HtmlEscape(ssid).c_str()); + // Print signal strength indicator + for (uint32_t k = 0; k < 4; ++k) { + WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + } + WSContentSend_P(PSTR("
")); + ssid_showed++; + skipduplicated = true; // For the simplified page, just show 1 SSID if there are many Networks with the same + } else { + // Print item + WSContentSend_P(PSTR("
%s(%d)
"), + rssi, rssi_as_quality, + WiFi.BSSIDstr(indices[j]).c_str(), + WiFi.channel(indices[j]) + ); + // Print signal strength indicator + for (uint32_t k = 0; k < 4; ++k) { + WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + } + WSContentSend_P(PSTR("
")); + } + } else { + if (ssid_showed <= networksToShow ) { networksToShow++; } } - WSContentSend_P(PSTR("
")); - indices[j] = n; } delay(0); @@ -1750,7 +1898,7 @@ void HandleWifiConfiguration(void) { } //display networks in page - for (uint32_t i = 0; i < n; i++) { + for (uint32_t i = 0; i < networksToShow; i++) { if (-1 == indices[i]) { continue; } // skip dups int32_t rssi = WiFi.RSSI(indices[i]); DEBUG_CORE_LOG(PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), @@ -1778,21 +1926,44 @@ void HandleWifiConfiguration(void) { WSContentSend_P(PSTR("
")); } + } + + if (limitScannedNetworks) { + WSContentSend_P(PSTR("
")); } else { WSContentSend_P(PSTR("
")); } // As WIFI_HOSTNAME may contain %s-%04d it cannot be part of HTTP_FORM_WIFI where it will exception - WSContentSend_P(HTTP_FORM_WIFI, SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsText(SET_HOSTNAME), SettingsText(SET_CORS)); + if (WifiIsInManagerMode()) { + WSContentSend_P(HTTP_FORM_WIFI_INITIAL, SettingsText(SET_STASSID1) ); + } else { + WSContentSend_P(HTTP_FORM_WIFI, SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsText(SET_HOSTNAME), SettingsText(SET_CORS)); + } WSContentSend_P(HTTP_FORM_END); } if (WifiIsInManagerMode()) { #ifndef FIRMWARE_MINIMAL - WSContentSpaceButton(BUTTON_RESTORE); - WSContentButton(BUTTON_RESET_CONFIGURATION); + if (WIFI_TESTING == Web.wifiTest) { + WSContentSend_P(PSTR("

" D_TRYING_TO_CONNECT "
%s

"), + WebColor(COL_TEXT_WARNING), + SettingsText(SET_STASSID1) + ); + } else if (WIFI_TEST_FINISHED_BAD == Web.wifiTest) { + WSContentSend_P(PSTR("

" D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS "

"), + WebColor(COL_TEXT_WARNING), + SettingsText(SET_STASSID1) + ); + } + // More Options Button + WSContentSend_P(PSTR("

"), + (WIFI_TEST_FINISHED_BAD == Web.wifiTest) ? "none" : Web.initial_config ? "block" : "none", Web.initial_config ? "block" : "none" + ); + WSContentSpaceButton(BUTTON_RESTORE, !Web.initial_config); + WSContentButton(BUTTON_RESET_CONFIGURATION, !Web.initial_config); #endif // FIRMWARE_MINIMAL - WSContentSpaceButton(BUTTON_RESTART); + WSContentSpaceButton(BUTTON_RESTART, !Web.initial_config); } else { WSContentSpaceButton(BUTTON_CONFIGURATION); } @@ -3116,6 +3287,47 @@ bool Xdrv01(uint8_t function) if (Settings.flag2.emulation) { PollUdp(); } #endif // USE_EMULATION break; + case FUNC_EVERY_SECOND: + if (Web.initial_config) { + Wifi.config_counter = 200; // Do not restart the device if it has SSId Blank + } + if (Web.wifi_test_counter) { + Web.wifi_test_counter--; + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_TRYING_TO_CONNECT " %s"), SettingsText(SET_STASSID1)); + if ( WifiCheck_hasIP(WiFi.localIP()) ) { // Got IP - Connection Established + Web.wifi_test_counter = 0; + Web.wifiTest = WIFI_TEST_FINISHED_SUCCESSFUL; + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CMND_SSID "1 %s: " D_CONNECTED " - " D_IP_ADDRESS " %_I"), SettingsText(SET_STASSID1), (uint32_t)WiFi.localIP()); +// TasmotaGlobal.blinks = 255; // Signal wifi connection with blinks + Settings.sta_config = Web.old_wificonfig; + TasmotaGlobal.wifi_state_flag = Settings.sta_config; + TasmotaGlobal.save_data_counter = Web.save_data_counter; + Settings.save_data = Web.save_data_counter; + SettingsSaveAll(); +#if (!RESTART_AFTER_INITIAL_WIFI_CONFIG) + Web.initial_config = false; + Web.state = HTTP_ADMIN; +#endif + } else if (!Web.wifi_test_counter) { // Test TimeOut + Web.wifi_test_counter = 0; + Web.wifiTest = WIFI_TEST_FINISHED_BAD; + switch (WiFi.status()) { + case WL_CONNECTED: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_NO_IP_ADDRESS)); + break; + case WL_NO_SSID_AVAIL: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_AP_NOT_REACHED)); + break; + case WL_CONNECT_FAILED: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_WRONG_PASSWORD)); + break; + default: // WL_IDLE_STATUS and WL_DISCONNECTED + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECT_FAILED_AP_TIMEOUT)); + } + int n = WiFi.scanNetworks(); // restart scan + } + } + break; case FUNC_COMMAND: result = DecodeCommand(kWebCommands, WebCommand); break; From 89f07f507e92cbef9898a31f31e14bea1061be00 Mon Sep 17 00:00:00 2001 From: Adrian Scillato Date: Mon, 12 Apr 2021 13:45:18 -0300 Subject: [PATCH 56/67] Add New Translation Keys --- tasmota/language/af_AF.h | 17 +++++++++++++---- tasmota/language/bg_BG.h | 17 +++++++++++++---- tasmota/language/cs_CZ.h | 17 +++++++++++++---- tasmota/language/de_DE.h | 13 +++++++++++-- tasmota/language/el_GR.h | 17 +++++++++++++---- tasmota/language/en_GB.h | 19 ++++++++++++++----- tasmota/language/es_ES.h | 17 +++++++++++++---- tasmota/language/fr_FR.h | 17 +++++++++++++---- tasmota/language/fy_NL.h | 17 +++++++++++++---- tasmota/language/he_HE.h | 17 +++++++++++++---- tasmota/language/hu_HU.h | 17 +++++++++++++---- tasmota/language/it_IT.h | 17 +++++++++++++---- tasmota/language/ko_KO.h | 17 +++++++++++++---- tasmota/language/nl_NL.h | 17 +++++++++++++---- tasmota/language/pl_PL.h | 15 ++++++++++++--- tasmota/language/pt_BR.h | 19 ++++++++++++++----- tasmota/language/pt_PT.h | 19 ++++++++++++++----- tasmota/language/ro_RO.h | 17 +++++++++++++---- tasmota/language/ru_RU.h | 17 +++++++++++++---- tasmota/language/sk_SK.h | 17 +++++++++++++---- tasmota/language/sv_SE.h | 17 +++++++++++++---- tasmota/language/tr_TR.h | 17 +++++++++++++---- tasmota/language/uk_UA.h | 17 +++++++++++++---- tasmota/language/vi_VN.h | 17 +++++++++++++---- tasmota/language/zh_CN.h | 17 +++++++++++++---- tasmota/language/zh_TW.h | 15 ++++++++++++--- 26 files changed, 337 insertions(+), 103 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 76b555acb..297ca7de0 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Wagwoord" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Wagwoord" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Wagwoord" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT-parameters" #define D_CLIENT "Kliënt" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 145448e04..589503792 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Парола" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Парола" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Парола" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Параметри на MQTT" #define D_CLIENT "Клиент" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index af7fa2d8b..9694301ee 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSID" -#define D_AP1_PASSWORD "Heslo AP1" -#define D_AP2_SSID "AP2 SSID" -#define D_AP2_PASSWORD "Heslo AP2" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "Heslo WiFi" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Nastavení MQTT" #define D_CLIENT "Klient" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index a466598c7..2625ceaf2 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -291,9 +291,18 @@ #define D_WPA_PSK "WPA-PSK" #define D_WPA2_PSK "WPA2-PSK" #define D_AP1_SSID "WLAN 1 - SSID" -#define D_AP1_PASSWORD "WLAN 1 - Passwort" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" #define D_AP2_SSID "WLAN 2 - SSID" -#define D_AP2_PASSWORD "WLAN 2 - Passwort" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WLAN - Passwort" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT-Einstellungen" #define D_CLIENT "client" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 16ad54b6f..27e4b332b 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Κωδικός" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Κωδικός" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Κωδικός" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Παράμετροι MQTT" #define D_CLIENT "Πελάτης" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 73dacd8a3..b592fc826 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.3.1.1 + * Updated until v9.3.1.2 \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Password" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Password" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Password" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT parameters" #define D_CLIENT "Client" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 8bcefba0d..acc823221 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "SSId AP1" -#define D_AP1_PASSWORD "Clave AP1" -#define D_AP2_SSID "SSId AP2" -#define D_AP2_PASSWORD "Clave AP2" +#define D_AP1_SSID "Red WiFi" +#define D_AP1_SSID_HELP "Escriba o Seleccione su Red WiFi" +#define D_AP2_SSID "Red WiFi Alternativa" +#define D_AP2_SSID_HELP "Escriba el nombre de la Red WiFi Alternativa" +#define D_AP_PASSWORD "Clave WiFi" +#define D_AP_PASSWORD_HELP "Escriba la clave de WiFi" +#define D_SELECT_YOUR_WIFI_NETWORK "Seleccione su Red WiFi" +#define D_SHOW_MORE_WIFI_NETWORKS "Buscar todas las Redes WiFi" +#define D_SHOW_MORE_OPTIONS "Mas Opciones" +#define D_CHECK_CREDENTIALS "Por favor, revise la clave" +#define D_SUCCESSFUL_WIFI_CONNECTION "Conexión WiFi Existosa" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Ahora puede cerrar esta ventana" +#define D_REDIRECTING_TO_NEW_IP "Redireccionando a la nueva dirección IP" #define D_MQTT_PARAMETERS "Parámetros MQTT" #define D_CLIENT "Cliente" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index a37dd796d..aa74db5dd 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSID" -#define D_AP1_PASSWORD "Mot de passe AP1" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "Mot de passe AP2" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "Mot de passe" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Paramètres MQTT" #define D_CLIENT "Client" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 5f00102ab..d76bf3fb9 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Wachtwurd" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Wachtwurd" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Wachtwurd" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT parameters" #define D_CLIENT "Client" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index f25d847eb..7d360e060 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Password" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Password" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Password" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT פרמטרים" #define D_CLIENT "לקוח" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index f4d210a5c..eb6f6b41b 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSID" -#define D_AP1_PASSWORD "AP1 megosztott kulcs" -#define D_AP2_SSID "AP2 SSID" -#define D_AP2_PASSWORD "AP2 megosztott kulcs" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi megosztott kulcs" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT paraméterek" #define D_CLIENT "Kliens" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index c73ad3d5c..b1831c489 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 - SSID" -#define D_AP1_PASSWORD "AP1 - Password" -#define D_AP2_SSID "AP2 - SSID" -#define D_AP2_PASSWORD "AP2 - Password" +#define D_AP1_SSID "Rete WiFi" +#define D_AP1_SSID_HELP "Digita o Seleziona la tua Rete WiFi" +#define D_AP2_SSID "Rete WiFi 2" +#define D_AP2_SSID_HELP "Digita la tua Rete WiFi Alternativa" +#define D_AP_PASSWORD "Password WiFi" +#define D_AP_PASSWORD_HELP "Inserisci la tua Password WiFi" +#define D_SELECT_YOUR_WIFI_NETWORK "Seleziona la tua Rete WiFi" +#define D_SHOW_MORE_WIFI_NETWORKS "Cerca tutte le Reti WiFi" +#define D_SHOW_MORE_OPTIONS "Più Opzioni" +#define D_CHECK_CREDENTIALS "Per favore, controlla le tue Credenziali" +#define D_SUCCESSFUL_WIFI_CONNECTION "Connessione WiFi riuscita" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Adesso puoi chiudere questa finestra" +#define D_REDIRECTING_TO_NEW_IP "Reindirizzamento al nuovo indirizzo IP del dispositivo" #define D_MQTT_PARAMETERS "Parametri MQTT" #define D_CLIENT "Client" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index ef341444e..9cce3e4ad 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 비밀번호" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 비밀번호" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi 비밀번호" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT 설정" #define D_CLIENT "클라이언트" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 667c7ac91..7917a6dd7 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Wachtwoord" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Wachtwoord" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Wachtwoord" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT parameters" #define D_CLIENT "Client" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 00840c694..ee345765b 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "Nazwa 1" -#define D_AP1_PASSWORD "Hasło 1" +#define D_AP1_SSID "Nazwa" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" #define D_AP2_SSID "Nazwa 2" -#define D_AP2_PASSWORD "Hasło 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "Hasło" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Parametry MQTT" #define D_CLIENT "Klient" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 398d49286..3be3dbc04 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.3.1.1 + * Updated until v9.3.1.2 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "Senha AP1" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "Senha AP2" +#define D_AP1_SSID "Rede WiFi" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "Rede WiFi 2" +#define D_AP2_SSID_HELP "Digite ou selecione sua rede WiFi" +#define D_AP_PASSWORD "Senha do WiFi" +#define D_AP_PASSWORD_HELP "Digite sua Senha WiFi" +#define D_SELECT_YOUR_WIFI_NETWORK "Selecione sua Rede WiFi" +#define D_SHOW_MORE_WIFI_NETWORKS "Procure todas as Redes WiFi" +#define D_SHOW_MORE_OPTIONS "Mais Opções" +#define D_CHECK_CREDENTIALS "Por favor, verifique suas credenciais" +#define D_SUCCESSFUL_WIFI_CONNECTION "Conexão WiFi bem-sucedida" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Agora você pode fechar esta janela" +#define D_REDIRECTING_TO_NEW_IP "Redirecionando para o novo endereço IP do dispositivo" #define D_MQTT_PARAMETERS "Parâmetros MQTT" #define D_CLIENT "Cliente" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index d2aeec758..245532523 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.3.1.1 + * Updated until v9.3.1.2 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "SSId do AP1" -#define D_AP1_PASSWORD "Palavra Chave do AP1" -#define D_AP2_SSID "SSId do AP2" -#define D_AP2_PASSWORD "Palavra Chave do AP2" +#define D_AP1_SSID "Rede WiFi" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "Rede WiFi 2" +#define D_AP2_SSID_HELP "Digite ou selecione sua rede WiFi" +#define D_AP_PASSWORD "Palavra Chave do WiFi" +#define D_AP_PASSWORD_HELP "Digite sua Palavra Chave do WiFi" +#define D_SELECT_YOUR_WIFI_NETWORK "Selecione sua Rede WiFi" +#define D_SHOW_MORE_WIFI_NETWORKS "Procure todas as Redes WiFi" +#define D_SHOW_MORE_OPTIONS "Mais Opções" +#define D_CHECK_CREDENTIALS "Por favor, verifique suas credenciais" +#define D_SUCCESSFUL_WIFI_CONNECTION "Conexão WiFi bem-sucedida" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Agora você pode fechar esta janela" +#define D_REDIRECTING_TO_NEW_IP "Redirecionando para o novo endereço IP do dispositivo" #define D_MQTT_PARAMETERS "Parametros MQTT" #define D_CLIENT "Cliente" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index d5d9733df..6c62d0c98 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "Parolă AP1" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "Parolă AP2" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "Parolă WiFi" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "parametri MQTT" #define D_CLIENT "Client" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 5a4ef6cad..4ef363376 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Пароль" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Пароль" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Пароль" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Параметры MQTT" #define D_CLIENT "Клиент" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 2f4d37a99..6570bccdd 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSID" -#define D_AP1_PASSWORD "Heslo AP1" -#define D_AP2_SSID "AP2 SSID" -#define D_AP2_PASSWORD "Heslo AP2" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "Heslo WiFi" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Nastavenia MQTT" #define D_CLIENT "Klient" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index a1a2077a2..c195d4735 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 lösenord" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 lösenord" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi lösenord" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT-parameterar" #define D_CLIENT "Klient" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index dd041c94c..8064479c7 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 Adı (SSId)" -#define D_AP1_PASSWORD "AP1 Parolası" -#define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Parolası" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Parolası" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT parametreleri" #define D_CLIENT "İstemci" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 0b6f967ae..2f18836f1 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSID" -#define D_AP1_PASSWORD "AP1 гасло" -#define D_AP2_SSID "AP2 SSID" -#define D_AP2_PASSWORD "AP2 гасло" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi гасло" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Параметри MQTT" #define D_CLIENT "Клієнт" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index e47e52952..5b0c3a247 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "Tên mạng wifi 1" -#define D_AP1_PASSWORD "Mật khẩu mạng wifi 1" -#define D_AP2_SSID "Tên mạng wifi 2" -#define D_AP2_PASSWORD "Mật khẩu mạng wifi 2" +#define D_AP1_SSID "Tên mạng WiFi" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "Tên mạng WiFi 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "Mật khẩu mạng WiFi" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "Thông số MQTT" #define D_CLIENT "Client" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 6451d3107..22580ed43 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 名称" -#define D_AP1_PASSWORD "AP1 密码" -#define D_AP2_SSID "AP2 名称" -#define D_AP2_PASSWORD "AP2 密码" +#define D_AP1_SSID "WiFi 名称" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi 名称 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi 密码" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT 设置" #define D_CLIENT "客户端" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 2a36f65b7..c84fe4607 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -290,10 +290,19 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "存取點1 SSID" -#define D_AP1_PASSWORD "存取點1 密碼" +#define D_AP1_SSID "存取點 SSID" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" #define D_AP2_SSID "存取點2 SSID" -#define D_AP2_PASSWORD "存取點2 密碼" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "存取點 密碼" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" #define D_MQTT_PARAMETERS "MQTT設定" #define D_CLIENT "客戶端" From c3bfdebcf182e90a9d7c502187af0337528ad5a4 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 12 Apr 2021 19:53:35 +0200 Subject: [PATCH 57/67] Berry directory reorg --- lib/libesp32/Berry-0.1.10/library.properties | 7 - lib/libesp32/Berry-0.1.10/src/berry_conf.h | 1 - lib/libesp32/{Berry-0.1.10 => Berry}/LICENSE | 0 lib/libesp32/Berry/berry-logo.png | Bin 0 -> 11325 bytes .../src/port => Berry/default}/be_driverlib.c | 0 .../src/port => Berry/default}/be_energylib.c | 0 .../src/port => Berry/default}/be_gpio_lib.c | 0 .../src/port => Berry/default}/be_light_lib.c | 0 .../src/port => Berry/default}/be_modtab.c | 0 .../src/port => Berry/default}/be_port.cpp | 0 .../port => Berry/default}/be_tasmotalib.c | 0 .../src/port => Berry/default}/be_wirelib.c | 0 .../src/port => Berry/default}/berry_conf.h | 0 .../src/port => Berry/default}/gpio.txt | 0 lib/libesp32/Berry/examples/anon_func.be | 20 ++ lib/libesp32/Berry/examples/bigloop.be | 15 ++ lib/libesp32/Berry/examples/bintree.be | 60 ++++++ lib/libesp32/Berry/examples/calcpi.be | 16 ++ lib/libesp32/Berry/examples/exception.be | 12 ++ lib/libesp32/Berry/examples/fib_rec.be | 12 ++ lib/libesp32/Berry/examples/guess_number.be | 26 +++ lib/libesp32/Berry/examples/json.be | 4 + lib/libesp32/Berry/examples/lambda.be | 8 + lib/libesp32/Berry/examples/listdir.be | 16 ++ lib/libesp32/Berry/examples/qsort.be | 42 ++++ lib/libesp32/Berry/examples/repl.be | 61 ++++++ lib/libesp32/Berry/examples/string.be | 32 +++ lib/libesp32/Berry/examples/strmod.be | 7 + .../generate/be_const_strtab.h | 0 .../generate/be_const_strtab_def.h | 0 .../generate/be_fixed_be_class_bytes.h | 0 .../generate/be_fixed_be_class_list.h | 0 .../generate/be_fixed_be_class_map.h | 0 .../generate/be_fixed_be_class_range.h | 0 .../generate/be_fixed_debug.h | 0 .../generate/be_fixed_gc.h | 0 .../generate/be_fixed_gpio.h | 0 .../generate/be_fixed_json.h | 0 .../generate/be_fixed_m_builtin.h | 0 .../generate/be_fixed_math.h | 0 .../generate/be_fixed_os.h | 0 .../generate/be_fixed_path.h | 0 .../generate/be_fixed_solidify.h | 0 .../generate/be_fixed_string.h | 0 .../generate/be_fixed_sys.h | 0 .../generate/be_fixed_tasmota.h | 0 .../generate/be_fixed_time.h | 0 lib/libesp32/Berry/library.json | 29 +++ .../{Berry-0.1.10 => Berry}/src/be_api.c | 0 .../{Berry-0.1.10 => Berry}/src/be_baselib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_bytecode.c | 0 .../{Berry-0.1.10 => Berry}/src/be_bytecode.h | 0 .../{Berry-0.1.10 => Berry}/src/be_byteslib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_class.c | 0 .../{Berry-0.1.10 => Berry}/src/be_class.h | 0 .../{Berry-0.1.10 => Berry}/src/be_code.c | 0 .../{Berry-0.1.10 => Berry}/src/be_code.h | 0 .../{Berry-0.1.10 => Berry}/src/be_constobj.h | 0 .../{Berry-0.1.10 => Berry}/src/be_debug.c | 0 .../{Berry-0.1.10 => Berry}/src/be_debug.h | 0 .../{Berry-0.1.10 => Berry}/src/be_debuglib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_decoder.h | 0 .../{Berry-0.1.10 => Berry}/src/be_exec.c | 0 .../{Berry-0.1.10 => Berry}/src/be_exec.h | 0 .../{Berry-0.1.10 => Berry}/src/be_filelib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_func.c | 0 .../{Berry-0.1.10 => Berry}/src/be_func.h | 0 .../{Berry-0.1.10 => Berry}/src/be_gc.c | 0 .../{Berry-0.1.10 => Berry}/src/be_gc.h | 0 .../{Berry-0.1.10 => Berry}/src/be_gclib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_jsonlib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_lexer.c | 0 .../{Berry-0.1.10 => Berry}/src/be_lexer.h | 0 .../{Berry-0.1.10 => Berry}/src/be_libs.c | 0 .../{Berry-0.1.10 => Berry}/src/be_libs.h | 0 .../{Berry-0.1.10 => Berry}/src/be_list.c | 0 .../{Berry-0.1.10 => Berry}/src/be_list.h | 0 .../{Berry-0.1.10 => Berry}/src/be_listlib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_map.c | 0 .../{Berry-0.1.10 => Berry}/src/be_map.h | 0 .../{Berry-0.1.10 => Berry}/src/be_maplib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_mathlib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_mem.c | 0 .../{Berry-0.1.10 => Berry}/src/be_mem.h | 0 .../{Berry-0.1.10 => Berry}/src/be_module.c | 0 .../{Berry-0.1.10 => Berry}/src/be_module.h | 0 .../{Berry-0.1.10 => Berry}/src/be_object.c | 0 .../{Berry-0.1.10 => Berry}/src/be_object.h | 0 .../{Berry-0.1.10 => Berry}/src/be_opcodes.h | 0 .../{Berry-0.1.10 => Berry}/src/be_oslib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_parser.c | 0 .../{Berry-0.1.10 => Berry}/src/be_parser.h | 0 .../{Berry-0.1.10 => Berry}/src/be_rangelib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_repl.c | 0 .../{Berry-0.1.10 => Berry}/src/be_repl.h | 0 .../src/be_solidifylib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_string.c | 0 .../{Berry-0.1.10 => Berry}/src/be_string.h | 0 .../{Berry-0.1.10 => Berry}/src/be_strlib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_strlib.h | 0 .../{Berry-0.1.10 => Berry}/src/be_sys.h | 0 .../{Berry-0.1.10 => Berry}/src/be_syslib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_timelib.c | 0 .../{Berry-0.1.10 => Berry}/src/be_var.c | 0 .../{Berry-0.1.10 => Berry}/src/be_var.h | 0 .../{Berry-0.1.10 => Berry}/src/be_vector.c | 0 .../{Berry-0.1.10 => Berry}/src/be_vector.h | 0 .../{Berry-0.1.10 => Berry}/src/be_vm.c | 0 .../{Berry-0.1.10 => Berry}/src/be_vm.h | 0 .../{Berry-0.1.10 => Berry}/src/berry.h | 0 lib/libesp32/Berry/src/berry_conf.h | 1 + lib/libesp32/Berry/testall.be | 44 ++++ lib/libesp32/Berry/tests/assignment.be | 34 +++ lib/libesp32/Berry/tests/bool.be | 18 ++ lib/libesp32/Berry/tests/bytes.be | 167 +++++++++++++++ lib/libesp32/Berry/tests/checkspace.be | 35 ++++ lib/libesp32/Berry/tests/class.be | 22 ++ lib/libesp32/Berry/tests/cond_expr.be | 10 + lib/libesp32/Berry/tests/debug.be | 4 + lib/libesp32/Berry/tests/for.be | 44 ++++ lib/libesp32/Berry/tests/function.be | 12 ++ lib/libesp32/Berry/tests/json.be | 53 +++++ lib/libesp32/Berry/tests/lexer.be | 62 ++++++ lib/libesp32/Berry/tests/list.be | 74 +++++++ lib/libesp32/Berry/tests/os.be | 51 +++++ lib/libesp32/Berry/tests/overload.be | 14 ++ lib/libesp32/Berry/tests/relop.be | 40 ++++ lib/libesp32/Berry/tests/string.be | 30 +++ lib/libesp32/Berry/tests/subobject.be | 29 +++ lib/libesp32/Berry/tests/suffix.be | 11 + lib/libesp32/Berry/tools/coc/.gitignore | 1 + lib/libesp32/Berry/tools/coc/Makefile | 26 +++ lib/libesp32/Berry/tools/coc/REEADME.md | 3 + .../Berry/tools/coc/block_builder.cpp | 197 ++++++++++++++++++ lib/libesp32/Berry/tools/coc/block_builder.h | 49 +++++ lib/libesp32/Berry/tools/coc/coc_parser.cpp | 189 +++++++++++++++++ lib/libesp32/Berry/tools/coc/coc_parser.h | 46 ++++ lib/libesp32/Berry/tools/coc/coc_string.cpp | 48 +++++ lib/libesp32/Berry/tools/coc/coc_string.h | 18 ++ lib/libesp32/Berry/tools/coc/hash_map.cpp | 161 ++++++++++++++ lib/libesp32/Berry/tools/coc/hash_map.h | 47 +++++ lib/libesp32/Berry/tools/coc/macro_table.cpp | 59 ++++++ lib/libesp32/Berry/tools/coc/macro_table.h | 30 +++ lib/libesp32/Berry/tools/coc/main.cpp | 141 +++++++++++++ lib/libesp32/Berry/tools/coc/main.h | 45 ++++ lib/libesp32/Berry/tools/coc/object_block.h | 25 +++ lib/libesp32/Berry/tools/coc/str_build.cpp | 129 ++++++++++++ lib/libesp32/Berry/tools/coc/str_build.h | 39 ++++ .../Berry/tools/grammar/berry.bytecode | 96 +++++++++ lib/libesp32/Berry/tools/grammar/berry.ebnf | 45 ++++ .../Berry/tools/grammar/const_obj.ebnf | 11 + lib/libesp32/Berry/tools/grammar/json.ebnf | 5 + .../vscode/skiars.berry-0.1.0/.vsixmanifest | 34 +++ .../vscode/skiars.berry-0.1.0/CHANGELOG.md | 7 + .../vscode/skiars.berry-0.1.0/README.md | 0 .../berry-configuration.json | 32 +++ .../vscode/skiars.berry-0.1.0/berry-icon.png | Bin 0 -> 5429 bytes .../vscode/skiars.berry-0.1.0/package.json | 52 +++++ .../skiars.berry-0.1.0/syntaxes/berry.json | 109 ++++++++++ .../skiars.berry-0.1.0/syntaxes/bytecode.json | 58 ++++++ 160 files changed, 2817 insertions(+), 8 deletions(-) delete mode 100644 lib/libesp32/Berry-0.1.10/library.properties delete mode 100644 lib/libesp32/Berry-0.1.10/src/berry_conf.h rename lib/libesp32/{Berry-0.1.10 => Berry}/LICENSE (100%) create mode 100644 lib/libesp32/Berry/berry-logo.png rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_driverlib.c (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_energylib.c (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_gpio_lib.c (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_light_lib.c (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_modtab.c (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_port.cpp (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_tasmotalib.c (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/be_wirelib.c (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/berry_conf.h (100%) rename lib/libesp32/{Berry-0.1.10/src/port => Berry/default}/gpio.txt (100%) create mode 100644 lib/libesp32/Berry/examples/anon_func.be create mode 100644 lib/libesp32/Berry/examples/bigloop.be create mode 100644 lib/libesp32/Berry/examples/bintree.be create mode 100644 lib/libesp32/Berry/examples/calcpi.be create mode 100644 lib/libesp32/Berry/examples/exception.be create mode 100644 lib/libesp32/Berry/examples/fib_rec.be create mode 100644 lib/libesp32/Berry/examples/guess_number.be create mode 100644 lib/libesp32/Berry/examples/json.be create mode 100644 lib/libesp32/Berry/examples/lambda.be create mode 100644 lib/libesp32/Berry/examples/listdir.be create mode 100644 lib/libesp32/Berry/examples/qsort.be create mode 100644 lib/libesp32/Berry/examples/repl.be create mode 100644 lib/libesp32/Berry/examples/string.be create mode 100644 lib/libesp32/Berry/examples/strmod.be rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_const_strtab.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_const_strtab_def.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_be_class_bytes.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_be_class_list.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_be_class_map.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_be_class_range.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_debug.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_gc.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_gpio.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_json.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_m_builtin.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_math.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_os.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_path.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_solidify.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_string.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_sys.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_tasmota.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/generate/be_fixed_time.h (100%) create mode 100644 lib/libesp32/Berry/library.json rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_api.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_baselib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_bytecode.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_bytecode.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_byteslib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_class.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_class.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_code.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_code.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_constobj.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_debug.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_debug.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_debuglib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_decoder.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_exec.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_exec.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_filelib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_func.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_func.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_gc.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_gc.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_gclib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_jsonlib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_lexer.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_lexer.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_libs.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_libs.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_list.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_list.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_listlib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_map.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_map.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_maplib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_mathlib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_mem.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_mem.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_module.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_module.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_object.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_object.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_opcodes.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_oslib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_parser.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_parser.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_rangelib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_repl.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_repl.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_solidifylib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_string.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_string.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_strlib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_strlib.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_sys.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_syslib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_timelib.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_var.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_var.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_vector.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_vector.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_vm.c (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/be_vm.h (100%) rename lib/libesp32/{Berry-0.1.10 => Berry}/src/berry.h (100%) create mode 100644 lib/libesp32/Berry/src/berry_conf.h create mode 100755 lib/libesp32/Berry/testall.be create mode 100644 lib/libesp32/Berry/tests/assignment.be create mode 100644 lib/libesp32/Berry/tests/bool.be create mode 100644 lib/libesp32/Berry/tests/bytes.be create mode 100644 lib/libesp32/Berry/tests/checkspace.be create mode 100644 lib/libesp32/Berry/tests/class.be create mode 100644 lib/libesp32/Berry/tests/cond_expr.be create mode 100644 lib/libesp32/Berry/tests/debug.be create mode 100644 lib/libesp32/Berry/tests/for.be create mode 100644 lib/libesp32/Berry/tests/function.be create mode 100644 lib/libesp32/Berry/tests/json.be create mode 100644 lib/libesp32/Berry/tests/lexer.be create mode 100644 lib/libesp32/Berry/tests/list.be create mode 100644 lib/libesp32/Berry/tests/os.be create mode 100644 lib/libesp32/Berry/tests/overload.be create mode 100644 lib/libesp32/Berry/tests/relop.be create mode 100644 lib/libesp32/Berry/tests/string.be create mode 100644 lib/libesp32/Berry/tests/subobject.be create mode 100644 lib/libesp32/Berry/tests/suffix.be create mode 100644 lib/libesp32/Berry/tools/coc/.gitignore create mode 100644 lib/libesp32/Berry/tools/coc/Makefile create mode 100644 lib/libesp32/Berry/tools/coc/REEADME.md create mode 100755 lib/libesp32/Berry/tools/coc/block_builder.cpp create mode 100755 lib/libesp32/Berry/tools/coc/block_builder.h create mode 100644 lib/libesp32/Berry/tools/coc/coc_parser.cpp create mode 100644 lib/libesp32/Berry/tools/coc/coc_parser.h create mode 100644 lib/libesp32/Berry/tools/coc/coc_string.cpp create mode 100644 lib/libesp32/Berry/tools/coc/coc_string.h create mode 100755 lib/libesp32/Berry/tools/coc/hash_map.cpp create mode 100755 lib/libesp32/Berry/tools/coc/hash_map.h create mode 100644 lib/libesp32/Berry/tools/coc/macro_table.cpp create mode 100644 lib/libesp32/Berry/tools/coc/macro_table.h create mode 100755 lib/libesp32/Berry/tools/coc/main.cpp create mode 100644 lib/libesp32/Berry/tools/coc/main.h create mode 100644 lib/libesp32/Berry/tools/coc/object_block.h create mode 100644 lib/libesp32/Berry/tools/coc/str_build.cpp create mode 100644 lib/libesp32/Berry/tools/coc/str_build.h create mode 100755 lib/libesp32/Berry/tools/grammar/berry.bytecode create mode 100644 lib/libesp32/Berry/tools/grammar/berry.ebnf create mode 100755 lib/libesp32/Berry/tools/grammar/const_obj.ebnf create mode 100644 lib/libesp32/Berry/tools/grammar/json.ebnf create mode 100755 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest create mode 100755 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md create mode 100755 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/README.md create mode 100755 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json create mode 100644 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png create mode 100755 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json create mode 100755 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json create mode 100755 lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json diff --git a/lib/libesp32/Berry-0.1.10/library.properties b/lib/libesp32/Berry-0.1.10/library.properties deleted file mode 100644 index 23cdd9946..000000000 --- a/lib/libesp32/Berry-0.1.10/library.properties +++ /dev/null @@ -1,7 +0,0 @@ -name=Berry -version=0.1.10 -author=Guan Wenliang , -maintainer=Stephan Hadinger -sentence=Berry scripting language for Tasmota32 -paragraph=Berry is a ultra-lightweight dynamically typed embedded scripting language. -architectures=esp32 diff --git a/lib/libesp32/Berry-0.1.10/src/berry_conf.h b/lib/libesp32/Berry-0.1.10/src/berry_conf.h deleted file mode 100644 index f645c0338..000000000 --- a/lib/libesp32/Berry-0.1.10/src/berry_conf.h +++ /dev/null @@ -1 +0,0 @@ -#include "port/berry_conf.h" \ No newline at end of file diff --git a/lib/libesp32/Berry-0.1.10/LICENSE b/lib/libesp32/Berry/LICENSE similarity index 100% rename from lib/libesp32/Berry-0.1.10/LICENSE rename to lib/libesp32/Berry/LICENSE diff --git a/lib/libesp32/Berry/berry-logo.png b/lib/libesp32/Berry/berry-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb41908963a04e02ea5aa91d264903b1c0895e2 GIT binary patch literal 11325 zcmX9^cRbYpAOD~TDI+6Mvd5jBz2|X8WS$i{oEaINnX=CwciG`iR!C=NWn`Sl6&kX) zvSo$e`TqX!IFI-H^?tqI@7MgiU$1BUeIs2u8g?200O<4}TBZO%4h8@+$}5zlk#ct& zJL!k|F~s@_0I)J%{E@j95=m6RO@D1G{|7!U{y~m@a6sMJ#|h4*=jG@MH-$SoBYg+p zN&p}-sHdfF_VmZ^{AnMKf&6bCI+=LlhF?>I-_Fg(+28UiJx13w9m2m^Q9V3ad^YoJ z{x>&u>YZmgKBJmkG*rA|WYQXEKvF@bEL~)X99O6Njh;BMVPtOYM6-74(p*1F&26Ixs+mM}%7_X{AYe-ZHKSUsA$MZIHrv z8Bl`(#MG=(1(jk+T947U>;nV}eKr683^sOKV5!(vrwy7EM%nnZ8=zx_eEc>=A!`*)t=nB4N4aE6w9(x?&IjWN2b9dorS965e&Os9Sk! zcQKl-1Hc1369`F3>#S`-RbTQ5$AxKSpe8WhyAFtRYQeaC9Mc9G+Q_LA zEBbGqVMdf#fM-$SN|&tr_04;kyfCz|OOh#kGe!VOS)Jb22w_!O`8<8A{=WYVsLn~T zGOgBMh-50*%c;z{Y4MF-31mR$eZ_7qTX8NC^}SIw3;Ty)Ml@wF06e_L4HmB~gRt1> zrSlUo9+~~Lo-2N27i;}8v-o~-p=!+p)6%-SdTfAa(m%LjVjq&5lvga9WNGU!SUKZ9 zGv4$e1Bj6jS`GnWMiXi?CClj9!htA0HLDAYhd7wB;IaL8O_;fbztGY`b1xJM(KAKI zXu-2h)&HZZ)xIBdJtmZ%<-bjtGfE2mY6qztFHDgu&F$)flbZO46!U!vK1t+^m>kNlq50$%O|T&edCGF1qU@4C^NGqxcxXLOZLit);10qRJ*?h(VtEI`j0N^ z!V2D^eL|NB5u2yF4yRNJ&K}yVEPolvfm-12ZH2C^S~K$z*-J_{vZ$zP{%sa+I^?bY zacDgpJ-bX(E;sqWH|p|#N2_AUy1XB%+4+{qE$yX7Ez5xZ3#W_iJ=3z>_eQ^VNj|C0 zNGWXn>*%vdTNB!J?osngl?$FgWt$v@GnBY+1DSsPSMc7$s2^=-s}85r0)-)mU;0or z5%_cDep5uw`yo!}==;iy=+xp1zB}lw7WzLCx17H?TND-D`1VjGQ^NXgTRLB)vXbIT2aIFTyEVa8}E77P~g zN+2f*WB_VGo<+=KzVz`HgpG>i77M~6V=E=hoFdis6yzDySEw9cVM*?iHt%%2WEdY!^Lf_yCBh_4mD@gIMFkYog(*;OiB%)F+q z2h1Y)D=#T}rN6F~E>2N2Gn9dh|0>)({qZ*>o^w96qr4Kp+hc^ zxV?S*!B&vylxn|nn#A12ATJ|}9%Wz__d(&*6st-DSNBE|#5U(EDe@2{-_$~CFkk;& zp4WXJ;U%)%mL#e>M=a&PIN-p_5S7j1*`2VbYY#U^j5%9(=D!%*pAa4x3mrY@3c1yG zz9NE4`X$zu`9&yHgb|aPbKw9VsR{kRata0OcV{O*oF+93Kn&DV;l%Yq(fl)1o5M)( zkei4C`Wpl3vj!orXT?9 zr$2&DNWN5Bv8c_y&ivD7=&HrdHs*L}EXiBdMzM=8LqSL`O_5}qH^kRKql zptEWPWn<8ohBx~ja%+Af>1cC%DgbELCoNwhpA6XVx}F)lC*XSUx35Yj-Tu&>SL9Fe z6j$&t%C;kbDUeRr?i(FD&bT^@<2GUa?*F+Zz9oHPk(AsF8q*@RhGF6T1=3?>H6y1uYqa!Pw}emFaw9dNzmRvKO! zW!qT)BbU2W()CTwZn@G=HUCHRv3HF*0RsWBZ{{M!$l%OlIYCAi`-Cqj)V=J~6z&kV zu#*g*)*IAApaV@ujGAs2w`6c1@k<88%6R(8U2ckJ_{0o!!;Z)x_sOMu+>Wb$B10fi z+7^blewsSp|< zthTF;t(M!H$vEE_y_V?21}!4@PV?`TRcQXeV>m66Yzwn<<9z&e!LmY^)3xj-4o*ob zr%xYuL+V?1nZ9`Z;|n)f(AAzUkb|24bH?YH*M*wSM3FvueLuuw1`uBw=e-=7uWK)D*b8>#%m~ma6j#YbOtX5?)%lc`D=zv}N+z zF&!MyqkXvU8WBEQC>nZzsX_Nq+F_UNu_3s%@B0wZqWi`m%4b~=CJ27<@6$O|i_(FU$9Ik%{A4{F=!%$XdF;M`5XDScm$STTaW8Nv zZ0+lRN;gxFZ@L3-HkfOg?8Q}b#98El|5#2{hn|mG4tsArJ>2M2Kd} zLW**WYVO*y-=2Whs~tSVS%fh8l0D9BPCKuc61!es$@JJqJf+vjo9c9mq{PIt;4jg; zVYt>OvwsE;g3h`HrsWPs&!V$P;-oEb>A!auY~$V_sAGPou1+@w`|g{*TDWnn0AnXB z!dEt`F;62GQt{Ubg zCPzt|1>bs1sT2=*oBlO`v741M$;nPb_*c%RDkF|Z!YZ%izwgm98?*A4N-s3>?^j&$ z5Y9*5U+^H?(t%BKvZs$}+%#l%BMPrb zSM`_d*@za*_P2IJ|G=EIVc&40A0Ox_lcwE$MsfU$iXNwz#D2&)@;5N)JiKksYr@jk z%(?edAqWL!P(d1n4qSFFo(xI0dzY2Z(I!SrXVE+2FgUiq&EudP*022i6W1EtCVMO( z)@HC$=Bo?@35lwHgPR!lV9PsywLvwqP}&|dj$OUvk4&@yeXcK8;+I=y9X=?-gA@Zt z8sh7osw*l~EBd!b>WYOjHH||8!NTWivMujgLom8+jU}5|AC1`Mtre!;{w}Dj7#(dZ zXD6S-7JQO@7H|`O@Qt_w3vm$_Z4XK{dA-&>M*dY5#@{%S&cAhgRC%)=!?W3m>~y zz+*#F4y+^=sDk-MbD+z=2U=MsNZRvTcsV$!xQJ4SyM~Zc{rtRO?6I5ndAt4IN$yR% zb>ipxsjo?fUe9-bCmz|S)dabM-v5veF&gMdy4GA1fhG7LpHJH;mh*tq890kXGpzlJ z?8b^EJEIQmKOM@Kjc|d){PDJEw9KbA%O;D$NGiBDFHy2O$a4kW_-cqZ`aNbF8muR4 zM*LR2U^NlD!aI$2<^4hJ%o-mT9dCbG`?tWU9p9o{no_xM&Ui3{i{putFrswdb`=Q zy!QU`xH!(?<($!kVHT()SX{$GGs}x*ew}}s4rZkRSNRg^_Fx(Q+_ktUT{i|#3R0DW zZ@!*hK^5XT6)f*yd$k_@AgtILCcgJ^k&rMyur<`8Bx+3U2LO1{qpXIG-z&6DZ%A*bj=nWeiN-gn^xn_+A3|z#Zst|~OSWFNb2b$DRK!hj z@EYNW6#uaKhP^dLI%+YyY-Q{|e?z0y;476|lm+pn27ZAiu!e7JqsF9gRp93qx1w)F z!y)R8;h)V(rHik_^7jVILE5Kr=8t1D9O!7O;!oTi%P1bTJQCM?Z*ng{70U(6)2*vGk$Dl_2^90ltDz45!QO^QRA%=^z;BT00@) zg8~Di>4<+>$t`8@l?t{W`G?zFkFhaJF_RK|S?aLthx^EJCFBzOpu@P*x0G`EI(2E; zh5F1zq_L34A68uN8~Pwib%raP@*~=@gr}no%O(ed3yOxH=$iA!l_>KQlt0OXY+zH1 zO}M$l(RJarR=KRijKsyMnL96%{>*-SskgwdfP@Mu@zBBL2DyiX8u^*H!M&Z?!R?Ib zir}#fDK^i%V9H^*-oeg#4BwU?tTK8}e%heK*K}K4=V`jV!N!#br z(b`j((&aHd<7W9)tc&s_-^9fDqL2Grg$U<2Fxc`}QBd#02Onq6b=OU-?}6K5J{V0Z zpIVRgjsD81F?{UcPxtF*WO@94OfiTD?q$?0EovN&*5FD*i8#hTuXTWV+RlZ@e+mU1 zYr9uiw&39KrBf@c3Hnz=R(Ai$bH0NyJ-Rjs#I;8Wm+TFqqU$hyXV`9NGpTjoMxe^Y z5p&Nx~A~S`uDtG(LYcMm)jd~s$r@78{lq-ovrY+15M>mwj3?$ z(#&J@j?@NuHIS4ksNm)@-=~HJG)pVhqd^UBRy~Pl_4;mc4Mm$0{2<-oPnHNh#b9*9=hvcNV-%33)os~( zFeCO-KOtgQDB9`new&5_mPvYRK|!XzDyp3IW%FqYk)Gu){*{VBBOfAbOz&mEqxvFK z+rS9ygTlQtTbZpqX|n_qmZGXj>ju4%_f}1&(~%DvoGh2V@YZp+ZMw5`Ih7sAy-L&J z@zlG`_{Aha2i=w4wUlOalN$Bbs4en9lep|0HYxRoxJ6Gi1;tf0kKP*2X(Z|oM0BB) z?zf*nX*v0Dn?l$-iyT!Xi#+!+9{6a5Wx~AJy z1_GLR!N5aHA4xH1qh##SCSO03l;NchJ;V)*!8UIujj#1H?fNzwb*bo9EJ3Sb;o-++ ztu@fTAT5zxru#7$QS#c&fA zP8#eJPhR#(CdMP7Z#V?BbDz438Y%wHartY5z5J>ZD{f7csb0^=7-nJi6bwPveQ;)l zFRqsIuSu7K%;@qorTSdEdyagTTD{cl6;%Y_?=Nz%bn z3Ke@inq74WuC6rv>$ZZ~oqasEGJiR#u+MoCv|LB3==YYuQrD&VL?gZEvhDBjG5Y_S znP^}vcrYb`$>a<0>P~HlA87jW)m3VC6P9bSW;ghS{PG+rL#wf2O;|{GvwBJY0j#M!2>LtF ze6!6;@!i!CHdqo~{?F!kN09nKAjN6+k`mUOA|uLB3$~MN%G(~37uy&^@Z~FUeV4s; zQ1xlYvxOH-O9Sj|FvO0cKK9tAd|2pHpSQJK^%No&n2Z}h2paxLvr+r$eSyNIl6yH# zH5Yuc&|qkRZ}W8Zt*0^=BN%z1WoGX^L|Se|$tyvw@+FB;arSkFb$bhA)rrbu?QhbP z&%~g6PBHei@hj@uiygZ=Z+mNo_q~up~^g;vz_k8%+}cNAD-pj6MiTe|FbS~cVPGXl~CmM6@_00yQdyp zgLPS2!GnWCo{!ii1cjA#hu^IY?yuRhV(7vb2d|#o00#$mT$9<6su!t^k8_)N;o4n# z@GO4ER&tV>jo*Y^C5^?Bh?BCt4E2<5VIuzOhY@(CSX+rKksHB*c^0iW$40wNpqX-Zy{lr z5U%L_*nv@}>5xvXzPYBms-#q^1vhUPqBkxsR@l|DNznY1w(GxmwL5)rxE%f3{!e52mc7A0rT5ZG&Vy?o{2(9<4Zp?Ph0&%c zdD{*#VqGbzk}1+VJ*$c3Lr@_IrTVh>ZU*%%oazv-#Zmi;iUjd9(n!0IQjiX*_;cM$ zRaZ0j!y>T>E1qX^3Bh2E@rx`rLevH z?))yGwZ1HyJ&8$9goC{~$_-(}ikH_KKe?7=YTH5nV-V72_ za19PEAUzYzvlQheZL_ai+#_nZ{CsgoIuU8mF8g+3B&S`Kl04JdX!K#n>jD)GD1Uf* z2_HXxD|?eYlydR5k>uuUgdgMKs^LlMZ3VUk-JMyu#cR#}{8H2AKg6ZTcybBN}&gC3UFhA|fs?A&=8_4^q zK7AbX`Jw)?5`VCMNz>fQktOX`Kfe)>y}O0E-fe@J+T9T~l9c{xFkd{F{8uBDMb)?5 z-p*Ryxng^0esQvP<#IAU)IyL+5ju=<)PQ+zY~?mByE1<q*j5WG8u^z%b)cL|yP_Q$ED`gi79`rMVY4qLB zF~6)b3kz%6X_cGEts0xk9E&8#k7vcNztNhQ-4$=Rp6y(Dnba1TdhkiQV-k+AHp@R! zi`=!PhU#Uo!at4wc{TlH!PYR-!(}t3tcVra=3ZCrva+A;9v8Y{btE2t&zF&q88|GX zH*Q*==90Onjfj6Y=29YT*7{$Gsn@+e`Q;Qo2E9ypwC@6(MSnx}CnW57P4Y?&)qR zp41qsR^QzO8B&dWXGTbH?;%>_{JSSUkNChs4Bvd(A)>Q%C{16fzBglb-7-4myqDRA zFDL%$AjB5koqmFEg;|LeLXpxkSpTqVZdUAroC z!_O#EKjPXKi!O{?-%J})@4D_K#84y~?DiBJ56lj=A+r4CK=CV5FK;-4QDV@&X_F+a zpwKC^jo)>OuWhHoqzkUHM_#|o5KX>YECB3p6d0HnBH4_E_UPV z)A;1=E<1LB6-v?qLamM?ZUlH({} zvg=6QWEN+@ttgy%dN%E-t;oZsS_y>0BeCsCdW`Au_0(3ds7zG!yuKAIK$_-$Pto0p zsNRLvH1wb-otCyLQ+MnDQk5V6vqvZXI!A;|aI*3(1bD=LBzQIW`wPsjcx77Cjr!Qt zgj$eb(C&KEp6v|@=FWwy$1}vltx$Idk}K zc1o~%Xvty(O`!}^}lY6fUMoPCD+Bn0bTK)Ys z!@C)gdW!7u;!#3~WH>QIkK4*lXUv8S5i#q z&o4q;PDv@*R%sjd#}Mga_wCT%PBz9bs)1%O3O;pzduIiN+4or)R#!whN`)o8(=ir% zod$J{@ko9065bzN+uFXqa+-|?cQD(9Y^-X1ghD~0?<^$eOr;fep+9kFjpyczv#iQZ zIX=yG6Q3o-%1Y~8%gSD-P{Hm8i_#8Wg5SBy$uCfJomcE@`TYaNCO`o)>-I2WpoLe{nI2Btn|NIb`I<{qhz1p|Zhp4)Z(}&b z_3wy$=)GYb>&`(+%?(`i-FS{5A9+5cuEnCioyTNsATimH@Ky=LWba`7={CGM&3}2% z6UXPB`eQJ~jdm`*uD1U?)NIY?RDH3C(5;E#K_DKy1!f}gyoioB@pV@gh0eUblqghj z$kgT^DKx$#)%U-q$%B?paD%c3Mw@cM+PS1A{!?z!=L2ZwbDfZ%Of$Y`U};>53G*Hl zYXkzBhHq9dIQBIL4R6Q?oBy`E478_WDfmrTDjOVxjE^>RZ(FQzD(_wXLJNiF*QR%l zx)E9)y_Y9}L$pTj>8JNL!GHe4u44I;8z#4Ey~VWY9$OmA#cbEr(Q`WPHCE1_mA@E8 z^D|!s3Q`xsT2PWXMBD9#Yb@6*G3D|vMwug_*)t_dkz=5L0=?L0>%)c5j18Qoy2Nhu=;xK zCwTF!Kuh4QADbc9nk1BlBdIiWJBtpeE@2wr8;JXbzc*nd z|6$~KN`zC(uB&S}AZ;C8_MlZk&_w@mdRqD9Z7=C9|B^rsgkM1=GV)rJH6ywMX_rXf z44lFzjjpnhiPYhb<)lqB@0L6jEGwS__3QjKIhs>Hn)6YXhp#isa!d}~1RmZn%<`O; ztyFxR;o75I?YsL(suvNw@TQxm;OBf{RZmQNj!u5K|JrKb`O=uN7%XrMyG{j&eU4v9 z_iW}dL05d5urk{F5^g-m87;jqVXicdTm4i!y4$aB?BF2GC_IWDQ3e0>U*s;Lvkw4f zs6XXJs05^I!wO`Bi}V}tgK%ExW1H)kW`2=6hg2&5O_yswb!*6Ox3_4RA{!1y-VsLQpotl!XjqOR`c(TjT3 zpl#a@Y@q&WE7XaT1n5X{Tl%+~{g9u?C>ukhpIU5>r=THKD`^eR6!rQTveXE0@aC5z zW7mU*je?N8*E55)pBbTfWSvy*^|Bca9Y$K#L;BE3IepExF7RG9rDSNJ^IeG%KKNF% z+k;3Y6Zd5YP^h11--D;9(`cZR2eHZ*I?}zbyL&q>J77D*Q;F&;|6ZfC~Ms5VPU9-z>^BDZF zL@Gl5_$Q}#d3M^Z&+B7W=|3FOKb?ARa6uV(<2issEn*&QU6dM?YD7#t4z%foMv^6W z7zU1nzg+C*q=sThxVJkbMOO>_%PIAk$ag6fljx-L2FoSO7UTshmpDJEyXln6NCl)o zggJ(_t%+G^IUDa+bG1sHkh8Om>=U8$gpjn_DpMjbLrZEnN_I#fOh1>RCJMY|S$!iV zLc=!q2twg)TF2~}lE70PV)Dxj6Z9UAj|C%2N5#>XXS&?p926`NUBhDHf};lxAQF6ZqTp& zAL6O!a^2kzQMUhqk<@Lu6kT4Xiez|CYg|mCLA{IY=42XMPv@>SzcAM@Xt_Y}NHVip zKi9s^`chg`l#p|QB(Uwpah@Kbxfdgfvbi*?u}cpBU*6iQt#L{=XX?p~koS&*qzmbh z`g}rUz>Sp99eiSmlvuo9*Gid*cJG42NJK@rNw~tlLhrXWQh?f9AseJcouYr3P2I`c zy0TaQ{d9ssW#5w*AWw0%+vwUC|d z$kv6CQgoJ#HVHZgA#Cpu6O${=?$wbmNRMZu3S_kg#jL?vdr|B@l*}a>d1F{ae>B&|DkT z2KSDo*c3t&x;!~(^g%+L!nZCsMDXcwONwecIrka|LCo0xUSQvF54ol2UsjxD@{Ht( zrz_%KFJglPh4=r6GXDn;&Eu7#g*j!O*|Hsy1NI67(0)(>Bto)_C~*e_#+`sQ>@~ literal 0 HcmV?d00001 diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c b/lib/libesp32/Berry/default/be_driverlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c rename to lib/libesp32/Berry/default/be_driverlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_energylib.c b/lib/libesp32/Berry/default/be_energylib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_energylib.c rename to lib/libesp32/Berry/default/be_energylib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_gpio_lib.c b/lib/libesp32/Berry/default/be_gpio_lib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_gpio_lib.c rename to lib/libesp32/Berry/default/be_gpio_lib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_light_lib.c b/lib/libesp32/Berry/default/be_light_lib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_light_lib.c rename to lib/libesp32/Berry/default/be_light_lib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_modtab.c b/lib/libesp32/Berry/default/be_modtab.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_modtab.c rename to lib/libesp32/Berry/default/be_modtab.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_port.cpp b/lib/libesp32/Berry/default/be_port.cpp similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_port.cpp rename to lib/libesp32/Berry/default/be_port.cpp diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c b/lib/libesp32/Berry/default/be_tasmotalib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c rename to lib/libesp32/Berry/default/be_tasmotalib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c b/lib/libesp32/Berry/default/be_wirelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c rename to lib/libesp32/Berry/default/be_wirelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/berry_conf.h b/lib/libesp32/Berry/default/berry_conf.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/berry_conf.h rename to lib/libesp32/Berry/default/berry_conf.h diff --git a/lib/libesp32/Berry-0.1.10/src/port/gpio.txt b/lib/libesp32/Berry/default/gpio.txt similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/gpio.txt rename to lib/libesp32/Berry/default/gpio.txt diff --git a/lib/libesp32/Berry/examples/anon_func.be b/lib/libesp32/Berry/examples/anon_func.be new file mode 100644 index 000000000..78854ce64 --- /dev/null +++ b/lib/libesp32/Berry/examples/anon_func.be @@ -0,0 +1,20 @@ +# anonymous function and closure +def count(x) + var arr = [] + for i : 0 .. x + arr.push( + def (n) # loop variable cannot be used directly as free variable + return def () + return n * n + end + end (i) # define and call anonymous function + ) + end + return arr +end + +for xx : count(6) + print(xx()) # 0, 1, 4 ... n * n +end + +return count diff --git a/lib/libesp32/Berry/examples/bigloop.be b/lib/libesp32/Berry/examples/bigloop.be new file mode 100644 index 000000000..a3a77768b --- /dev/null +++ b/lib/libesp32/Berry/examples/bigloop.be @@ -0,0 +1,15 @@ +import time + +c = time.clock() +do + i = 0 + while i < 100000000 + i += 1 + end +end +print('while iteration 100000000 times', time.clock() - c, 's') + +c = time.clock() +for i : 1 .. 100000000 +end +print('for iteration 100000000 times', time.clock() - c, 's') diff --git a/lib/libesp32/Berry/examples/bintree.be b/lib/libesp32/Berry/examples/bintree.be new file mode 100644 index 000000000..81936f8a0 --- /dev/null +++ b/lib/libesp32/Berry/examples/bintree.be @@ -0,0 +1,60 @@ +# Reference from https://github.com/BerryMathDevelopmentTeam/BerryMath/blob/master/testscript/BinaryTree.bm + +class node + var v, l, r + def init(v, l, r) + self.v = v + self.l = l + self.r = r + end + def insert(v) + if v < self.v + if self.l + self.l.insert(v) + else + self.l = node(v) + end + else + if self.r + self.r.insert(v) + else + self.r = node (v) + end + end + end + def sort(l) + if (self.l) self.l.sort(l) end + l.push(self.v) + if (self.r) self.r.sort(l) end + end +end + +class btree + var root + def insert(v) + if self.root + self.root.insert(v) + else + self.root = node(v) + end + end + def sort() + var l = [] + if self.root + self.root.sort(l) + end + return l + end +end + +var tree = btree() +tree.insert(-100) +tree.insert(5); +tree.insert(3); +tree.insert(9); +tree.insert(10); +tree.insert(10000000); +tree.insert(1); +tree.insert(-1); +tree.insert(-10); +print(tree.sort()); diff --git a/lib/libesp32/Berry/examples/calcpi.be b/lib/libesp32/Berry/examples/calcpi.be new file mode 100644 index 000000000..053f87875 --- /dev/null +++ b/lib/libesp32/Berry/examples/calcpi.be @@ -0,0 +1,16 @@ +def cpi(n) + i = 2 + pi = 3 + while i <= n + term = 4.0 / (i * (i + 1) * (i + 2)) + if i % 4 + pi = pi + term + else + pi = pi - term + end + i = i + 2 + end + return pi +end + +print("pi =", cpi(100)) diff --git a/lib/libesp32/Berry/examples/exception.be b/lib/libesp32/Berry/examples/exception.be new file mode 100644 index 000000000..3a3098dce --- /dev/null +++ b/lib/libesp32/Berry/examples/exception.be @@ -0,0 +1,12 @@ +import debug + +def test_func() + try + compile('def +() end')() + except .. as e, v + print('catch execption:', str(e) + ' >>>\n ' + str(v)) + debug.traceback() + end +end + +test_func() diff --git a/lib/libesp32/Berry/examples/fib_rec.be b/lib/libesp32/Berry/examples/fib_rec.be new file mode 100644 index 000000000..31ed3817b --- /dev/null +++ b/lib/libesp32/Berry/examples/fib_rec.be @@ -0,0 +1,12 @@ +import time + +def fib(x) + if x <= 2 + return 1 + end + return fib(x - 1) + fib(x - 2) +end + +c = time.clock() +print("fib:", fib(38)) # minimum stack size: 78!! +print("time:", time.clock() - c, 's') diff --git a/lib/libesp32/Berry/examples/guess_number.be b/lib/libesp32/Berry/examples/guess_number.be new file mode 100644 index 000000000..6cbd07e7c --- /dev/null +++ b/lib/libesp32/Berry/examples/guess_number.be @@ -0,0 +1,26 @@ +import time +import math + +math.srand(time.time()) +res = math.rand() % 100 +max_test = 7 +test = -1 +idx = 1 +print('Guess a number between 0 and 99. You have', max_test, 'chances.') +while test != res && idx <= max_test + test = number(input(str(idx) + ': enter the number you guessed: ')) + if type(test) != 'int' + print('This is not an integer. Continue!') + continue + elif test > res + print('This number is too large.') + elif test < res + print('This number is too small.') + end + idx = idx + 1 +end +if test == res + print('You win!') +else + print('You failed, the correct answer is', res) +end diff --git a/lib/libesp32/Berry/examples/json.be b/lib/libesp32/Berry/examples/json.be new file mode 100644 index 000000000..d98dff8bb --- /dev/null +++ b/lib/libesp32/Berry/examples/json.be @@ -0,0 +1,4 @@ +import json +print(json.load('{"key": "value"}')) +print(json.dump({'test key': nil})) +print(json.dump({'key1': nil, 45: true}, 'format')) diff --git a/lib/libesp32/Berry/examples/lambda.be b/lib/libesp32/Berry/examples/lambda.be new file mode 100644 index 000000000..1d0b709bb --- /dev/null +++ b/lib/libesp32/Berry/examples/lambda.be @@ -0,0 +1,8 @@ +# simple lambda example +print((/a b c-> a * b + c)(2, 3, 4)) + +# Y-Combinator and factorial functions +Y = /f-> (/x-> f(/n-> x(x)(n)))(/x-> f(/n-> x(x)(n))) +F = /f-> /x-> x ? f(x - 1) * x : 1 +fact = Y(F) +print('fact(10) == ' .. fact(10)) diff --git a/lib/libesp32/Berry/examples/listdir.be b/lib/libesp32/Berry/examples/listdir.be new file mode 100644 index 000000000..2dd880118 --- /dev/null +++ b/lib/libesp32/Berry/examples/listdir.be @@ -0,0 +1,16 @@ +import os + +def scandir(path) + print('path: ' + path) + for name : os.listdir(path) + var fullname = os.path.join(path, name) + if os.path.isfile(fullname) + print('file: ' + fullname) + else + print('path: ' + fullname) + scandir(fullname) + end + end +end + +scandir('.') diff --git a/lib/libesp32/Berry/examples/qsort.be b/lib/libesp32/Berry/examples/qsort.be new file mode 100644 index 000000000..b09b65672 --- /dev/null +++ b/lib/libesp32/Berry/examples/qsort.be @@ -0,0 +1,42 @@ +def qsort(data) + # do once sort + def once(left, right) + var pivot = data[left] # use the 0th value as the pivot + while left < right # check if sort is complete + # put the value less than the pivot to the left + while left < right && data[right] >= pivot + right -= 1 # skip values greater than pivot + end + data[left] = data[right] + # put the value greater than the pivot on the right + while left < right && data[left] <= pivot + left += 1 # skip values less than pivot + end + data[right] = data[left] + end + # now we have the index of the pivot, store it + data[left] = pivot + return left # return the index of the pivot + end + # recursive quick sort algorithm + def _sort(left, right) + if left < right # executed when the array is not empty + var index = once(left, right) # get index of pivot for divide and conquer + _sort(left, index - 1) # sort the data on the left + _sort(index + 1, right) # sort the data on the right + end + end + # start quick sort + _sort(0, data.size() - 1) + return data +end + +import time, math +math.srand(time.time()) # sse system time as a random seed +data = [] +# put 20 random numbers into the array +for i : 1 .. 20 + data.push(math.rand() % 100) +end +# sort and print +print(qsort(data)) diff --git a/lib/libesp32/Berry/examples/repl.be b/lib/libesp32/Berry/examples/repl.be new file mode 100644 index 000000000..aac26b0a1 --- /dev/null +++ b/lib/libesp32/Berry/examples/repl.be @@ -0,0 +1,61 @@ +do + def ismult(msg) + import string + return string.split(msg, -5)[1] == '\'EOS\'' + end + + def multline(src, msg) + if !ismult(msg) + print('syntax_error: ' + msg) + return + end + while true + try + src += '\n' + input('>> ') + return compile(src) + except 'syntax_error' as e, m + if !ismult(m) + print('syntax_error: ' + m) + return + end + end + end + end + + def parse() + var fun, src = input('> ') + try + fun = compile('return (' + src + ')') + except 'syntax_error' as e, m + try + fun = compile(src) + except 'syntax_error' as e, m + fun = multline(src, m) + end + end + return fun + end + + def run(fun) + try + var res = fun() + if res print(res) end + except .. as e, m + import debug + print(e .. ': ' .. m) + debug.traceback() + end + end + + def repl() + while true + var fun = parse() + if fun != nil + run(fun) + end + end + end + + print("Berry Berry REPL!") + repl() +end diff --git a/lib/libesp32/Berry/examples/string.be b/lib/libesp32/Berry/examples/string.be new file mode 100644 index 000000000..299834e21 --- /dev/null +++ b/lib/libesp32/Berry/examples/string.be @@ -0,0 +1,32 @@ +s = "This is a long string test. 0123456789 abcdefg ABCDEFG" +print(s) + +a = .5 +print(a) + +import string as s + +print(s.hex(0x45678ABCD, 16)) + +def bin(x, num) + assert(type(x) == 'int', 'the type of \'x\' must be integer') + # test the 'x' bits + var bits = 1 + for i : 0 .. 62 + if x & (1 << 63 - i) + bits = 64 - i + break + end + end + if type(num) == 'int' && num > 0 && num <= 64 + bits = bits < num ? num : bits + end + var result = '' + bits -= 1 + for i : 0 .. bits + result += x & (1 << (bits - i)) ? '1' : '0' + end + return result +end + +print(bin(33)) diff --git a/lib/libesp32/Berry/examples/strmod.be b/lib/libesp32/Berry/examples/strmod.be new file mode 100644 index 000000000..8660f5b4e --- /dev/null +++ b/lib/libesp32/Berry/examples/strmod.be @@ -0,0 +1,7 @@ +import string + +print(string.format('%.3d', 12)) +print(string.format('%.3f', 12)) +print(string.format('%20.7f', 14.5)) +print(string.format('-- %-40s ---', 'this is a string format test')) +print(string.format('-- %40s ---', 'this is a string format test')) diff --git a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h b/lib/libesp32/Berry/generate/be_const_strtab.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h rename to lib/libesp32/Berry/generate/be_const_strtab.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h b/lib/libesp32/Berry/generate/be_const_strtab_def.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h rename to lib/libesp32/Berry/generate/be_const_strtab_def.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_bytes.h b/lib/libesp32/Berry/generate/be_fixed_be_class_bytes.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_bytes.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_bytes.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_list.h b/lib/libesp32/Berry/generate/be_fixed_be_class_list.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_list.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_list.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_map.h b/lib/libesp32/Berry/generate/be_fixed_be_class_map.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_map.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_map.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_range.h b/lib/libesp32/Berry/generate/be_fixed_be_class_range.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_range.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_range.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h b/lib/libesp32/Berry/generate/be_fixed_debug.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h rename to lib/libesp32/Berry/generate/be_fixed_debug.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_gc.h b/lib/libesp32/Berry/generate/be_fixed_gc.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_gc.h rename to lib/libesp32/Berry/generate/be_fixed_gc.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_gpio.h b/lib/libesp32/Berry/generate/be_fixed_gpio.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_gpio.h rename to lib/libesp32/Berry/generate/be_fixed_gpio.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_json.h b/lib/libesp32/Berry/generate/be_fixed_json.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_json.h rename to lib/libesp32/Berry/generate/be_fixed_json.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_m_builtin.h b/lib/libesp32/Berry/generate/be_fixed_m_builtin.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_m_builtin.h rename to lib/libesp32/Berry/generate/be_fixed_m_builtin.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_math.h b/lib/libesp32/Berry/generate/be_fixed_math.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_math.h rename to lib/libesp32/Berry/generate/be_fixed_math.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h b/lib/libesp32/Berry/generate/be_fixed_os.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h rename to lib/libesp32/Berry/generate/be_fixed_os.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h b/lib/libesp32/Berry/generate/be_fixed_path.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h rename to lib/libesp32/Berry/generate/be_fixed_path.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_solidify.h b/lib/libesp32/Berry/generate/be_fixed_solidify.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_solidify.h rename to lib/libesp32/Berry/generate/be_fixed_solidify.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_string.h b/lib/libesp32/Berry/generate/be_fixed_string.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_string.h rename to lib/libesp32/Berry/generate/be_fixed_string.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h b/lib/libesp32/Berry/generate/be_fixed_sys.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h rename to lib/libesp32/Berry/generate/be_fixed_sys.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_tasmota.h b/lib/libesp32/Berry/generate/be_fixed_tasmota.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_tasmota.h rename to lib/libesp32/Berry/generate/be_fixed_tasmota.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h b/lib/libesp32/Berry/generate/be_fixed_time.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h rename to lib/libesp32/Berry/generate/be_fixed_time.h diff --git a/lib/libesp32/Berry/library.json b/lib/libesp32/Berry/library.json new file mode 100644 index 000000000..c1a6bf633 --- /dev/null +++ b/lib/libesp32/Berry/library.json @@ -0,0 +1,29 @@ +{ + "name":"Berry", + "description":"Berry scripting language for Tasmota32", + "keywords":"berry, script", + "authors": + { + "name": "Guan Wenliang , ", + "maintainer": true + }, + "repository": + { + "type": "git", + "url": "https://github.com/Skiars/berry" + }, + "version": "7.0", + "license": "MIT License", + "frameworks": "*", + "platforms": "*", + "build": { + "srcFilter": [ + "+<*.c>", + "+<../default/*.c>", + "+<../default/*.cpp>", + "+<../default/*.hpp>", + "+<*.cpp>", + "+<*.h>" + ] + } +} \ No newline at end of file diff --git a/lib/libesp32/Berry-0.1.10/src/be_api.c b/lib/libesp32/Berry/src/be_api.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_api.c rename to lib/libesp32/Berry/src/be_api.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_baselib.c b/lib/libesp32/Berry/src/be_baselib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_baselib.c rename to lib/libesp32/Berry/src/be_baselib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_bytecode.c b/lib/libesp32/Berry/src/be_bytecode.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_bytecode.c rename to lib/libesp32/Berry/src/be_bytecode.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_bytecode.h b/lib/libesp32/Berry/src/be_bytecode.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_bytecode.h rename to lib/libesp32/Berry/src/be_bytecode.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_byteslib.c b/lib/libesp32/Berry/src/be_byteslib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_byteslib.c rename to lib/libesp32/Berry/src/be_byteslib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_class.c b/lib/libesp32/Berry/src/be_class.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_class.c rename to lib/libesp32/Berry/src/be_class.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_class.h b/lib/libesp32/Berry/src/be_class.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_class.h rename to lib/libesp32/Berry/src/be_class.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_code.c b/lib/libesp32/Berry/src/be_code.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_code.c rename to lib/libesp32/Berry/src/be_code.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_code.h b/lib/libesp32/Berry/src/be_code.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_code.h rename to lib/libesp32/Berry/src/be_code.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_constobj.h b/lib/libesp32/Berry/src/be_constobj.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_constobj.h rename to lib/libesp32/Berry/src/be_constobj.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_debug.c b/lib/libesp32/Berry/src/be_debug.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_debug.c rename to lib/libesp32/Berry/src/be_debug.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_debug.h b/lib/libesp32/Berry/src/be_debug.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_debug.h rename to lib/libesp32/Berry/src/be_debug.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_debuglib.c b/lib/libesp32/Berry/src/be_debuglib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_debuglib.c rename to lib/libesp32/Berry/src/be_debuglib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_decoder.h b/lib/libesp32/Berry/src/be_decoder.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_decoder.h rename to lib/libesp32/Berry/src/be_decoder.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_exec.c b/lib/libesp32/Berry/src/be_exec.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_exec.c rename to lib/libesp32/Berry/src/be_exec.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_exec.h b/lib/libesp32/Berry/src/be_exec.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_exec.h rename to lib/libesp32/Berry/src/be_exec.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_filelib.c b/lib/libesp32/Berry/src/be_filelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_filelib.c rename to lib/libesp32/Berry/src/be_filelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_func.c b/lib/libesp32/Berry/src/be_func.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_func.c rename to lib/libesp32/Berry/src/be_func.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_func.h b/lib/libesp32/Berry/src/be_func.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_func.h rename to lib/libesp32/Berry/src/be_func.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_gc.c b/lib/libesp32/Berry/src/be_gc.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_gc.c rename to lib/libesp32/Berry/src/be_gc.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_gc.h b/lib/libesp32/Berry/src/be_gc.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_gc.h rename to lib/libesp32/Berry/src/be_gc.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_gclib.c b/lib/libesp32/Berry/src/be_gclib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_gclib.c rename to lib/libesp32/Berry/src/be_gclib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_jsonlib.c b/lib/libesp32/Berry/src/be_jsonlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_jsonlib.c rename to lib/libesp32/Berry/src/be_jsonlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_lexer.c b/lib/libesp32/Berry/src/be_lexer.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_lexer.c rename to lib/libesp32/Berry/src/be_lexer.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_lexer.h b/lib/libesp32/Berry/src/be_lexer.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_lexer.h rename to lib/libesp32/Berry/src/be_lexer.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_libs.c b/lib/libesp32/Berry/src/be_libs.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_libs.c rename to lib/libesp32/Berry/src/be_libs.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_libs.h b/lib/libesp32/Berry/src/be_libs.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_libs.h rename to lib/libesp32/Berry/src/be_libs.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_list.c b/lib/libesp32/Berry/src/be_list.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_list.c rename to lib/libesp32/Berry/src/be_list.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_list.h b/lib/libesp32/Berry/src/be_list.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_list.h rename to lib/libesp32/Berry/src/be_list.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_listlib.c b/lib/libesp32/Berry/src/be_listlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_listlib.c rename to lib/libesp32/Berry/src/be_listlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_map.c b/lib/libesp32/Berry/src/be_map.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_map.c rename to lib/libesp32/Berry/src/be_map.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_map.h b/lib/libesp32/Berry/src/be_map.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_map.h rename to lib/libesp32/Berry/src/be_map.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_maplib.c b/lib/libesp32/Berry/src/be_maplib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_maplib.c rename to lib/libesp32/Berry/src/be_maplib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_mathlib.c b/lib/libesp32/Berry/src/be_mathlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_mathlib.c rename to lib/libesp32/Berry/src/be_mathlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_mem.c b/lib/libesp32/Berry/src/be_mem.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_mem.c rename to lib/libesp32/Berry/src/be_mem.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_mem.h b/lib/libesp32/Berry/src/be_mem.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_mem.h rename to lib/libesp32/Berry/src/be_mem.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_module.c b/lib/libesp32/Berry/src/be_module.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_module.c rename to lib/libesp32/Berry/src/be_module.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_module.h b/lib/libesp32/Berry/src/be_module.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_module.h rename to lib/libesp32/Berry/src/be_module.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_object.c b/lib/libesp32/Berry/src/be_object.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_object.c rename to lib/libesp32/Berry/src/be_object.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_object.h b/lib/libesp32/Berry/src/be_object.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_object.h rename to lib/libesp32/Berry/src/be_object.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_opcodes.h b/lib/libesp32/Berry/src/be_opcodes.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_opcodes.h rename to lib/libesp32/Berry/src/be_opcodes.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_oslib.c b/lib/libesp32/Berry/src/be_oslib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_oslib.c rename to lib/libesp32/Berry/src/be_oslib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_parser.c b/lib/libesp32/Berry/src/be_parser.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_parser.c rename to lib/libesp32/Berry/src/be_parser.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_parser.h b/lib/libesp32/Berry/src/be_parser.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_parser.h rename to lib/libesp32/Berry/src/be_parser.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_rangelib.c b/lib/libesp32/Berry/src/be_rangelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_rangelib.c rename to lib/libesp32/Berry/src/be_rangelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_repl.c b/lib/libesp32/Berry/src/be_repl.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_repl.c rename to lib/libesp32/Berry/src/be_repl.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_repl.h b/lib/libesp32/Berry/src/be_repl.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_repl.h rename to lib/libesp32/Berry/src/be_repl.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_solidifylib.c b/lib/libesp32/Berry/src/be_solidifylib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_solidifylib.c rename to lib/libesp32/Berry/src/be_solidifylib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_string.c b/lib/libesp32/Berry/src/be_string.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_string.c rename to lib/libesp32/Berry/src/be_string.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_string.h b/lib/libesp32/Berry/src/be_string.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_string.h rename to lib/libesp32/Berry/src/be_string.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_strlib.c b/lib/libesp32/Berry/src/be_strlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_strlib.c rename to lib/libesp32/Berry/src/be_strlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_strlib.h b/lib/libesp32/Berry/src/be_strlib.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_strlib.h rename to lib/libesp32/Berry/src/be_strlib.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_sys.h b/lib/libesp32/Berry/src/be_sys.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_sys.h rename to lib/libesp32/Berry/src/be_sys.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_syslib.c b/lib/libesp32/Berry/src/be_syslib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_syslib.c rename to lib/libesp32/Berry/src/be_syslib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_timelib.c b/lib/libesp32/Berry/src/be_timelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_timelib.c rename to lib/libesp32/Berry/src/be_timelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_var.c b/lib/libesp32/Berry/src/be_var.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_var.c rename to lib/libesp32/Berry/src/be_var.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_var.h b/lib/libesp32/Berry/src/be_var.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_var.h rename to lib/libesp32/Berry/src/be_var.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_vector.c b/lib/libesp32/Berry/src/be_vector.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vector.c rename to lib/libesp32/Berry/src/be_vector.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_vector.h b/lib/libesp32/Berry/src/be_vector.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vector.h rename to lib/libesp32/Berry/src/be_vector.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vm.c rename to lib/libesp32/Berry/src/be_vm.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_vm.h b/lib/libesp32/Berry/src/be_vm.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vm.h rename to lib/libesp32/Berry/src/be_vm.h diff --git a/lib/libesp32/Berry-0.1.10/src/berry.h b/lib/libesp32/Berry/src/berry.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/berry.h rename to lib/libesp32/Berry/src/berry.h diff --git a/lib/libesp32/Berry/src/berry_conf.h b/lib/libesp32/Berry/src/berry_conf.h new file mode 100644 index 000000000..c0ec957c4 --- /dev/null +++ b/lib/libesp32/Berry/src/berry_conf.h @@ -0,0 +1 @@ +#include "../default/berry_conf.h" \ No newline at end of file diff --git a/lib/libesp32/Berry/testall.be b/lib/libesp32/Berry/testall.be new file mode 100755 index 000000000..57414dbc5 --- /dev/null +++ b/lib/libesp32/Berry/testall.be @@ -0,0 +1,44 @@ +#! ./berry +import os + +os.system('lcov', '-q -c -i -d . -o init.info') + +var exec = './berry' +var path = 'tests' +var testcases = os.listdir(path) +var total = 0, failed = 0 + +for i : testcases + if os.path.splitext(i)[1] == '.be' + print('\033[0;36mrun testcase: ' + i + '\033[0m') + var ret = os.system(exec, os.path.join(path, i)) + if ret != 0 + print('\033[0;31mreturn code:', ret, '\033[0m') + failed += 1 + end + total += 1 + end +end + +print('\033[0;32mtest results: ' + + str(total) + ' total, ' + str(failed) + ' failed' + + (failed ? '' : ' (all tests passed)') + + '.\033[0m') + +if failed != 0 + os.exit(-1) +end + +var cmds = [ + 'lcov -q -c -d ./ -o cover.info', + 'lcov -q -a init.info -a cover.info -o total.info', + 'lcov --remove total.info */usr/include/* -o final.info', + 'genhtml -q -o test_report --legend --title "lcov" --prefix=./ final.info', + 'rm -f init.info cover.info total.info final.info' +] + +for cmd : cmds + if os.system(cmd) + os.exit(-1) + end +end diff --git a/lib/libesp32/Berry/tests/assignment.be b/lib/libesp32/Berry/tests/assignment.be new file mode 100644 index 000000000..71bb81ebf --- /dev/null +++ b/lib/libesp32/Berry/tests/assignment.be @@ -0,0 +1,34 @@ +class Test + var a +end + +# continuous assignment of global suffix expressions +o = Test() +o.a = 100 +assert(o.a == 100) +o.a += 10 +assert(o.a == 110) + +p = Test() +p.a = Test() +p.a.a = 50 +assert(p.a.a == 50) +p.a.a += 10 +assert(p.a.a == 60) + +# continuous assignment of local suffix expressions +def test_func() + var o = Test() + o.a = 100 + assert(o.a == 100) + o.a += 10 + assert(o.a == 110) + + var p = Test() + p.a = Test() + p.a.a = 50 + assert(p.a.a == 50) + p.a.a += 10 + assert(p.a.a == 60) +end +test_func() diff --git a/lib/libesp32/Berry/tests/bool.be b/lib/libesp32/Berry/tests/bool.be new file mode 100644 index 000000000..670f9bfd8 --- /dev/null +++ b/lib/libesp32/Berry/tests/bool.be @@ -0,0 +1,18 @@ +# test cases for boolean expressions + +assert(1 != false && 1 != true) +assert(0 != false && 0 != true) +assert(!!1 == true) +assert(!!0 == false) + +a = true +b = false +assert(!!list == true) +assert(a && b == false) +assert(!(a && b)) +def test(a, b) + while !(a && b) + assert(false) + end +end +test(true, true) diff --git a/lib/libesp32/Berry/tests/bytes.be b/lib/libesp32/Berry/tests/bytes.be new file mode 100644 index 000000000..cce46120f --- /dev/null +++ b/lib/libesp32/Berry/tests/bytes.be @@ -0,0 +1,167 @@ +#- basic initialization -# +b=bytes() +assert(str(b) == "bytes('')") +b=bytes("") +assert(str(b) == "bytes('')") +b=bytes(0) +assert(str(b) == "bytes('')") +b=bytes(1) +assert(str(b) == "bytes('')") +b=bytes(-1) +assert(str(b) == "bytes('')") +assert(b.size() == 0) + +b=bytes("a") +assert(str(b) == "bytes('')") +b=bytes(3.5) +assert(str(b) == "bytes('')") +b=bytes([]) +assert(str(b) == "bytes('')") + +b=bytes("1122AAaaBBbb") +assert(str(b) == "bytes('1122AAAABBBB')") +assert(b.size() == 6) +b=bytes("112") +assert(str(b) == "bytes('11')") +b=bytes("++") +assert(str(b) == "bytes('00')") + +#- add -# +b=bytes() +b.add(0x22) +assert(str(b) == "bytes('22')") +b.add(0x12345678, 0) +assert(str(b) == "bytes('22')") +b.add(0x12345678, 1) +assert(str(b) == "bytes('2278')") +b.add(0x12345678, 2) +assert(str(b) == "bytes('22787856')") +b.add(0x12345678, 4) +assert(str(b) == "bytes('2278785678563412')") +b.add(0x12345678, -1) #- big endian -# +assert(str(b) == "bytes('227878567856341278')") +b.add(0x12345678, -2) +assert(str(b) == "bytes('2278785678563412785678')") +b.add(0x12345678, -4) +assert(str(b) == "bytes('227878567856341278567812345678')") + +#- get -# +b=bytes("000102030405") +assert(b.get(0) == 0) +assert(b.get(-1) == 0) #- could consider nil as well -# +assert(b.get(6) == 0) #- could consider nil as well -# +assert(b.get(1) == 1) +assert(b.get(5) == 5) + +assert(b.get(1,0) == nil) +assert(b.get(1,1) == 0x01) +assert(b.get(1,2) == 0x0201) +assert(b.get(1,4) == 0x04030201) +assert(b.get(1,-1) == 0x01) +assert(b.get(1,-2) == 0x0102) #- big endian -# +assert(b.get(1,-4) == 0x01020304) + +#- resize -# +assert(bytes().size() == 0) +b=bytes("112233") +b.resize(2) +assert(str(b) == "bytes('1122')") +assert(b.size() == 2) +b.resize(4) +assert(str(b) == "bytes('11220000')") +assert(b.size() == 4) +b.resize(20) +assert(str(b) == "bytes('1122000000000000000000000000000000000000')") +assert(b.size() == 20) +b.resize(0) +assert(str(b) == "bytes('')") +assert(b.size() == 0) + +#- clear -# +b=bytes("aabb") +b.clear() +assert(str(b) == "bytes('')") + +#- == != -# +assert(bytes() == bytes()) +assert(bytes("11") == bytes("11")) +assert(bytes("11") == bytes()..0x11) +assert(! (bytes("11") == bytes(0x12)) ) +assert(! (bytes("11") == 0x11) ) +assert(! (bytes("11") != bytes("11")) ) +assert(bytes("11") != bytes("1122")) +assert(bytes("11") != bytes("12")) +assert(bytes("11") != bytes()) + +#- + -# +b1 = bytes("1122") +b2 = bytes("334455") +b = b1 + b2 +assert(str(b1) == "bytes('1122')") +assert(str(b2) == "bytes('334455')") +assert(str(b) == "bytes('1122334455')") +b = b2 + b1 +assert(str(b) == "bytes('3344551122')") + +#- .. -# +b1 = bytes("1122") +b2 = bytes("334455") +b = b1..b2 +assert(str(b1) == "bytes('1122334455')") +assert(str(b2) == "bytes('334455')") +assert(str(b) == "bytes('1122334455')") + +#- item -# +b = bytes("334455") +assert(b[0] == 0x33) +assert(b[1] == 0x44) +assert(b[2] == 0x55) + +#- item range -# +b = bytes("00112233445566778899AABBCCDDEEFF") +assert(str(b[1..1]) =="bytes('11')") +assert(str(b[-11..1]) =="bytes('0011')") +assert(str(b[0..40]) =="bytes('00112233445566778899AABBCCDDEEFF')") +assert(str(b[1..0]) =="bytes('')") + +#- copy -# +b=bytes("112233") +b2=b.copy() +assert(str(b) =="bytes('112233')") +assert(str(b2) =="bytes('112233')") +b2.clear() +assert(str(b) =="bytes('112233')") +assert(str(b2) =="bytes('')") + +#- setitem -# +b=bytes("112233") +assert(str(b) =="bytes('112233')") +b[1]=0xAA +assert(str(b) =="bytes('11AA33')") +b[0]=0xBB +assert(str(b) =="bytes('BBAA33')") +b[2]=-1 +assert(str(b) =="bytes('BBAAFF')") + +#- resize -# +b=bytes() +b.resize(20) +assert(str(b) =="bytes('0000000000000000000000000000000000000000')") +b2=b.copy() +assert(str(b2) =="bytes('0000000000000000000000000000000000000000')") + +#- asstring -# +b=bytes() +assert(b.asstring() == '') +b=bytes("334455") +assert(b.asstring() == '3DU') +b=bytes("33456502") +assert(b.asstring() == '3Ee\x02') + +#- fromstring -# +b=bytes() +b.fromstring("Aa0") +assert(str(b) =="bytes('416130')") +b=bytes() +b.fromstring("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") +assert(str(b) =="bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')") diff --git a/lib/libesp32/Berry/tests/checkspace.be b/lib/libesp32/Berry/tests/checkspace.be new file mode 100644 index 000000000..f4079d952 --- /dev/null +++ b/lib/libesp32/Berry/tests/checkspace.be @@ -0,0 +1,35 @@ +import os + +def strfind(str, char) + var len = size(str) + for i : 0 .. len - 1 + if str[i] == char + return true + end + end + return false +end + +def checkfile(path) + var subname = os.path.splitext(path)[1] + if (subname == '.c' || subname == '.h' || + subname == '.cpp' || subname == '.be' || subname == '.json') + var f = open(path) + assert(!strfind(f.read(), '\t'), 'file \'' + path + '\' has tab character') + f.close() + end +end + +def findpath(path) + var ls = os.listdir(path) + for name : ls + var fullname = os.path.join(path, name) + if os.path.isfile(fullname) + checkfile(fullname) + elif fullname != '.' && fullname != '..' + findpath(fullname) + end + end +end + +findpath('.') diff --git a/lib/libesp32/Berry/tests/class.be b/lib/libesp32/Berry/tests/class.be new file mode 100644 index 000000000..fb310e802 --- /dev/null +++ b/lib/libesp32/Berry/tests/class.be @@ -0,0 +1,22 @@ +class Test + var maximum + def init(maximum) + self.maximum = maximum + end + def iter() # method closure upvalues test + var i = -1, maximum = self.maximum + return def () + i += 1 + if i > maximum + raise 'stop_iteration' + end + return i + end + end +end + +var sum = 0 +for i : Test(10) + sum += i +end +assert(sum == 55, 'iteraion sum is ' + str(sum) + ' (expected 55).') diff --git a/lib/libesp32/Berry/tests/cond_expr.be b/lib/libesp32/Berry/tests/cond_expr.be new file mode 100644 index 000000000..dc70fd306 --- /dev/null +++ b/lib/libesp32/Berry/tests/cond_expr.be @@ -0,0 +1,10 @@ +assert("" != 0 ? true : false) +assert(false || !(true ? false : true) && true) +var t1 = 8, t2 = false +if t1 ? 7 + t1 : t2 + var a = 'good' + assert((a == 'good' ? a + '!' : a) == 'good!') + assert((a == 'good?' ? a + '!' : a) != 'good!') +else + assert('condition expression test failed') +end diff --git a/lib/libesp32/Berry/tests/debug.be b/lib/libesp32/Berry/tests/debug.be new file mode 100644 index 000000000..9e732f6c3 --- /dev/null +++ b/lib/libesp32/Berry/tests/debug.be @@ -0,0 +1,4 @@ +import debug + +class A end +debug.attrdump(A) #- should not crash -# \ No newline at end of file diff --git a/lib/libesp32/Berry/tests/for.be b/lib/libesp32/Berry/tests/for.be new file mode 100644 index 000000000..ec4a910cd --- /dev/null +++ b/lib/libesp32/Berry/tests/for.be @@ -0,0 +1,44 @@ +var global + +global = 0 +for i : 0 .. 10 + global += i +end +assert(global == 55) + +global = 0 +for i : 0 .. 20 + if i > 10 + break + end + global += i +end +assert(global == 55) + +global = 0 +for i : 0 .. 20 + if i > 10 + continue + end + global += i +end +assert(global == 55) + +assert(def () + for i : 0 .. 20 + if i > 10 + return i + end + end + end() == 11) + +# test for "stop_iteration" exception as recurrence +def for_rec(depth) + for i : 0 .. 10 + if i == 4 && depth < 200 + for_rec(depth + 1) + end + end +end + +for_rec(0) diff --git a/lib/libesp32/Berry/tests/function.be b/lib/libesp32/Berry/tests/function.be new file mode 100644 index 000000000..81310408b --- /dev/null +++ b/lib/libesp32/Berry/tests/function.be @@ -0,0 +1,12 @@ +# CLOSE opcode test +var gbl +def func1() + var a = 'func1_a' + def func2() + return a + end + gbl = func2 + return 400000 + 500 +end +assert(func1() == 400500) +assert(gbl() == 'func1_a') diff --git a/lib/libesp32/Berry/tests/json.be b/lib/libesp32/Berry/tests/json.be new file mode 100644 index 000000000..ee009755b --- /dev/null +++ b/lib/libesp32/Berry/tests/json.be @@ -0,0 +1,53 @@ +import json + +# load tests + +def assert_load(text, value) + assert(json.load(text) == value) +end + +def assert_load_failed(text) + assert(json.load(text) == nil) +end + +assert_load('null', nil) +assert_load('true', true) +assert_load('false', false) +assert_load('123', 123) +assert_load('12.3', 12.3) +assert_load('"abc"', 'abc') +# strings +assert_load('"\\"\\\\\\/\\b\\f\\n\\r\\t"', '\"\\/\b\f\n\r\t') +assert_load('"\\u1234\\u2345\\u04aF\\u003A"', 'ሴ⍅ү:') +assert_load_failed('"\\u3fr"'); +assert_load_failed('"\\q"'); +assert_load_failed('"123'); +# list +assert_load('[1, null]', [1, nil]) +assert_load_failed('[x]') +assert_load_failed('[1, nil]') +assert_load_failed('[1, null') +# object +var o = json.load('{"key": 1}') +assert(o['key'] == 1 && o.size() == 1) +assert_load_failed('{"ke: 1}') +assert_load_failed('{"key": 1x}') +assert_load_failed('{"key"}') +assert_load_failed('{"key": 1, }') + +# dump tests + +def assert_dump(value, text, format) + assert(json.dump(value, format) == text) +end + +assert_dump(nil, 'null'); +assert_dump(true, 'true'); +assert_dump(false, 'false'); +assert_dump(1.23, '1.23'); +assert_dump('String', '"String"'); +assert_dump([1, 'x'], '[1,"x"]'); +assert_dump({1: 'x'}, '{"1":"x"}'); +assert_dump([1, 'x'], '[\n 1,\n "x"\n]', 'format'); +assert_dump({1: 'x'}, '{\n "1": "x"\n}', 'format'); +assert_dump({1: 'x', 'k': 'v'}, '{"k":"v","1":"x"}'); diff --git a/lib/libesp32/Berry/tests/lexer.be b/lib/libesp32/Berry/tests/lexer.be new file mode 100644 index 000000000..3dc34169d --- /dev/null +++ b/lib/libesp32/Berry/tests/lexer.be @@ -0,0 +1,62 @@ +import math + +def check(a, b) + assert(math.abs(a - b) < 1e-6) +end + +def test_source(src, msg) + try + compile(src) + assert(false, 'unexpected execution flow') + except .. as e, m + assert(e == 'syntax_error') + assert(m == 'string:1: ' + msg) + end +end + +#---- + this is a + mult-line comment +----# + +compile('x = 5; 0..x') +assert('\x5a' == 'Z') +assert('\132' == 'Z') +assert('\a\b\f\n\r\t\v\\\'\"\?' == '\x07\x08\x0c\x0a\x0d\x09\x0b\x5c\x27\x22\x3f') +assert(.45 == 0.45) +assert(0X10 == 16) +assert(0x10 == 16) +assert(0X1A == 26) +assert(0x1a == 26) +check(45., 45) +check(45.e-1, 4.5) +check(45.E-1, 4.5) +check(45.1e-1, 4.51) +check(45.1e2, 4510) +check(45.e2, 4500) +check(45.e+2, 4500) + +test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'') +test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'') +test_source('45..', 'unexpected symbol near \'EOS\'') +test_source('0xg', 'invalid hexadecimal number') +test_source('"\\x5g"', 'invalid hexadecimal number') +test_source('0x5g', 'malformed number') +test_source('"\\779"', 'invalid octal number') +test_source('"\n', 'unfinished string') + +var malformed_numbers = [ + '45f', + '45.f', + '45.ef', + '45.e-f', + '45.e-1f', + '45.e-1.', + '45.5.', + '0x45.', + '0x45j' +] + +for i : malformed_numbers + test_source(i, 'malformed number') +end diff --git a/lib/libesp32/Berry/tests/list.be b/lib/libesp32/Berry/tests/list.be new file mode 100644 index 000000000..a6ec7ecc7 --- /dev/null +++ b/lib/libesp32/Berry/tests/list.be @@ -0,0 +1,74 @@ +l = [1, 2, 3, 4, 5] +assert(l[0] == 1) +assert(l[1] == 2) +assert(l[2] == 3) +assert(l[3] == 4) +assert(l[4] == 5) +assert(str(l) == '[1, 2, 3, 4, 5]') + +it = l.iter() +assert(it() == 1) +assert(it() == 2) +assert(it() == 3) +assert(it() == 4) +assert(it() == 5) + +l.insert(0, 10) +assert(l[0] == 10) +assert(l.size() == 6) +l.remove(0) +assert(l.size() == 5) +assert(l[0] == 1) +l.setitem(0, 42) +assert(l[0] == 42) +assert(l.item(2) == 3) +l.resize(10) +assert(l.size() == 10) +assert(l.tostring() == '[42, 2, 3, 4, 5, nil, nil, nil, nil, nil]') + +assert(([] == []) == true) +assert(([] != []) == false) +assert(([1] == [1]) == true) +assert(([1] != [1]) == false) +assert(([1] == [0]) == false) +assert(([1] != [0]) == true) +assert(([1, 2, 3] == [1, 2, 3]) == true) +assert(([1, 2, 3] != [1, 2, 3]) == false) +assert(([1, 2, 3] == [1, 2, 4]) == false) +assert(([1, 2, 3] != [1, 2, 4]) == true) +assert(([1, 2, ['w']] == [1, 2, ['w']]) == true) +assert(([1, 2, ['w']] != [1, 2, ['w']]) == false) +assert(([1, 2, ['w']] == [1, 2, ['z']]) == false) +assert(([1, 2, ['w']] != [1, 2, ['z']]) == true) +assert(([1, 2, ['w']] == [1, 2, []]) == false) +assert(([1, 2, ['w']] != [1, 2, []]) == true) + +var l = [0, 1, 2, 3] +assert(l[-1] == 3) +assert(l[-2] == 2) +var t = l.copy() +l.insert(-2, 4) +assert(t == [0, 1, 2, 3] && t != l) +assert(l == [0, 1, 4, 2, 3]) +l.remove(-2) +assert(l == [0, 1, 4, 3]) +assert(l.reverse() == [3, 4, 1, 0]) +assert(l + [5, 6] == [3, 4, 1, 0, 5, 6]) +l = [0] +assert(l .. '3' == [0, '3']) +l.push(1) +assert(l == [0, '3', 1]) +assert(l.concat() == '031') +l.pop() +assert(l == [0, '3']) +l.pop(0) +assert(l == ['3']) + +l1 = [0, 1] +l2 = [2, 3] +assert(l1+l2==[0, 1, 2, 3]) +assert(l1 == [0, 1]) +assert(l2 == [2, 3]) +assert(l1+[2] == [0, 1, 2]) +assert([-1]+l1 == [-1, 0, 1]) +assert(l1 == [0, 1]) diff --git a/lib/libesp32/Berry/tests/os.be b/lib/libesp32/Berry/tests/os.be new file mode 100644 index 000000000..37811bef1 --- /dev/null +++ b/lib/libesp32/Berry/tests/os.be @@ -0,0 +1,51 @@ +import os + +# os.path.join test +assert(os.path.join('') == '') +assert(os.path.join('abc', 'de') == 'abc/de') +assert(os.path.join('abc', '/de') == '/de') +assert(os.path.join('a', 'de') == 'a/de') +assert(os.path.join('abc/', 'de') == 'abc/de') +assert(os.path.join('abc', 'de', '') == 'abc/de/') +assert(os.path.join('abc', '', '', 'de') == 'abc/de') +assert(os.path.join('abc', '/de', 'fghij') == '/de/fghij') +assert(os.path.join('abc', 'xyz', '/de', 'fghij') == '/de/fghij') + +# os.path.split test +def split(str, list) + var res = os.path.split(str) + assert(res[0] == list[0] && res[1] == list[1], + 'unexpected results: ' .. res .. ', reference value: ' .. list) +end + +split('/', ['/', '']) +split('//', ['//', '']) +split('///', ['///', '']) +split('a/', ['a', '']) +split('a//', ['a', '']) +split('a/b/c', ['a/b', 'c']) +split('a/b/', ['a/b', '']) +split('a//b//', ['a//b', '']) +split('a/../b', ['a/..', 'b']) +split('abcd////ef/////', ['abcd////ef', '']) +split('abcd////ef', ['abcd', 'ef']) + +# os.path.splitext test +def splitext(str, list) + var res = os.path.splitext(str) + assert(res[0] == list[0] && res[1] == list[1], + 'unexpected results: ' .. res .. ', reference value: ' .. list) +end + +splitext('a.b', ['a', '.b']) +splitext('a..b', ['a.', '.b']) +splitext('/a..b', ['/a.', '.b']) +splitext('/.b', ['/.b', '']) +splitext('/..b', ['/..b', '']) +splitext('..b', ['..b', '']) +splitext('...b', ['...b', '']) +splitext('.b', ['.b', '']) +splitext('ac..b', ['ac.', '.b']) +splitext('ac.b', ['ac', '.b']) +splitext('ac/.b', ['ac/.b', '']) +splitext('ac/..b', ['ac/..b', '']) diff --git a/lib/libesp32/Berry/tests/overload.be b/lib/libesp32/Berry/tests/overload.be new file mode 100644 index 000000000..a9e72081b --- /dev/null +++ b/lib/libesp32/Berry/tests/overload.be @@ -0,0 +1,14 @@ +class test + def init() + self._a = 123 + end + def +() + return self._a + end + def ()() + return self._a + end + var _a +end + +print(test() + test()) diff --git a/lib/libesp32/Berry/tests/relop.be b/lib/libesp32/Berry/tests/relop.be new file mode 100644 index 000000000..a9a9805f1 --- /dev/null +++ b/lib/libesp32/Berry/tests/relop.be @@ -0,0 +1,40 @@ +def assert_true(status) + assert(status == true, 'assert(true) failed!') +end + +def assert_false(status) + assert(status == false, 'assert(false) failed!') +end + +assert_true(0 == 0) +assert_false(0 != 0) +assert_true(0 != 1) +assert_false(0 == 1) + + +assert_true(0.0 == 0) +assert_false(0.0 != 0) +assert_true(0.0 != 1.0) +assert_false(0.0 == 1.0) + +assert_true(nil == nil) +assert_false(nil != nil) +assert_true(true != nil) +assert_false(true == nil) +assert_true(nil != false) +assert_false(nil == false) + +assert_true(list == list) +assert_false(list == map) + +assert_true([] == []) +assert_true([true] == [true]) +assert_true([[]] == [[]]) +assert_false([[]] != [[]]) +assert_false([0] == []) +assert_false([] != []) +assert_true([] != nil) +assert_false([] == nil) + +assert_true({} != nil) +assert_false({} == nil) diff --git a/lib/libesp32/Berry/tests/string.be b/lib/libesp32/Berry/tests/string.be new file mode 100644 index 000000000..fad58f935 --- /dev/null +++ b/lib/libesp32/Berry/tests/string.be @@ -0,0 +1,30 @@ +import string as s + +assert(s.find('012345', '23') == 2) +assert(s.find('012345', '23', 1) == 2) +assert(s.find('012345', '23', 1, 3) == -1) +assert(s.find('012345', '23', 2, 4) == 2) +assert(s.find('012345', '23', 3) == -1) + +assert(s.find('012345', '') == 0) +assert(s.find('012345', '', 0, 0) == 0) +assert(s.find('012345', '', 1) == 1) +assert(s.find('012345', '', 1, 1) == 1) +assert(s.find('012345', '', 1, 0) == -1) +assert(s.find('012345', '', 6) == 6) +assert(s.find('012345', '', 7) == -1) + +assert(s.count('012345', '') == 7) +assert(s.count('012345', '', 2) == 5) +assert(s.count('012345', '', 6) == 1) + +assert(s.count('121314', '1') == 3) +assert(s.count('121314', '1', 1) == 2) +assert(s.count('121314', '1', 2) == 2) +assert(s.count('121314', '1', 1, 2) == 0) +assert(s.count('121314', '1', 1, 3) == 1) + +assert(s.split('a b c d e f', '1') == ['a b c d e f']) +assert(s.split('a b c d e f', ' ') == ['a', 'b', 'c', 'd', 'e', 'f']) +assert(s.split('a b c d e f', ' ', 2) == ['a', 'b', 'c d e f']) +assert(s.split('a b c d e f', '') == ['a b c d e f']) diff --git a/lib/libesp32/Berry/tests/subobject.be b/lib/libesp32/Berry/tests/subobject.be new file mode 100644 index 000000000..010e8af29 --- /dev/null +++ b/lib/libesp32/Berry/tests/subobject.be @@ -0,0 +1,29 @@ +class mylist : classof([]) end + +assert(issubclass(mylist, list) == true) +assert(issubclass(mylist, []) == true) +assert(issubclass(mylist(), list) == false) +assert(issubclass(mylist(), []) == false) + +assert(isinstance(mylist, list) == false) +assert(isinstance(mylist, []) == false) +assert(isinstance(mylist(), list) == true) +assert(isinstance(mylist(), []) == true) + +assert(issubclass(list, list) == true) +assert(issubclass(list, []) == true) +assert(issubclass(list(), list) == false) +assert(issubclass(list(), []) == false) + +assert(isinstance(list, list) == false) +assert(isinstance(list, []) == false) +assert(isinstance(list(), list) == true) +assert(isinstance(list(), []) == true) + +assert(issubclass(list, list) == true) +assert(issubclass(list, []) == true) +assert(issubclass(list(), list) == false) +assert(issubclass(list(), []) == false) + +assert(issubclass(list, mylist) == false) +assert(isinstance([], mylist) == false) diff --git a/lib/libesp32/Berry/tests/suffix.be b/lib/libesp32/Berry/tests/suffix.be new file mode 100644 index 000000000..222b092d8 --- /dev/null +++ b/lib/libesp32/Berry/tests/suffix.be @@ -0,0 +1,11 @@ +var keys = [ 'key1', 'key2', 'key3', 'key4' ] +var pairs = { + keys[0]: 'value1', + keys[1]: 'value2', + keys[2]: 'value3', + keys[3]: 'value4' +} + +for i : 0 .. keys.size() - 1 + assert(pairs[keys[i]] == 'value' .. i + 1) +end diff --git a/lib/libesp32/Berry/tools/coc/.gitignore b/lib/libesp32/Berry/tools/coc/.gitignore new file mode 100644 index 000000000..be1fbe796 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/.gitignore @@ -0,0 +1 @@ +coc diff --git a/lib/libesp32/Berry/tools/coc/Makefile b/lib/libesp32/Berry/tools/coc/Makefile new file mode 100644 index 000000000..773994b3c --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/Makefile @@ -0,0 +1,26 @@ +TARGET = coc +CXXFLAGS = -std=c++11 -O2 +CXX = g++ + +OBJS = coc_string.o \ + hash_map.o \ + macro_table.o \ + main.o \ + block_builder.o \ + str_build.o \ + coc_parser.o + +ifeq ($(OS), Windows_NT) # Windows + TARGET := $(TARGET).exe +endif + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(Q) $(CXX) $(OBJS) -o $@ + +$(OBJS): %.o: %.cpp + $(Q) $(CXX) $(CXXFLAGS) -c $< -o $@ + +clean: + $(Q) $(RM) $(OBJS) diff --git a/lib/libesp32/Berry/tools/coc/REEADME.md b/lib/libesp32/Berry/tools/coc/REEADME.md new file mode 100644 index 000000000..329c66d46 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/REEADME.md @@ -0,0 +1,3 @@ +# The Constant Object Compiler (coc) + +The constant object compiler (coc) is a C preprocessor that generates the corresponding C99 code based on the constant object declaration block. diff --git a/lib/libesp32/Berry/tools/coc/block_builder.cpp b/lib/libesp32/Berry/tools/coc/block_builder.cpp new file mode 100755 index 000000000..eecf9fd8e --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/block_builder.cpp @@ -0,0 +1,197 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "block_builder.h" +#include "hash_map.h" +#include "macro_table.h" +#include "object_block.h" +#include +#include + +static bool depend(const object_block *object, const macro_table *macro) +{ + auto it = object->attr.find("depend"); + if (it != object->attr.end()) { + return macro->query(it->second); + } + return true; +} + +block_builder::block_builder(const object_block *object, const macro_table *macro) +{ + m_block.name = object->name; + if (depend(object, macro)) { + m_block.type = object->type; + m_block.attr = object->attr; + for (auto i : object->data) { + if (i.second.depend.empty() || macro->query(i.second.depend)) { + m_block.data[i.first] = i.second.value; + m_strtab.push_back(i.first); + } + } + } +} + +std::string block_builder::block_tostring(const block &block) +{ + std::ostringstream ostr; + if (block.type == "map") { + ostr << map_tostring(block, block.name); + } else if (block.type == "class") { + ostr << class_tostring(block); + } else if (block.type == "vartab") { + ostr << vartab_tostring(block); + } else if (block.type == "module") { + ostr << module_tostring(block); + } + return ostr.str(); +} + +std::string block_builder::class_tostring(const block &block) +{ + bool empty_map = block.data.empty(); + std::ostringstream ostr; + hash_map map(block.data); + std::string map_name(block.name + "_map"); + + if (!empty_map) { + ostr << map_tostring(block, map_name, true) << std::endl; + } + ostr << scope(block) << " be_define_const_class(\n " + << block.name << ",\n " + << map.var_count() << ",\n " + << super(block) << ",\n " + << name(block) << "\n" + ");" << std::endl; + return ostr.str(); +} + +std::string block_builder::map_tostring(const block &block, const std::string &name, bool local) +{ + std::ostringstream ostr; + hash_map map(block.data); + + hash_map::entry_table list = map.entry_list(); + ostr << "static be_define_const_map_slots(" << name << ") {\n"; + for (auto it : list) { + ostr << " { be_const_key(" << it.key << ", " + << it.next << "), " << it.value << " }," << std::endl; + } + ostr << "};\n\n"; + + ostr << (local ? "static" : scope(block)) + << " be_define_const_map(\n " + << name << ",\n " + << list.size() << "\n" + ");" << std::endl; + return ostr.str(); +} + +std::string block_builder::vartab_tostring(const block &block) +{ + std::ostringstream ostr; + struct block idxblk; + std::vector varvec; + int index = 0; + + idxblk = block; + idxblk.data.clear(); + for (auto it : block.data) { + varvec.push_back(it.second); + it.second = "int(" + std::to_string(index++) + ")"; + idxblk.data.insert(it); + } + + ostr << map_tostring(idxblk, block.name + "_map", true) << std::endl; + ostr << "static const bvalue __vlist_array[] = {\n"; + for (auto it : varvec) { + ostr << " be_const_" << it << "," << std::endl; + } + ostr << "};\n\n"; + + ostr << "static be_define_const_vector(\n " + << block.name << "_vector,\n " + "__vlist_array,\n " + << varvec.size() << "\n" + ");" << std::endl; + return ostr.str(); +} + +std::string block_builder::module_tostring(const block &block) +{ + std::ostringstream ostr; + std::string name("m_lib" + block.name); + std::string map_name(name + "_map"); + + ostr << map_tostring(block, map_name, true) << std::endl + << "static be_define_const_module(\n " + << name << ",\n " + "\"" << block.name << "\"\n" + ");" << std::endl; + std::string scp = scope(block); + if (scp != "static") { /* extern */ + ostr << "\n" << scp + << " be_define_const_native_module(" + << block.name << ", " + << init(block) << ");" << std::endl; + } + return ostr.str(); +} + +std::string block_builder::scope(const block &block) +{ + auto it = block.attr.find("scope"); + return it != block.attr.end() && it->second == "local" ? + "static" : "BE_EXPORT_VARIABLE"; +} + +std::string block_builder::super(const block &block) +{ + auto it = block.attr.find("super"); + return it == block.attr.end() ? "NULL" : "(bclass *)&" + it->second; +} + +std::string block_builder::name(const block &block) +{ + auto it = block.attr.find("name"); + return it == block.attr.end() ? block.name : it->second; +} + +std::string block_builder::init(const block &block) +{ + auto it = block.attr.find("init"); + return it == block.attr.end() ? "NULL" : it->second; +} + +void block_builder::writefile(const std::string &filename, const std::string &text) +{ + std::string pathname(filename); + std::string otext("#include \"be_constobj.h\"\n\n" + text); + + std::ostringstream buf; + std::ifstream fin(pathname); + buf << fin.rdbuf(); + if (buf.str() != otext) { + std::ofstream fout; + fout.open(pathname, std::ios::out); + fout << otext; + fout.close(); + } +} + +void block_builder::dumpfile(const std::string &path) +{ + std::string s = block_tostring(m_block); + auto it = m_block.attr.find("file"); + std::string &name = it != m_block.attr.end() ? it->second : m_block.name; + writefile(path + "/be_fixed_" + name + ".h", s); +} + +const std::vector& block_builder::strtab() const +{ + return m_strtab; +} diff --git a/lib/libesp32/Berry/tools/coc/block_builder.h b/lib/libesp32/Berry/tools/coc/block_builder.h new file mode 100755 index 000000000..7eb82bd3e --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/block_builder.h @@ -0,0 +1,49 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __BLOCK_BUILDER_H +#define __BLOCK_BUILDER_H + +#include +#include +#include +#include "object_block.h" + +class macro_table; +class object_block; + +class block_builder { +public: + block_builder(const object_block *object, const macro_table *macro); + void dumpfile(const std::string &path); + const std::vector& strtab() const; + +private: + struct block { + std::string type; + std::string name; + std::map attr; + std::map data; + }; + + std::string block_tostring(const block &block); + std::string class_tostring(const block &block); + std::string vartab_tostring(const block &block); + std::string module_tostring(const block &block); + std::string map_tostring(const block &block, const std::string &name, bool local = false); + std::string scope(const block &block); + std::string super(const block &block); + std::string name(const block &block); + std::string init(const block &block); + void writefile(const std::string &filename, const std::string &text); + +private: + block m_block; + std::vector m_strtab; +}; + +#endif // !__BLOCK_BUILDER_H diff --git a/lib/libesp32/Berry/tools/coc/coc_parser.cpp b/lib/libesp32/Berry/tools/coc/coc_parser.cpp new file mode 100644 index 000000000..f1e86ecb5 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_parser.cpp @@ -0,0 +1,189 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "coc_parser.h" +#include + +static inline int _isalnum(int c) +{ + return isalnum(c) || c == '_'; +} + +coc_parser::coc_parser(const std::string &text) +{ + m_ptr = text.c_str(); + while (*m_ptr) { + switch (*m_ptr) { + case '@': + parse_object(); + break; + case 'b': + scan_const_string(); + break; + default: + ++m_ptr; + } + } +} + +const std::vector& coc_parser::objects() const +{ + return m_objects; +} + +const std::vector& coc_parser::strtab() const +{ + return m_strtab; +} + +void coc_parser::scan_const_string() +{ + const char prefix[] = "be_const_str_"; + const size_t len = sizeof(prefix) - 1; + if (!strncmp(m_ptr, prefix, len)) { + m_ptr += len; + const char *p = m_ptr; + while (_isalnum(*m_ptr)) + ++m_ptr; + m_strtab.push_back(std::string(p, m_ptr - p)); + } else { + ++m_ptr; + } +} + +void coc_parser::skip_space() +{ + while (isspace(*m_ptr)) + ++m_ptr; +} + +bool coc_parser::parse_char_base(int c, bool necessary) +{ + bool res = *m_ptr == c; + if (!res && necessary) + throw "error"; + if (res) + ++m_ptr; + return res; +} + +bool coc_parser::parse_char(int c, bool necessary) +{ + skip_space(); + return parse_char_base(c, necessary); +} + +bool coc_parser::parse_char_continue(int c, bool necessary) +{ + int ch; + while (((ch = *m_ptr) == ' ') || ch == '\t') + ++m_ptr; + return parse_char_base(c, necessary); +} + +std::string coc_parser::parse_word() +{ + skip_space(); + const char *p = m_ptr; + if (_isalnum(*m_ptr)) { + while (_isalnum(*(++m_ptr))); + return std::string(p, m_ptr - p); + } + throw "error"; +} + +std::string coc_parser::parse_tocomma() +{ + int c; + skip_space(); + const char *p = m_ptr; + while (((c = *m_ptr) != ',') && !isspace(c)) + ++m_ptr; + if (p == m_ptr) + throw "error"; + return std::string(p, m_ptr - p); +} + +std::string coc_parser::parse_tonewline() +{ + int c; + skip_space(); + const char *p = m_ptr; + while (((c = *m_ptr) != '\r') && c != '\n') + ++m_ptr; + if (p == m_ptr) + throw "error"; + return std::string(p, m_ptr - p); +} + +void coc_parser::parse_object() +{ + const char begin_text[] = "@const_object_info_begin"; + const size_t begin_len = sizeof(begin_text) - 1; + if (!strncmp(m_ptr, begin_text, begin_len)) { + m_ptr += begin_len; + do { + object_block object; + parse_block(&object); + m_objects.push_back(object); + } while (!parse_char('@')); + const char end_text[] = "const_object_info_end"; + const size_t end_len = sizeof(end_text) - 1; + if (strncmp(m_ptr, end_text, end_len)) + throw "error"; + m_ptr += end_len; + } else { + ++m_ptr; + } +} + +void coc_parser::parse_block(object_block *object) +{ + object->type = parse_word(); + object->name = parse_word(); + parse_attr(object); + parse_body(object); +} + +void coc_parser::parse_attr(object_block *object) +{ + skip_char('('); + parse_attr_pair(object); + while (parse_char(',')) { + parse_attr_pair(object); + } + skip_char(')'); +} + +void coc_parser::parse_attr_pair(object_block *object) +{ + std::string key = parse_word(); + skip_char(':'); + std::string value = parse_word(); + object->attr[key] = value; +} + +void coc_parser::parse_body(object_block *object) +{ + skip_char('{'); + if (!parse_char('}')) { + do { + parse_body_item(object); + } while (!parse_char('}')); + } +} + +void coc_parser::parse_body_item(object_block *object) +{ + object_block::data_value value; + std::string key = parse_tocomma(); + parse_char_continue(',', true); + value.value = parse_tocomma(); + if (parse_char_continue(',')) + value.depend = parse_tonewline(); + object->data[key] = value; +} diff --git a/lib/libesp32/Berry/tools/coc/coc_parser.h b/lib/libesp32/Berry/tools/coc/coc_parser.h new file mode 100644 index 000000000..b17a68a67 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_parser.h @@ -0,0 +1,46 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __COC_PARSER_H +#define __COC_PARSER_H + +#include +#include +#include "object_block.h" + +class coc_parser { +public: + coc_parser(const std::string &text); + const std::vector& objects() const; + const std::vector& strtab() const; + +private: + void scan_const_string(); + void skip_space(); + void skip_char(int c) { + parse_char(c, true); + } + bool parse_char_base(int c, bool necessary); + bool parse_char(int c, bool necessary = false); + bool parse_char_continue(int c, bool necessary = false); + std::string parse_word(); + std::string parse_tocomma(); + std::string parse_tonewline(); + void parse_object(); + void parse_block(object_block *object); + void parse_attr(object_block *object); + void parse_attr_pair(object_block *object); + void parse_body(object_block *object); + void parse_body_item(object_block *object); + +private: + const char *m_ptr; + std::vector m_objects; + std::vector m_strtab; +}; + +#endif // !__COC_PARSER_H diff --git a/lib/libesp32/Berry/tools/coc/coc_string.cpp b/lib/libesp32/Berry/tools/coc/coc_string.cpp new file mode 100644 index 000000000..1ae9384ac --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_string.cpp @@ -0,0 +1,48 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "coc_string.h" +#include + +namespace coc { + +uint32_t hashcode(const std::string &string) +{ + size_t len = string.size(); + const char *str = string.data(); + uint32_t hash = 2166136261u; + while (len--) + hash = (hash ^ (unsigned char)*str++) * 16777619u; + return hash; +} + +std::string escape_operator(const std::string &string) +{ + int c = string[0]; + if (string == "..") + return "opt_connect"; + if (c == '.') + return "dot_" + string.substr(1); + if (isalpha(c) || c == '_') + return string; + const static std::map tab = { + { "+", "opt_add" }, { "-", "opt_sub" }, + { "*", "opt_mul" }, { "/", "opt_div" }, + { "%", "opt_mod" }, { "&", "opt_and" }, + { "^", "opt_xor" }, { "|", "opt_or" }, + { "<", "opt_lt" }, { ">", "opt_gt" }, + { "<=", "opt_le" }, { ">=", "opt_ge" }, + { "==", "opt_eq" }, { "!=", "opt_neq" }, + { "<<", "opt_shl" }, { ">>", "opt_shr" }, + { "-*", "opt_neg" }, { "~", "opt_flip" }, + { "()", "opt_call" } + }; + auto it = tab.find(string); + return it != tab.end() ? it->second : string; +} + +} diff --git a/lib/libesp32/Berry/tools/coc/coc_string.h b/lib/libesp32/Berry/tools/coc/coc_string.h new file mode 100644 index 000000000..5fb63ce2c --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_string.h @@ -0,0 +1,18 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __COC_STRING_H +#define __COC_STRING_H + +#include + +namespace coc { + uint32_t hashcode(const std::string &string); + std::string escape_operator(const std::string &string); +} + +#endif diff --git a/lib/libesp32/Berry/tools/coc/hash_map.cpp b/lib/libesp32/Berry/tools/coc/hash_map.cpp new file mode 100755 index 000000000..988b8a03a --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/hash_map.cpp @@ -0,0 +1,161 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "hash_map.h" +#include "coc_string.h" + +#define is_empty(entry) ((entry).next == NODE_EMPTY) + +hash_map::hash_map() +{ + resize(2); +} + +hash_map::hash_map(std::map map) +{ + resize(2); + for (auto it : map) { + insert(it.first, it.second); + } +} + +hash_map::~hash_map() +{ +} + +void hash_map::resize(size_t size) +{ + entry_table bucket = m_bucket; + m_bucket.resize(size); + /* set all slot to empty */ + for (int i = 0; i < size; ++i) { + m_bucket[i].next = NODE_EMPTY; + } + m_lastfree = size - 1; + for (auto slot : bucket) { + if (!is_empty(slot)) { + insert_p(slot.key, slot.value); + } + } +} + +hash_map::entry* hash_map::findprev(entry *list, entry *slot) +{ + int next; + entry *prev = list; + for (;;) { + next = prev->next; + if (next == NODE_NULL || &m_bucket[next] == slot) { + break; + } + prev = &m_bucket[next]; + } + if (next == NODE_NULL) { + return NULL; + } + return prev; +} + +int hash_map::nextfree() +{ + while (m_lastfree >= 0) { + if (is_empty(m_bucket[m_lastfree])) { + return int(m_lastfree); + } + --m_lastfree; + } + return -1; +} + +hash_map::entry hash_map::find(const std::string &key) +{ + uint32_t hash = coc::hashcode(key); + entry null, *slot = &m_bucket[hash % m_bucket.size()]; + if (is_empty(*slot)) { + return null; + } + while (slot->key != key) { + if (slot->next == NODE_NULL) { + return null; + } + slot = &m_bucket[slot->next]; + } + return *slot; +} + +void hash_map::insert_p(const std::string &key, const std::string value) +{ + entry *slot = &m_bucket[coc::hashcode(key) % m_bucket.size()]; + if (is_empty(*slot)) { /* empty slot */ + slot->next = NODE_NULL; + } else { + int newidx = nextfree(); + /* get the main-slot index */ + entry *mainslot = &m_bucket[coc::hashcode(slot->key) % m_bucket.size()]; + entry *newslot = &m_bucket[newidx]; /* get a free slot index */ + if (mainslot == slot) { /* old is main slot */ + newslot->next = mainslot->next; + mainslot->next = newidx; + slot = newslot; + } else { /* link to list */ + entry *prev = findprev(mainslot, slot); + prev->next = newidx; /* link the previous node */ + *newslot = *slot; /* copy to new slot */ + slot->next = NODE_NULL; + } + } + slot->key = key; + slot->value = value; +} + +void hash_map::insert(const std::string &key, const std::string value) +{ + entry slot = find(key); + if (slot.next == NODE_EMPTY) { /* new entry */ + if (m_count >= m_bucket.size()) { + resize(m_bucket.size() * 2); + } + insert_p(key, value); + ++m_count; + } +} + +hash_map::entry hash_map::entry_modify(entry entry, int *var_count) +{ + entry.key = coc::escape_operator(entry.key); + if (entry.value == "var") { + entry.value = "be_const_int(" + + std::to_string(*var_count) + ")"; + ++(*var_count); + } else { + entry.value = "be_const_" + entry.value; + } + return entry; +} + +hash_map::entry_table hash_map::entry_list() +{ + entry_table list; + int var_count = 0; + + resize(m_count); + for (auto it : m_bucket) { + list.push_back(entry_modify(it, &var_count)); + } + return list; +} + +int hash_map::var_count() +{ + int count = 0; + + resize(m_count); + for (auto it : m_bucket) { + count += it.value == "var" ? 1 : 0; + } + return count; +} diff --git a/lib/libesp32/Berry/tools/coc/hash_map.h b/lib/libesp32/Berry/tools/coc/hash_map.h new file mode 100755 index 000000000..c1aca3e5b --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/hash_map.h @@ -0,0 +1,47 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __HASH_MAP +#define __HASH_MAP + +#include +#include +#include + +#define NODE_EMPTY -2 +#define NODE_NULL -1 + +class hash_map { +public: + struct entry { + std::string key; + std::string value; + int next = NODE_EMPTY; + }; + typedef std::vector entry_table; + + hash_map(); + hash_map(std::map map); + ~hash_map(); + void insert(const std::string &key, const std::string value); + hash_map::entry find(const std::string &key); + entry_table entry_list(); + int var_count(); + +private: + int nextfree(); + hash_map::entry* findprev(entry *list, entry *slot); + void resize(size_t size); + void insert_p(const std::string &key, const std::string value); + hash_map::entry entry_modify(entry entry, int *var_count); + +private: + size_t m_count = 0, m_lastfree = 0; + entry_table m_bucket; +}; + +#endif // !__HASH_MAP diff --git a/lib/libesp32/Berry/tools/coc/macro_table.cpp b/lib/libesp32/Berry/tools/coc/macro_table.cpp new file mode 100644 index 000000000..ea6d7bea7 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/macro_table.cpp @@ -0,0 +1,59 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "macro_table.h" +#include +#include +#include + +std::string macro_table::readfile(const std::string &filename) +{ + std::ifstream in(filename); + std::ostringstream tmp; + tmp << in.rdbuf(); + return tmp.str(); +} + +int macro_table::parse_value(std::string str) +{ + if (!str.length()) { + return 1; /* defined a macro name but no content, considered true */ + } + if (!(str[0] >= '0' && str[0] <= '9')) { + return 1; + } + return atoi(str.c_str()); +} + +void macro_table::scan_file(const std::string &filename) +{ + std::string str(readfile(filename)); + std::regex reg("(?:\\n|$)\\s*#define\\s+(\\w+)[ \\t]+(\\w+)"); + std::sregex_iterator it(str.begin(), str.end(), reg); + std::sregex_iterator end; + while (it != end) { + m_map[it->str(1)] = parse_value(it->str(2)); + ++it; + } +} + +bool macro_table::query(const std::string &str) const +{ + std::regex reg("(!?)(\\w+)"); + std::match_results res; + if (regex_match(str, res, reg)) { + auto it = m_map.find(res[2]); + int value = it == m_map.end() ? 0 : it->second; + return res[1] == "!" ? value == 0 : value != 0; + } + return 0; +} + +std::map macro_table::table() const +{ + return m_map; +} diff --git a/lib/libesp32/Berry/tools/coc/macro_table.h b/lib/libesp32/Berry/tools/coc/macro_table.h new file mode 100644 index 000000000..8999f63e6 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/macro_table.h @@ -0,0 +1,30 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __MACRO_TABLE_H +#define __MACRO_TABLE_H + +#include +#include +#include + +class macro_table { +public: + macro_table() {} + void scan_file(const std::string &filename); + bool query(const std::string &str) const; + std::map table() const; + +private: + std::string readfile(const std::string &filename); + int parse_value(std::string str); + +private: + std::map m_map; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/coc/main.cpp b/lib/libesp32/Berry/tools/coc/main.cpp new file mode 100755 index 000000000..0b876ba65 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/main.cpp @@ -0,0 +1,141 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "main.h" +#include "block_builder.h" +#include "coc_parser.h" +#include "macro_table.h" +#include "str_build.h" +#include +#include + +void builder::parse_all(const std::string &filename) +{ + size_t pos = filename.find_last_of("."); + std::string ext = pos < filename.size() ? filename.substr(pos) : ""; + if (ext == ".c" || ext == ".cc" || ext == ".cpp") { + std::string text = readfile(filename); + coc_parser parser(text); + push_strtab(parser.strtab()); + for (auto object : parser.objects()) { + block_builder builder(&object, m_macro); + push_strtab(builder.strtab()); + builder.dumpfile(m_output); + } + } +} + +void builder::push_strtab(const std::vector &list) +{ + for (auto s : list) + m_strmap[s] = 0; +} + +std::string builder::readfile(const std::string &filename) +{ + std::ifstream in(filename); + std::ostringstream tmp; + tmp << in.rdbuf(); + return tmp.str(); +} + +#ifndef _MSC_VER +#include +#include +#include +#else +#include +#include +#endif + +#ifndef _MSC_VER +void builder::scandir(const std::string &srcpath) +{ + DIR *dp; + struct dirent *ep; + dp = opendir(srcpath.data()); + if (dp != NULL) { + while ((ep = readdir(dp)) != NULL) { + std::string fname(ep->d_name); + parse_all(srcpath + "/" + fname); + } + closedir(dp); + } +} +#else +void builder::scandir(const std::string &srcpath) +{ + HANDLE find; + WIN32_FIND_DATA data; + find = FindFirstFile((srcpath + "/*").data(), &data); + if (find != INVALID_HANDLE_VALUE) { + do { + std::string fname(data.cFileName); + parse_all(srcpath + "/" + fname); + } while (FindNextFile(find, &data) != 0); + FindClose(find); + } +} +#endif + +void builder::build() +{ + for (auto it : m_input) { + scandir(it); + } + str_build sb(m_strmap); + sb.build(m_output); +} + +builder::builder(int argc, char **argv) +{ + m_state = Input; + for (int i = 1; i < argc; ++i) { + add_arg(argv[i]); + } + m_macro = new macro_table(); + for (auto it : m_config) { + m_macro->scan_file(it); + } +} + +builder::~builder() +{ + delete m_macro; +} + +void builder::add_arg(const std::string &arg) +{ + if (arg == "-i") { + m_state = Input; + } else if (arg == "-o") { + m_state = Output; + } else if (arg == "-c") { + m_state = Config; + } else { + switch (m_state) { + case Output: + m_output = arg; + break; + case Config: + m_config.push_back(arg); + break; + case Input: + default: + m_input.push_back(arg); + break; + } + m_state = Input; + } +} + +int main(int argc, char *argv[]) +{ + builder arg(argc, argv); + arg.build(); + return 0; +} diff --git a/lib/libesp32/Berry/tools/coc/main.h b/lib/libesp32/Berry/tools/coc/main.h new file mode 100644 index 000000000..bba65d533 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/main.h @@ -0,0 +1,45 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __MAIN_H +#define __MAIN_H + +#include +#include +#include + +class macro_table; + +class builder { +public: + builder(int argc, char **argv); + ~builder(); + void build(); + +private: + void push_strtab(const std::vector& list); + void add_arg(const std::string& arg); + std::string info_block(const std::string &text); + void parse_all(const std::string &filename); + void scandir(const std::string &srcpath); + std::string readfile(const std::string &filename); + +private: + enum arg_state { + Input, + Output, + Config + }; + std::string m_output; + std::vector m_input; + std::vector m_config; + arg_state m_state; + macro_table *m_macro; + std::map m_strmap; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/coc/object_block.h b/lib/libesp32/Berry/tools/coc/object_block.h new file mode 100644 index 000000000..474545457 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/object_block.h @@ -0,0 +1,25 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __OBJECT_BLOCK_H +#define __OBJECT_BLOCK_H + +#include +#include + +struct object_block { + struct data_value { + std::string value; + std::string depend; + }; + std::string type; + std::string name; + std::map attr; + std::map data; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/coc/str_build.cpp b/lib/libesp32/Berry/tools/coc/str_build.cpp new file mode 100644 index 000000000..affd5016e --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/str_build.cpp @@ -0,0 +1,129 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "str_build.h" +#include "coc_string.h" +#include +#include + +str_build::str_build(std::map map) +{ + size_t size = map.size() / 2; + m_count = map.size(); + m_hashtable.resize(size < 4 ? 4 : size); + for (auto it : map) { + make_ceil(it.first, it.second); + } + keywords(); +} + +str_build::~str_build() +{ +} + +void str_build::build(const std::string &path) +{ + std::string prefix(path + "/be_const_strtab"); + writefile(prefix + "_def.h", build_table_def()); + writefile(prefix + ".h", build_table_ext()); +} + +void str_build::keywords() +{ + const int opif = 50; /* note the definition in be_lexer.h */ + const static std::map tab = { + { "if", opif}, { "elif", opif + 1 }, + { "else", opif + 2 }, { "while", opif + 3 }, + { "for", opif + 4 }, { "def", opif + 5 }, + { "end", opif + 6 }, { "class", opif + 7 }, + { "break", opif + 8 }, { "continue", opif + 9 }, + { "return", opif + 10 }, { "true", opif + 11 }, + { "false", opif + 12 }, { "nil", opif + 13 }, + { "var", opif + 14 }, { "do", opif + 15 }, + { "import", opif + 16 }, { "as", opif + 17 }, + { "try", opif + 18 }, { "except", opif + 19 }, + { "raise", opif + 20 } + }; + for (auto it : tab) { + make_ceil(it.first, it.second); + } +} + +void str_build::make_ceil(const std::string &string, int extra) +{ + str_info info; + info.hash = coc::hashcode(string); + info.str = string; + info.extra = extra; + m_hashtable[info.hash % m_hashtable.size()].push_back(info); +} + +void str_build::writefile(const std::string &filename, const std::string &text) +{ + std::ostringstream buf; + std::ifstream fin(filename); + buf << fin.rdbuf(); + if (buf.str() != text) { + std::ofstream fout; + fout.open(filename, std::ios::out); + fout << text; + fout.close(); + } +} + +std::string str_build::build_table_def() +{ + std::ostringstream ostr; + for (auto bucket : m_hashtable) { + size_t size = bucket.size(); + for (size_t i = 0; i < size; ++i) { + str_info info = bucket[i]; + std::string node = coc::escape_operator(info.str); + std::string next = i < size - 1 ? + "&be_const_str_" + coc::escape_operator(bucket[i + 1].str) : + "NULL"; + ostr << "be_define_const_str(" + << node << ", \"" << info.str << "\", " + << info.hash << "u, " << info.extra << ", " + << info.str.size() << ", " << next << ");" + << std::endl; + } + } + ostr << std::endl; + ostr << "static const bstring* const m_string_table[] = {" << std::endl; + size_t size = m_hashtable.size(); + for (size_t i = 0; i < size; ++i) { + auto bucket = m_hashtable[i]; + if (bucket.size()) { + ostr << " (const bstring *)&be_const_str_" + << coc::escape_operator(bucket[0].str); + } else { + ostr << " NULL"; + } + ostr << (i < size - 1 ? "," : "") << std::endl; + } + ostr << "};" << std::endl << std::endl; + ostr << + "static const struct bconststrtab m_const_string_table = {\n" + " .size = " << size << ",\n" << + " .count = " << m_count << ",\n" << + " .table = m_string_table\n" << + "};" << std::endl; + return ostr.str(); +} + +std::string str_build::build_table_ext() +{ + std::ostringstream ostr; + for (auto bucket : m_hashtable) { + for (auto info : bucket) { + ostr << "extern const bcstring be_const_str_" + << coc::escape_operator(info.str) << ";" << std::endl; + } + } + return ostr.str(); +} diff --git a/lib/libesp32/Berry/tools/coc/str_build.h b/lib/libesp32/Berry/tools/coc/str_build.h new file mode 100644 index 000000000..3a3527409 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/str_build.h @@ -0,0 +1,39 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __BUILD_MAP_H +#define __BUILD_MAP_H + +#include +#include +#include + +class str_build +{ +public: + str_build(std::map map); + ~str_build(); + void build(const std::string &path); + +private: + void keywords(); + void make_ceil(const std::string &string, int extra = 0); + std::string build_table_def(); + std::string build_table_ext(); + void writefile(const std::string &filename, const std::string &text); + +private: + struct str_info { + uint32_t hash; + std::string str; + int extra; + }; + size_t m_count; + std::vector< std::vector > m_hashtable; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/grammar/berry.bytecode b/lib/libesp32/Berry/tools/grammar/berry.bytecode new file mode 100755 index 000000000..9e150635d --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/berry.bytecode @@ -0,0 +1,96 @@ +------------------------------------------------------------------------------- +-- the Berry's bytecode file structure (version 1) +-- +-- description +-- +-- a double dash ('--') start a line comment. +-- a: n means that the size of entity 'a' is 'n' bytes. +-- 'a: .n means that the size of entity 'a' is 'n' bits. +-- a: +-- b means that the entity 'a' is realized by the 'b' structure. +-- a: +-- b +-- c 'b' and 'c' are arranged in a compact order (one byte alignment). +-- [a] means that structure 'a' can be repeated 0 to any times. +-- [a](b) means that structure 'a' can be repeated 'b' times. +-- a | b means that the entity can be implemented by structure 'a' or 'b'. +-- a -> b is equivalent to 'a: +-- b'. +-- only the first entity is a file entity (the root). +------------------------------------------------------------------------------- + +bytecode_file: -- little endian + header + global_desc + main_function + +header: 8 + magic_number: 3 -- 0xbecdfe (berry code file) + version: 1 -- update with file structure definition + integer_size: .1 + float_size: .1 + -- reserved space + +main_function -> function + +global_desc: + builtin_count: 4 + global_count: 4 + global_name -> [ + string + ](global_count) + +function: + information: + function_name: + string + source: + string + argc: 1 -- arguments count + nstack: 1 -- number of stack size by this function + extra: 2 -- extra data + bytecode: + code_size: 4 + code_array -> [ -- bytecode array + instruction: 4 + ](code_size) + constant_table: + constant_count: 4 + [constant_value](constant_count) + proto_table: + proto_count: 4 + [function](proto_count) + upval_table: + upval_count: 1 + upvals -> [ + instack: 1 + index: 1 + ](upval_count) + debug_info: + -- reserved + +constant_value: + type: 1 -- type of value + integer | float | string | class + +string: + string_size: 2 + byte_array: string_size + +class: + class_name: + string + member_count: 4 -- number of member variables + method_count: 4 -- number of method + method_table -> [ + string -- method name + function -- method function body + ](method_count) + member_index_table -> [ + string -- member name + ](member_count) + +nil: 1 +boolean: 1 +integer: 4 or 8 +float: 4 or 8 diff --git a/lib/libesp32/Berry/tools/grammar/berry.ebnf b/lib/libesp32/Berry/tools/grammar/berry.ebnf new file mode 100644 index 000000000..dedf72a90 --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/berry.ebnf @@ -0,0 +1,45 @@ +(* program define *) +program = block; +(* block define *) +block = {statement}; +(* statement define *) +statement = class_stmt | func_stmt | var_stmt | if_stmt | while_stmt | + for_stmt | break_stmt | return_stmt | expr_stmt | import_stmt | + try_stmt | throw_stmt | ';'; +if_stmt = 'if' expr block {'elif' expr block} ['else' block] 'end'; +while_stmt = 'while' expr block 'end'; +for_stmt = 'for' ID ':' expr block 'end'; +break_stmt = 'break' | 'continue'; +return_stmt = 'return' [expr]; +(* function define statement *) +func_stmt = 'def' ID func_body; +func_body = '(' [arg_field {',' arg_field}] ')' block 'end'; +arg_field = ['*'] ID; +(* class define statement *) +class_stmt = 'class' ID [':' ID] class_block 'end'; +class_block = {'var' ID {',' ID} | func_stmt}; +import_stmt = 'import' (ID (['as' ID] | {',' ID}) | STRING 'as' ID); +(* exceptional handling statement *) +try_stmt = 'try' block except_block {except_block} 'end'; +except_block = except_stmt block; +except_stmt = 'except' (expr {',' expr} | '..') ['as' ID [',' ID]]; +throw_stmt = 'raise' expr [',' expr]; +(* variable define statement *) +var_stmt = 'var' ID ['=' expr] {',' ID ['=' expr]}; +(* expression define *) +expr_stmt = expr [assign_op expr]; +expr = suffix_expr | unop expr | expr binop expr | cond_expr; +cond_expr = expr '?' expr ':' expr; (* conditional expression *) +assign_op = '=' | '+=' | '-=' | '*=' | '/=' | + '%=' | '&=' | '|=' | '^=' | '<<=' | '>>='; +binop = '..' | '<' | '<=' | '==' | '!=' | '>' | '>=' | '||' | '&&' | + '<<' | '>>' | '&' | '|' | '^' | '+' | '-' | '*' | '/' | '%'; +unop = '-' | '!' | '~'; +suffix_expr = primary_expr {call_expr | ('.' ID) | '[' expr ']'}; +primary_expr = '(' expr ')' | simple_expr | list_expr | map_expr | anon_func | lambda_expr; +simple_expr = INTEGER | REAL | STRING | ID | 'true' | 'false' | 'nil'; +call_expr = '(' [expr {',' expr}] ')'; +list_expr = '[' {expr ','} [expr] ']'; +map_expr = '{' {expr ':' expr ','} [expr ':' expr] '}'; +anon_func = 'def' func_body; (* anonymous function *) +lambda_expr = '/' [arg_field {',' arg_field}] | {arg_field}] '->' expr; diff --git a/lib/libesp32/Berry/tools/grammar/const_obj.ebnf b/lib/libesp32/Berry/tools/grammar/const_obj.ebnf new file mode 100755 index 000000000..6c38a4262 --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/const_obj.ebnf @@ -0,0 +1,11 @@ +block = type name ['(' {attributes} ')'] '{' {data_fields} '}'; +type = 'map' | 'class' | 'module' | 'vartab'; + +attributes = name ':' name [',']; +data_fields = data_name ',' data_value [':' depend_macro] '\n'; + +(* regular expression *) +name = [_a-zA-Z]\w*; +data_name = [\._a-zA-Z]\w*; +data_value = [\w\()]+; +depend_macro = [_a-zA-Z]\w*; diff --git a/lib/libesp32/Berry/tools/grammar/json.ebnf b/lib/libesp32/Berry/tools/grammar/json.ebnf new file mode 100644 index 000000000..47c317193 --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/json.ebnf @@ -0,0 +1,5 @@ +json = value; +value = object | array | + string | number | 'true' | 'false' | 'null'; +object = '{' [ string ':' value ] { ',' string ':' value } '}'; +array = '[' [json] { ',' json } ']'; diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest new file mode 100755 index 000000000..e14b7eabc --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest @@ -0,0 +1,34 @@ + + + + + Embedded Script + none + berry,Embedded Script,__ext_.berry + Languages + Public + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md new file mode 100755 index 000000000..6f51bbcca --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md @@ -0,0 +1,7 @@ +# Change Log +All notable changes to the "none" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] +- Initial release \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/README.md b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/README.md new file mode 100755 index 000000000..e69de29bb diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json new file mode 100755 index 000000000..4be01969f --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json @@ -0,0 +1,32 @@ +{ + "comments": { + // symbol used for single line comment. Remove this entry if your language does not support line comments + "lineComment": "#", + "blockComment": [ "#-", "-#" ] + }, + // symbols used as brackets + "brackets": [ + ["[", "]"], + ["(", ")"], + ["{", "}"] + ], + // symbols that are auto closed when typing + "autoClosingPairs": [ + ["[", "]"], + ["(", ")"], + ["{", "}"], + ["\"", "\""], + ["'", "'"] + ], + // symbols that that can be used to surround a selection + "surroundingPairs": [ + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "indentationRules": { + "increaseIndentPattern": "(^((\\s*(class|while|for|if|elif|else|try|except))|(.*\\bdef))\\b((?!\\b(end)\\b).)*)$", + "decreaseIndentPattern": "^\\s*((\\b(elif|else|except|end)\\b)|(\\)))" + } +} \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2869d55527d5d5c2d77e750e9a7de2b3f283c82a GIT binary patch literal 5429 zcmV-570T*~P)rSI?3NA)+Xdt09x>_VLA)s;EjkAcyq=YVF7~A=s5^-3`p9Sasj)t0x`nMdln4Y6GgZlat^$k@gS8!SR(8)oW+&sLMC5!5N`YMXjavYqN~5 zh+KLZFhU{fBExGcnU@4$go1I!iz=JG#9?%SzM!8G3IW7QdpO8cr_q`U`3@qv;otOe znE9370*sK)Aad!(=tuXFGeSOVRq^S@=%o^1gnV^H$`MO~t~d`EAs<0pP{U6Qb|$o@ zLcW1W5H3r+bifD!M8F6^se(xP;kx8o0F00iAiACs1sEa77Z6EkO@(|2P4hn74q$|& zf>`khM6Cv3grtJF?Acw#fDw`g;;e@tlCGiw2a*ILL0Iwd&YJ3#H@GluE86lUs;l+R;Y|j%L-Tnd22)O`p*5rnvfw;8aR^rGRp)4UR z88<8jc=uiNM1-l3i;z^>(ury3iPOD)2rxpnA*B5fD*-=+T@c&)69FRx2;FE-gIMq9 z2LU4l2LC9C&Ik<)AdQ-#t_j-cvxo=s4b@xW z>41VWLW4qBGyoEac|4G=AokT@0~n!UbHT&~3wR)ViU6G4YlIELRA>|jOmablq5Xk4 zJuHZDMyN9fB>1L`3&H^h2eCfNF9D2U!&htru!M)=4n)8h9(Z(2w0#dT0TD3z30!hM z)&?C~J(+_D7~KQZ2}(bq;;D{&4zPIuB4Er0wt@jBfhdm<5g-CayWo|OlL17)=mx&B z0S+yZ01+@c2ssJ5bAT^65r9>jAOgl7`pw%Xi~s!MB^rT(PVlfn9BQm7U>s4eueYGP z&<@~d4^ODiwvRtKL&0cGb*%ag80`Z%&~zZc8H5I&j|dn?cfolz;&hP0yV`fh9vFbp4ulm0VIix} zB*$zyCtQ=e>ITGys|$z#VRjGRp z;S%=?jf8?2gd6swmRoLp4`J-yZdi5McjzsQA-iEeVQk`-^gY~=PnU&vFlrEs#tkup z9&WjxYKmb?sW&j1&U@;zz`{#IxaGg^e?NrWvTh)ZrQSfq9KyVTumZG3Q!9kkZt3AL zJTVP4Vqr8L_^Sv@(-pPEex#j};PgOC2E?WhHxn@hkpNsrSc(vKpS*BUN-L>Y7)^e- z3|z8NGRo(}ug^$ng{7^z=X@-SF=ikxm>dzxsscni>coM&>L-UkQAcxMsVz0m9m=1n z*UsEgmv3D2tt=u&Ad(wafQNh0glKX~=8Zj>uTc{Oi~tc(0!YU&nyw3KF)g9$^A&}y z1SQiJSZ{!g9D_(Lrs%o=l%oSFbkvP=7y%-nw4hkSI4$|P<{W)4Kol%$b)9~8Q@wg@ zL!CT$o6BXD)RnWMyTmegMl{y=CuR*jVspp{AVO(E`QDd5;VSK!LwDjMx zo%K)09w~iRA0K$wIzwTI+>xN9nIeufEoF{lWEsS+voF4m9&0EcnFDZ!AnFcz@2elV zSbc!{9w#Nt@Q5se*mqyz?c7ca%+;*Kooy{mUoc)uC&KBYEaH zFV7KK0I_7k)6_+7`TqEJ>+G58CbyyEdLKVOVe;_2@?a!W#{H9%oHo0$2BXOnZz{{n zWspM>lBROIz%NwA)@|p&d z;A9G4td9*krvcu8kWyKkGi4$IP6}Puznrw)>dG>Ij8X)VR{3_eWCl6pweg4QUpl{Z zoLdrrD^%bbz6O_qHmmI=aI)VrFN0Rs8E(5#MJa*EW;Hhgks5p6JiL`<2-`3K);Iy! z155&vw$LkZcFB)S=xRX}rJUvzuBHX!CdV*{LRZUBQV4oU1GuJy%7n7#72^T?G|rV= z(n13dt8g_+0YsA zT5w4=;p(U`X5M=02+G(%7^^^Jpj_r!zA3vTi-nP+5kRB{fK{oLjT(BWpRz~mYiplB z4Pi|MD$X0zrtFf=XLpPZ31YIuqS(DK4(j*Nix0=tueJ`VySc~RW{%LXsTmF8H5ITv zTv3geDy^2{2i#opNbW&vGBb&~LPk_UUB0m*&Kc7jd&)%wQ^f) z)gU4)9WHETxsN8fWuTA)u+}BaDX_pOV(QzclSB661n8rqwlI; zYNs4fc~|b(w=;U^iV27aOVi0Csr!TF0Q4amcbvH6AkOHME5-mZ^*oZsc-A;x-|?|K zt*r=7kN=OgJND&_p1ER8Ls$hu)?AYHs_`^|nU?zC=#Kq5qc5(w1`w^gWR3L6c29iWDo_+qk{RRn~&+1yD9w92d6{K%i zGpRwW0}nUiJTRbL)a~*1y_ffz0dhKv?E!i@qjXoS0z~HyDI!;=1|4$9GlxEP#zAf$ zR}{JSW}B!BqXryU07=VQEONh2$|Gre^e&@zDo$a{GFG;rx@kaw_yD=UJ%3C@-5(u! zWL{l4TXqR!MR3_y(O|<;G)hNAxtu)kc?-xBV|Ow$r`#SPYFWvhCbft>k*zy6B!sJp zs6Uc`JbCao{jsdwF`qe%YIoIXiE3yN7f|h414+x7#8R#|nf+lJcFHbbEDJ4bjIfa* zarrzo?7Vs`K9?zsfq+R#%vAbn6T`V(alo+BmCFLT}Zf>uX$R$q7 zS;ANn_<$~HS8Skui*iS)FVLw>U^E^51%a-(gz7C4NGdmJFVW1LQK~DVPf>QbDoJ@W z-qt#d((*;PqI`F(!5#f@#u{AF3#|yd-YKgv>U>dTh>Cjbg``C{C95zBbj3Bapn4Ok zQgl<3bj>#M#++^IMQ8(gTAn4FFiM)c*wn7LhWhK3JH|>@L(YU17|jZBl7_$mM7X1C zSqoE(C^U$HYJgE*h#I5bdKs!VB!#MGi}loDoDfuI2vPl(r1CA=fUzLx0c@bYdabL1 zt~GB1MoD2RoYC)4RZ0Y(Udyo522;(`Dp4;4{dK`9RyAqX$uLDWbSMk$@E6R4jM zL)}UfMk&LNkTZs*snBj1IU|IZ?`UeK38R!SHUD_^DBKY_BRAF4gz*jv2;!s=JNy$E z8-lL4gsK{Z3Q{gK&AmaS!H5>sFfl=JY4Q-v{_xhDz6ys%xfpuzLSf}k)p z)o#I@4Z`u(gaRqw>o#DNy@OHXKWM3SlGiT=uowUI_yP=N&`704d!Ut*y{WVj5=?mFjd2vNz|A#i#pHJ6)Q^aT-2KF57=*c{}sXI zei0*c*nvptgXAu#6_+s9gqQy^<~*{}s*<~TQ9bQh{R6>h1^}!HF8m_$M>ejwtYmM^ zkV%x7<8TocRYrFQi#)L+_!gR3MTz^usNIpAu_3%Z%xfSkz`_ZLWe=j0H65Zhox|vf zJCe|#lRb#OqzQ{zeNaCzE-87FjypvS2kQVbQxMmc{N1Kw8#DTchS97Xx8^||0gxGp zp6{RUKI;RBnYv=X&Y1Z{0Z6$Z((^sBlgs~n>!9@8iER!F9~wr}%~1o8P%jV@NBsT$ zap|{|d0RW;DP*%_(8Xx!09AS=3JZDKBD-w@Ic z(&UCcXU7P1M`!grH^l$(q2IBar~zUVd1Oxz>G{x#Zl!*HUYI*(-hw(3jHcgl(bKw? zt471Ke+O zDa+9|slmwMEs~*2u7{dS(tT5upmtkJM|uXoe!$utSwwr$h=sMP!r9WBqJc#drh6Zf z8W&7;;i!wxeWgA=@QC9r&$wzqO%ukvN#;YzuL#6T1g4Krwn2EoMwt?b1SB(2qs=sj z3(1W{vfqt4dxfs^CZAmJC44oFGYjU$I&bUc`r^Z}R{qHB<;o`Aic%^}$|*{Lwr|w* zv7%p0u|Nom#sw=`edhb)+v=}J?sItrbJ`V`e1nl3Vl$v{wVN6ygk3X(Be()sFnK;f z=)~FochI+S@w}fY5zj=R^9|}BfDug2QB)Nm*39q zs6RdbrHhx~bXKdqIfu~zSy5O(80w*n2LUtyX~Ya%jaK^YH`o8t_k zH5ikd-y_t5pq6Oxct(Q&mRu~O!3IV%I%it>IrkAt%^j`Jb)*%+=OjD}tFI*h3H6fY ziN_R~iJ4twJw`D7YE@J_sGFX79N7XgX|QPm#%}_-1|XrmL)G!%LCg$B10*HTi>P`~ zr@r$j*E&)LQC#C;rt?`ekP8Z39*|vktV#qia~KVfRR9Tfsjk~NZPEk zf~xAZTKl({?yjH|NxNXPayhL$hn<#5HRioWywH^fdc$h)5ly0Te1fUV;hte10_ONeu|A7#&{F~z}ObLTHBi* z8dwbjVGWNWFc>?aoHt-XfDkY;fU;nqEW;@QAz(!K3J4*O$(|Lt{%0Wfl66AoF2HE}`0*w8-WyOGrzRJBtvnj436a|b~fmt+AmJ!CbL_^h9 z$O+L=4;Wp8Nl=~(%rRRINckYbP{7C$Oma!eF{jMgC)XtRi}kT#76yX=qgXhL!kjZU z0B#ufL-+|8y#uslpgh$EsLMXhhB-FOxsK^dfDw@HLYcVdL>r{T0-J!Ae1A*rb~zAi fO+Y70{}*5YlNG>QUKt?D00000NkvXXu0mjf`LfK> literal 0 HcmV?d00001 diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json new file mode 100755 index 000000000..8faf7e245 --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json @@ -0,0 +1,52 @@ +{ + "name": "berry", + "displayName": "Berry Script Language", + "description": "A small embedded script language.", + "version": "0.1.0", + "icon": "berry-icon.png", + "publisher": "skiars", + "engines": { + "vscode": "^1.15.1" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [ + { + "id": "berry", + "aliases": [ + "Berry", + "berry" + ], + "extensions": [ + ".be" + ], + "configuration": "./berry-configuration.json" + }, + { + "id": "berry-bytecode", + "aliases": [ + "Berry Bytecode", + "berry bytecode" + ], + "extensions": [ + "berry.bytecode" + ] + } + ], + "grammars": [ + { + "language": "berry", + "scopeName": "source.berry", + "path": "./syntaxes/berry.json" + }, + { + "language": "berry-bytecode", + "scopeName": "source.berry.bytecode", + "path": "./syntaxes/bytecode.json" + } + ] + }, + "__metadata": null +} \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json new file mode 100755 index 000000000..1cd1d7cfd --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json @@ -0,0 +1,109 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Berry", + "patterns": [ + { + "include": "#controls" + }, + { + "include": "#strings" + }, + { + "include": "#comment-block" + }, + { + "include": "#comments" + }, + { + "include": "#keywords" + }, + { + "include": "#function" + }, + { + "include": "#member" + }, + { + "include": "#identifier" + }, + { + "include": "#number" + }, + { + "include": "#operator" + } + ], + "repository": { + "controls": { + "patterns": [{ + "name": "keyword.control.berry", + "match": "\\b(if|elif|else|for|while|do|end|break|continue|return|try|except|raise)\\b" + }] + }, + "strings": { + "patterns": [ + { + "name": "string.quoted.double.berry", + "match": "\"(\\\\.|[^\"])*\"" + }, + { + "name": "string.quoted.single.berry", + "match": "'(\\\\.|[^'])*'" + } + ] + }, + "comment-block": { + "name": "comment.berry", + "begin": "\\#\\-", + "end": "\\-#", + "patterns": [{}] + }, + "comments": { + "name": "comment.line.berry", + "begin": "\\#", + "end": "\\n", + "patterns": [{}] + }, + "keywords": { + "patterns": [{ + "name": "keyword.berry", + "match": "\\b(var|def|class|true|false|nil|self|super|import|as)\\b" + }] + }, + "identifier": { + "patterns": [{ + "name": "identifier.berry", + "match": "\\b[_A-Za-z]\\w+\\b" + }] + }, + "number": { + "patterns": [{ + "name": "constant.numeric.berry", + "match": "0x[a-fA-F0-9]+|\\d+|(\\d+\\.?|\\.\\d)\\d*([eE][+-]?\\d+)?" + }] + }, + "operator": { + "patterns": [{ + "name": "keyword.operator.berry", + "match": "\\(|\\)|\\[|\\]|\\.|-|\\!|~|\\*|/|%|\\+|&|\\^|\\||<|>|=|:" + }] + }, + "member": { + "patterns": [{ + "match": "\\.([a-zA-Z_][a-zA-Z0-9_]*)", + "captures": { + "0": { + "name": "entity.other.attribute-name.berry" + } + } + }] + }, + "function": { + "patterns": [{ + "name": "entity.name.function.berry", + "match": "\\b([a-zA-Z_][a-zA-Z0-9_]*(?=\\s*\\())" + }] + } + }, + "scopeName": "source.berry" +} \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json new file mode 100755 index 000000000..4bd10a843 --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Berry", + "patterns": [ + { + "include": "#comments" + }, + { + "include": "#keywords" + }, + { + "include": "#number" + }, + { + "include": "#operator" + }, + { + "include": "#entity" + } + ], + "repository": { + "comments": { + "name": "comment.line.berry.bytecode", + "begin": "\\--", + "end": "\\n", + "patterns": [{}] + }, + "keywords": { + "patterns": [{ + "name": "keyword.berry.bytecode", + "match": "or" + }] + }, + "number": { + "patterns": [{ + "name": "constant.numeric.berry.bytecode", + "match": "\\b((0x)?[0-9]+)\\b" + }] + }, + "operator": { + "patterns": [ + { + "name": "keyword.operator.berry.bytecode", + "match": "\\(|\\)|:|\\[|\\]|\\||->" + } + ] + }, + "entity": { + "patterns": [ + { + "name": "entity.name.function.berry", + "match": "^\\s*\\w+(?=\\s*(:|->))" + } + ] + } + }, + "scopeName": "source.berry.bytecode" +} \ No newline at end of file From 63a672e9dd5f03b191abfaea66275a7984ae2c14 Mon Sep 17 00:00:00 2001 From: Barbudor Date: Mon, 12 Apr 2021 21:16:13 +0200 Subject: [PATCH 58/67] allow DEVICE_NAME in user_config_override --- tasmota/settings.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 11f835592..9b52b867e 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -750,7 +750,11 @@ void SettingsDefaultSet2(void) { SettingsUpdateText(SET_FRIENDLYNAME2, PSTR(FRIENDLY_NAME"2")); SettingsUpdateText(SET_FRIENDLYNAME3, PSTR(FRIENDLY_NAME"3")); SettingsUpdateText(SET_FRIENDLYNAME4, PSTR(FRIENDLY_NAME"4")); + #ifdef DEVICE_NAME + SettingsUpdateText(SET_DEVICENAME, PSTR(DEVICE_NAME)); + #else SettingsUpdateText(SET_DEVICENAME, SettingsText(SET_FRIENDLYNAME1)); + #endif SettingsUpdateText(SET_OTAURL, PSTR(OTA_URL)); // Power From ecd9c37db98938b1d84e6dd1b7e87a05e7a7c97f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 13 Apr 2021 10:15:35 +0200 Subject: [PATCH 59/67] Fix Gui save settings regression (#11698) --- tasmota/xdrv_01_webserver.ino | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e61df582f..e12256151 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1505,7 +1505,7 @@ uint16_t WebGetGpioArg(uint32_t i) { void TemplateSaveSettings(void) { char tmp[TOPSZ]; // WebGetArg NAME and GPIO/BASE/FLAG byte value - char command[300]; // Template command string + char command[300]; // Template command string WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // NAME snprintf_P(command, sizeof(command), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp); @@ -1800,17 +1800,17 @@ void HandleWifiConfiguration(void) { } void WifiSaveSettings(void) { - char tmp1[CMDSZ]; + char tmp1[TOPSZ]; WebGetArg(PSTR("h"), tmp1, sizeof(tmp1)); // Host name - char tmp2[CMDSZ]; + char tmp2[TOPSZ]; WebGetArg(PSTR("c"), tmp2, sizeof(tmp2)); // Cors domain - char tmp3[CMDSZ]; + char tmp3[TOPSZ]; WebGetArg(PSTR("s1"), tmp3, sizeof(tmp3)); // Ssid1 - char tmp4[CMDSZ]; + char tmp4[TOPSZ]; WebGetArg(PSTR("s2"), tmp4, sizeof(tmp4)); // Ssid2 - char tmp5[CMDSZ]; + char tmp5[TOPSZ]; WebGetArg(PSTR("p1"), tmp5, sizeof(tmp5)); // Password1 - char tmp6[CMDSZ]; + char tmp6[TOPSZ]; WebGetArg(PSTR("p2"), tmp6, sizeof(tmp6)); // Password2 char command[300]; snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_HOSTNAME " %s;" D_CMND_CORS " %s;" D_CMND_SSID "1 %s;" D_CMND_SSID "2 %s;" D_CMND_PASSWORD "3 %s;" D_CMND_PASSWORD "4 %s"), @@ -1871,7 +1871,7 @@ void LoggingSaveSettings(void) { WebGetArg(PSTR("l2"), tmp3, sizeof(tmp3)); // Mqtt log level char tmp4[CMDSZ]; WebGetArg(PSTR("l3"), tmp4, sizeof(tmp4)); // Syslog level - char tmp5[CMDSZ]; + char tmp5[TOPSZ]; WebGetArg(PSTR("lh"), tmp5, sizeof(tmp5)); // Syslog host name char tmp6[CMDSZ]; WebGetArg(PSTR("lp"), tmp6, sizeof(tmp6)); // Syslog port number @@ -1954,9 +1954,9 @@ void HandleOtherConfiguration(void) { } void OtherSaveSettings(void) { - char tmp1[300]; // Needs to hold complete ESP32 template of minimal 230 chars + char tmp1[300]; // Needs to hold complete ESP32 template of minimal 230 chars WebGetArg(PSTR("dn"), tmp1, sizeof(tmp1)); // Device name - char tmp2[100]; + char tmp2[TOPSZ]; WebGetArg(PSTR("wp"), tmp2, sizeof(tmp2)); // Web password char command[500]; snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_WEBPASSWORD "2 %s;" D_CMND_SO "3 %d;" D_CMND_DEVICENAME " %s"), From 6fda2401e3bbcb8eb2973fbdd602c9322aea2095 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 13 Apr 2021 12:00:42 +0200 Subject: [PATCH 60/67] Refactor new webserver boarding code --- tasmota/xdrv_01_webserver.ino | 39 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 7959d66a8..bb3b32dfc 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -283,17 +283,14 @@ const char HTTP_FORM_MODULE[] PROGMEM = "

" D_MODULE_TYPE " (%s)

" "
"; -const char HTTP_FORM_WIFI_INITIAL[] PROGMEM = +const char HTTP_FORM_WIFI_PART1[] PROGMEM = "
 " D_WIFI_PARAMETERS " " "
" - "

" D_AP1_SSID "

" // Need \" instead of ' to be able to use ' in text (#8489) - "


"; + "

" D_AP1_SSID "%s

" // Need \" instead of ' to be able to use ' in text (#8489) + "


 " D_WIFI_PARAMETERS " " - "" - "

" D_AP1_SSID " (" STA_SSID1 ")

" // Need \" instead of ' to be able to use ' in text (#8489) - "


" +const char HTTP_FORM_WIFI_PART2[] PROGMEM = + " value=\"" D_ASTERISK_PWD "\">

" "

" D_AP2_SSID " (" STA_SSID2 ")

" "


" "

" D_HOSTNAME " (%s)

" @@ -915,7 +912,7 @@ void WebRestart(uint32_t type) #endif } } - if (type<2) { + if (type<2) { WSContentSend_P(HTTP_MSG_RSTRT); if (HTTP_MANAGER == Web.state || reset_only) { Web.state = HTTP_ADMIN; @@ -991,7 +988,7 @@ void HandleRoot(void) if (!Web.initial_config) { Web.initial_config = !strlen(SettingsText(SET_STASSID1)); if (Web.initial_config) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Blank Device - Initial Configuration")); } - } + } HandleWifiConfiguration(); } else { // wrong user and pass @@ -1741,7 +1738,7 @@ void HandleWifiConfiguration(void) { Web.old_wificonfig = TasmotaGlobal.wifi_state_flag; Settings.sta_config = WIFI_MANAGER; TasmotaGlobal.wifi_state_flag = Settings.sta_config; - + TasmotaGlobal.sleep = 0; // Disable sleep TasmotaGlobal.restart_flag = 0; // No restart TasmotaGlobal.ota_state_flag = 0; // No OTA @@ -1761,7 +1758,7 @@ void HandleWifiConfiguration(void) { } else { // STATION MODE or MIXED // Save the config and restart - WifiSaveSettings(); + WifiSaveSettings(); WebRestart(1); } return; @@ -1872,7 +1869,7 @@ void HandleWifiConfiguration(void) { WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); } WSContentSend_P(PSTR("")); - } + } } else { if (ssid_showed <= networksToShow ) { networksToShow++; } } @@ -1934,12 +1931,14 @@ void HandleWifiConfiguration(void) { WSContentSend_P(PSTR("

")); } - // As WIFI_HOSTNAME may contain %s-%04d it cannot be part of HTTP_FORM_WIFI where it will exception + WSContentSend_P(HTTP_FORM_WIFI_PART1, (WifiIsInManagerMode()) ? "" : PSTR(" (" STA_SSID1 ")"), SettingsText(SET_STASSID1)); if (WifiIsInManagerMode()) { - WSContentSend_P(HTTP_FORM_WIFI_INITIAL, SettingsText(SET_STASSID1) ); + // As WIFI_HOSTNAME may contain %s-%04d it cannot be part of HTTP_FORM_WIFI where it will exception + WSContentSend_P(PSTR(">

")); } else { - WSContentSend_P(HTTP_FORM_WIFI, SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsText(SET_HOSTNAME), SettingsText(SET_CORS)); + WSContentSend_P(HTTP_FORM_WIFI_PART2, SettingsText(SET_STASSID2), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsText(SET_HOSTNAME), SettingsText(SET_CORS)); } + WSContentSend_P(HTTP_FORM_END); } @@ -1949,8 +1948,8 @@ void HandleWifiConfiguration(void) { WSContentSend_P(PSTR("

" D_TRYING_TO_CONNECT "
%s

"), WebColor(COL_TEXT_WARNING), SettingsText(SET_STASSID1) - ); - } else if (WIFI_TEST_FINISHED_BAD == Web.wifiTest) { + ); + } else if (WIFI_TEST_FINISHED_BAD == Web.wifiTest) { WSContentSend_P(PSTR("

" D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS "

"), WebColor(COL_TEXT_WARNING), SettingsText(SET_STASSID1) @@ -3304,7 +3303,7 @@ bool Xdrv01(uint8_t function) TasmotaGlobal.save_data_counter = Web.save_data_counter; Settings.save_data = Web.save_data_counter; SettingsSaveAll(); -#if (!RESTART_AFTER_INITIAL_WIFI_CONFIG) +#if (!RESTART_AFTER_INITIAL_WIFI_CONFIG) Web.initial_config = false; Web.state = HTTP_ADMIN; #endif @@ -3327,7 +3326,7 @@ bool Xdrv01(uint8_t function) int n = WiFi.scanNetworks(); // restart scan } } - break; + break; case FUNC_COMMAND: result = DecodeCommand(kWebCommands, WebCommand); break; From 27cee8868b42c53617edca43dabca027b0658c80 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 13 Apr 2021 12:41:13 +0200 Subject: [PATCH 61/67] Refactor new webserver boarding code --- tasmota/xdrv_01_webserver.ino | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index bb3b32dfc..c97825240 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -817,20 +817,18 @@ void WSContentButton(uint32_t title_index, bool show=true) char action[4]; char title[100]; // Large to accomodate UTF-16 as used by Russian + WSContentSend_P(PSTR("

"), - title_index, - show ? "block":"none", - GetTextIndexed(action, sizeof(action), title_index, kButtonAction), + WSContentSend_P(PSTR(" onsubmit='return confirm(\"%s\");'>

"), GetTextIndexed(confirm, sizeof(confirm), title_index, kButtonConfirm), (!title_index) ? PSTR("rst") : PSTR("non"), GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); } else { - WSContentSend_P(PSTR("

"), - title_index, - show ? "block":"none", - GetTextIndexed(action, sizeof(action), title_index, kButtonAction), + WSContentSend_P(PSTR(">

"), GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); } } @@ -1925,12 +1923,7 @@ void HandleWifiConfiguration(void) { } } - if (limitScannedNetworks) { - WSContentSend_P(PSTR("
")); - } else { - WSContentSend_P(PSTR("
")); - } - + WSContentSend_P(PSTR("
"), (limitScannedNetworks) ? PSTR(D_SHOW_MORE_WIFI_NETWORKS) : PSTR(D_SCAN_FOR_WIFI_NETWORKS)); WSContentSend_P(HTTP_FORM_WIFI_PART1, (WifiIsInManagerMode()) ? "" : PSTR(" (" STA_SSID1 ")"), SettingsText(SET_STASSID1)); if (WifiIsInManagerMode()) { // As WIFI_HOSTNAME may contain %s-%04d it cannot be part of HTTP_FORM_WIFI where it will exception @@ -1944,19 +1937,14 @@ void HandleWifiConfiguration(void) { if (WifiIsInManagerMode()) { #ifndef FIRMWARE_MINIMAL + WSContentSend_P(PSTR("

"), WebColor(COL_TEXT_WARNING)); if (WIFI_TESTING == Web.wifiTest) { - WSContentSend_P(PSTR("

" D_TRYING_TO_CONNECT "
%s

"), - WebColor(COL_TEXT_WARNING), - SettingsText(SET_STASSID1) - ); + WSContentSend_P(PSTR(D_TRYING_TO_CONNECT "
%s

"), SettingsText(SET_STASSID1)); } else if (WIFI_TEST_FINISHED_BAD == Web.wifiTest) { - WSContentSend_P(PSTR("

" D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS "

"), - WebColor(COL_TEXT_WARNING), - SettingsText(SET_STASSID1) - ); + WSContentSend_P(PSTR(D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS ""), SettingsText(SET_STASSID1)); } // More Options Button - WSContentSend_P(PSTR("

"), + WSContentSend_P(PSTR("

"), (WIFI_TEST_FINISHED_BAD == Web.wifiTest) ? "none" : Web.initial_config ? "block" : "none", Web.initial_config ? "block" : "none" ); WSContentSpaceButton(BUTTON_RESTORE, !Web.initial_config); From 3751a3ff07044d12ef7e6f508011836a2fb601ad Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 13 Apr 2021 12:52:09 +0200 Subject: [PATCH 62/67] Every sperm counts --- tasmota/xdrv_01_webserver.ino | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index c97825240..f67c9d4ca 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -25,17 +25,17 @@ * Based on source by AlexT (https://github.com/tzapu) \*********************************************************************************************/ -#define XDRV_01 1 +#define XDRV_01 1 // Enable below demo feature only if defines USE_UNISHOX_COMPRESSION and USE_SCRIPT_WEB_DISPLAY are disabled //#define USE_WEB_SSE #ifndef WIFI_SOFT_AP_CHANNEL -#define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 11 as used by WifiManager web GUI +#define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 11 as used by WifiManager web GUI #endif #ifndef MAX_WIFI_NETWORKS_TO_SHOW -#define MAX_WIFI_NETWORKS_TO_SHOW 3 // Maximum number of Wifi Networks to show in the Wifi Configuration Menu BEFORE clicking on Show More Networks. +#define MAX_WIFI_NETWORKS_TO_SHOW 3 // Maximum number of Wifi Networks to show in the Wifi Configuration Menu BEFORE clicking on Show More Networks. #endif #ifndef RESTART_AFTER_INITIAL_WIFI_CONFIG @@ -108,7 +108,6 @@ const char HTTP_SCRIPT_COUNTER[] PROGMEM = #include "./html_uncompressed/HTTP_SCRIPT_ROOT_PART2.h" #endif - const char HTTP_SCRIPT_WIFI[] PROGMEM = "function c(l){" "eb('s1').value=l.innerText||l.textContent;" @@ -117,13 +116,13 @@ const char HTTP_SCRIPT_WIFI[] PROGMEM = const char HTTP_SCRIPT_HIDE[] PROGMEM = "function hidBtns() {" - "eb('butmo').style.display = 'none';" - "eb('butmod').style.display = 'none';" - "eb('but0').style.display = 'block';" - "eb('but1').style.display = 'block';" - "eb('but13').style.display = 'block';" - "eb('but0d').style.display = 'block';" - "eb('but13d').style.display = 'block';" + "eb('butmo').style.display='none';" + "eb('butmod').style.display='none';" + "eb('but0').style.display='block';" + "eb('but1').style.display='block';" + "eb('but13').style.display='block';" + "eb('but0d').style.display='block';" + "eb('but13d').style.display='block';" "}"; const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = @@ -135,14 +134,11 @@ const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = #include "./html_uncompressed/HTTP_SCRIPT_CONSOL.h" #endif - const char HTTP_MODULE_TEMPLATE_REPLACE_INDEX[] PROGMEM = "}2%d'>%s (%d)}3"; // }2 and }3 are used in below os.replace const char HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX[] PROGMEM = "}2%d'>%s}3"; // }2 and }3 are used in below os.replace - - #ifdef USE_UNISHOX_COMPRESSION #include "./html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h" #include "./html_compressed/HTTP_SCRIPT_TEMPLATE.h" @@ -151,7 +147,6 @@ const char HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX[] PROGMEM = #include "./html_uncompressed/HTTP_SCRIPT_TEMPLATE.h" #endif - const char HTTP_SCRIPT_TEMPLATE2[] PROGMEM = "j=0;" "for(i=0;i<" STR(MAX_USER_PINS) ";i++){" // Supports 13 GPIOs @@ -199,7 +194,6 @@ const char HTTP_SCRIPT_INFO_END[] PROGMEM = "}" "wl(i);"; - #ifdef USE_UNISHOX_COMPRESSION #include "./html_compressed/HTTP_HEAD_LAST_SCRIPT.h" #include "./html_compressed/HTTP_HEAD_STYLE1.h" @@ -210,7 +204,6 @@ const char HTTP_SCRIPT_INFO_END[] PROGMEM = #include "./html_uncompressed/HTTP_HEAD_STYLE2.h" #endif - #ifdef USE_ZIGBEE // Styles used for Zigbee Web UI // Battery icon from https://css.gg/battery From 22fcf5061dfb619f1d9ff0ec6f2348205fdfdc21 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 13 Apr 2021 16:04:22 +0200 Subject: [PATCH 63/67] Fix webserver enhanced wifi scan --- tasmota/xdrv_01_webserver.ino | 46 +++++++++++++---------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index f67c9d4ca..7e0a08096 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1822,11 +1822,12 @@ void HandleWifiConfiguration(void) { DEBUG_CORE_LOG(PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), ssid.c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), rssi); + String ssid_copy = ssid; + if (!ssid_copy.length()) { ssid_copy = F("no_name"); } // Print SSID if (!limitScannedNetworks) { - WSContentSend_P(PSTR("
%s
"), HtmlEscape(ssid).c_str()); + WSContentSend_P(PSTR("
%s
"), HtmlEscape(ssid_copy).c_str()); } - skipduplicated = false; String nextSSID = ""; // Handle all APs with the same SSID @@ -1838,29 +1839,22 @@ void HandleWifiConfiguration(void) { uint32_t rssi_as_quality = WifiGetRssiAsQuality(rssi); uint32_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4); + WSContentSend_P(PSTR("
"), rssi, rssi_as_quality); if (limitScannedNetworks) { // Print SSID and item - WSContentSend_P(PSTR("
%s
"), rssi, rssi_as_quality, HtmlEscape(ssid).c_str()); - // Print signal strength indicator - for (uint32_t k = 0; k < 4; ++k) { - WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); - } - WSContentSend_P(PSTR("
")); + WSContentSend_P(PSTR("%s
"), HtmlEscape(ssid_copy).c_str()); ssid_showed++; skipduplicated = true; // For the simplified page, just show 1 SSID if there are many Networks with the same } else { // Print item - WSContentSend_P(PSTR("
%s(%d)
"), - rssi, rssi_as_quality, - WiFi.BSSIDstr(indices[j]).c_str(), - WiFi.channel(indices[j]) + WSContentSend_P(PSTR("%s(%d)
"), WiFi.BSSIDstr(indices[j]).c_str(), WiFi.channel(indices[j]) ); - // Print signal strength indicator - for (uint32_t k = 0; k < 4; ++k) { - WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); - } - WSContentSend_P(PSTR("
")); } + // Print signal strength indicator + for (uint32_t k = 0; k < 4; ++k) { + WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + } + WSContentSend_P(PSTR("
")); } else { if (ssid_showed <= networksToShow ) { networksToShow++; } } @@ -1868,7 +1862,9 @@ void HandleWifiConfiguration(void) { } delay(0); } - WSContentSend_P(PSTR("
")); + if (!limitScannedNetworks) { + WSContentSend_P(PSTR("
")); + } } } #else // No USE_ENHANCED_GUI_WIFI_SCAN @@ -1892,18 +1888,10 @@ void HandleWifiConfiguration(void) { DEBUG_CORE_LOG(PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), WiFi.SSID(indices[i]).c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), rssi); int quality = WifiGetRssiAsQuality(rssi); -/* - int auth = WiFi.encryptionType(indices[i]); - char encryption[20]; - WSContentSend_P(PSTR("
%s (%d) %s %d%% (%d dBm)
"), - HtmlEscape(WiFi.SSID(indices[i])).c_str(), - WiFi.channel(indices[i]), - GetTextIndexed(encryption, sizeof(encryption), auth +1, kEncryptionType), - quality, rssi - ); -*/ + String ssid_copy = WiFi.SSID(indices[i]); + if (!ssid_copy.length()) { ssid_copy = F("no_name"); } WSContentSend_P(PSTR("
%s (%d) %d%% (%d dBm)
"), - HtmlEscape(WiFi.SSID(indices[i])).c_str(), + HtmlEscape(ssid_copy).c_str(), WiFi.channel(indices[i]), quality, rssi ); From 06ac5c4053e285977383f12748c9f0655e658d78 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 13 Apr 2021 17:00:54 +0200 Subject: [PATCH 64/67] Add scan start logging --- tasmota/xdrv_01_webserver.ino | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 7e0a08096..342fd3f97 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1705,9 +1705,6 @@ String HtmlEscape(const String unescaped) { return result; } -// Indexed by enum wl_enc_type in file wl_definitions.h starting from -1 -const char kEncryptionType[] PROGMEM = "|||" D_WPA_PSK "||" D_WPA2_PSK "|" D_WEP "||" D_NONE "|" D_AUTO; - void HandleWifiConfiguration(void) { char tmp[TOPSZ]; // Max length is currently 150 @@ -1780,6 +1777,8 @@ void HandleWifiConfiguration(void) { limitScannedNetworks = false; } else { if (Webserver->hasArg(F("scan"))) { limitScannedNetworks = false; } + + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI "Scanning...")); #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION From 07265e36cd2bc5cb0edd7f113a246c7df8ea6dbb Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 13 Apr 2021 16:58:27 -0300 Subject: [PATCH 65/67] KNX: Fix Energy Yesterday Value --- tasmota/xdrv_11_knx.ino | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino index 445bcf0f0..037f22b73 100644 --- a/tasmota/xdrv_11_knx.ino +++ b/tasmota/xdrv_11_knx.ino @@ -107,7 +107,7 @@ device_parameters_t device_param[] = { { KNX_ENERGY_POWER , false, false, KNX_Empty }, { KNX_ENERGY_POWERFACTOR , false, false, KNX_Empty }, { KNX_ENERGY_DAILY , false, false, KNX_Empty }, - { KNX_ENERGY_START , false, false, KNX_Empty }, + { KNX_ENERGY_YESTERDAY , false, false, KNX_Empty }, { KNX_ENERGY_TOTAL , false, false, KNX_Empty }, { KNX_SLOT1 , false, false, KNX_Empty }, { KNX_SLOT2 , false, false, KNX_Empty }, @@ -501,7 +501,7 @@ void KNX_INIT(void) if ( TasmotaGlobal.energy_driver != ENERGY_NONE ) { device_param[KNX_ENERGY_POWER-1].show = true; device_param[KNX_ENERGY_DAILY-1].show = true; - device_param[KNX_ENERGY_START-1].show = true; + device_param[KNX_ENERGY_YESTERDAY-1].show = true; device_param[KNX_ENERGY_TOTAL-1].show = true; device_param[KNX_ENERGY_VOLTAGE-1].show = true; device_param[KNX_ENERGY_CURRENT-1].show = true; @@ -684,13 +684,14 @@ void KNX_CB_Action(message_t const &msg, void *arg) } } } - else if (chan->type == KNX_ENERGY_START) // Reply KNX_ENERGY_START + else if (chan->type == KNX_ENERGY_YESTERDAY) // Reply KNX_ENERGY_YESTERDAY { if (Energy.data_valid[0]) { - knx.answer_4byte_float(msg.received_on, Energy.start_energy); + float energy_kWhyesterday = (float)Settings.energy_kWhyesterday / 100000; + knx.answer_4byte_float(msg.received_on, energy_kWhyesterday); if (Settings.flag.knx_enable_enhancement) { - knx.answer_4byte_float(msg.received_on, Energy.start_energy); - knx.answer_4byte_float(msg.received_on, Energy.start_energy); + knx.answer_4byte_float(msg.received_on, energy_kWhyesterday); + knx.answer_4byte_float(msg.received_on, energy_kWhyesterday); } } } @@ -813,7 +814,7 @@ void KnxSensor(uint8_t sensor_type, float value) knx.write_4byte_float(KNX_addr, value); } - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s " D_SENT_TO " %d.%d.%d "), + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s " D_SENT_TO " %d.%d.%d"), device_param_ga[sensor_type -1], KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); From 6b35cb94d3d3a12e40a35b6b2ca5466602000dea Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 13 Apr 2021 17:00:36 -0300 Subject: [PATCH 66/67] KNX: Fix Energy Yesterday --- tasmota/tasmota.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index f270e5cef..c9d58fd05 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -234,7 +234,7 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define KNX_ENERGY_POWER 21 #define KNX_ENERGY_POWERFACTOR 22 #define KNX_ENERGY_DAILY 23 -#define KNX_ENERGY_START 24 +#define KNX_ENERGY_YESTERDAY 24 #define KNX_ENERGY_TOTAL 25 #define KNX_SLOT1 26 #define KNX_SLOT2 27 From cbea6f21efdec2cc5052bf18eb69af4730bfe638 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 13 Apr 2021 17:01:27 -0300 Subject: [PATCH 67/67] KNX: Fix Energy Yesterday --- tasmota/xdrv_03_energy.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 9351ceb9b..b9697dfca 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -1144,7 +1144,7 @@ void EnergyShow(bool json) } KnxSensor(KNX_ENERGY_DAILY, Energy.daily); KnxSensor(KNX_ENERGY_TOTAL, Energy.total); - KnxSensor(KNX_ENERGY_START, Energy.start_energy); + KnxSensor(KNX_ENERGY_YESTERDAY, (float)Settings.energy_kWhyesterday / 100000); } #endif // USE_KNX #ifdef USE_WEBSERVER