From 64af7728eb041786cf9545cd64111a574e2f6274 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 15 Feb 2021 15:49:18 +0100 Subject: [PATCH 1/8] correct library.properties --- .../Display_Renderer-gemu-1.0/library.properties | 6 +++--- .../Epaper_29-gemu-1.0/library.properties | 9 +++++++++ .../Epaper_42-gemu-1.0/library.properties | 9 +++++++++ lib/lib_display/ILI9341-gemu-1.0/library.properties | 9 +++++++++ .../Xlatb_RA8876-gemu-1.0/library.properties | 12 ++++++------ lib/lib_div/ProcessControl/library.properties | 9 +++++++++ .../stm32flash-1.0-tasmota/library.properties | 9 +++++++++ lib/libesp32/NimBLE-Arduino/library.json | 2 +- 8 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 lib/lib_display/Epaper_29-gemu-1.0/library.properties create mode 100644 lib/lib_display/Epaper_42-gemu-1.0/library.properties create mode 100644 lib/lib_display/ILI9341-gemu-1.0/library.properties create mode 100644 lib/lib_div/ProcessControl/library.properties create mode 100644 lib/lib_div/stm32flash-1.0-tasmota/library.properties diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/library.properties b/lib/lib_display/Display_Renderer-gemu-1.0/library.properties index 29a16c0e7..7f8d6dc82 100644 --- a/lib/lib_display/Display_Renderer-gemu-1.0/library.properties +++ b/lib/lib_display/Display_Renderer-gemu-1.0/library.properties @@ -1,9 +1,9 @@ -name=Waveshare esp 2.9 inch e-paper display driver +name=Display renderer version=1.0 author=Gerhard Mutz maintainer=Gerhard Mutz -sentence=ESP8266 library for Waveshare e-paper display. +sentence=ESP8266 ESP32 library for Tasmota displays paragraph= category=Display -url=https://github.com/gemu2015/Sonoff-Tasmota/tree/displays/lib/esp-epaper-29-ws-20171230-gemu-1.0# +url=https://github.com/arendst/Tasmota architectures=* diff --git a/lib/lib_display/Epaper_29-gemu-1.0/library.properties b/lib/lib_display/Epaper_29-gemu-1.0/library.properties new file mode 100644 index 000000000..d6b5f57c6 --- /dev/null +++ b/lib/lib_display/Epaper_29-gemu-1.0/library.properties @@ -0,0 +1,9 @@ +name=Waveshare esp 2.9 inch e-paper display driver +version=1.0 +author=Gerhard Mutz +maintainer=Gerhard Mutz +sentence=ESP8266 ESP32 library for Waveshare 2.9 inch e-paper display +paragraph= +category=Display +url=https://github.com/arendst/Tasmota +architectures=* diff --git a/lib/lib_display/Epaper_42-gemu-1.0/library.properties b/lib/lib_display/Epaper_42-gemu-1.0/library.properties new file mode 100644 index 000000000..923da7925 --- /dev/null +++ b/lib/lib_display/Epaper_42-gemu-1.0/library.properties @@ -0,0 +1,9 @@ +name=Waveshare esp 4.2 inch e-paper display driver +version=1.0 +author=Gerhard Mutz +maintainer=Gerhard Mutz +sentence=ESP8266 ESP32 library for Waveshare e-paper display. +paragraph= +category=Display +url=https://github.com/arendst/Tasmota +architectures=* diff --git a/lib/lib_display/ILI9341-gemu-1.0/library.properties b/lib/lib_display/ILI9341-gemu-1.0/library.properties new file mode 100644 index 000000000..5373590b5 --- /dev/null +++ b/lib/lib_display/ILI9341-gemu-1.0/library.properties @@ -0,0 +1,9 @@ +name=ILI9341 +version=1.0.0 +author=Gerhard Mutz +maintainer=Gerhard Mutz +sentence=ILI9341 ESP8266 ESP32 display driver for Tasmota +paragraph=ILI9341 ESP8266 ESP32 display driver for Tasmota +category=Display +url=https://github.com/arendst/Tasmota +architectures=* diff --git a/lib/lib_display/Xlatb_RA8876-gemu-1.0/library.properties b/lib/lib_display/Xlatb_RA8876-gemu-1.0/library.properties index 6e478adf0..5eea15179 100644 --- a/lib/lib_display/Xlatb_RA8876-gemu-1.0/library.properties +++ b/lib/lib_display/Xlatb_RA8876-gemu-1.0/library.properties @@ -1,9 +1,9 @@ name=RA8876 -version=1.0.2 -author=Jaret Burkett -maintainer=Jaret Burkett -sentence=Library for RA8876 displays -paragraph=Library for RA8876 displays +version=1.0.0 +author=Jaret Burkett / Gerhard Mutz +maintainer=Gerhard Mutz +sentence=Tasmota Library for RA8876 displays +paragraph=Tasmota Library for RA8876 displays category=Display -url=https://github.com/jaretburkett/ILI9488 +url=https://github.com/arendst/Tasmota architectures=* diff --git a/lib/lib_div/ProcessControl/library.properties b/lib/lib_div/ProcessControl/library.properties new file mode 100644 index 000000000..bdfadee30 --- /dev/null +++ b/lib/lib_div/ProcessControl/library.properties @@ -0,0 +1,9 @@ +name=Process_control +version=1.0.0 +author=Colin Law +maintainer=Colin Law +sentence=C++ library of process control algorithms +paragraph=C++ library of process control algorithms +category=Heating +url=https://github.com/colinl/process-control.git +architectures=* \ No newline at end of file diff --git a/lib/lib_div/stm32flash-1.0-tasmota/library.properties b/lib/lib_div/stm32flash-1.0-tasmota/library.properties new file mode 100644 index 000000000..6161b02e1 --- /dev/null +++ b/lib/lib_div/stm32flash-1.0-tasmota/library.properties @@ -0,0 +1,9 @@ +name=stm32_flash +version=1.0.0 +author=Tormod Volden +maintainer=Tormod Volden +sentence=STM32 Flasher +paragraph=STM32 Flaher +category=Tools +url= +architectures=esp8266 \ No newline at end of file diff --git a/lib/libesp32/NimBLE-Arduino/library.json b/lib/libesp32/NimBLE-Arduino/library.json index 5eb6ec5b4..a64024df6 100644 --- a/lib/libesp32/NimBLE-Arduino/library.json +++ b/lib/libesp32/NimBLE-Arduino/library.json @@ -2,7 +2,7 @@ "name": "NimBLE-Arduino", "keywords": "esp32, bluetooth", "description": "Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE", - "version": "1.0.2", + "version": "1.1.0", "frameworks": "arduino", "platforms": "espressif32" } From 68baafc6858cb78353157bb367efc96bb5672833 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Feb 2021 16:37:09 +0100 Subject: [PATCH 2/8] Initial support for autoexec.bat using filesystem --- tasmota/tasmota.h | 4 +-- tasmota/tasmota_globals.h | 2 ++ tasmota/xdrv_03_energy.ino | 2 +- tasmota/xdrv_50_filesystem.ino | 63 +++++++++++++++++++++++++++++++--- 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 34e2a562a..613fd019f 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -370,10 +370,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER, SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER, - SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_MAX }; + SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_AUTOEXEC, SRC_MAX }; const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|" "Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|" - "Thermostat|Chat|TCL|Berry"; + "Thermostat|Chat|TCL|Berry|Autoexec"; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 2ac6a2343..9c05574d7 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -261,6 +261,8 @@ const uint16_t LOG_BUFFER_SIZE = 4000; // Max number of characters in lo #define TASM_FILE_DRIVER "/.drvset%03d" #define TASM_FILE_SENSOR "/.snsset%03d" #define TASM_FILE_ZIGBEE "/zb" // Zigbee settings blob as used by CC2530 on ESP32 +#define TASM_FILE_AUTOEXEC "/autoexec.bat" // Commands executed after restart +#define TASM_FILE_CONFIG "/config.sys" // Settings executed after restart #ifndef MQTT_MAX_PACKET_SIZE #define MQTT_MAX_PACKET_SIZE 1200 // Bytes diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index d63472a9d..822bb6401 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -501,7 +501,7 @@ void EnergyEverySecond(void) { // Overtemp check if (TasmotaGlobal.global_update) { - if (TasmotaGlobal.power && !isnan(TasmotaGlobal.temperature_celsius) && (TasmotaGlobal.temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays + 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: GlobTemp %1_f"), &TasmotaGlobal.temperature_celsius); diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index f748ed16a..fddccb214 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -83,7 +83,11 @@ uint8_t ufs_dir; // 0 = None, 1 = SD, 2 = ffat, 3 = littlefs uint8_t ufs_type; uint8_t ffs_type; -bool download_busy; + +struct { + bool download_busy; + bool autoexec = false; +} UfsData; /*********************************************************************************************/ @@ -332,6 +336,45 @@ bool TfsDeleteFile(const char *fname) { return true; } +/*********************************************************************************************\ + * Autoexec support +\*********************************************************************************************/ + +void UfsAutoexec(void) { + if (!ffs_type) { return; } + File file = ffsp->open(TASM_FILE_AUTOEXEC, "r"); + if (!file) { return; } + + char cmd_line[512]; + while (file.available()) { + uint16_t index = 0; + while (file.available()) { + uint8_t buf[1]; + file.read(buf, 1); + if ((buf[0] == '\n') || (buf[0] == '\r')) { + // Line terminated with linefeed or carriage return + break; + } + else if ((0 == index) && isspace(buf[0])) { + // Skip leading spaces (' ','\t','\n','\v','\f','\r') + } else { + cmd_line[index] = buf[0]; + index++; + if (index >= sizeof(cmd_line) - 1) { + break; + } + } + } + if ((index > 0) && (cmd_line[0] != ';')) { // Information but no comment + cmd_line[index] = 0; + ExecuteCommand(cmd_line, SRC_AUTOEXEC); + } + delay(0); + } + + file.close(); +} + /*********************************************************************************************\ * Commands \*********************************************************************************************/ @@ -396,7 +439,6 @@ void UFSDelete(void) { * Web support \*********************************************************************************************/ - #ifdef USE_WEBSERVER const char UFS_WEB_DIR[] PROGMEM = @@ -654,12 +696,12 @@ uint8_t UfsDownloadFile(char *file) { #ifdef ESP32_DOWNLOAD_TASK download_file.close(); - if (download_busy == true) { + if (UfsData.download_busy == true) { AddLog(LOG_LEVEL_INFO, PSTR("UFS: Download is busy")); return 0; } - download_busy = true; + UfsData.download_busy = true; char *path = (char*)malloc(128); strcpy(path,file); xTaskCreatePinnedToCore(donload_task, "DT", 6000, (void*)path, 3, NULL, 1); @@ -710,7 +752,7 @@ void donload_task(void *path) { } download_file.close(); download_Client.stop(); - download_busy = false; + UfsData.download_busy = false; vTaskDelete( NULL ); } #endif // ESP32_DOWNLOAD_TASK @@ -752,6 +794,17 @@ bool Xdrv50(uint8_t function) { UfsCheckSDCardInit(); break; #endif // USE_SDCARD + case FUNC_EVERY_SECOND: + if (UfsData.autoexec) { + // Safe to execute autoexec commands here + UfsData.autoexec = false; + UfsAutoexec(); + } + break; + case FUNC_MQTT_INIT: + // Do not execute autoexec commands here + UfsData.autoexec = true; + break; case FUNC_COMMAND: result = DecodeCommand(kUFSCommands, kUFSCommand); break; From 3c623b52337fbb740023e35fcfb1c84ee85120d0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Feb 2021 16:51:13 +0100 Subject: [PATCH 3/8] Add autoexec failsafe --- tasmota/tasmota.ino | 2 ++ tasmota/xdrv_50_filesystem.ino | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 79c36def4..c0b7b4669 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -146,6 +146,7 @@ struct { bool restart_halt; // Do not restart but stay in wait loop bool module_changed; // Indicate module changed since last restart bool wifi_stay_asleep; // Allow sleep only incase of ESP32 BLE + bool no_autoexec; // Disable autoexec StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits) uint8_t spi_enabled; // SPI configured @@ -303,6 +304,7 @@ void setup(void) { } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +2) { // Restarted 4 times Settings.rule_enabled = 0; // Disable all rules + TasmotaGlobal.no_autoexec = true; } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +3) { // Restarted 5 times for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index fddccb214..08c7f18c8 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -798,7 +798,7 @@ bool Xdrv50(uint8_t function) { if (UfsData.autoexec) { // Safe to execute autoexec commands here UfsData.autoexec = false; - UfsAutoexec(); + if (!TasmotaGlobal.no_autoexec) { UfsAutoexec(); } } break; case FUNC_MQTT_INIT: From f6572a863b050017a461d8b779d72d719ac05a38 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 15 Feb 2021 17:22:06 +0100 Subject: [PATCH 4/8] display text vars --- tasmota/support.ino | 91 +++++++++- tasmota/support_tasmota.ino | 7 +- tasmota/xdrv_10_scripter.ino | 33 ++-- tasmota/xdrv_13_display.ino | 334 +++++++++++++++++++++++------------ 4 files changed, 338 insertions(+), 127 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 1b99b5cf1..56ba71ab2 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1338,7 +1338,7 @@ int ICACHE_RAM_ATTR Pin(uint32_t gpio, uint32_t index) { bool PinUsed(uint32_t gpio, uint32_t index = 0); bool PinUsed(uint32_t gpio, uint32_t index) { - return (Pin(gpio, index) >= 0); + return (Pin(gpio, index) > -1); } uint32_t GetPin(uint32_t lpin) { @@ -1667,6 +1667,92 @@ void TemplateJson(void) ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1); } +#if ( defined(USE_SCRIPT) && defined(SUPPORT_MQTT_EVENT) ) || defined (USE_DT_VARS) + +/*********************************************************************************************\ + * Parse json paylod with path +\*********************************************************************************************/ +// parser object, source keys, delimiter, float result or NULL, string result or NULL, string size +// return 1 if numeric 2 if string, else 0 = not found +uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, float *nres, char *sres, uint32_t slen) { + uint32_t res = 0; + const char *cp = spath; +#ifdef DEBUG_JSON_PARSE_PATH + AddLog(LOG_LEVEL_INFO, PSTR("JSON: parsing json key: %s from json: %s"), cp, jpath); +#endif + JsonParserObject obj = *jobj; + JsonParserObject lastobj = obj; + char selem[32]; + uint8_t aindex = 0; + String value = ""; + while (1) { + // read next element + for (uint32_t sp=0; sp= 0) { + else if (led_pin > -1) { if (state) { state = 1; } digitalWrite(led_pin, (led_inv) ? !state : state); } @@ -716,6 +716,11 @@ void MqttPublishTeleState(void) ResponseClear(); MqttShowState(); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); + +#ifdef USE_DT_VARS + DTVarsTeleperiod(); +#endif // USE_DT_VARS + #if defined(USE_RULES) || defined(USE_SCRIPT) RulesTeleperiod(); // Allow rule based HA messages #endif // USE_SCRIPT diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 330ddc13d..cc39a9af6 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -4326,14 +4326,13 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) { goto next_line; } #ifdef USE_SENDMAIL -/* - else if (!strncmp(lp, "sm", 2)) { - lp+=3; + else if (!strncmp(lp, "mail", 4)) { + lp+=5; char tmp[256]; Replace_Cmd_Vars(lp ,1 , tmp, sizeof(tmp)); SendMail(tmp); goto next_line; - }*/ + } #endif else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) { // execute cmd @@ -5819,14 +5818,14 @@ void dateTime(uint16_t* date, uint16_t* time) { #ifdef SUPPORT_MQTT_EVENT - +/* //#define DEBUG_MQTT_EVENT - +// parser object, source keys, delimiter, float result or NULL, string result or NULL, string size uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, float *nres, char *sres, uint32_t slen) { uint32_t res = 0; const char *cp = spath; -#ifdef DEBUG_MQTT_EVENT -// AddLog(LOG_LEVEL_INFO, PSTR("Script: parsing json key: %s from json: %s"), cp, jpath); +#ifdef DEBUG_JSON_PARSE_PATH + AddLog(LOG_LEVEL_INFO, PSTR("JSON: parsing json key: %s from json: %s"), cp, jpath); #endif JsonParserObject obj = *jobj; JsonParserObject lastobj = obj; @@ -5843,8 +5842,8 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl } selem[sp] = *cp++; } -#ifdef DEBUG_MQTT_EVENT - AddLog(LOG_LEVEL_INFO, PSTR("Script: cmp current key: %s"), selem); +#ifdef DEBUG_JSON_PARSE_PATH + AddLog(LOG_LEVEL_INFO, PSTR("JSON: cmp current key: %s"), selem); #endif // check for array char *sp = strchr(selem,'['); @@ -5856,8 +5855,8 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl // now check element obj = obj[selem]; if (!obj.isValid()) { -#ifdef DEBUG_MQTT_EVENT - AddLog(LOG_LEVEL_INFO, PSTR("Script: obj invalid: %s"), selem); +#ifdef DEBUG_JSON_PARSE_PATH + AddLog(LOG_LEVEL_INFO, PSTR("JSON: obj invalid: %s"), selem); #endif JsonParserToken tok = lastobj[selem]; if (tok.isValid()) { @@ -5881,8 +5880,8 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl } } -#ifdef DEBUG_MQTT_EVENT - AddLog(LOG_LEVEL_INFO, PSTR("Script: token invalid: %s"), selem); +#ifdef DEBUG_JSON_PARSE_PATH + AddLog(LOG_LEVEL_INFO, PSTR("JSON: token invalid: %s"), selem); #endif break; } @@ -5892,11 +5891,13 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl } if (!*cp) break; } - strlcpy(sres,value.c_str(),slen); + if (sres) { + strlcpy(sres,value.c_str(), slen); + } return res; } - +*/ #ifndef MQTT_EVENT_MSIZE #define MQTT_EVENT_MSIZE 256 #endif // MQTT_EVENT_MSIZE diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index a69504d78..fffe2255d 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -156,95 +156,6 @@ void DisplayClear(void) XdspCall(FUNC_DISPLAY_CLEAR); } -void DisplayDrawHLine(uint16_t x, uint16_t y, int16_t len, uint16_t color) -{ - dsp_x = x; - dsp_y = y; - dsp_len = len; - dsp_color = color; - XdspCall(FUNC_DISPLAY_DRAW_HLINE); -} - -void DisplayDrawVLine(uint16_t x, uint16_t y, int16_t len, uint16_t color) -{ - dsp_x = x; - dsp_y = y; - dsp_len = len; - dsp_color = color; - XdspCall(FUNC_DISPLAY_DRAW_VLINE); -} - -void DisplayDrawLine(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2, uint16_t color) -{ - dsp_x = x; - dsp_y = y; - dsp_x2 = x2; - dsp_y2 = y2; - dsp_color = color; - XdspCall(FUNC_DISPLAY_DRAW_LINE); -} - -void DisplayDrawCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color) -{ - dsp_x = x; - dsp_y = y; - dsp_rad = rad; - dsp_color = color; - XdspCall(FUNC_DISPLAY_DRAW_CIRCLE); -} - -void DisplayDrawFilledCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color) -{ - dsp_x = x; - dsp_y = y; - dsp_rad = rad; - dsp_color = color; - XdspCall(FUNC_DISPLAY_FILL_CIRCLE); -} - -void DisplayDrawRectangle(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2, uint16_t color) -{ - dsp_x = x; - dsp_y = y; - dsp_x2 = x2; - dsp_y2 = y2; - dsp_color = color; - XdspCall(FUNC_DISPLAY_DRAW_RECTANGLE); -} - -void DisplayDrawFilledRectangle(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2, uint16_t color) -{ - dsp_x = x; - dsp_y = y; - dsp_x2 = x2; - dsp_y2 = y2; - dsp_color = color; - XdspCall(FUNC_DISPLAY_FILL_RECTANGLE); -} - -void DisplayDrawFrame(void) -{ - XdspCall(FUNC_DISPLAY_DRAW_FRAME); -} - -void DisplaySetSize(uint8_t size) -{ - Settings.display_size = size &3; - XdspCall(FUNC_DISPLAY_TEXT_SIZE); -} - -void DisplaySetFont(uint8_t font) -{ - Settings.display_font = font &3; - XdspCall(FUNC_DISPLAY_FONT_SIZE); -} - -void DisplaySetRotation(uint8_t rotation) -{ - Settings.display_rotate = rotation &3; - XdspCall(FUNC_DISPLAY_ROTATION); -} - void DisplayDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) { dsp_x = x; @@ -535,10 +446,10 @@ void DisplayText(void) cp += var; if (temp < 0) { if (renderer) renderer->writeFastHLine(disp_xpos + temp, disp_ypos, -temp, fg_color); - else DisplayDrawHLine(disp_xpos + temp, disp_ypos, -temp, fg_color); + //else DisplayDrawHLine(disp_xpos + temp, disp_ypos, -temp, fg_color); } else { if (renderer) renderer->writeFastHLine(disp_xpos, disp_ypos, temp, fg_color); - else DisplayDrawHLine(disp_xpos, disp_ypos, temp, fg_color); + //else DisplayDrawHLine(disp_xpos, disp_ypos, temp, fg_color); } disp_xpos += temp; break; @@ -548,10 +459,10 @@ void DisplayText(void) cp += var; if (temp < 0) { if (renderer) renderer->writeFastVLine(disp_xpos, disp_ypos + temp, -temp, fg_color); - else DisplayDrawVLine(disp_xpos, disp_ypos + temp, -temp, fg_color); + //else DisplayDrawVLine(disp_xpos, disp_ypos + temp, -temp, fg_color); } else { if (renderer) renderer->writeFastVLine(disp_xpos, disp_ypos, temp, fg_color); - else DisplayDrawVLine(disp_xpos, disp_ypos, temp, fg_color); + //else DisplayDrawVLine(disp_xpos, disp_ypos, temp, fg_color); } disp_ypos += temp; break; @@ -563,7 +474,7 @@ void DisplayText(void) var = atoiv(cp, &temp1); cp += var; if (renderer) renderer->writeLine(disp_xpos, disp_ypos, temp, temp1, fg_color); - else DisplayDrawLine(disp_xpos, disp_ypos, temp, temp1, fg_color); + //else DisplayDrawLine(disp_xpos, disp_ypos, temp, temp1, fg_color); disp_xpos += temp; disp_ypos += temp1; break; @@ -572,14 +483,14 @@ void DisplayText(void) var = atoiv(cp, &temp); cp += var; if (renderer) renderer->drawCircle(disp_xpos, disp_ypos, temp, fg_color); - else DisplayDrawCircle(disp_xpos, disp_ypos, temp, fg_color); + //else DisplayDrawCircle(disp_xpos, disp_ypos, temp, fg_color); break; case 'K': // filled circle var = atoiv(cp, &temp); cp += var; if (renderer) renderer->fillCircle(disp_xpos, disp_ypos, temp, fg_color); - else DisplayDrawFilledCircle(disp_xpos, disp_ypos, temp, fg_color); + //else DisplayDrawFilledCircle(disp_xpos, disp_ypos, temp, fg_color); break; case 'r': // rectangle @@ -589,7 +500,7 @@ void DisplayText(void) var = atoiv(cp, &temp1); cp += var; if (renderer) renderer->drawRect(disp_xpos, disp_ypos, temp, temp1, fg_color); - else DisplayDrawRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color); + //else DisplayDrawRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color); break; case 'R': // filled rectangle @@ -599,7 +510,7 @@ void DisplayText(void) var = atoiv(cp, &temp1); cp += var; if (renderer) renderer->fillRect(disp_xpos, disp_ypos, temp, temp1, fg_color); - else DisplayDrawFilledRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color); + //else DisplayDrawFilledRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color); break; case 'u': // rounded rectangle @@ -672,9 +583,49 @@ void DisplayText(void) index_colors[temp] = ftemp; break; } +#ifdef USE_DT_VARS + if (*cp == 'v') { + cp++; + { int16_t num, gxp, gyp, textbcol, textfcol, font, textsize, txlen, dp; + var=atoiv(cp,&num); + cp+=var; + cp++; + var=atoiv(cp,&gxp); + cp+=var; + cp++; + var=atoiv(cp,&gyp); + cp+=var; + cp++; + var=atoiv(cp,&textbcol); + cp+=var; + cp++; + var=atoiv(cp,&textfcol); + cp+=var; + cp++; + var=atoiv(cp,&font); + cp+=var; + cp++; + var=atoiv(cp,&textsize); + cp+=var; + cp++; + var=atoiv(cp,&txlen); + cp+=var; + cp++; + var=atoiv(cp,&dp); + cp+=var; + cp++; + // text itself + char bbuff[32]; + cp = get_string(bbuff, sizeof(bbuff), cp); + char unit[4]; + cp = get_string(unit, sizeof(unit), cp); + define_dt_var(num, gxp, gyp, textbcol, textfcol, font, textsize, txlen, dp, bbuff, unit); + } + } +#endif // USE_DT_VARS // force draw grafics buffer if (renderer) renderer->Updateframe(); - else DisplayDrawFrame(); + //else DisplayDrawFrame(); break; case 'D': // set auto draw mode @@ -685,18 +636,18 @@ void DisplayText(void) case 's': // size sx if (renderer) renderer->setTextSize(*cp&7); - else DisplaySetSize(*cp&3); + //else DisplaySetSize(*cp&3); cp += 1; break; case 'f': // font sx { uint8_t font = *cp&7; if (renderer) renderer->setTextFont(font); - else DisplaySetFont(font); + //else DisplaySetFont(font); if (font) { // for backward compatibility set size to 1 on non GFX fonts if (renderer) renderer->setTextSize(1); - else DisplaySetSize(1); + //else DisplaySetSize(1); } cp += 1; } @@ -704,7 +655,7 @@ void DisplayText(void) case 'a': // rotation angle if (renderer) renderer->setRotation(*cp&3); - else DisplaySetRotation(*cp&3); + //else DisplaySetRotation(*cp&3); cp+=1; break; @@ -952,7 +903,7 @@ void DisplayText(void) // draw buffer if (auto_draw&1) { if (renderer) renderer->Updateframe(); - else DisplayDrawFrame(); + //else DisplayDrawFrame(); } } @@ -995,6 +946,164 @@ void Display_Text_From_File(const char *file) { } #endif + +#ifdef USE_DT_VARS + +#define MAX_DT_VARS 8 +#define MAX_DVTSIZE 24 + +typedef struct { + uint16_t xp; + uint16_t yp; + uint8_t txtbcol; + uint8_t txtfcol; + int8_t txtsiz; + int8_t txtlen; + int8_t dp; + int8_t font; + char unit[6]; + char *jstrbuf; + char rstr[32]; +} DT_VARS; + +DT_VARS *dt_vars[MAX_DT_VARS]; + +void define_dt_var(uint32_t num, uint32_t xp, uint32_t yp, uint32_t txtbcol, uint32_t txtfcol, int32_t font, int32_t txtsiz, int32_t txtlen, int32_t dp, char *jstr, char *unit) { + if (num >= MAX_DT_VARS) return; + + if (dt_vars[num]) { + if (dt_vars[num]->jstrbuf) free(dt_vars[num]->jstrbuf); + free(dt_vars[num]); + } + //dt [dv0:100:100:0:3:2:1:10:2:WLAN#ID:uV:] + + DT_VARS *dtp = (DT_VARS*)malloc(sizeof(DT_VARS)); + if (!dtp) return; + + dt_vars[num] = dtp; + + dtp->xp = xp; + dtp->yp = yp; + dtp->txtbcol = txtbcol; + dtp->txtfcol = txtfcol; + dtp->font = font; + dtp->txtsiz = txtsiz; + if (txtlen > MAX_DVTSIZE) {txtlen = MAX_DVTSIZE;} + dtp->txtlen = txtlen; + dtp->dp = dp; + dtp->jstrbuf = (char*)malloc(strlen(jstr + 1)); + if (!dtp->jstrbuf) { + free (dtp); + return; + } + strcpy(dtp->jstrbuf, jstr); + strcpy(dtp->unit,unit); +} + +void draw_dt_vars(void) { + if (!renderer) return; + + for (uint32_t cnt = 0; cnt < MAX_DT_VARS; cnt++) { + if (dt_vars[cnt]) { + if (dt_vars[cnt]->jstrbuf) { + // draw + char vstr[MAX_DVTSIZE + 7]; + memset(vstr, ' ', sizeof(vstr)); + strcpy(vstr, dt_vars[cnt]->rstr); + strcat(vstr, " "); + strcat(vstr, dt_vars[cnt]->unit); + uint16_t slen = strlen(vstr); + vstr[slen] = ' '; + + if (!dt_vars[cnt]->txtlen) { + vstr[slen] = 0; + } else { + vstr[abs(int(dt_vars[cnt]->txtlen))] = 0; + } + if (dt_vars[cnt]->txtlen < 0) { + // right align + alignright(vstr); + } + + if (dt_vars[cnt]->txtsiz > 0) { + renderer->setDrawMode(0); + } else { + renderer->setDrawMode(2); + } + renderer->setTextColor(GetColorFromIndex(dt_vars[cnt]->txtfcol),GetColorFromIndex(dt_vars[cnt]->txtbcol)); + renderer->setTextFont(dt_vars[cnt]->font); + renderer->setTextSize(abs(dt_vars[cnt]->txtsiz)); + renderer->DrawStringAt(dt_vars[cnt]->xp, dt_vars[cnt]->yp, vstr, GetColorFromIndex(dt_vars[cnt]->txtfcol), 0); + + // reset display vars + renderer->setTextColor(fg_color, bg_color); + renderer->setDrawMode(auto_draw); + } + } + } +} + +#define DTV_JSON_SIZE 1024 + +void DTVarsTeleperiod(void) { + char *json = (char*)malloc(DTV_JSON_SIZE); + if (json) { + strlcpy(json, TasmotaGlobal.mqtt_data, DTV_JSON_SIZE); + get_dt_vars(json); + free(json); + } +} + +void get_dt_mqtt(void) { + ResponseClear(); + uint16_t script_tele_period_save = TasmotaGlobal.tele_period; + TasmotaGlobal.tele_period = 2; + XsnsNextCall(FUNC_JSON_APPEND, script_xsns_index); + TasmotaGlobal.tele_period = script_tele_period_save; + if (strlen(TasmotaGlobal.mqtt_data)) { + TasmotaGlobal.mqtt_data[0] = '{'; + snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("%s}"), TasmotaGlobal.mqtt_data); + } + get_dt_vars(TasmotaGlobal.mqtt_data); +} + +void get_dt_vars(char *json) { + if (strlen(json)) { + JsonParser parser(json); + JsonParserObject obj = parser.getRootObject(); + + for (uint32_t cnt = 0; cnt < MAX_DT_VARS; cnt++) { + if (dt_vars[cnt]) { + if (dt_vars[cnt]->jstrbuf) { + char sbuf[32]; + uint32_t res = JsonParsePath(&obj, dt_vars[cnt]->jstrbuf, '#', NULL, sbuf, sizeof(sbuf)); + if (res) { + if (dt_vars[cnt]->dp < 0) { + // use string + strcpy(dt_vars[cnt]->rstr, sbuf); + } else { + // convert back and forth + dtostrfd(CharToFloat(sbuf), dt_vars[cnt]->dp, dt_vars[cnt]->rstr); + } + } + } + } + } + } +} + +void free_dt_vars(void) { + for (uint32_t cnt = 0; cnt < MAX_DT_VARS; cnt++) { + if (dt_vars[cnt]) { + if (dt_vars[cnt]->jstrbuf) free(dt_vars[cnt]->jstrbuf); + free(dt_vars[cnt]); + dt_vars[cnt] = 0; + } + } +} + +#endif // USE_DT_VARS + /*********************************************************************************************/ #ifdef USE_DISPLAY_MODES1TO5 @@ -1399,6 +1508,10 @@ void DisplayInitDriver(void) Display_Text_From_File("/display.ini"); #endif +#ifdef USE_DT_VARS + free_dt_vars(); +#endif + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings.display_model); if (Settings.display_model) { @@ -1558,7 +1671,7 @@ void CmndDisplaySize(void) if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) { Settings.display_size = XdrvMailbox.payload; if (renderer) renderer->setTextSize(Settings.display_size); - else DisplaySetSize(Settings.display_size); + //else DisplaySetSize(Settings.display_size); } ResponseCmndNumber(Settings.display_size); } @@ -1568,7 +1681,7 @@ void CmndDisplayFont(void) if ((XdrvMailbox.payload >=0) && (XdrvMailbox.payload <= 4)) { Settings.display_font = XdrvMailbox.payload; if (renderer) renderer->setTextFont(Settings.display_font); - else DisplaySetFont(Settings.display_font); + //else DisplaySetFont(Settings.display_font); } ResponseCmndNumber(Settings.display_font); } @@ -2415,9 +2528,7 @@ bool Xdrv13(uint8_t function) case FUNC_PRE_INIT: DisplayInitDriver(); #ifdef USE_GRAPH - for (uint8_t count=0;count Date: Mon, 15 Feb 2021 17:26:55 +0100 Subject: [PATCH 5/8] upd --- tasmota/support.ino | 2 +- tasmota/support_tasmota.ino | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 56ba71ab2..0cb0daf5a 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1338,7 +1338,7 @@ int ICACHE_RAM_ATTR Pin(uint32_t gpio, uint32_t index) { bool PinUsed(uint32_t gpio, uint32_t index = 0); bool PinUsed(uint32_t gpio, uint32_t index) { - return (Pin(gpio, index) > -1); + return (Pin(gpio, index) >= 0); } uint32_t GetPin(uint32_t lpin) { diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 8579c16c9..37f36b673 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -412,7 +412,7 @@ void SetLedLink(uint32_t state) if (-1 == led_pin) { // Legacy - LED1 is status SetLedPowerIdx(0, state); } - else if (led_pin > -1) { + else if (led_pin >= 0) { if (state) { state = 1; } digitalWrite(led_pin, (led_inv) ? !state : state); } @@ -717,7 +717,7 @@ void MqttPublishTeleState(void) MqttShowState(); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); -#ifdef USE_DT_VARS +#ifdef USE_DT_VARS DTVarsTeleperiod(); #endif // USE_DT_VARS From 6fa53b85ef5ed1624fbd2fd4b0123afe5a1f7d97 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Feb 2021 17:29:31 +0100 Subject: [PATCH 6/8] Basic support for filesystem ``autoexec.bat`` --- CHANGELOG.md | 2 ++ RELEASENOTES.md | 2 ++ tasmota/xdrv_50_filesystem.ino | 36 ++++++++++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45ce15fd8..7899108dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file. - Support for Frysk language translations by Christiaan Heerze - ESP8266 Fallback to ``*.bin.gz`` binary when OTA upload of ``*.bin`` binary fails - Berry language improved Tasmota integration +- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete`` and ``UfsRename`` +- Basic support for filesystem ``autoexec.bat`` ### Changed - IRremoteESP8266 library from v2.7.14 to v2.7.15 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 175054b38..f68cf0a34 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -95,6 +95,8 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind`` and ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110`` and ``112`` - Commands ``ZbNoAutoBind``, ``ZbReceivedTopic`` and ``ZbOmitDevice`` as synonyms for ``SetOption116, 118`` and ``119`` - Commands ``BuzzerActive`` and ``BuzzerPwm`` as synonyms for ``SetOption67`` and ``111`` +- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete`` and ``UfsRename`` +- Basic support for filesystem ``autoexec.bat`` - Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152) - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - Rotary No Pullup GPIO selection ``Rotary A/B_n`` [#10407](https://github.com/arendst/Tasmota/issues/10407) diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index 08c7f18c8..c022e89be 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -336,6 +336,16 @@ bool TfsDeleteFile(const char *fname) { return true; } +bool TfsRenameFile(const char *fname1, const char *fname2) { + if (!ffs_type) { return false; } + + if (!ffsp->rename(fname1, fname2)) { + AddLog(LOG_LEVEL_INFO, PSTR("TFS: Rename failed")); + return false; + } + return true; +} + /*********************************************************************************************\ * Autoexec support \*********************************************************************************************/ @@ -380,10 +390,10 @@ void UfsAutoexec(void) { \*********************************************************************************************/ const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix - "|Type|Size|Free|Delete"; + "|Type|Size|Free|Delete|Rename"; void (* const kUFSCommand[])(void) PROGMEM = { - &UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete}; + &UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete, &UFSRename}; void UFSInfo(void) { Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}"), ufs_type, UfsInfo(0, 0), UfsInfo(1, 0)); @@ -435,6 +445,28 @@ void UFSDelete(void) { } } +void UFSRename(void) { + // UfsRename sdcard or flashfs file if only one of them available + // UfsRename2 flashfs file if available + if (XdrvMailbox.data_len > 0) { + bool result = false; + const char *fname1 = strtok(XdrvMailbox.data, ","); + const char *fname2 = strtok(nullptr, ","); + if (fname1 && fname2) { + if (ffs_type && (ffs_type != ufs_type) && (2 == XdrvMailbox.index)) { + result = TfsRenameFile(fname1, fname2); + } else { + result = (ufs_type && ufsp->rename(fname1, fname2)); + } + } + if (!result) { + ResponseCmndChar(PSTR(D_JSON_FAILED)); + } else { + ResponseCmndDone(); + } + } +} + /*********************************************************************************************\ * Web support \*********************************************************************************************/ From 6b36244bbb225df6c38c2f2a58314c366d7e3c24 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 15 Feb 2021 17:32:15 +0100 Subject: [PATCH 7/8] Update xdrv_13_display.ino --- tasmota/xdrv_13_display.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index fffe2255d..2acefcdf8 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -949,7 +949,10 @@ void Display_Text_From_File(const char *file) { #ifdef USE_DT_VARS +#ifndef MAX_DT_VARS #define MAX_DT_VARS 8 +#endif // MAX_DT_VARS + #define MAX_DVTSIZE 24 typedef struct { From 0aac8125ea591e3fc66407f0246282a91c2335a4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Feb 2021 18:01:02 +0100 Subject: [PATCH 8/8] Add more failsafe to autoexec.bat --- tasmota/xdrv_50_filesystem.ino | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index c022e89be..68af9e892 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -363,16 +363,19 @@ void UfsAutoexec(void) { file.read(buf, 1); if ((buf[0] == '\n') || (buf[0] == '\r')) { // Line terminated with linefeed or carriage return - break; + if (index < sizeof(cmd_line) - 1) { + // Process line + break; + } else { + // Discard too long line and start with next line + index = 0; + } } else if ((0 == index) && isspace(buf[0])) { // Skip leading spaces (' ','\t','\n','\v','\f','\r') - } else { - cmd_line[index] = buf[0]; - index++; - if (index >= sizeof(cmd_line) - 1) { - break; - } + } + else if (index < sizeof(cmd_line) - 2) { + cmd_line[index++] = buf[0]; } } if ((index > 0) && (cmd_line[0] != ';')) { // Information but no comment