diff --git a/CHANGELOG.md b/CHANGELOG.md
index b5176046c..277d5877c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,11 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [9.2.0.2]
+## [9.2.0.3]
+### Changed
+- Force initial default state ``SetOption57 1`` to scan wifi network every 44 minutes for strongest signal (#10395)
+
+## [9.2.0.2] 20210105
### Added
- Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630)
- Command ``CTRange`` to specify the visible CT range the bulb is capable of (#10311)
@@ -13,6 +17,7 @@ All notable changes to this project will be documented in this file.
- Command ``RuleTimer0`` to access all RuleTimers at once (#10352)
- SPI display driver SSD1331 Color oled by Jeroen Vermeulen (#10376)
- IRremoteESP8266 library from v2.7.13 to v2.7.14
+- Rotary No Pullup GPIO selection ``Rotary A/B_n`` (#10407)
### Breaking Changed
- Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``SPI CS`` by ``RC522 CS``
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 01f4cc1fc..c17382b99 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -56,7 +56,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v9.2.0.2
+## Changelog v9.2.0.3
### Added
- Command ``CTRange`` to specify the visible CT range the bulb is capable of [#10311](https://github.com/arendst/Tasmota/issues/10311)
- Command ``RuleTimer0`` to access all RuleTimers at once [#10352](https://github.com/arendst/Tasmota/issues/10352)
@@ -65,6 +65,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
- Command ``SetOption119 1`` to remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic [#10355](https://github.com/arendst/Tasmota/issues/10355)
- 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)
- BSSID and Signal Strength Indicator to GUI wifi scan result [#10253](https://github.com/arendst/Tasmota/issues/10253)
- Support for P9813 RGB Led MOSFET controller [#10104](https://github.com/arendst/Tasmota/issues/10104)
- Support for GPIO option selection
@@ -90,7 +91,8 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
### Changed
- Logging from heap to stack freeing 700 bytes RAM
-- Disabled ``USE_LIGHT`` light support for ZBBridge saving 17.6kB (#10374)
+- Disabled ``USE_LIGHT`` light support for ZBBridge saving 17.6kB [#10374](https://github.com/arendst/Tasmota/issues/10374)
+- Force initial default state ``SetOption57 1`` to scan wifi network every 44 minutes for strongest signal [#10395](https://github.com/arendst/Tasmota/issues/10395)
### Fixed
- Redesign syslog and mqttlog using log buffer [#10164](https://github.com/arendst/Tasmota/issues/10164)
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 8741e6247..a40702660 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
@@ -1579,6 +1579,8 @@ void Adafruit_GFX_Button::initButtonUL(
strncpy(_label, label, 9);
}
+void draw_picture(char *path, uint32_t xp, uint32_t yp, uint32_t xs, uint32_t ys, bool inverted);
+
/**************************************************************************/
/*!
@brief Draw the button on the screen
@@ -1598,16 +1600,20 @@ void Adafruit_GFX_Button::drawButton(boolean inverted) {
text = _fillcolor;
}
- uint8_t r = min(_w, _h) / 4; // Corner radius
- _gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill);
- _gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline);
-
- _gfx->setCursor(_x1 + (_w/2) - (strlen(_label) * 3 * _textsize_x),
- _y1 + (_h/2) - (4 * _textsize_y));
- _gfx->setTextColor(text);
- _gfx->setTextSize(_textsize_x, _textsize_y);
- _gfx->print(_label);
+ if (_label[0]=='/') {
+ // picture path
+ draw_picture(_label, _x1, _y1, _w, _h, inverted);
+ _gfx->drawRect(_x1, _y1, _w, _h, text);
+ } else {
+ uint8_t r = min(_w, _h) / 4; // Corner radius
+ _gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill);
+ _gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline);
+ _gfx->setCursor(_x1 + (_w/2) - (strlen(_label) * 3 * _textsize_x), _y1 + (_h/2) - (4 * _textsize_y));
+ _gfx->setTextColor(text);
+ _gfx->setTextSize(_textsize_x, _textsize_y);
+ _gfx->print(_label);
+ }
}
/**************************************************************************/
diff --git a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp
index a4391f10e..d590cdc14 100644
--- a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp
+++ b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp
@@ -545,6 +545,12 @@ void ILI9341_2::DisplayOnff(int8_t on) {
}
}
+void ILI9341_2::invertDisplay(boolean i) {
+ ILI9341_2_CS_LOW
+ writecmd(i ? ILI9341_2_INVOFF : ILI9341_2_INVON);
+ ILI9341_2_CS_HIGH
+}
+
void ili9342_dimm(uint8_t dim);
// dimmer 0-100
diff --git a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h
index 27ff00e5d..a4608e6ba 100644
--- a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h
+++ b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h
@@ -119,30 +119,6 @@ class ILI9341_2 : public Renderer {
ILI9341_2(int8_t cs, int8_t res, int8_t dc, int8_t bp);
void init(uint16_t width, uint16_t height);
- /*
- void begin(void);
- void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font);
- void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
- void setScrollArea(uint16_t topFixedArea, uint16_t bottomFixedArea);
- void scroll(uint16_t pixels);
- void pushColor(uint16_t color);
- void pushColors(uint16_t *data, uint8_t len, boolean first);
- //void drawImage(const uint8_t* img, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
- void fillScreen(uint16_t color);
- void drawPixel(int16_t x, int16_t y, uint16_t color);
- void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
- void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
- void fillRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color);
- void setRotation(uint8_t r);
- void invertDisplay(boolean i);
- uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
- void DisplayOnff(int8_t on);
- void writecommand(uint8_t c);
- void writedata(uint8_t d);
- void write16BitColor(uint16_t color);
- void commandList(uint8_t *addr);
- void hw_spi_init();
- void dim(uint8_t contrast);*/
uint16_t GetColorFromIndex(uint8_t index);
private:
@@ -161,7 +137,7 @@ class ILI9341_2 : public Renderer {
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void dim(uint8_t dim);
void pushColors(uint16_t *data, uint8_t len, boolean first);
-
+ void invertDisplay(boolean i);
void spiwrite(uint8_t c);
void spiwrite16(uint16_t c);
void spiwrite32(uint32_t c);
diff --git a/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp b/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp
index 357000a69..61dea05c1 100644
--- a/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp
+++ b/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp
@@ -503,6 +503,16 @@ void ILI9488::scroll(uint16_t pixels){
}*/
void ILI9488::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
+ if (!x0 && !y0 && !x1 && !y1) {
+ x0=0;
+ y0=0;
+ x1=_width;
+ y1=_height;
+ }
+ setAddrWindow_int(x0, y0, x1-1, y1-1);
+}
+
+void ILI9488::setAddrWindow_int(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
uint8_t flag=0;
if (!x0 && !y0 && !x1 && !y1) {
@@ -594,6 +604,7 @@ void ILI9488::pushColor(uint16_t color) {
ILI9488_STOP
}
+#if 1
void ILI9488::pushColors(uint16_t *data, uint8_t len, boolean first) {
uint16_t color;
uint8_t buff[len*3+1];
@@ -616,6 +627,17 @@ void ILI9488::pushColors(uint16_t *data, uint8_t len, boolean first) {
ILI9488_STOP
}
+#else
+
+void ILI9488::pushColors(uint16_t *data, uint8_t len, boolean first) {
+ uint16_t color;
+
+ while (len--) {
+ write16BitColor(*data++);
+ }
+ ILI9488_STOP
+}
+#endif
void ILI9488::write16BitColor(uint16_t color){
// #if (__STM32F1__)
@@ -688,7 +710,7 @@ void ILI9488::drawPixel(int16_t x, int16_t y, uint16_t color) {
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
- setAddrWindow(x,y,x+1,y+1);
+ setAddrWindow_int(x,y,x+1,y+1);
write16BitColor(color);
ILI9488_STOP
}
@@ -702,7 +724,7 @@ void ILI9488::drawFastVLine(int16_t x, int16_t y, int16_t h,
if((y+h-1) >= _height)
h = _height-y;
- setAddrWindow(x, y, x, y+h-1);
+ setAddrWindow_int(x, y, x, y+h-1);
uint8_t r = (color & 0xF800) >> 11;
uint8_t g = (color & 0x07E0) >> 5;
@@ -770,7 +792,7 @@ void ILI9488::drawFastHLine(int16_t x, int16_t y, int16_t w,
if((x >= _width) || (y >= _height)) return;
if((x+w-1) >= _width) w = _width-x;
- setAddrWindow(x, y, x+w-1, y);
+ setAddrWindow_int(x, y, x+w-1, y);
uint8_t r = (color & 0xF800) >> 11;
uint8_t g = (color & 0x07E0) >> 5;
@@ -905,7 +927,7 @@ void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colo
if((x + w - 1) >= _width) w = _width - x;
if((y + h - 1) >= _height) h = _height - y;
- setAddrWindow(x, y, x+w-1, y+h-1);
+ setAddrWindow_int(x, y, x+w-1, y+h-1);
//ILI9488_START
uint8_t r = (color & 0xF800) >> 11;
@@ -1050,7 +1072,7 @@ void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colo
if((x + w - 1) >= _width) w = _width - x;
if((y + h - 1) >= _height) h = _height - y;
- setAddrWindow(x, y, x+w-1, y+h-1);
+ setAddrWindow_int(x, y, x+w-1, y+h-1);
uint8_t r = (color & 0xF800) >> 11;
uint8_t g = (color & 0x07E0) >> 5;
diff --git a/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.h b/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.h
index 5fd2e39e5..50557822e 100644
--- a/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.h
+++ b/lib/lib_display/JaretBurkett_ILI9488-gemu-1.0/ILI9488.h
@@ -136,6 +136,7 @@ class ILI9488 : public Renderer {
void begin(void);
void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font);
+ void setAddrWindow_int(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void setScrollArea(uint16_t topFixedArea, uint16_t bottomFixedArea);
void scroll(uint16_t pixels);
diff --git a/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp b/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp
index a8f0f9e57..1b78aaa9a 100644
--- a/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp
+++ b/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp
@@ -32,6 +32,10 @@
//#define USE_GFX_FONTS
#define USE_TINY_FONT
+#ifdef ESP32
+#define USE_ICON_FONT
+#endif
+
uint8_t wr_redir=0;
uint8_t *buffer;
@@ -223,27 +227,32 @@ void Renderer::setTextFont(uint8_t f) {
break;
case 7:
selected_font = &RAFont;
+ break;
default:
- font=0;
+ selected_font = &Font12;
+ break;
}
#else
#ifdef USE_EPD_FONTS
- if (1 == font) {
+ switch (font) {
selected_font = &Font12;
- } else {
- #ifdef USE_TINY_FONT
- if (2 == font) {
- selected_font = &Font24;
- } else {
- selected_font = &Font8;
- }
- #else
+ break;
+ case 2:
selected_font = &Font24;
- #endif
+ break;
+ case 3:
+#ifdef USE_TINY_FONT
+ selected_font = &Font8;
+#else
+ selected_font = &Font24;
+#endif
+ break;
+ default:
+ selected_font = &Font12;
+ break;
}
#endif
#endif
-
}
@@ -513,6 +522,9 @@ void Renderer::setDrawMode(uint8_t mode) {
drawmode=mode;
}
+void Renderer::invertDisplay(boolean i) {
+}
+
void VButton::xdrawButton(bool inverted) {
wr_redir=1;
drawButton(inverted);
@@ -520,4 +532,6 @@ void VButton::xdrawButton(bool inverted) {
}
+
+
/* END OF FILE */
diff --git a/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h b/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h
index 27ff56efe..0685b9bb1 100644
--- a/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h
+++ b/lib/lib_display/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h
@@ -35,6 +35,7 @@ public:
virtual void dim(uint8_t contrast);
virtual void pushColors(uint16_t *data, uint8_t len, boolean first);
virtual void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+ virtual void invertDisplay(boolean i);
void setDrawMode(uint8_t mode);
uint8_t drawmode;
virtual void FastString(uint16_t x,uint16_t y,uint16_t tcolor, const char* str);
diff --git a/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp b/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp
index 687661ac9..395c43028 100755
--- a/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp
+++ b/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp
@@ -3723,6 +3723,8 @@ void IMAPData::setFetchUID(const String &fetchUID)
std::string().swap(tmp);
}
+extern FS *ufsp;
+
void IMAPData::setFileStorageType(uint8_t storageType)
{
_storageType = storageType;
@@ -3736,6 +3738,9 @@ void IMAPData::setFileStorageType(uint8_t storageType)
case MailClientStorageType::FFat:
fsp = &FFat;
break;
+ case MailClientStorageType::Univ:
+ fsp = ufsp;
+ break;
}
}
@@ -4766,6 +4771,9 @@ void SMTPData::setFileStorageType(uint8_t storageType)
case MailClientStorageType::FFat:
fsp = &FFat;
break;
+ case MailClientStorageType::Univ:
+ fsp = ufsp;
+ break;
}
}
diff --git a/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h b/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h
index b6a8da775..0b1f4496c 100755
--- a/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h
+++ b/lib/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h
@@ -92,6 +92,7 @@ struct MailClientStorageType
static const uint8_t SPIFFS = 0;
static const uint8_t SD = 1;
static const uint8_t FFat = 2;
+ static const uint8_t Univ = 3;
};
static const char ESP32_MAIL_STR_1[] PROGMEM = "Content-Type: multipart/mixed; boundary=\"";
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index eaaf59729..aa8ed16be 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -134,6 +134,7 @@ lib_extra_dirs = ${library.lib_extra_dirs}
[core32_stage]
platform = espressif32 @ 2.1.0
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc4/esp32-1.0.5-rc4.zip
+ platformio/tool-mklittlefs @ ~1.203.200522
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}
;-DESP32_STAGE=true
diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini
index 430fcc344..cb5d9c2e5 100644
--- a/platformio_tasmota32.ini
+++ b/platformio_tasmota32.ini
@@ -90,5 +90,6 @@ build_flags = ${esp_defaults.build_flags}
[core32]
platform = espressif32 @ 2.1.0
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc4/esp32-1.0.5-rc4.zip
+ platformio/tool-mklittlefs @ ~1.203.200522
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}
diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini
index 1d64e6650..108792fce 100644
--- a/platformio_tasmota_env32.ini
+++ b/platformio_tasmota_env32.ini
@@ -40,8 +40,8 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic
extends = env:tasmota32
board = odroid_esp32
board_build.f_cpu = 240000000L
-board_build.partitions = esp32_partition_app1984k_ffat12M.csv
-build_flags = ${common32.build_flags} -DBOARD_HAS_PSRAM=true -DFIRMWARE_ODROID_GO
+board_build.partitions = esp32_partition_app1984k_spiffs12M.csv
+build_flags = ${common32.build_flags} -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DFIRMWARE_ODROID_GO
lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display
[env:tasmota32-minimal]
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 029b22a88..049cd5af6 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Wysig skrif"
#define D_SCRIPT "wysig skrif"
#define D_SDCARD_UPLOAD "lêer oplaai"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Klaar"
#define D_SCRIPT_CHARS_LEFT "karakters oor"
#define D_SCRIPT_CHARS_NO_MORE "nie meer karakters nie"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index febb69927..df87380c0 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -864,7 +864,7 @@
#define D_CONFIGURE_SCRIPT "Редакция на скрипт"
#define D_SCRIPT "редактирай скрипт"
#define D_SDCARD_UPLOAD "изпрати файл"
-#define D_SDCARD_DIR "директория на SD картата"
+#define D_UFSDIR "директория на UFS картата"
#define D_UPL_DONE "Готово"
#define D_SCRIPT_CHARS_LEFT "оставащи символи"
#define D_SCRIPT_CHARS_NO_MORE "няма повече символи"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index 93b82116c..99e61570c 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs card directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 8051388a9..f60108589 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Skript konfigurieren"
#define D_SCRIPT "Skript bearbeiten"
#define D_SDCARD_UPLOAD "Datei speichern"
-#define D_SDCARD_DIR "SD Card Verzeichnis"
+#define D_UFSDIR "UFS Verzeichnis"
#define D_UPL_DONE "Fertig"
#define D_SCRIPT_CHARS_LEFT "Zeichen übrig"
#define D_SCRIPT_CHARS_NO_MORE "kein Speicher mehr"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index 150262930..5c903e821 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index e864d67fa..6f5c7c345 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index 2dcb250ec..fbb2688b6 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Editar Script"
#define D_SCRIPT "Editar Script"
#define D_SDCARD_UPLOAD "Subir Archivo"
-#define D_SDCARD_DIR "Directorio en Tarjeta SD"
+#define D_UFSDIR "Directorio en Tarjeta UFS"
#define D_UPL_DONE "Listo"
#define D_SCRIPT_CHARS_LEFT "Caracteres disponibles"
#define D_SCRIPT_CHARS_NO_MORE "No hay mas espacio"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 6f4dbefad..9a62e90c6 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -858,7 +858,7 @@
#define D_CONFIGURE_SCRIPT "Éditer le script"
#define D_SCRIPT "édition du script"
#define D_SDCARD_UPLOAD "Envoi du fichier"
-#define D_SDCARD_DIR "Dossier carte SD"
+#define D_UFSDIR "Dossier UFS"
#define D_UPL_DONE "Terminé"
#define D_SCRIPT_CHARS_LEFT "car. restant"
#define D_SCRIPT_CHARS_NO_MORE "plus de car."
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 660afb117..10c45e1f0 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index ce31bb641..ba628122a 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 0d100c074..763986451 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Modifica script"
#define D_SCRIPT "modifica script"
#define D_SDCARD_UPLOAD "upload file"
-#define D_SDCARD_DIR "cartella scheda SD"
+#define D_UFSDIR "cartella scheda UFS"
#define D_UPL_DONE "Completato"
#define D_SCRIPT_CHARS_LEFT "caratteri rimanenti"
#define D_SCRIPT_CHARS_NO_MORE "nessun altro carattere"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 58a2b0344..25493d6c1 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 3535c3049..6481799f2 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index b4ecd5201..b33e0e221 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index 41bd49646..35eacffea 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index ed2c24f27..4985d386d 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index 50c89e778..8f44f53ca 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Configurare script"
#define D_SCRIPT "editează script"
#define D_SDCARD_UPLOAD "Încarcă fișier"
-#define D_SDCARD_DIR "director sd card"
+#define D_UFSDIR "director ufs"
#define D_UPL_DONE "Terminat"
#define D_SCRIPT_CHARS_LEFT "caractere rămase"
#define D_SCRIPT_CHARS_NO_MORE "caractere terminate"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index 9188c931a..678eae852 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 3bca04ce9..2d567b1a4 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index 69b83afea..95303ab60 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index 12c05ff6e..82d684839 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index 219a261e7..738886f35 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Конфігурація сценарія"
#define D_SCRIPT "Редагування сценарія"
#define D_SDCARD_UPLOAD "завантажити файл на карту SD"
-#define D_SDCARD_DIR "завантажити файл в каталог на карту SD"
+#define D_UFSDIR "завантажити файл в каталог на карту UFS"
#define D_UPL_DONE "Готово"
#define D_SCRIPT_CHARS_LEFT "символів ще вільно"
#define D_SCRIPT_CHARS_NO_MORE "більше немає місця"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index b215b110e..2fa5e4282 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Chỉnh sửa kịch bản"
#define D_SCRIPT "chỉnh sửa kịch bản"
#define D_SDCARD_UPLOAD "tải lên tệp"
-#define D_SDCARD_DIR "thư mục thẻ nhớ sd"
+#define D_UFSDIR "thư mục thẻ nhớ ufs"
#define D_UPL_DONE "Hoàn thành"
#define D_SCRIPT_CHARS_LEFT "ký tự đã dùng"
#define D_SCRIPT_CHARS_NO_MORE "không còn ký tự trống"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 48c46ba5b..d5079a834 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "Edit script"
#define D_SCRIPT "edit script"
#define D_SDCARD_UPLOAD "file upload"
-#define D_SDCARD_DIR "sd card directory"
+#define D_UFSDIR "ufs directory"
#define D_UPL_DONE "Done"
#define D_SCRIPT_CHARS_LEFT "chars left"
#define D_SCRIPT_CHARS_NO_MORE "no more chars"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 5bde78ae2..d68e00380 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -865,7 +865,7 @@
#define D_CONFIGURE_SCRIPT "編輯腳本"
#define D_SCRIPT "編輯腳本"
#define D_SDCARD_UPLOAD "上傳檔案"
-#define D_SDCARD_DIR "記憶卡目錄"
+#define D_UFSDIR "記憶卡目錄"
#define D_UPL_DONE "完成"
#define D_SCRIPT_CHARS_LEFT "剩餘字元"
#define D_SCRIPT_CHARS_NO_MORE "放不下更多字元了"
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index fb9c30774..9d33e6312 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -80,7 +80,7 @@
// The configuration can be changed after first setup using WifiConfig 0, 2, 4, 5, 6 and 7.
#define WIFI_ARP_INTERVAL 0 // [SetOption41] Send gratuitous ARP interval
#define WIFI_SCAN_AT_RESTART false // [SetOption56] Scan wifi network at restart for configured AP's
-#define WIFI_SCAN_REGULARLY false // [SetOption57] Scan wifi network every 44 minutes for configured AP's
+#define WIFI_SCAN_REGULARLY true // [SetOption57] Scan wifi network every 44 minutes for configured AP's
// -- Syslog --------------------------------------
#define SYS_LOG_HOST "" // [LogHost] (Linux) syslog host
diff --git a/tasmota/sendemail.ino b/tasmota/sendemail.ino
index 467646487..6d075599b 100644
--- a/tasmota/sendemail.ino
+++ b/tasmota/sendemail.ino
@@ -389,7 +389,7 @@ void xsend_message_txt(char *msg) {
#ifdef DEBUG_EMAIL_PORT
AddLog_P(LOG_LEVEL_INFO, PSTR("%s"),msg);
#endif
-#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)
+#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(UFILESYSTEM)
if (*msg=='@') {
msg++;
attach_File(msg);
@@ -415,9 +415,9 @@ void xsend_message_txt(char *msg) {
#endif
}
-#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)
+#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(UFILESYSTEM)
#include
-extern FS *fsp;
+extern FS *ufsp;
void attach_File(char *path) {
g_client->print(F("--frontier\r\n"));
@@ -425,7 +425,7 @@ void attach_File(char *path) {
char buff[64];
char *cp = path;
while (*cp=='/') cp++;
- File file = fsp->open(path, "r");
+ File file = ufsp->open(path, "r");
if (file) {
sprintf_P(buff,PSTR("Content-Disposition: attachment; filename=\"%s\"\r\n\r\n"), cp);
g_client->write(buff);
@@ -717,6 +717,8 @@ uint16_t SendMail(char *buffer) {
//Set the storage types to read the attach files (SD is default)
//smtpData.setFileStorageType(MailClientStorageType::SPIFFS);
+
+/*
#ifdef USE_SCRIPT_FATFS
#if USE_SCRIPT_FATFS<0
smtpData.setFileStorageType(MailClientStorageType::FFat);
@@ -724,6 +726,9 @@ uint16_t SendMail(char *buffer) {
smtpData.setFileStorageType(MailClientStorageType::SD);
#endif
#endif
+*/
+
+smtpData.setFileStorageType(MailClientStorageType::Univ);
//smtpData.setSendCallback(sendCallback);
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index 465789eb8..d1985fee8 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -51,31 +51,33 @@ void RtcSettingsSave(void)
}
}
-bool RtcSettingsLoad(void) {
- bool was_read_valid = true;
+bool RtcSettingsLoad(uint32_t update) {
#ifdef ESP8266
ESP.rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RtcSettings)); // 0x290
#endif // ESP8266
#ifdef ESP32
RtcSettings = RtcDataSettings;
#endif // ESP32
- if (RtcSettings.valid != RTC_MEM_VALID) {
- was_read_valid = false;
- memset(&RtcSettings, 0, sizeof(RtcSettings));
- RtcSettings.valid = RTC_MEM_VALID;
- RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday;
- RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
- RtcSettings.energy_usage = Settings.energy_usage;
- for (uint32_t i = 0; i < MAX_COUNTERS; i++) {
- RtcSettings.pulse_counter[i] = Settings.pulse_counter[i];
+
+ bool read_valid = (RTC_MEM_VALID == RtcSettings.valid);
+ if (update) {
+ if (!read_valid) {
+ memset(&RtcSettings, 0, sizeof(RtcSettings));
+ RtcSettings.valid = RTC_MEM_VALID;
+ RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday;
+ RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
+ RtcSettings.energy_usage = Settings.energy_usage;
+ for (uint32_t i = 0; i < MAX_COUNTERS; i++) {
+ RtcSettings.pulse_counter[i] = Settings.pulse_counter[i];
+ }
+ RtcSettings.power = Settings.power;
+ // RtcSettings.baudrate = Settings.baudrate * 300;
+ RtcSettings.baudrate = APP_BAUDRATE;
+ RtcSettingsSave();
}
- RtcSettings.power = Settings.power;
-// RtcSettings.baudrate = Settings.baudrate * 300;
- RtcSettings.baudrate = APP_BAUDRATE;
- RtcSettingsSave();
+ rtc_settings_crc = GetRtcSettingsCrc();
}
- rtc_settings_crc = GetRtcSettingsCrc();
- return was_read_valid;
+ return read_valid;
}
bool RtcSettingsValid(void)
@@ -571,7 +573,7 @@ void SettingsLoad(void) {
settings_crc32 = GetSettingsCrc32();
#endif // FIRMWARE_MINIMAL
- RtcSettingsLoad();
+ RtcSettingsLoad(1);
}
// Used in TLS - returns the timestamp of the last Flash settings write
@@ -1323,6 +1325,9 @@ void SettingsDelta(void)
if (Settings.version < 0x09010000) {
Settings.dimmer_step = DEFAULT_DIMMER_STEP;
}
+ if (Settings.version < 0x09020003) {
+ Settings.flag3.use_wifi_rescan = true; // As a result of #10395
+ }
Settings.version = VERSION;
SettingsSave(1);
diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino
index 0554129e8..79821806b 100644
--- a/tasmota/support_esp32.ino
+++ b/tasmota/support_esp32.ino
@@ -86,6 +86,11 @@ uint32_t FlashWriteMaxSector(void) {
uint8_t* FlashDirectAccess(void) {
return (uint8_t*)(0x40200000 + (FlashWriteStartSector() * SPI_FLASH_SEC_SIZE));
}
+
+void *special_malloc(uint32_t size) {
+ return malloc(size);
+}
+
#endif
/*********************************************************************************************\
@@ -414,4 +419,13 @@ uint8_t* FlashDirectAccess(void) {
return data;
}
-#endif // ESP32
\ No newline at end of file
+
+void *special_malloc(uint32_t size) {
+ if (psramFound()) {
+ return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+ } else {
+ return malloc(size);
+ }
+}
+
+#endif // ESP32
diff --git a/tasmota/support_jpeg.ino b/tasmota/support_jpeg.ino
index 4669b9ad7..2ebce0e4c 100644
--- a/tasmota/support_jpeg.ino
+++ b/tasmota/support_jpeg.ino
@@ -29,9 +29,27 @@ uint8_t red, grn, blu;
uint16_t b , g, r;
for (uint32_t cnt=0; cnt> 3) & 0x1f;
+ g = ((grn >> 2) & 0x3f) << 5;
+ r = ((red >> 3) & 0x1f) << 11;
+ *out++ = (r | g | b);
+ }
+
+}
+
+void rgb888_to_565i(uint8_t *in, uint16_t *out, uint32_t len) {
+uint8_t red, grn, blu;
+uint16_t b , g, r;
+
+ for (uint32_t cnt=0; cnt> 3) & 0x1f;
g = ((grn >> 2) & 0x3f) << 5;
r = ((red >> 3) & 0x1f) << 11;
diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino
index 7470a0985..538aeff2f 100644
--- a/tasmota/support_rotary.ino
+++ b/tasmota/support_rotary.ino
@@ -55,6 +55,8 @@ const uint8_t rotary_offset = 128;
const int8_t rotary_state_pos[16] = { 0, 1, -1, 2, -1, 0, -2, 1, 1, -2, 0, -1, 2, -1, 1, 0 };
struct ROTARY {
+ uint8_t no_pullup_mask_a = 0; // Rotary A pull-up bitmask flags
+ uint8_t no_pullup_mask_b = 0; // Rotary B pull-up bitmask flags
uint8_t model;
bool present;
} Rotary;
@@ -74,6 +76,14 @@ tEncoder Encoder[MAX_ROTARIES];
/********************************************************************************************/
+void RotaryAPullupFlag(uint32 switch_bit) {
+ bitSet(Rotary.no_pullup_mask_a, switch_bit);
+}
+
+void RotaryBPullupFlag(uint32 switch_bit) {
+ bitSet(Rotary.no_pullup_mask_b, switch_bit);
+}
+
bool RotaryButtonPressed(uint32_t button_index) {
if (!Rotary.present) { return false; }
@@ -136,8 +146,8 @@ void RotaryInit(void) {
Encoder[index].position = rotary_offset;
Encoder[index].pina = Pin(GPIO_ROT1A, index);
Encoder[index].pinb = Pin(GPIO_ROT1B, index);
- pinMode(Encoder[index].pina, INPUT_PULLUP);
- pinMode(Encoder[index].pinb, INPUT_PULLUP);
+ pinMode(Encoder[index].pina, bitRead(Rotary.no_pullup_mask_a, index) ? INPUT : INPUT_PULLUP);
+ pinMode(Encoder[index].pinb, bitRead(Rotary.no_pullup_mask_b, index) ? INPUT : INPUT_PULLUP);
if (0 == Rotary.model) {
attachInterruptArg(Encoder[index].pina, RotaryIsrArgMiDesk, &Encoder[index], CHANGE);
attachInterruptArg(Encoder[index].pinb, RotaryIsrArgMiDesk, &Encoder[index], CHANGE);
diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino
index 9884b337f..e9afa4597 100644
--- a/tasmota/support_rtc.ino
+++ b/tasmota/support_rtc.ino
@@ -400,15 +400,6 @@ void RtcSecond(void)
} else {
TasmotaGlobal.rules_flag.time_set = 1;
}
-
-#ifdef ESP32
- // Sync RTOS time to be used by SD Card time stamps
- struct timeval tv;
- tv.tv_sec = Rtc.local_time;
- tv.tv_usec = 0;
- settimeofday(&tv, nullptr);
-#endif // ESP32
-
} else {
Rtc.utc_time++; // Increment every second
}
@@ -463,6 +454,17 @@ void RtcSecond(void)
Rtc.midnight = Rtc.local_time;
Rtc.midnight_now = true;
}
+
+#ifdef ESP32
+ if (mutex) { // Time is just synced and is valid
+ // Sync RTOS time to be used by SD Card time stamps
+ struct timeval tv;
+ tv.tv_sec = Rtc.local_time;
+ tv.tv_usec = 0;
+ settimeofday(&tv, nullptr);
+ }
+#endif // ESP32
+
}
RtcTime.year += 1970;
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index d58447337..060f71eb4 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -1538,6 +1538,16 @@ void GpioInit(void)
bitSet(TasmotaGlobal.gpio_optiona.data, mpin - AGPIO(GPIO_OPTION_A));
mpin = GPIO_NONE;
}
+#ifdef ROTARY_V1
+ else if ((mpin >= AGPIO(GPIO_ROT1A_NP)) && (mpin < (AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES))) {
+ RotaryAPullupFlag(mpin - AGPIO(GPIO_ROT1A_NP));
+ mpin -= (AGPIO(GPIO_ROT1A_NP) - AGPIO(GPIO_ROT1A));
+ }
+ else if ((mpin >= AGPIO(GPIO_ROT1B_NP)) && (mpin < (AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES))) {
+ RotaryBPullupFlag(mpin - AGPIO(GPIO_ROT1B_NP));
+ mpin -= (AGPIO(GPIO_ROT1B_NP) - AGPIO(GPIO_ROT1B));
+ }
+#endif // ROTARY_V1
else if ((mpin >= AGPIO(GPIO_SWT1_NP)) && (mpin < (AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES))) {
SwitchPullupFlag(mpin - AGPIO(GPIO_SWT1_NP));
mpin -= (AGPIO(GPIO_SWT1_NP) - AGPIO(GPIO_SWT1));
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 8eb7303fb..e060853ea 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -220,7 +220,7 @@ void setup(void) {
#endif
RtcRebootSave();
- if (RtcSettingsLoad()) {
+ if (RtcSettingsLoad(0)) {
uint32_t baudrate = (RtcSettings.baudrate / 300) * 300; // Make it a valid baudrate
if (baudrate) { TasmotaGlobal.baudrate = baudrate; }
}
diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h
index 3ce9881f6..63a973e19 100644
--- a/tasmota/tasmota_configurations_ESP32.h
+++ b/tasmota/tasmota_configurations_ESP32.h
@@ -52,6 +52,8 @@
#define FALLBACK_MODULE ODROID_GO // [Module2] Select default module on fast reboot where USER_MODULE is user template
#define USE_ODROID_GO // Add support for Odroid Go
+#define USE_UFILESYS
+#define USE_SDCARD
#define USE_ADC
#define USE_SPI
#define USE_DISPLAY // Add SPI Display Support (+2k code)
diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h
index 5d616c137..0a48c3a66 100644
--- a/tasmota/tasmota_template.h
+++ b/tasmota/tasmota_template.h
@@ -143,6 +143,7 @@ enum UserSelectablePins {
GPIO_ST7789_CS, GPIO_ST7789_DC,
GPIO_SSD1331_CS, GPIO_SSD1331_DC,
GPIO_SDCARD_CS,
+ GPIO_ROT1A_NP, GPIO_ROT1B_NP, // Rotary switch
GPIO_ADC_PH, // Analog PH Sensor
GPIO_SENSOR_END };
@@ -237,7 +238,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|"
D_SENSOR_ARIRFRCV "|" D_SENSOR_ARIRFSEL "|"
D_SENSOR_TXD "|" D_SENSOR_RXD "|"
- D_SENSOR_ROTARY "_a|" D_SENSOR_ROTARY "_b|"
+ D_SENSOR_ROTARY " A|" D_SENSOR_ROTARY " B|"
D_SENSOR_ADC_JOYSTICK "|"
D_SENSOR_MAX31865_CS "|"
D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|"
@@ -294,7 +295,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_SHELLY_DIMMER_BOOT0 "|" D_SENSOR_SHELLY_DIMMER_RST_INV "|"
D_SENSOR_RC522_RST "|"
D_SENSOR_P9813_CLK "|" D_SENSOR_P9813_DAT "|"
- D_SENSOR_OPTION "_a|"
+ D_SENSOR_OPTION " A|"
D_SENSOR_FTC532 "|"
D_SENSOR_RC522_CS "|"
D_SENSOR_NRF24_CS "|" D_SENSOR_NRF24_DC "|"
@@ -307,6 +308,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_ST7789_CS "|" D_SENSOR_ST7789_DC "|"
D_SENSOR_SSD1331_CS "|" D_SENSOR_SSD1331_DC "|"
D_SENSOR_SDCARD_CS "|"
+ D_SENSOR_ROTARY " A_n|" D_SENSOR_ROTARY " B_n|"
D_SENSOR_ADC_PH "|"
;
@@ -332,6 +334,8 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#ifdef ROTARY_V1
AGPIO(GPIO_ROT1A) + MAX_ROTARIES, // Rotary A Pin
AGPIO(GPIO_ROT1B) + MAX_ROTARIES, // Rotary B Pin
+ AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES, // Rotary A Pin No Pullup
+ AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES, // Rotary B Pin No Pullup
#endif
AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays
AGPIO(GPIO_REL1_INV) + MAX_RELAYS,
@@ -2475,7 +2479,7 @@ const mytmplt kModules[] PROGMEM =
AGPIO(GPIO_SPI_MISO), // 19 IO GPIO19, VSPI_MISO
0, // 20
AGPIO(GPIO_ILI9341_DC), // 21 IO GPIO21, SPI_DC_LCD
- 0, // 22 IO LED GPIO22, VSPI_CS1_TFLASH
+ AGPIO(GPIO_SDCARD_CS), // 22 IO LED GPIO22, VSPI_CS1_TFLASH
AGPIO(GPIO_SPI_MOSI), // 23 IO GPIO23, VSPI_MOSI
0, // 24
0, // 25 IO GPIO25, DAC_1 (PAM8304A)
diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h
index c61d7dbaa..d4b504f4f 100644
--- a/tasmota/tasmota_version.h
+++ b/tasmota/tasmota_version.h
@@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
-const uint32_t VERSION = 0x09020002;
+const uint32_t VERSION = 0x09020003;
#endif // _TASMOTA_VERSION_H_
diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino
index 3d57bdc95..4a63588f8 100644
--- a/tasmota/xdrv_01_webserver.ino
+++ b/tasmota/xdrv_01_webserver.ino
@@ -1583,7 +1583,7 @@ void ModuleSaveSettings(void)
} else {
if (ValidGPIO(i, template_gp.io[i])) {
Settings.my_gp.io[i] = WebGetGpioArg(i);
- gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(Settings.my_gp.io[i]);
+ gpios += F(", "); gpios += String(i); gpios += F(" "); gpios += String(Settings.my_gp.io[i]);
}
}
}
diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino
index e7b52b9ab..7c7ba932e 100644
--- a/tasmota/xdrv_03_energy.ino
+++ b/tasmota/xdrv_03_energy.ino
@@ -558,14 +558,16 @@ void EnergyCommandCalResponse(uint32_t nvalue)
void CmndEnergyReset(void)
{
- if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
- char *p;
- unsigned long lnum = strtoul(XdrvMailbox.data, &p, 10);
- if (p != XdrvMailbox.data) {
+ uint32_t values[2] = { 0 };
+ uint32_t params = ParseParameters(2, values);
+ values[0] *= 100;
+
+ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 5)) {
+ if (params > 0) {
switch (XdrvMailbox.index) {
case 1:
// Reset Energy Today
- Energy.kWhtoday_offset = lnum *100;
+ Energy.kWhtoday_offset = values[0];
Energy.kWhtoday = 0;
Energy.kWhtoday_delta = 0;
Energy.start_energy = 0;
@@ -573,56 +575,55 @@ void CmndEnergyReset(void)
Settings.energy_kWhtoday = Energy.kWhtoday_offset;
RtcSettings.energy_kWhtoday = Energy.kWhtoday_offset;
Energy.daily = (float)Energy.kWhtoday_offset / 100000;
- if (!RtcSettings.energy_kWhtotal && !Energy.kWhtoday_offset) {
- Settings.energy_kWhtotal_time = LocalTime();
+ if( params > 1) {
+ Settings.energy_kWhtotal_time = values[1];
+ }
+ else {
+ if (!RtcSettings.energy_kWhtotal && !Energy.kWhtoday_offset) {
+ Settings.energy_kWhtotal_time = LocalTime();
+ }
}
break;
case 2:
// Reset Energy Yesterday
- Settings.energy_kWhyesterday = lnum *100;
+ Settings.energy_kWhyesterday = values[0];
+ if( params > 1) {
+ Settings.energy_kWhtotal_time = values[1];
+ }
break;
case 3:
// Reset Energy Total
- RtcSettings.energy_kWhtotal = lnum *100;
+ RtcSettings.energy_kWhtotal = values[0];
Settings.energy_kWhtotal = RtcSettings.energy_kWhtotal;
// Energy.total = (float)(RtcSettings.energy_kWhtotal + Energy.kWhtoday_offset + Energy.kWhtoday) / 100000;
- Settings.energy_kWhtotal_time = (!Energy.kWhtoday_offset) ? LocalTime() : Midnight();
+ if( params > 1) {
+ Settings.energy_kWhtotal_time = values[1];
+ }
+ else {
+ Settings.energy_kWhtotal_time = (!Energy.kWhtoday_offset) ? LocalTime() : Midnight();
+ }
RtcSettings.energy_usage.last_usage_kWhtotal = (uint32_t)(Energy.total * 1000);
break;
- }
- }
- }
- else if ((XdrvMailbox.index > 3) && (XdrvMailbox.index <= 5)) {
- uint32_t values[2] = { 0 };
- uint32_t position = ParseParameters(2, values);
- values[0] *= 100;
- values[1] *= 100;
-
- switch (XdrvMailbox.index)
- {
case 4:
// Reset energy_usage.usage totals
- if (position > 0) {
- RtcSettings.energy_usage.usage1_kWhtotal = values[0];
- }
- if (position > 1) {
- RtcSettings.energy_usage.usage2_kWhtotal = values[1];
+ RtcSettings.energy_usage.usage1_kWhtotal = values[0];
+ if (params > 1) {
+ RtcSettings.energy_usage.usage2_kWhtotal = values[1] * 100;
}
Settings.energy_usage.usage1_kWhtotal = RtcSettings.energy_usage.usage1_kWhtotal;
Settings.energy_usage.usage2_kWhtotal = RtcSettings.energy_usage.usage2_kWhtotal;
break;
case 5:
// Reset energy_usage.return totals
- if (position > 0) {
- RtcSettings.energy_usage.return1_kWhtotal = values[0];
- }
- if (position > 1) {
- RtcSettings.energy_usage.return2_kWhtotal = values[1];
+ RtcSettings.energy_usage.return1_kWhtotal = values[0];
+ if (params > 1) {
+ RtcSettings.energy_usage.return2_kWhtotal = values[1] * 100;
}
Settings.energy_usage.return1_kWhtotal = RtcSettings.energy_usage.return1_kWhtotal;
Settings.energy_usage.return2_kWhtotal = RtcSettings.energy_usage.return2_kWhtotal;
break;
}
+ }
}
Energy.total = (float)(RtcSettings.energy_kWhtotal + Energy.kWhtoday_offset + Energy.kWhtoday) / 100000;
diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino
index fdcb7e0ba..7992ab555 100755
--- a/tasmota/xdrv_10_scripter.ino
+++ b/tasmota/xdrv_10_scripter.ino
@@ -36,6 +36,13 @@ no math hierarchy (costs ram and execution time, better group with brackets, an
(will probably make math hierarchy an ifdefed option)
keywords if then else endif, or, and are better readable for beginners (others may use {})
+// to doo
+remove all filesystem inititialization and gui
+adapt 3 options
+1. ufilesystem
+2. eeprom hardware and emulation
+3. compression
+
\*********************************************************************************************/
#define XDRV_10 10
@@ -70,69 +77,50 @@ keywords if then else endif, or, and are better readable for beginners (others m
//uint32_t EncodeLightId(uint8_t relay_id);
//uint32_t DecodeLightId(uint32_t hue_id);
-#ifdef USE_UNISHOX_COMPRESSION
-#define USE_SCRIPT_COMPRESSION
-#endif
+#define SPECIAL_EEPMODE_SIZE 6200
-// solve conficting defines
-// highest priority
-#ifdef USE_SCRIPT_FATFS
-#undef LITTLEFS_SCRIPT_SIZE
-#undef EEP_SCRIPT_SIZE
-#undef USE_SCRIPT_COMPRESSION
+#ifdef USE_UFILESYS
-#if USE_SCRIPT_FATFS==-1
+#undef USE_SCRIPT_FATFS
+#define USE_SCRIPT_FATFS -1
+#pragma message "universal file system used"
-#ifdef ESP32
-#pragma message "script fat file option -1 used"
-#else
-#pragma message "script fat file option -1 used"
-#endif
-
-#else
-#pragma message "script fat file SDC option used"
-#endif
-#endif // USE_SCRIPT_FATFS
-
-// lfs on esp8266 spiffs on esp32
-#ifdef LITTLEFS_SCRIPT_SIZE
-#undef EEP_SCRIPT_SIZE
-#undef USE_SCRIPT_COMPRESSION
-#pragma message "script little file system option used"
-#endif // LITTLEFS_SCRIPT_SIZE
+#else // USE_UFILESYS
// eeprom script
#ifdef EEP_SCRIPT_SIZE
-#undef USE_SCRIPT_COMPRESSION
+
+#ifdef ESP32
+#error "unsupported option for ESP32"
+#endif
+
#ifdef USE_24C256
#pragma message "script 24c256 file option used"
#else
-//#warning "EEP_SCRIPT_SIZE also needs USE_24C256"
-#if EEP_SCRIPT_SIZE==SPI_FLASH_SEC_SIZE
-#pragma message "internal eeprom script buffer used"
-#else
+
+#if EEP_SCRIPT_SIZE==SPECIAL_EEPMODE_SIZE
#pragma message "internal compressed eeprom script buffer used"
+#else
+#error "unsupported eeprom option used"
#endif
-//#define USE_24C256
-#endif
+#endif // USE_24C256
+
+#else // EEP_SCRIPT_SIZE
+
+// default
+#pragma message "script compression option used"
+
#endif // EEP_SCRIPT_SIZE
-// compression last option before default
-#ifdef USE_SCRIPT_COMPRESSION
-#pragma message "script compression option used"
-#endif // USE_UNISHOX_COMPRESSION
+#endif // USE_UFILESYS
-
-//#ifdef USE_SCRIPT_COMPRESSION
#include
-
#define SCRIPT_COMPRESS compressor.unishox_compress
#define SCRIPT_DECOMPRESS compressor.unishox_decompress
#ifndef UNISHOXRSIZE
#define UNISHOXRSIZE 2560
#endif
-//#endif // USE_SCRIPT_COMPRESSION
#ifndef STASK_PRIO
#define STASK_PRIO 1
@@ -165,22 +153,14 @@ void Script_ticker4_end(void) {
// EEPROM MACROS
// i2c eeprom
+#define EEP_WRITE(A,B,C) eeprom_writeBytes(A, B, (uint8_t*)C);
+#define EEP_READ(A,B,C) eeprom_readBytes(A, B, (uint8_t*)C);
+#define EEP_INIT(A) eeprom_init(A)
-#if defined(ALT_EEPROM) && !defined(ESP32)
-#undef EEP_WRITE
-#undef EEP_READ
-#undef EEP_INIT
-#define EEP_WRITE(A,B,C) alt_eeprom_writeBytes(A, B, (uint8_t*)C);
-#define EEP_READ(A,B,C) alt_eeprom_readBytes(A, B, (uint8_t*)C);
-#define EEP_INIT(A) alt_eeprom_init(A)
-#if EEP_SCRIPT_SIZE>6500
-#undef EEP_SCRIPT_SIZE
-#define EEP_SCRIPT_SIZE 6500
-#endif
+#if defined(EEP_SCRIPT_SIZE) && !defined(ESP32)
uint32_t eeprom_block;
-
// these support only one 4 k block below EEPROM this steals 4k of application area
uint32_t alt_eeprom_init(uint32_t size) {
//EEPROM.begin(size);
@@ -198,28 +178,30 @@ void alt_eeprom_readBytes(uint32_t adr, uint32_t len, uint8_t *buf) {
uint32_t *lwp=(uint32_t*)buf;
ESP.flashRead(eeprom_block , lwp, SPI_FLASH_SEC_SIZE);
}
-#else
-#undef EEP_WRITE
-#undef EEP_READ
-#undef EEP_INIT
-#define EEP_WRITE(A,B,C) eeprom_writeBytes(A, B, (uint8_t*)C);
-#define EEP_READ(A,B,C) eeprom_readBytes(A, B, (uint8_t*)C);
-#define EEP_INIT(A) eeprom_init(A)
-#endif // ALT_EEPROM
+#endif // EEP_SCRIPT_SIZE
+
+#include "FS.h"
+
+#define FS_FILE_WRITE "w"
+#define FS_FILE_READ "r"
+#define FS_FILE_APPEND "a"
#if USE_SCRIPT_FATFS==-1
#ifdef ESP32
-#include "FS.h"
-#include "FFat.h"
+//#include "FS.h"
+//#include "FFat.h"
#else
-#include
+//#include
#endif
-FS *fsp;
+
+#ifndef UFILESYSTEM
+//FS *ufsp;
+#endif
+
#endif // LITTLEFS_SCRIPT_SIZE
-//extern FS *ufsp;
// offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution
#define EPOCH_OFFSET 1546300800
@@ -230,50 +212,65 @@ enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD,SCRIPT_EVENT_HANDLED};
#ifdef USE_SCRIPT_FATFS
#if USE_SCRIPT_FATFS>=0
-#include
-#include
-#include
+//#include
+//#include
+//#include
#ifdef ESP32
-#include "FFat.h"
-FS *fsp;
+//#include "FFat.h"
+#ifndef UFILESYSTEM
+//FS *ufsp;
+#endif
#else
-SDClass *fsp;
+#ifndef UFILESYSTEM
+//SDClass *ufsp;
+#endif
#endif
#endif //USE_SCRIPT_FATFS
+#ifndef FAT_SCRIPT_SIZE
+#define FAT_SCRIPT_SIZE 4096
+#endif
+
+
#ifndef ESP32
// esp8266
#if USE_SCRIPT_FATFS>=0
// old fs
-#undef FILE_WRITE
-#define FILE_WRITE (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT)
-#define FILE_APPEND (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT | sdfat::O_APPEND)
+//#undef FILE_WRITE
+//#define FILE_WRITE (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT)
+//#undef FILE_APPEND
+//#define FILE_APPEND (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT | sdfat::O_APPEND)
#else
// new fs
-#undef FILE_WRITE
-#define FILE_WRITE "w"
-#undef FILE_READ
-#define FILE_READ "r"
-#undef FILE_APPEND
-#define FILE_APPEND "a"
+//undef FILE_WRITE
+//#define FILE_WRITE "w"
+//#undef FILE_READ
+//#define FILE_READ "r"
+//#undef FILE_APPEND
+//#define FILE_APPEND "a"
#endif
#endif // USE_SCRIPT_FATFS>=0
-#ifndef FAT_SCRIPT_SIZE
-#define FAT_SCRIPT_SIZE 4096
+extern uint8_t ufs_type;
+extern FS *ufsp;
+
+
+#ifndef UFSYS_SIZE
+#define UFSYS_SIZE 8192
#endif
+
#ifdef ESP32
#undef FAT_SCRIPT_NAME
#define FAT_SCRIPT_NAME "/script.txt"
#else
#undef FAT_SCRIPT_NAME
-#define FAT_SCRIPT_NAME "script.txt"
+#define FAT_SCRIPT_NAME "/script.txt"
#endif
//#if USE_STANDARD_SPI_LIBRARY==0
@@ -383,6 +380,20 @@ typedef union {
};
} UDP_FLAGS;
+typedef union {
+ uint8_t data;
+ struct {
+ uint8_t nutu8 : 1;
+ uint8_t nutu7 : 1;
+ uint8_t nutu6 : 1;
+ uint8_t nutu5 : 1;
+ uint8_t nutu4 : 1;
+ uint8_t nutu3 : 1;
+ bool fsys : 1;
+ bool eeprom : 1;
+ };
+} FS_FLAGS;
+
#define NUM_RES 0xfe
#define STR_RES 0xfd
@@ -425,7 +436,7 @@ struct SCRIPT_MEM {
uint8_t glob_error;
uint8_t max_ssize;
uint8_t script_loglevel;
- uint8_t flags;
+ FS_FLAGS FLAGS;
uint8_t si_num[3];
uint8_t siro_num[3];
uint8_t sind_num;
@@ -512,7 +523,7 @@ char *GetNumericArgument(char *lp,uint8_t lastop,float *fp, JsonParserObject *jo
char *GetStringArgument(char *lp,uint8_t lastop,char *cp, JsonParserObject *jo);
char *ForceStringVar(char *lp,char *dstr);
void send_download(void);
-uint8_t reject(char *name);
+uint8_t ufs_reject(char *name);
void ScriptEverySecond(void) {
@@ -965,42 +976,6 @@ char *script;
}
}
-// init file system
-//#ifndef USE_UFILESYS
-#if 1
-
-#ifdef USE_SCRIPT_FATFS
- if (!glob_script_mem.script_sd_found) {
-
-#if USE_SCRIPT_FATFS>=0
- // user sd card
- fsp = &SD;
- if (SD.begin(USE_SCRIPT_FATFS)) {
-#else
- // use flash file
-#ifdef ESP32
- // if (SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
- if (FFat.begin(true)) {
-#else
- if (fsp->begin()) {
-#endif // ESP32
-
-#endif // USE_SCRIPT_FATFS>=0
-
- glob_script_mem.script_sd_found = 1;
- } else {
- glob_script_mem.script_sd_found = 0;
- }
- }
- for (uint8_t cnt = 0; cnt0
ClaimSerial();
SetSerialBaudrate(9600);
@@ -1023,63 +998,6 @@ char *script;
return err;
}
-#ifdef USE_SCRIPT_FATFS
-uint32_t get_fsinfo(uint32_t sel) {
-uint32_t result = 0;
-#ifdef ESP32
-#if USE_SCRIPT_FATFS >=0
- if (sel == 0) {
- result = SD.totalBytes()/1000;
- } else if (sel == 1) {
- result = (SD.totalBytes() - SD.usedBytes())/1000;
- }
-#else
- if (sel == 0) {
- result = FFat.totalBytes()/1000;
- } else if (sel == 1) {
- result = FFat.freeBytes()/1000;
- }
-#endif // USE_SCRIPT_FATFS>=0
-#else
- // ESP8266
- FSInfo64 fsinfo;
- fsp->info64(fsinfo);
- if (sel == 0) {
- result = fsinfo.totalBytes/1000;
- } else if (sel == 1) {
- result = (fsinfo.totalBytes - fsinfo.usedBytes)/1000;
- }
-#endif // ESP32
- return result;
-}
-
-// format number with thousand marker
-void form1000(uint32_t number, char *dp, char sc) {
- char str[32];
- sprintf(str, "%d", number);
- char *sp = str;
- uint32_t inum = strlen(sp)/3;
- uint32_t fnum = strlen(sp)%3;
- if (!fnum) inum--;
- for (uint32_t count=0; count<=inum; count++) {
- if (fnum){
- memcpy(dp,sp,fnum);
- dp+=fnum;
- sp+=fnum;
- fnum=0;
- } else {
- memcpy(dp,sp,3);
- dp+=3;
- sp+=3;
- }
- if (count!=inum) {
- *dp++=sc;
- }
- }
- *dp=0;
-}
-
-#endif //USE_SCRIPT_FATFS
#ifdef USE_SCRIPT_GLOBVARS
#define SCRIPT_UDP_BUFFER_SIZE 128
@@ -2090,7 +2008,7 @@ chknext:
#ifdef DEBUG_FS
Script_AddLog_P(LOG_LEVEL_INFO, PSTR("open file for read %d"), cnt);
#endif
- glob_script_mem.files[cnt] = fsp->open(str, FILE_READ);
+ glob_script_mem.files[cnt] = ufsp->open(str, FS_FILE_READ);
if (glob_script_mem.files[cnt].isDirectory()) {
glob_script_mem.files[cnt].rewindDirectory();
glob_script_mem.file_flags[cnt].is_dir = 1;
@@ -2100,12 +2018,12 @@ chknext:
}
else {
if (mode==1) {
- glob_script_mem.files[cnt] = fsp->open(str,FILE_WRITE);
+ glob_script_mem.files[cnt] = ufsp->open(str,FS_FILE_WRITE);
#ifdef DEBUG_FS
Script_AddLog_P(LOG_LEVEL_INFO, PSTR("open file for write %d"), cnt);
#endif
} else {
- glob_script_mem.files[cnt] = fsp->open(str,FILE_APPEND);
+ glob_script_mem.files[cnt] = ufsp->open(str,FS_FILE_APPEND);
#ifdef DEBUG_FS
Script_AddLog_P(LOG_LEVEL_INFO, PSTR("open file for append %d"), cnt);
#endif
@@ -2198,7 +2116,7 @@ chknext:
while (true) {
File entry = glob_script_mem.files[find].openNextFile();
if (entry) {
- if (!reject((char*)entry.name())) {
+ if (!ufs_reject((char*)entry.name())) {
char *ep = (char*)entry.name();
if (*ep=='/') ep++;
char *lcp = strrchr(ep,'/');
@@ -2242,7 +2160,7 @@ chknext:
if (!strncmp(vname, "fd(", 3)) {
char str[glob_script_mem.max_ssize + 1];
lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
- fsp->remove(str);
+ ufsp->remove(str);
lp++;
len = 0;
goto exit;
@@ -2280,7 +2198,7 @@ chknext:
char str[glob_script_mem.max_ssize + 1];
lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
// execute script
- File ef = fsp->open(str, FILE_READ);
+ File ef = ufsp->open(str, FS_FILE_READ);
if (ef) {
uint16_t fsiz = ef.size();
if (fsiz<2048) {
@@ -2301,7 +2219,7 @@ chknext:
if (!strncmp(vname, "fmd(", 4)) {
char str[glob_script_mem.max_ssize + 1];
lp = GetStringArgument(lp + 4, OPER_EQU, str, 0);
- fvar = fsp->mkdir(str);
+ fvar = ufsp->mkdir(str);
lp++;
len = 0;
goto exit;
@@ -2309,7 +2227,7 @@ chknext:
if (!strncmp(vname, "frd(", 4)) {
char str[glob_script_mem.max_ssize + 1];
lp = GetStringArgument(lp + 4, OPER_EQU, str, 0);
- fvar = fsp->rmdir(str);
+ fvar = ufsp->rmdir(str);
lp++;
len = 0;
goto exit;
@@ -2317,7 +2235,7 @@ chknext:
if (!strncmp(vname, "fx(", 3)) {
char str[glob_script_mem.max_ssize + 1];
lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
- if (fsp->exists(str)) fvar = 1;
+ if (ufsp->exists(str)) fvar = 1;
else fvar = 0;
lp++;
len = 0;
@@ -2326,7 +2244,7 @@ chknext:
if (!strncmp(vname, "fsi(", 4)) {
lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
- fvar = get_fsinfo(fvar);
+ fvar = ufs_fsinfo(fvar);
lp++;
len = 0;
goto exit;
@@ -4852,46 +4770,13 @@ const char HTTP_SCRIPT_FORM_END[] PROGMEM =
#ifdef USE_SCRIPT_FATFS
const char HTTP_FORM_SCRIPT1c[] PROGMEM =
"";
-#ifdef SDCARD_DIR
-const char HTTP_FORM_SCRIPT1d[] PROGMEM =
- "";
-#else
+
+
const char HTTP_FORM_SCRIPT1d[] PROGMEM =
"";
-#endif
-#ifdef SDCARD_DIR
-const char S_SCRIPT_FILE_UPLOAD[] PROGMEM = D_SDCARD_DIR;
-#else
const char S_SCRIPT_FILE_UPLOAD[] PROGMEM = D_SDCARD_UPLOAD;
-#endif
-const char HTTP_FORM_FILE_UPLOAD[] PROGMEM =
-""
-"
"
-"
"
-"" D_UPLOAD_STARTED " ...
";
-
-const char HTTP_FORM_FILE_UPGc[] PROGMEM =
-"total size: %s kB - free: %s kB
";
-
-const char HTTP_FORM_SDC_DIRa[] PROGMEM =
-"";
-const char HTTP_FORM_SDC_DIRb[] PROGMEM =
- "
%s %s : %8d
";
-const char HTTP_FORM_SDC_DIRd[] PROGMEM =
-"
%s
";
-const char HTTP_FORM_SDC_DIRc[] PROGMEM =
-"
";
-const char HTTP_FORM_SDC_HREF[] PROGMEM =
-"http://%s/upl?download=%s/%s";
#endif
@@ -4968,194 +4853,16 @@ void ScriptExecuteUploadSuccess(void) {
#ifdef USE_SCRIPT_FATFS
-#if USE_LONG_FILE_NAMES>0
-#undef REJCMPL
-#define REJCMPL 6
-#else
-#undef REJCMPL
-#define REJCMPL 8
-#endif
-
-uint8_t reject(char *name) {
-
- char *lcp = strrchr(name,'/');
- if (lcp) {
- name = lcp + 1;
- }
-
- while (*name=='/') name++;
- if (*name=='_') return 1;
- if (*name=='.') return 1;
-
- if (!strncasecmp(name, "SPOTLI~1", REJCMPL)) return 1;
- if (!strncasecmp(name, "TRASHE~1", REJCMPL)) return 1;
- if (!strncasecmp(name, "FSEVEN~1", REJCMPL)) return 1;
- if (!strncasecmp(name, "SYSTEM~1", REJCMPL)) return 1;
- if (!strncasecmp(name, "System Volume", 13)) return 1;
- return 0;
-}
-
-void ListDir(char *path, uint8_t depth) {
- char name[32];
- char npath[128];
- char format[12];
- sprintf(format, "%%-%ds", 24 - depth);
-
- File dir = fsp->open(path, FILE_READ);
- if (dir) {
- dir.rewindDirectory();
- if (strlen(path)>1) {
- snprintf_P(npath, sizeof(npath), PSTR("http://%s/upl?download=%s"), WiFi.localIP().toString().c_str(),path);
- for (uint8_t cnt = strlen(npath) - 1; cnt>0; cnt--) {
- if (npath[cnt]=='/') {
- if (npath[cnt - 1]=='=') npath[cnt + 1] = 0;
- else npath[cnt] = 0;
- break;
- }
- }
- WSContentSend_P(HTTP_FORM_SDC_DIRd, npath,path, "..");
- }
- char *ep;
- while (true) {
- File entry = dir.openNextFile();
- if (!entry) {
- break;
- }
- // esp32 returns path here, shorten to filename
- ep = (char*)entry.name();
- if (*ep=='/') ep++;
- char *lcp = strrchr(ep,'/');
- if (lcp) {
- ep = lcp + 1;
- }
- //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("entry: %s"),ep);
- time_t tm = entry.getLastWrite();
- char tstr[24];
- strftime(tstr, 22, "%d-%m-%Y - %H:%M:%S ", localtime(&tm));
-
- char *pp = path;
- if (!*(pp + 1)) pp++;
- char *cp = name;
- // osx formatted disks contain a lot of stuff we dont want
- if (reject((char*)ep)) goto fclose;
-
- for (uint8_t cnt = 0; cnt1) {
- strcat(path, "/");
- }
- strcat(path, ep);
- ListDir(path, depth + 4);
- path[plen] = 0;
- } else {
- snprintf_P(npath, sizeof(npath), HTTP_FORM_SDC_HREF, WiFi.localIP().toString().c_str(), pp,ep);
- WSContentSend_P(HTTP_FORM_SDC_DIRb, npath, ep, name, tstr, entry.size());
- }
- fclose:
- entry.close();
- }
- dir.close();
- }
-}
-
-char path[48];
-
-void Script_FileUploadConfiguration(void) {
- uint8_t depth = 0;
-
- strcpy(path, "/");
-
- if (!HttpCheckPriviledgedAccess()) { return; }
-
- if (Webserver->hasArg("download")) {
- String stmp = Webserver->arg("download");
- char *cp = (char*)stmp.c_str();
- if (DownloadFile(cp)) {
- // is directory
- strcpy(path, cp);
- }
- }
-
- WSContentStart_P(S_SCRIPT_FILE_UPLOAD);
- WSContentSendStyle();
- WSContentSend_P(HTTP_FORM_FILE_UPLOAD,D_SDCARD_DIR);
- WSContentSend_P(HTTP_FORM_FILE_UPG, D_SCRIPT_UPLOAD);
-#ifdef SDCARD_DIR
- char ts[16];
- char fs[16];
- form1000(get_fsinfo(0), ts, '.');
- form1000(get_fsinfo(1), fs, '.');
- WSContentSend_P(HTTP_FORM_FILE_UPGc, ts, fs);
- WSContentSend_P(HTTP_FORM_SDC_DIRa);
- if (glob_script_mem.script_sd_found) {
- ListDir(path, depth);
- }
- WSContentSend_P(HTTP_FORM_SDC_DIRc);
-#endif
- WSContentSend_P(HTTP_FORM_FILE_UPGb);
- WSContentSpaceButton(BUTTON_CONFIGURATION);
- WSContentStop();
- Web.upload_error = 0;
-}
-
-void ScriptFileUploadSuccess(void) {
- WSContentStart_P(PSTR(D_INFORMATION));
- WSContentSendStyle();
- WSContentSend_P(PSTR("" D_UPLOAD " " D_SUCCESSFUL "
"), WebColor(COL_TEXT_SUCCESS));
- WSContentSend_P(PSTR("
"));
- WSContentSend_P(PSTR(""),"/upl",D_UPL_DONE);
- //WSContentSpaceButton(BUTTON_MAIN);
- WSContentStop();
-}
-
-
-File upload_file;
-
-void script_upload(void) {
- //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload"));
- HTTPUpload& upload = Webserver->upload();
- if (upload.status == UPLOAD_FILE_START) {
- char npath[48];
-#if defined(ESP32) && defined(USE_SCRIPT_FATFS) && USE_SCRIPT_FATFS==-1
- //sprintf(npath,"/%s",upload.filename.c_str());
- sprintf(npath, "%s/%s", path, upload.filename.c_str());
-#else
- sprintf(npath, "%s/%s", path, upload.filename.c_str());
-#endif
- fsp->remove(npath);
- upload_file = fsp->open(npath, FILE_WRITE);
- if (!upload_file) Web.upload_error = 1;
- } else if(upload.status == UPLOAD_FILE_WRITE) {
- if (upload_file) upload_file.write(upload.buf, upload.currentSize);
- } else if(upload.status == UPLOAD_FILE_END) {
- if (upload_file) upload_file.close();
- if (Web.upload_error) {
- Script_AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload error"));
- }
- } else {
- Web.upload_error=1;
- Webserver->send(500, "text/plain", "500: couldn't create file");
- }
-}
-
uint8_t DownloadFile(char *file) {
File download_file;
WiFiClient download_Client;
- if (!fsp->exists(file)) {
+ if (!ufsp->exists(file)) {
Script_AddLog_P(LOG_LEVEL_INFO,PSTR("file not found"));
return 0;
}
- download_file = fsp->open(file, FILE_READ);
+ download_file = ufsp->open(file, FS_FILE_READ);
if (!download_file) {
Script_AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file"));
return 0;
@@ -5233,9 +4940,6 @@ void HandleScriptConfiguration(void) {
if (Webserver->hasArg("d2")) {
DownloadFile(glob_script_mem.flink[1]);
}
- if (Webserver->hasArg("upl")) {
- Script_FileUploadConfiguration();
- }
#endif
WSContentStart_P(PSTR(D_CONFIGURE_SCRIPT));
@@ -5273,30 +4977,40 @@ void HandleScriptConfiguration(void) {
void SaveScript(void) {
-#ifdef EEP_SCRIPT_SIZE
- if (glob_script_mem.flags&1) {
-#if EEP_SCRIPT_SIZE==SPI_FLASH_SEC_SIZE
- EEP_WRITE(0, EEP_SCRIPT_SIZE, glob_script_mem.script_ram);
-#else
- char *ucs;
- ucs = (char*)calloc(SPI_FLASH_SEC_SIZE + 4, 1);
- if (!script_compress(ucs,EEP_SCRIPT_SIZE-1)) {
- EEP_WRITE(0, EEP_SCRIPT_SIZE, ucs);
- }
- if (ucs) free(ucs);
-#endif
+
+#ifdef USE_UFILESYS
+ if (glob_script_mem.FLAGS.fsys == true) {
+ ufsp->remove(FAT_SCRIPT_NAME);
+ File file = ufsp->open(FAT_SCRIPT_NAME, FS_FILE_WRITE);
+ file.write((const uint8_t*)glob_script_mem.script_ram, strlen(glob_script_mem.script_ram));
+ file.close();
+ } else {
+ // fallback to compressed mode
+ script_compress(Settings.rules[0],MAX_SCRIPT_SIZE-1);
}
+#else // USE_UFILESYS
+
+#ifdef EEP_SCRIPT_SIZE
+ // here we handle EEPROM modes
+ if (glob_script_mem.FLAGS.eeprom == true) {
+ if (EEP_SCRIPT_SIZE!=SPECIAL_EEPMODE_SIZE) {
+ EEP_WRITE(0, EEP_SCRIPT_SIZE, glob_script_mem.script_ram);
+ } else {
+ uint8_t *ucs;
+ ucs = (uint8_t*)calloc(SPI_FLASH_SEC_SIZE + 4, 1);
+ if (!script_compress((char*)ucs,EEP_SCRIPT_SIZE-1)) {
+ alt_eeprom_writeBytes(0, EEP_SCRIPT_SIZE, ucs);
+ }
+ if (ucs) free(ucs);
+ }
+ }
+#else
+ // default mode is compression
+ script_compress(Settings.rules[0],MAX_SCRIPT_SIZE-1);
#endif // EEP_SCRIPT_SIZE
-#ifdef USE_SCRIPT_FATFS
- if (glob_script_mem.flags & 1) {
- fsp->remove(FAT_SCRIPT_NAME);
- File file = fsp->open(FAT_SCRIPT_NAME, FILE_WRITE);
- file.write((const uint8_t*)glob_script_mem.script_ram, FAT_SCRIPT_SIZE);
- file.close();
- }
-#endif // USE_SCRIPT_FATFS
+#endif // USE_UFILESYS
}
void ScriptSaveSettings(void) {
@@ -5307,7 +5021,6 @@ void ScriptSaveSettings(void) {
bitWrite(Settings.rule_enabled, 0, 0);
}
-
String str = Webserver->arg("t1");
if (*str.c_str()) {
@@ -5315,38 +5028,6 @@ void ScriptSaveSettings(void) {
str.replace("\r\n", "\n");
str.replace("\r", "\n");
-#ifdef xSCRIPT_STRIP_COMMENTS
- if (bitRead(Settings.rule_enabled, 1)) {
- char *sp = (char*)str.c_str();
- char *sp1 = sp;
- char *dp = sp;
- uint8_t flg = 0;
- while (*sp) {
- while (*sp==' ') sp++;
- sp1 = sp;
- sp = strchr(sp,'\n');
- if (!sp) {
- flg = 1;
- } else {
- *sp = 0;
- }
- if (*sp1!=';') {
- uint8_t slen = strlen(sp1);
- if (slen) {
- strcpy(dp, sp1);
- dp += slen;
- *dp++ = '\n';
- }
- }
- if (flg) {
- *dp = 0;
- break;
- }
- sp++;
- }
- }
-#endif //xSCRIPT_STRIP_COMMENTS
-
strlcpy(glob_script_mem.script_ram, str.c_str(), glob_script_mem.script_size);
if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') {
@@ -5389,10 +5070,6 @@ void SaveScriptEnd(void) {
glob_script_mem.script_mem_size = 0;
}
-#ifdef USE_SCRIPT_COMPRESSION
- script_compress(Settings.rules[0],MAX_SCRIPT_SIZE-1);
-#endif // USE_SCRIPT_COMPRESSION
-
if (bitRead(Settings.rule_enabled, 0)) {
int16_t res = Init_Scripter();
@@ -6460,7 +6137,7 @@ void ScriptGetSDCard(void) {
SendFile(cp);
return;
} else {
- if (fsp->exists(cp)) {
+ if (ufsp->exists(cp)) {
SendFile(cp);
return;
}
@@ -6543,7 +6220,7 @@ char buff[512];
}
#endif // USE_DISPLAY_DUMP
} else {
- File file = fsp->open(fname,FILE_READ);
+ File file = ufsp->open(fname,FS_FILE_READ);
uint32_t siz = file.size();
uint32_t len = sizeof(buff);
while (siz > 0) {
@@ -7645,6 +7322,8 @@ void cpy2lf(char *dst, uint32_t dstlen, char *src) {
\*********************************************************************************************/
//const esp_partition_t *esp32_part;
+
+
bool Xdrv10(uint8_t function)
{
bool result = false;
@@ -7658,13 +7337,93 @@ bool Xdrv10(uint8_t function)
//bitWrite(Settings.rule_enabled,0,0);
glob_script_mem.script_ram = Settings.rules[0];
glob_script_mem.script_size = MAX_SCRIPT_SIZE;
- glob_script_mem.flags = 0;
+ glob_script_mem.FLAGS.fsys = false;
+ glob_script_mem.FLAGS.eeprom = false;
glob_script_mem.script_pram = (uint8_t*)Settings.script_pram[0];
glob_script_mem.script_pram_size = PMEM_SIZE;
- // indicates scripter enabled (use rules[][] as single array)
- bitWrite(Settings.rule_once, 7, 1);
-#ifdef USE_SCRIPT_COMPRESSION
+#ifdef USE_UFILESYS
+ if (ufs_type) {
+ // we have a file system
+ Script_AddLog_P(LOG_LEVEL_INFO,PSTR("UFILESYSTEM OK!"));
+ char *script;
+ script = (char*)calloc(UFSYS_SIZE + 4, 1);
+ if (!script) break;
+ glob_script_mem.script_ram = script;
+ glob_script_mem.script_size = UFSYS_SIZE;
+ if (ufsp->exists(FAT_SCRIPT_NAME)) {
+ File file = ufsp->open(FAT_SCRIPT_NAME, FS_FILE_READ);
+ file.read((uint8_t*)script, UFSYS_SIZE);
+ file.close();
+ }
+ script[UFSYS_SIZE - 1] = 0;
+ // use rules storage for permanent vars
+ glob_script_mem.script_pram = (uint8_t*)Settings.rules[0];
+ glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE;
+ glob_script_mem.FLAGS.fsys = true;
+ // indicates scripter use no compression
+ bitWrite(Settings.rule_once, 6, 0);
+ } else {
+ Script_AddLog_P(LOG_LEVEL_INFO,PSTR("UFILESYSTEM fail, using compression!"));
+ int32_t len_decompressed;
+ sprt = (char*)calloc(UNISHOXRSIZE + 8,1);
+ if (!sprt) { break; }
+ glob_script_mem.script_ram = sprt;
+ glob_script_mem.script_size = UNISHOXRSIZE;
+ len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size);
+ if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed] = 0;
+ // indicates scripter use compression
+ bitWrite(Settings.rule_once, 6, 1);
+ }
+#else // USE_UFILESYS
+
+#ifdef EEP_SCRIPT_SIZE
+
+ if (EEP_INIT(EEP_SCRIPT_SIZE)) {
+ // found 32kb eeprom,
+ char *script;
+ if (EEP_SCRIPT_SIZE!=SPECIAL_EEPMODE_SIZE) {
+ script = (char*)calloc(EEP_SCRIPT_SIZE + 4, 1);
+ if (!script) break;
+ glob_script_mem.script_ram = script;
+ glob_script_mem.script_size = EEP_SCRIPT_SIZE;
+ EEP_READ(0, EEP_SCRIPT_SIZE, script);
+ if (*script==0xff) {
+ memset(script, EEP_SCRIPT_SIZE, 0);
+ }
+ script[EEP_SCRIPT_SIZE - 1] = 0;
+ } else {
+ uint8_t *ucs;
+ ucs = (uint8_t*)calloc(SPI_FLASH_SEC_SIZE + 4, 1);
+ if (!ucs) break;
+ alt_eeprom_readBytes(0, SPI_FLASH_SEC_SIZE, ucs);
+ if (*ucs==0xff) {
+ memset(ucs, SPI_FLASH_SEC_SIZE, 0);
+ }
+ ucs[SPI_FLASH_SEC_SIZE - 1] = 0;
+
+ script = (char*)calloc(EEP_SCRIPT_SIZE + 4, 1);
+ if (!script) break;
+ glob_script_mem.script_ram = script;
+ glob_script_mem.script_size = EEP_SCRIPT_SIZE;
+
+ int32_t len_decompressed;
+ len_decompressed = SCRIPT_DECOMPRESS((char*)ucs, strlen((char*)ucs), glob_script_mem.script_ram, glob_script_mem.script_size);
+ if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed] = 0;
+
+ if (ucs) free(ucs);
+
+ }
+
+ // use rules storage for permanent vars
+ glob_script_mem.script_pram = (uint8_t*)Settings.rules[0];
+ glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE;
+
+ glob_script_mem.FLAGS.fsys = true;
+ }
+#else // EEP_SCRIPT_SIZE
+
+ // default mode is compression
int32_t len_decompressed;
sprt = (char*)calloc(UNISHOXRSIZE + 8,1);
if (!sprt) { break; }
@@ -7674,11 +7433,14 @@ bool Xdrv10(uint8_t function)
if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed] = 0;
// indicates scripter use compression
bitWrite(Settings.rule_once, 6, 1);
- //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed);
-#else // USE_SCRIPT_COMPRESSION
- // indicates scripter does not use compression
- bitWrite(Settings.rule_once, 6, 0);
-#endif // USE_SCRIPT_COMPRESSION
+
+#endif
+
+#endif // UFILESYSTEM
+
+
+// indicates scripter enabled (use rules[][] as single array)
+ bitWrite(Settings.rule_once, 7, 1);
#ifdef USE_BUTTON_EVENT
for (uint32_t cnt = 0; cnt < MAX_KEYS; cnt++) {
@@ -7686,110 +7448,13 @@ bool Xdrv10(uint8_t function)
}
#endif //USE_BUTTON_EVENT
-#ifdef EEP_SCRIPT_SIZE
- if (EEP_INIT(EEP_SCRIPT_SIZE)) {
- // found 32kb eeprom,
- char *script;
-#if EEP_SCRIPT_SIZE==SPI_FLASH_SEC_SIZE
- script = (char*)calloc(EEP_SCRIPT_SIZE + 4, 1);
- if (!script) break;
- glob_script_mem.script_ram = script;
- glob_script_mem.script_size = EEP_SCRIPT_SIZE;
- EEP_READ(0, EEP_SCRIPT_SIZE, script);
- if (*script==0xff) {
- memset(script, EEP_SCRIPT_SIZE, 0);
- }
- script[EEP_SCRIPT_SIZE - 1] = 0;
-#else
- char *ucs;
- ucs = (char*)calloc(SPI_FLASH_SEC_SIZE + 4, 1);
- if (!ucs) break;
- EEP_READ(0, SPI_FLASH_SEC_SIZE, ucs);
- if (*ucs==0xff) {
- memset(ucs, SPI_FLASH_SEC_SIZE, 0);
- }
- ucs[SPI_FLASH_SEC_SIZE - 1] = 0;
-
- script = (char*)calloc(EEP_SCRIPT_SIZE + 4, 1);
- if (!script) break;
- glob_script_mem.script_ram = script;
- glob_script_mem.script_size = EEP_SCRIPT_SIZE;
-
- int32_t len_decompressed;
- len_decompressed = SCRIPT_DECOMPRESS(ucs, strlen(ucs), glob_script_mem.script_ram, glob_script_mem.script_size);
- if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed] = 0;
-
- if (ucs) free(ucs);
-
-#endif
- // use rules storage for permanent vars
- glob_script_mem.script_pram = (uint8_t*)Settings.rules[0];
- glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE;
-
- glob_script_mem.flags = 1;
+ // a valid script MUST start with >D
+ if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') {
+ // clr all
+ memset(glob_script_mem.script_ram, 0 ,glob_script_mem.script_size);
+ strcpy_P(glob_script_mem.script_ram, PSTR(">D\nscript error must start with >D"));
+ bitWrite(Settings.rule_enabled, 0, 0);
}
-#endif // EEP_SCRIPT_SIZE
-
-
-#ifdef USE_SCRIPT_FATFS
-
-#if USE_SCRIPT_FATFS>=0
- // fs on SD card
-#ifdef ESP32
- if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) {
- SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
- }
-#endif // ESP32
- fsp = &SD;
- if (SD.begin(USE_SCRIPT_FATFS)) {
-#else
- // flash file system
-#ifdef ESP32
- fsp = &FFat;
- if (FFat.begin(true)) {
-#else
- // fs on flash
- fsp = &LittleFS;
- if (fsp->begin()) {
-#endif // ESP
-
-#endif // USE_SCRIPT_FATFS>=0
-
- Script_AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount OK!"));
-
- //fsp->dateTimeCallback(dateTime);
- glob_script_mem.script_sd_found = 1;
- char *script;
- script = (char*)calloc(FAT_SCRIPT_SIZE + 4, 1);
- if (!script) break;
- glob_script_mem.script_ram = script;
- glob_script_mem.script_size = FAT_SCRIPT_SIZE;
- if (fsp->exists(FAT_SCRIPT_NAME)) {
- File file = fsp->open(FAT_SCRIPT_NAME, FILE_READ);
- file.read((uint8_t*)script, FAT_SCRIPT_SIZE);
- file.close();
- }
- script[FAT_SCRIPT_SIZE - 1] = 0;
- // use rules storage for permanent vars
- glob_script_mem.script_pram = (uint8_t*)Settings.rules[0];
- glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE;
-
- glob_script_mem.flags = 1;
-
- } else {
- Script_AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount failed!"));
- glob_script_mem.script_sd_found = 0;
- }
-#endif // USE_SCRIPT_FATFS
-
-
- // a valid script MUST start with >D
- if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') {
- // clr all
- memset(glob_script_mem.script_ram, 0 ,glob_script_mem.script_size);
- strcpy_P(glob_script_mem.script_ram, PSTR(">D\nscript error must start with >D"));
- bitWrite(Settings.rule_enabled, 0, 0);
- }
// assure permanent memory is 4 byte aligned
{ uint32_t ptr = (uint32_t)glob_script_mem.script_pram;
@@ -7800,6 +7465,7 @@ bool Xdrv10(uint8_t function)
}
if (bitRead(Settings.rule_enabled, 0)) Init_Scripter();
+
// break;
//case FUNC_INIT:
if (bitRead(Settings.rule_enabled, 0)) {
@@ -7863,12 +7529,6 @@ bool Xdrv10(uint8_t function)
Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration);
Webserver->on("/exs", HTTP_POST,[]() { Webserver->sendHeader("Location","/exs");Webserver->send(303);}, script_upload_start);
Webserver->on("/exs", HTTP_GET, ScriptExecuteUploadSuccess);
-
-#ifdef USE_SCRIPT_FATFS
- Webserver->on("/u13", HTTP_POST,[]() { Webserver->sendHeader("Location","/u13");Webserver->send(303);}, script_upload);
- Webserver->on("/u13", HTTP_GET, ScriptFileUploadSuccess);
- Webserver->on("/upl", HTTP_GET, Script_FileUploadConfiguration);
-#endif //USE_SCRIPT_FATFS
break;
#endif // USE_WEBSERVER
case FUNC_SAVE_BEFORE_RESTART:
diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino
old mode 100644
new mode 100755
index 6bdab9d03..6e5e7a138
--- a/tasmota/xdrv_13_display.ino
+++ b/tasmota/xdrv_13_display.ino
@@ -497,13 +497,13 @@ void DisplayText(void)
cp += var;
linebuf[fill] = 0;
break;
-#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)
+#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(UFILESYSTEM)
case 'P':
{ char *ep=strchr(cp,':');
if (ep) {
*ep=0;
ep++;
- Draw_RGB_Bitmap(cp,disp_xpos,disp_ypos);
+ Draw_RGB_Bitmap(cp,disp_xpos,disp_ypos, false);
cp=ep;
}
}
@@ -682,7 +682,7 @@ void DisplayText(void)
RedrawGraph(temp,temp1);
break;
}
-#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)
+#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(UFILESYSTEM)
if (*cp=='s') {
cp++;
var=atoiv(cp,&temp);
@@ -1423,7 +1423,7 @@ void CmndDisplayDimmer(void)
void CmndDisplayBlinkrate(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) {
-
+
if (!renderer)
XdspCall(FUNC_DISPLAY_BLINKRATE);
}
@@ -1540,20 +1540,39 @@ void CmndDisplayRows(void)
/*********************************************************************************************\
* optional drivers
\*********************************************************************************************/
+
+#ifdef USE_TOUCH_BUTTONS
+// very limited path size, so, add .jpg
+void draw_picture(char *path, uint32_t xp, uint32_t yp, uint32_t xs, uint32_t ys, bool inverted) {
+char ppath[16];
+ strcpy(ppath, path);
+ uint8_t plen = strlen(path) -1;
+ if (ppath[plen]=='1') {
+ // index mode
+ if (inverted) {
+ ppath[plen] = '2';
+ }
+ inverted = false;
+ }
+ strcat(ppath, ".jpg");
+ Draw_RGB_Bitmap(ppath, xp, yp, inverted);
+}
+#endif
+
+
#ifdef ESP32
#ifdef JPEG_PICTS
#include "img_converters.h"
#include "esp_jpg_decode.h"
bool jpg2rgb888(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale);
char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height);
-void rgb888_to_565(uint8_t *in, uint16_t *out, uint32_t len);
#endif // JPEG_PICTS
#endif // ESP32
-#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)
-extern FS *fsp;
+#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(UFILESYSTEM)
+extern FS *ufsp;
#define XBUFF_LEN 128
-void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) {
+void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp, bool inverted ) {
if (!renderer) return;
File fp;
char *ending = strrchr(file,'.');
@@ -1567,7 +1586,7 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) {
if (!strcmp(estr,"rgb")) {
// special rgb format
- fp=fsp->open(file,FILE_READ);
+ fp=ufsp->open(file,FS_FILE_READ);
if (!fp) return;
uint16_t xsize;
fp.read((uint8_t*)&xsize,2);
@@ -1602,34 +1621,41 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) {
// jpeg files on ESP32 with more memory
#ifdef ESP32
#ifdef JPEG_PICTS
- if (psramFound()) {
- fp=fsp->open(file,FILE_READ);
- if (!fp) return;
- uint32_t size = fp.size();
- uint8_t *mem = (uint8_t *)heap_caps_malloc(size+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
- if (mem) {
- uint8_t res=fp.read(mem, size);
- if (res) {
- uint16_t xsize;
- uint16_t ysize;
- if (mem[0]==0xff && mem[1]==0xd8) {
- get_jpeg_size(mem, size, &xsize, &ysize);
- //Serial.printf(" x,y %d - %d\n",xsize, ysize );
- if (xsize && ysize) {
- uint8_t *out_buf = (uint8_t *)heap_caps_malloc((xsize*ysize*3)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
- if (out_buf) {
+ fp=ufsp->open(file,FS_FILE_READ);
+ if (!fp) return;
+ uint32_t size = fp.size();
+ uint8_t *mem = (uint8_t *)special_malloc(size+4);
+ if (mem) {
+ uint8_t res=fp.read(mem, size);
+ if (res) {
+ uint16_t xsize;
+ uint16_t ysize;
+ if (mem[0]==0xff && mem[1]==0xd8) {
+ get_jpeg_size(mem, size, &xsize, &ysize);
+ //Serial.printf(" x,y,fs %d - %d - %d\n",xsize, ysize, size );
+ if (xsize && ysize) {
+ uint8_t *out_buf = (uint8_t *)special_malloc((xsize*ysize*3)+4);
+ if (out_buf) {
+ uint16_t *pixb = (uint16_t *)special_malloc((xsize*2)+4);
+ if (pixb) {
uint8_t *ob=out_buf;
- jpg2rgb888(mem, size, out_buf, (jpg_scale_t)JPG_SCALE_NONE);
- uint16_t pixels=xsize*ysize/XBUFF_LEN;
- renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize);
- for(int32_t j=0; jpushColors(rbuff,XBUFF_LEN,true);
- OsWatchLoop();
+ if (jpg2rgb888(mem, size, out_buf, (jpg_scale_t)JPG_SCALE_NONE)) {
+ renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize);
+ for(int32_t j=0; jpushColors(pixb, xsize, true);
+ OsWatchLoop();
+ }
+ renderer->setAddrWindow(0,0,0,0);
}
- renderer->setAddrWindow(0,0,0,0);
+ free(out_buf);
+ free(pixb);
+ } else {
free(out_buf);
}
}
@@ -1888,7 +1914,7 @@ void DisplayCheckGraph() {
}
-#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)
+#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(UFILESYSTEM)
#ifdef ESP32
#include
#endif
@@ -1899,8 +1925,8 @@ void Save_graph(uint8_t num, char *path) {
struct GRAPH *gp=graph[index];
if (!gp) return;
File fp;
- fsp->remove(path);
- fp=fsp->open(path,FILE_WRITE);
+ ufsp->remove(path);
+ fp=ufsp->open(path,FS_FILE_WRITE);
if (!fp) return;
char str[32];
sprintf_P(str,PSTR("%d\t%d\t%d\t"),gp->xcnt,gp->xs,gp->ys);
@@ -1925,7 +1951,7 @@ void Restore_graph(uint8_t num, char *path) {
struct GRAPH *gp=graph[index];
if (!gp) return;
File fp;
- fp=fsp->open(path,FILE_READ);
+ fp=ufsp->open(path,FS_FILE_READ);
if (!fp) return;
char vbuff[32];
char *cp=vbuff;
diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino
index 93252af12..84e9ed508 100644
--- a/tasmota/xdrv_20_hue.ino
+++ b/tasmota/xdrv_20_hue.ino
@@ -30,26 +30,145 @@
#define XDRV_20 20
-const char HUE_RESPONSE[] PROGMEM =
+#include "UnishoxStrings.h"
+
+const char HUE_RESP_MSG_U[] PROGMEM =
+ //=HUE_RESP_RESPONSE
"HTTP/1.1 200 OK\r\n"
"HOST: 239.255.255.250:1900\r\n"
"CACHE-CONTROL: max-age=100\r\n"
"EXT:\r\n"
"LOCATION: http://%s:80/description.xml\r\n"
"SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.24.0\r\n" // was 1.17
- "hue-bridgeid: %s\r\n";
-const char HUE_ST1[] PROGMEM =
+ "hue-bridgeid: %s\r\n"
+ "\0"
+ //=HUE_RESP_ST1
"ST: upnp:rootdevice\r\n"
"USN: uuid:%s::upnp:rootdevice\r\n"
- "\r\n";
-const char HUE_ST2[] PROGMEM =
+ "\r\n"
+ "\0"
+ //=HUE_RESP_ST2
"ST: uuid:%s\r\n"
"USN: uuid:%s\r\n"
- "\r\n";
-const char HUE_ST3[] PROGMEM =
+ "\r\n"
+ "\0"
+ //=HUE_RESP_ST3
"ST: urn:schemas-upnp-org:device:basic:1\r\n"
"USN: uuid:%s\r\n"
- "\r\n";
+ "\r\n"
+ "\0";
+
+
+// Use the tool at https://tasmota.hadinger.fr/util and choose "Compress Strings template with Unishox"
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// ++++++++++++++++++++ DO NOT EDIT BELOW ++++++++++++++++++++
+// ++++++++++++++++++++vvvvvvvvvvvvvvvvvvv++++++++++++++++++++
+enum {
+ HUE_RESP_RESPONSE=0,
+ HUE_RESP_ST1=185,
+ HUE_RESP_ST2=240,
+ HUE_RESP_ST3=270,
+};
+
+// Compressed from 328 to 247, -24.7%
+const char HUE_RESP_MSG[] PROGMEM = "\x00\x15\x21\x45\x45\x44\x30\xEC\x39\x0E\x90\xEE\x53\x67\x70\x8B\x08\xD2\x70\xA4"
+ "\x6E\x21\x45\x85\xE2\xA3\xCD\x1C\xAB\x47\x4A\xDD\x3A\x56\xE9\xD2\xB5\x9E\x71\x36"
+ "\x53\x85\x23\x71\x06\x56\x41\x90\xA2\x67\x59\x10\x79\xD5\xFC\x08\x8F\x34\x36\xCD"
+ "\x87\x5D\x8F\x33\xE1\xC8\xD9\x4E\x14\x8D\xC4\xC8\xD8\x54\x79\xCE\x14\x8D\xC4\x41"
+ "\x60\x77\x5B\x9C\x47\x9A\x15\x54\x30\xF3\x3B\x0E\xC3\xEB\xC7\x99\xCF\xB3\xB0\x84"
+ "\x7E\x0F\xFA\x32\xB7\x38\xE8\x6C\x1A\x14\xE1\x48\xDC\x45\xE7\xF3\x37\xF2\x3C\xD1"
+ "\x05\xBC\x2C\xD8\x76\x1C\xB3\xA4\xC3\xA3\x3B\x84\x42\xC8\x67\x10\xC3\xB0\xE4\x3A"
+ "\x33\xB8\x45\xA3\x08\x77\xF4\x41\xE6\x76\x1C\x87\x4A\xC3\xA3\x29\xC2\x91\xB8\x50"
+ "\xB6\x75\x8E\xFE\x88\x3C\xF4\x43\xCD\x1F\x5E\x9C\x29\x1B\xA7\x0B\xE5\xE2\xA3\xCD"
+ "\x0B\x19\xC3\x0F\x3F\xE6\x50\x8C\xCF\x43\x73\x85\x23\x71\x0B\x2F\x17\x1E\x68\x58"
+ "\xBD\x10\xF3\x3E\xBC\x79\x9E\x60\x99\x6C\x10\xF1\x30\x41\xBA\x09\x38\x58\x22\xDA"
+ "\xFF\x1E\x7E\x0C\x53\x1B\x7E\x3A\xC5\x8C\xE1\x87\x5E\x7C\x78\xF3\x04\x1C\x78\xF3"
+ "\x1D\x7E\xD0\xCF\x33\x90\x81\x3B\x16";
+
+// ++++++++++++++++++++^^^^^^^^^^^^^^^^^^^++++++++++++++++++++
+// ++++++++++++++++++++ DO NOT EDIT ABOVE ++++++++++++++++++++
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+// const char HUE_RESPONSE[] PROGMEM =
+// "HTTP/1.1 200 OK\r\n"
+// "HOST: 239.255.255.250:1900\r\n"
+// "CACHE-CONTROL: max-age=100\r\n"
+// "EXT:\r\n"
+// "LOCATION: http://%s:80/description.xml\r\n"
+// "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.24.0\r\n" // was 1.17
+// "hue-bridgeid: %s\r\n";
+// const char HUE_ST1[] PROGMEM =
+// "ST: upnp:rootdevice\r\n"
+// "USN: uuid:%s::upnp:rootdevice\r\n"
+// "\r\n";
+// const char HUE_ST2[] PROGMEM =
+// "ST: uuid:%s\r\n"
+// "USN: uuid:%s\r\n"
+// "\r\n";
+// const char HUE_ST3[] PROGMEM =
+// "ST: urn:schemas-upnp-org:device:basic:1\r\n"
+// "USN: uuid:%s\r\n"
+// "\r\n";
+
+const char HUE_API_U[] PROGMEM =
+ //=HUE_INVALID
+ "/invalid/"
+ "\0"
+ //=HUE_ROOT
+ "/"
+ "\0"
+ //=HUE_CONFIG
+ "/config"
+ "\0"
+ //=HUE_LIGHTS_API
+ "/lights"
+ "\0"
+ //=HUE_GROUPS
+ "/groups"
+ "\0"
+ //=HUE_SCHEDULES
+ "/schedules"
+ "\0"
+ //=HUE_SENSORS
+ "/sensors"
+ "\0"
+ //=HUE_SCENES
+ "/scenes"
+ "\0"
+ //=HUE_RULES
+ "/rules"
+ "\0"
+ //=HUE_RESOURCELINKS
+ "/resourcelinks"
+ "\0"
+ ;
+
+// Use the tool at https://tasmota.hadinger.fr/util and choose "Compress Strings template with Unishox"
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// ++++++++++++++++++++ DO NOT EDIT BELOW ++++++++++++++++++++
+// ++++++++++++++++++++vvvvvvvvvvvvvvvvvvv++++++++++++++++++++
+enum {
+ HUE_INVALID=0,
+ HUE_ROOT=10,
+ HUE_CONFIG=12,
+ HUE_LIGHTS_API=20,
+ HUE_GROUPS=28,
+ HUE_SCHEDULES=36,
+ HUE_SENSORS=47,
+ HUE_SCENES=56,
+ HUE_RULES=64,
+ HUE_RESOURCELINKS=71,
+};
+
+// Compressed from 86 to 74, -14.0%
+const char HUE_API[] PROGMEM = "\x00\x06\x3B\x37\x8C\xEC\x2D\x10\xEC\x9C\x2F\x9D\x93\x85\xF3\xB0\x3C\xE3\x1A\x3D"
+ "\x38\x5F\x3B\x02\xD1\xE1\x55\xE9\xC2\xF9\xD8\x3D\xFC\x16\x33\xD3\x85\xF3\xB3\xC1"
+ "\x8A\x62\x0B\x09\xFA\x70\xBE\x76\x79\xF7\xB3\xFE\x9C\x2F\x9D\x9E\x0D\xF3\xF4\xE1"
+ "\x7C\xEC\xF8\x20\xD4\xFB\xF6\x0B\xF8\x6C\x2D\xE3\x4F\x4E\x17\xCD";
+// ++++++++++++++++++++^^^^^^^^^^^^^^^^^^^++++++++++++++++++++
+// ++++++++++++++++++++ DO NOT EDIT ABOVE ++++++++++++++++++++
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
String HueBridgeId(void)
{
@@ -81,20 +200,21 @@ void HueRespondToMSearch(void)
char message[TOPSZ];
if (PortUdp.beginPacket(udp_remote_ip, udp_remote_port)) {
+ UnishoxStrings msg(HUE_RESP_MSG);
char response[320];
- snprintf_P(response, sizeof(response), HUE_RESPONSE, WiFi.localIP().toString().c_str(), HueBridgeId().c_str());
+ snprintf_P(response, sizeof(response), msg[HUE_RESP_RESPONSE], WiFi.localIP().toString().c_str(), HueBridgeId().c_str());
int len = strlen(response);
String uuid = HueUuid();
- snprintf_P(response + len, sizeof(response) - len, HUE_ST1, uuid.c_str());
+ snprintf_P(response + len, sizeof(response) - len, msg[HUE_RESP_ST1], uuid.c_str());
PortUdp.write(response);
PortUdp.endPacket();
- snprintf_P(response + len, sizeof(response) - len, HUE_ST2, uuid.c_str(), uuid.c_str());
+ snprintf_P(response + len, sizeof(response) - len, msg[HUE_RESP_ST2], uuid.c_str(), uuid.c_str());
PortUdp.write(response);
PortUdp.endPacket();
- snprintf_P(response + len, sizeof(response) - len, HUE_ST3, uuid.c_str());
+ snprintf_P(response + len, sizeof(response) - len, msg[HUE_RESP_ST3], uuid.c_str());
PortUdp.write(response);
PortUdp.endPacket();
@@ -158,81 +278,135 @@ const char HUE_DESCRIPTION_XML_COMPRESSED[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\
// "\r\n"
// "\r\n";
-//%s"alert":"none","effect":"none","reachable":true}
-//Successfully compressed from 50 to 34 bytes (-32%)
-// const size_t HUE_LIGHTS_STATUS_JSON1_SUFFIX_size = 50;
-// const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM = "\x3E\xBC\x7B\x2C\x27\xFA\x3D\x87\x99\xEC\xEC\xE6\x7B\x0E\xA3\xD8\xCC\x18\x61\x82"
-// "\x34\xCF\xBB\x0C\x55\x8E\x09\x9E\xC3\xCE\xBE\x2D\x9E\xE3";
-const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM =
+const char HUE_LIGHTS_U[] PROGMEM =
+ //=HUE_LIGHTS_STATUS_JSON1_SUFFIX
"%s\"alert\":\"none\","
"\"effect\":\"none\","
- "\"reachable\":true}";
-
-//,"type":"Extended color light","name":"%s","modelid":"%s","manufacturername":"%s","uniqueid":"%s"}
-//Successfully compressed from 98 to 64 bytes (-34.7%)
-// const size_t HUE_LIGHTS_STATUS_JSON2_size = 98;
-// const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = "\x3A\x8F\x65\x19\x0C\x67\xB0\xF3\x3D\x84\xCD\x94\xF8\x46\x22\x0F\x02\xCF\xA0\xB4"
-// "\x78\x55\x1E\xC3\xA8\xF6\x75\x8D\x67\xB0\xF3\x3D\x87\xD7\x8F\x61\xD4\x7B\x06\xE0"
-// "\x8C\x2D\x10\x11\x25\xDF\x0B\x31\x61\xD0\xBF\xBF\x82\x3E\x06\x2F\xB4\xD4\x2D\x82"
-// "\x1E\x08\x7B\x8D";
-const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM =
+ "\"reachable\":true}"
+ "\0"
+ //=HUE_LIGHTS_STATUS_JSON2
",\"type\":\"Extended color light\","
"\"name\":\"%s\","
"\"modelid\":\"%s\","
"\"manufacturername\":\"%s\","
- "\"uniqueid\":\"%s\"}";
-
-//{"name":"Group 0","lights":[{l1],"type":"LightGroup","action":
-//Successfully compressed from 62 to 61 bytes (-1.6%)
-const char HUE_GROUP0_STATUS_JSON[] PROGMEM =
+ "\"uniqueid\":\"%s\"}"
+ "\0"
+ //=HUE_GROUP0_STATUS_JSON
"{\"name\":\"Group 0\","
"\"lights\":[{l1],"
"\"type\":\"LightGroup\","
- "\"action\":";
-// "\"scene\":\"none\",";
+ "\"action\":"
+ "\0"
+ //=HUE_ERROR_JSON
+ "[{\"error\":{\"type\":901,\"address\":\"/\",\"description\":\"Internal Error\"}}]"
+ "\0"
+ //=HUE_RESP_ON
+ "{\"success\":{\"/lights/%d/state/on\":%s}}"
+ "\0"
+ //=HUE_RESP_NUM
+ "{\"success\":{\"/lights/%d/state/%s\":%d}}"
+ "\0"
+ //=HUE_RESP_XY
+ "{\"success\":{\"/lights/%d/state/xy\":[%s,%s]}}"
+ "\0"
+ ;
+// Use the tool at https://tasmota.hadinger.fr/util and choose "Compress Strings template with Unishox"
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// ++++++++++++++++++++ DO NOT EDIT BELOW ++++++++++++++++++++
+// ++++++++++++++++++++vvvvvvvvvvvvvvvvvvv++++++++++++++++++++
+enum {
+ HUE_LIGHTS_STATUS_JSON1_SUFFIX=0,
+ HUE_LIGHTS_STATUS_JSON2=51,
+ HUE_GROUP0_STATUS_JSON=150,
+ HUE_ERROR_JSON=213,
+ HUE_RESP_ON=283,
+ HUE_RESP_NUM=322,
+ HUE_RESP_XY=361,
+};
+
+// Compressed from 405 to 275, -32.1%
+const char HUE_LIGHTS[] PROGMEM = "\x00\x1A\x3E\xBC\x7B\x2C\x27\xFA\x3D\x87\x99\xEC\xEC\xE6\x7B\x0E\xA3\xD8\xCC\x18"
+ "\x61\x82\x34\xCF\xBB\x0C\x55\x8E\x09\x9E\xC3\xCE\xBE\x2D\x9E\xE9\xC2\xF9\xD4\x7B"
+ "\x28\xC8\x63\x3D\x87\x99\xEC\x26\x6C\xA7\xC2\x31\x10\x78\x16\x7D\x05\xA3\xC2\xA8"
+ "\xF6\x1D\x47\xB3\xAC\x6B\x3D\x87\x99\xEC\x3E\xBC\x7B\x0E\xA3\xD8\x37\x04\x61\x68"
+ "\x80\x89\x2E\xF8\x59\x8B\x0E\x85\xFD\xFC\x11\xF0\x31\x7D\xA6\xA1\x6C\x10\xF0\x43"
+ "\xDD\x38\x5F\x3D\xA0\x87\x90\x90\xF7\xF0\x58\xC4\x71\x9E\xC3\xA8\xF6\x10\x5A\x3C"
+ "\x2A\x2B\xBC\x7B\x0F\x33\xDE\x3D\xA1\x1C\x87\xBE\x40\x89\xAF\x90\x5A\x3C\x2A\x2B"
+ "\x88\x7B\xF8\x2C\x61\xEC\x3A\x8F\x65\x87\x5B\x9C\x7B\x0F\x39\xC2\xF9\xEF\x1E\xD3"
+ "\xD8\xFF\xFC\xF9\xEC\x3C\xCF\x68\x21\x60\xA7\x13\x87\x51\xEC\x2B\x10\x4F\xBF\x78"
+ "\xF6\x1E\x67\xB0\xEC\x3D\x87\x51\xEC\x11\xF8\x3F\xE8\xC0\x41\xC3\xCF\x61\x6F\x53"
+ "\xFF\x58\x48\x9F\xFF\x9F\x3D\x87\xB8\xF7\x1E\xFC\xE1\x7C\xF6\x9E\xCF\x0B\x0C\x37"
+ "\xEF\x1E\xC3\xCC\xF6\x9E\xC3\xB0\x10\x75\xC3\xB0\xFA\x10\xEC\xF5\x5D\x33\xB3\x38"
+ "\xF6\x1E\x67\xD7\x8F\x71\xEE\x05\xAC\x0C\xFA\xF1\xEC\x3C\xCF\xA1\x01\x73\x03\x36"
+ "\x19\x1E\xC3\xCC\xF7\x8F\xAF\x1D\x47\xD7\x8F\x7C\xF7\x1E\xE9\xC2\xF9";
+// ++++++++++++++++++++^^^^^^^^^^^^^^^^^^^++++++++++++++++++++
+// ++++++++++++++++++++ DO NOT EDIT ABOVE ++++++++++++++++++++
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+
+
+// const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM =
+// "%s\"alert\":\"none\","
+// "\"effect\":\"none\","
+// "\"reachable\":true}";
+
+// const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM =
+// ",\"type\":\"Extended color light\","
+// "\"name\":\"%s\","
+// "\"modelid\":\"%s\","
+// "\"manufacturername\":\"%s\","
+// "\"uniqueid\":\"%s\"}";
+
+// const char HUE_GROUP0_STATUS_JSON[] PROGMEM =
+// "{\"name\":\"Group 0\","
+// "\"lights\":[{l1],"
+// "\"type\":\"LightGroup\","
+// "\"action\":";
+
+// const char HueConfigResponse_JSON[] PROGMEM =
+// "{\"name\":\"Philips hue\","
+// "\"mac\":\"{ma\","
+// "\"dhcp\":true,"
+// "\"ipaddress\":\"{ip\","
+// "\"netmask\":\"{ms\","
+// "\"gateway\":\"{gw\","
+// "\"proxyaddress\":\"none\","
+// "\"proxyport\":0,"
+// "\"bridgeid\":\"{br\","
+// "\"UTC\":\"{dt\","
+// "\"whitelist\":{\"{id\":{"
+// "\"last use date\":\"{dt\","
+// "\"create date\":\"{dt\","
+// "\"name\":\"Remote\"}},"
+// "\"swversion\":\"01041302\","
+// "\"apiversion\":\"1.17.0\","
+// "\"swupdate\":{\"updatestate\":0,\"url\":\"\",\"text\":\"\",\"notify\": false},"
+// "\"linkbutton\":false,"
+// "\"portalservices\":false"
+// "}";
//{"name":"Philips hue","mac":"{ma","dhcp":true,"ipaddress":"{ip","netmask":"{ms","gateway":"{gw","proxyaddress":"none","proxyport":0,"bridgeid":"{br","UTC":"{dt","whitelist":{"{id":{"last use date":"{dt","create date":"{dt","name":"Remote"}},"swversion":"01041302","apiversion":"1.17.0","swupdate":{"updatestate":0,"url":"","text":"","notify": false},"linkbutton":false,"portalservices":false}
-//Successfully compressed from 392 to 302 bytes (-23%)
-// const size_t HueConfigResponse_JSON_size = 392;
-// const char HueConfigResponse_JSON[] PROGMEM = "\x3D\xA7\xB3\xAC\x6B\x3D\x87\x99\xEC\x21\x82\xB4\x2D\x19\xE4\x28\x5B\x3D\x87\x51"
-// "\xEC\x1B\x61\x9E\xC3\xCC\xF6\x1E\xD1\xB6\x7B\x0E\xA3\xD8\x20\xA0\xC6\x1E\xC3\xCE"
-// "\xBE\x2D\x9D\x47\xB3\x46\x58\x82\x7D\xFB\xC7\xB0\xF3\x3D\x87\xB7\x46\x1E\xC3\xA8"
-// "\xF6\x73\xA1\xB7\xE3\x43\xD8\x79\x9E\xC3\xDA\x37\xC7\xB0\xEA\x3D\x83\xD7\x4C\x7E"
-// "\xCC\x8F\x61\xE6\x7B\x0F\x68\xF0\xF9\xEC\x3A\x8F\x60\xCF\xE1\xB0\xC8\x11\x71\x1E"
-// "\xCE\x60\x87\x48\x66\x7E\x8F\x61\xE6\x71\x9D\x47\xB0\x87\x7F\x44\x1E\x7A\x21\xEC"
-// "\x3C\xCF\x61\xED\x1D\xF3\xD8\x75\x1E\xC2\x16\x54\x41\x9E\xC3\xCC\xF6\x1E\xD1\x28"
-// "\xF6\x1D\x47\xB0\x7C\x56\xD3\x0B\x7D\x47\xB0\xF3\x3D\xA7\xB0\xF6\xE8\x87\xB0\xF3"
-// "\x3D\xA7\xB0\x2B\xF5\x21\x7E\x68\x4B\xA6\x08\x98\x30\x7F\x77\x40\x95\x40\x10\xB8"
-// "\x3A\x2F\xB1\xB9\x4C\xF6\x1E\xE3\xDC\x75\x1E\xCF\x0F\x99\xBF\xFB\x73\x8F\x61\xE6"
-// "\x7B\x0E\x38\xF2\x5B\xA3\xD8\x75\x1E\xC2\xB1\x9A\x08\xB5\x0E\x43\xA4\xF1\xD1\x9E"
-// "\xC3\xA8\xF6\x17\x87\xC5\x8C\x04\x1C\xB0\xF6\x9E\xC0\x41\x8D\xEA\xBA\x67\xB0\xF3"
-// "\x38\xCE\xA3\xD8\x42\xFE\x11\xEC\x3C\xCF\x61\xEC\x3A\x8F\x65\x33\x65\x02\x0C\x6E"
-// "\xCA\xD3\x06\x47\xB0\xF3\x46\x2C\x2F\x33\xDC\x75\x1E\xC0\xB7\x8D\x07\x0B\xAA\xCE"
-// "\x3D\x87\x99\x8B\x0B\xCC\xEA\x3D\x83\x33\xF5\x61\x79\xFC\xCF\x43\x7E\x04\x2A\x2B"
-// "\x67\xB8";
-const char HueConfigResponse_JSON[] PROGMEM =
- "{\"name\":\"Philips hue\","
- "\"mac\":\"{ma\","
- "\"dhcp\":true,"
- "\"ipaddress\":\"{ip\","
- "\"netmask\":\"{ms\","
- "\"gateway\":\"{gw\","
- "\"proxyaddress\":\"none\","
- "\"proxyport\":0,"
- "\"bridgeid\":\"{br\","
- "\"UTC\":\"{dt\","
- "\"whitelist\":{\"{id\":{"
- "\"last use date\":\"{dt\","
- "\"create date\":\"{dt\","
- "\"name\":\"Remote\"}},"
- "\"swversion\":\"01041302\","
- "\"apiversion\":\"1.17.0\","
- "\"swupdate\":{\"updatestate\":0,\"url\":\"\",\"text\":\"\",\"notify\": false},"
- "\"linkbutton\":false,"
- "\"portalservices\":false"
- "}";
-const char HUE_ERROR_JSON[] PROGMEM =
- "[{\"error\":{\"type\":901,\"address\":\"/\",\"description\":\"Internal Error\"}}]";
+const size_t HueConfigResponse_JSON_SIZE = 392;
+const char HueConfigResponse_JSON[] PROGMEM = "\x3D\xA7\xB3\xAC\x6B\x3D\x87\x99\xEC\x21\x82\xB4\x2D\x19\xE4\x28\x5B\x3D\x87\x51"
+ "\xEC\x1B\x61\x9E\xC3\xCC\xF6\x1E\xD1\xB6\x7B\x0E\xA3\xD8\x20\xA0\xC6\x1E\xC3\xCE"
+ "\xBE\x2D\x9D\x47\xB3\x46\x58\x82\x7D\xFB\xC7\xB0\xF3\x3D\x87\xB7\x46\x1E\xC3\xA8"
+ "\xF6\x73\xA1\xB7\xE3\x43\xD8\x79\x9E\xC3\xDA\x37\xC7\xB0\xEA\x3D\x83\xD7\x4C\x7E"
+ "\xCC\x8F\x61\xE6\x7B\x0F\x68\xF0\xF9\xEC\x3A\x8F\x60\xCF\xE1\xB0\xC8\x11\x71\x1E"
+ "\xCE\x60\x87\x48\x66\x7E\x8F\x61\xE6\x71\x9D\x47\xB0\x87\x7F\x44\x1E\x7A\x21\xEC"
+ "\x3C\xCF\x61\xED\x1D\xF3\xD8\x75\x1E\xC2\x16\x54\x41\x9E\xC3\xCC\xF6\x1E\xD1\x28"
+ "\xF6\x1D\x47\xB0\x7C\x56\xD3\x0B\x7D\x47\xB0\xF3\x3D\xA7\xB0\xF6\xE8\x87\xB0\xF3"
+ "\x3D\xA7\xB0\x2B\xF5\x21\x7E\x68\x4B\xA6\x08\x98\x30\x7F\x77\x40\x95\x40\x10\xB8"
+ "\x3A\x2F\xB1\xB9\x4C\xF6\x1E\xE3\xDC\x75\x1E\xCF\x0F\x99\xBF\xFB\x73\x8F\x61\xE6"
+ "\x7B\x0E\x38\xF2\x5B\xA3\xD8\x75\x1E\xC2\xB1\x9A\x08\xB5\x0E\x43\xA4\xF1\xD1\x9E"
+ "\xC3\xA8\xF6\x17\x87\xC5\x8C\x04\x1C\xB0\xF6\x9E\xC0\x41\x8D\xEA\xBA\x67\xB0\xF3"
+ "\x38\xCE\xA3\xD8\x42\xFE\x11\xEC\x3C\xCF\x61\xEC\x3A\x8F\x65\x33\x65\x02\x0C\x6E"
+ "\xCA\xD3\x06\x47\xB0\xF3\x46\x2C\x2F\x33\xDC\x75\x1E\xC0\xB7\x8D\x07\x0B\xAA\xCE"
+ "\x3D\x87\x99\x8B\x0B\xCC\xEA\x3D\x83\x33\xF5\x61\x79\xFC\xCF\x43\x7E\x04\x2A\x2B"
+ "\x67\xB8";
+
+// const char HUE_ERROR_JSON[] PROGMEM =
+// "[{\"error\":{\"type\":901,\"address\":\"/\",\"description\":\"Internal Error\"}}]";
/********************************************************************************************/
@@ -272,7 +446,7 @@ void HueNotImplemented(String *path)
void HueConfigResponse(String *response)
{
- *response += FPSTR(HueConfigResponse_JSON);
+ *response += Decompress(HueConfigResponse_JSON, HueConfigResponse_JSON_SIZE);
response->replace("{ma", WiFi.macAddress());
response->replace("{ip", WiFi.localIP().toString());
response->replace("{ms", WiFi.subnetMask().toString());
@@ -360,6 +534,7 @@ void HueLightStatus1(uint8_t device, String *response)
const size_t buf_size = 256;
char * buf = (char*) malloc(buf_size); // temp buffer for strings, avoid stack
+ UnishoxStrings msg(HUE_LIGHTS);
snprintf_P(buf, buf_size, PSTR("{\"on\":%s,"), (TasmotaGlobal.power & (1 << (device-1))) ? "true" : "false");
// Brightness for all devices with PWM
@@ -382,7 +557,7 @@ void HueLightStatus1(uint8_t device, String *response)
if (LST_COLDWARM == local_light_subtype || LST_RGBW <= local_light_subtype) { // white temp
snprintf_P(buf, buf_size, PSTR("%s\"ct\":%d,"), buf, ct > 0 ? ct : 284);
}
- snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON1_SUFFIX, buf);
+ snprintf_P(buf, buf_size, msg[HUE_LIGHTS_STATUS_JSON1_SUFFIX], buf);
*response += buf;
free(buf);
@@ -415,7 +590,8 @@ void HueLightStatus2(uint8_t device, String *response)
}
fname[fname_len] = 0x00;
}
- snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON2,
+ UnishoxStrings msg(HUE_LIGHTS);
+ snprintf_P(buf, buf_size, msg[HUE_LIGHTS_STATUS_JSON2],
EscapeJSONString(fname).c_str(),
EscapeJSONString(Settings.user_template_name).c_str(),
PSTR("Tasmota"),
@@ -548,6 +724,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
const size_t buf_size = 100;
char * buf = (char*) malloc(buf_size);
+ UnishoxStrings msg(HUE_LIGHTS);
if (Webserver->args()) {
response = "[";
@@ -559,7 +736,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
if (hue_on) {
on = hue_on.getBool();
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/on\":%s}}"),
+ msg[HUE_RESP_ON],
device_id, on ? "true" : "false");
#ifdef USE_SHUTTER
@@ -602,7 +779,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
prev_bri = bri; // store command value
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "bri", bri);
response += buf;
if (LST_SINGLE <= Light.subtype) {
@@ -633,7 +810,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
//AddLog_P(LOG_LEVEL_DEBUG_MORE, "XY RGB (%d %d %d) HS (%d %d)", rr,gg,bb,hue,sat);
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/xy\":[%s,%s]}}"),
+ msg[HUE_RESP_XY],
device_id, prev_x_str, prev_y_str);
response += buf;
g_gotct = false;
@@ -648,7 +825,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
prev_hue = hue;
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "hue", hue);
response += buf;
if (LST_RGB <= Light.subtype) {
@@ -667,7 +844,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
prev_sat = sat; // store command value
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "sat", sat);
response += buf;
if (LST_RGB <= Light.subtype) {
@@ -686,7 +863,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
prev_ct = ct; // store commande value
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "ct", ct);
response += buf;
if ((LST_COLDWARM == Light.subtype) || (LST_RGBW <= Light.subtype)) {
@@ -725,11 +902,11 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
}
response += "]";
if (2 == response.length()) {
- response = FPSTR(HUE_ERROR_JSON);
+ response = msg[HUE_ERROR_JSON];
}
}
else {
- response = FPSTR(HUE_ERROR_JSON);
+ response = msg[HUE_ERROR_JSON];
}
free(buf);
}
@@ -835,7 +1012,8 @@ void HueGroups(String *path)
//AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " HueGroups (%s)"), path->c_str());
if (path->endsWith("/0")) {
- response = FPSTR(HUE_GROUP0_STATUS_JSON);
+ UnishoxStrings msg(HUE_LIGHTS);
+ response = msg[HUE_GROUP0_STATUS_JSON];
String lights = F("\"1\"");
for (uint32_t i = 2; i <= maxhue; i++) {
lights += ",\"";
@@ -881,17 +1059,18 @@ void HandleHueApi(String *path)
AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_POST_ARGS " (%s)"), json.c_str()); // HTP: Hue POST args ({"on":false})
}
- if (path->endsWith(F("/invalid/"))) {} // Just ignore
+ UnishoxStrings msg(HUE_API);
+ if (path->endsWith(msg[HUE_INVALID])) {} // Just ignore
else if (!apilen) HueAuthentication(path); // New HUE App setup
- else if (path->endsWith(F("/"))) HueAuthentication(path); // New HUE App setup
- else if (path->endsWith(F("/config"))) HueConfig(path);
- else if (path->indexOf(F("/lights")) >= 0) HueLights(path);
- else if (path->indexOf(F("/groups")) >= 0) HueGroups(path);
- else if (path->endsWith(F("/schedules"))) HueNotImplemented(path);
- else if (path->endsWith(F("/sensors"))) HueNotImplemented(path);
- else if (path->endsWith(F("/scenes"))) HueNotImplemented(path);
- else if (path->endsWith(F("/rules"))) HueNotImplemented(path);
- else if (path->endsWith(F("/resourcelinks"))) HueNotImplemented(path);
+ else if (path->endsWith(msg[HUE_ROOT])) HueAuthentication(path); // New HUE App setup
+ else if (path->endsWith(msg[HUE_CONFIG])) HueConfig(path);
+ else if (path->indexOf(msg[HUE_LIGHTS_API]) >= 0) HueLights(path);
+ else if (path->indexOf(msg[HUE_GROUPS]) >= 0) HueGroups(path);
+ else if (path->endsWith(msg[HUE_SCHEDULES])) HueNotImplemented(path);
+ else if (path->endsWith(msg[HUE_SENSORS])) HueNotImplemented(path);
+ else if (path->endsWith(msg[HUE_SCENES])) HueNotImplemented(path);
+ else if (path->endsWith(msg[HUE_RULES])) HueNotImplemented(path);
+ else if (path->endsWith(msg[HUE_RESOURCELINKS])) HueNotImplemented(path);
else HueGlobalConfig(path);
}
diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino
index cc77d2314..a77c8b67f 100644
--- a/tasmota/xdrv_23_zigbee_3_hue.ino
+++ b/tasmota/xdrv_23_zigbee_3_hue.ino
@@ -101,7 +101,8 @@ void HueLightStatus2Zigbee(uint16_t shortaddr, String *response)
char shortaddrname[8];
snprintf_P(shortaddrname, sizeof(shortaddrname), PSTR("0x%04X"), shortaddr);
- snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON2,
+ UnishoxStrings msg(HUE_LIGHTS);
+ snprintf_P(buf, buf_size, msg[HUE_LIGHTS_STATUS_JSON2],
(friendlyName) ? EscapeJSONString(friendlyName).c_str() : shortaddrname,
(modelId) ? EscapeJSONString(modelId).c_str() : PSTR("Unknown"),
(manufacturerId) ? EscapeJSONString(manufacturerId).c_str() : PSTR("Tasmota"),
@@ -219,6 +220,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
const size_t buf_size = 100;
char * buf = (char*) malloc(buf_size);
+ UnishoxStrings msg(HUE_LIGHTS);
if (Webserver->args()) {
response = "[";
@@ -230,7 +232,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
if (hue_on) {
on = hue_on.getBool();
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/on\":%s}}"),
+ msg[HUE_RESP_ON],
device_id, on ? "true" : "false");
if (on) {
@@ -249,7 +251,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
prev_bri = bri; // store command value
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "bri", bri);
response += buf;
if (LST_SINGLE <= bulbtype) {
@@ -273,7 +275,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
strlcpy(prev_y_str, tok_y.getStr(), sizeof(prev_y_str));
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/xy\":[%s,%s]}}"),
+ msg[HUE_RESP_XY],
device_id, prev_x_str, prev_y_str);
response += buf;
resp = true;
@@ -290,7 +292,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
prev_hue = hue;
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "hue", hue);
response += buf;
if (LST_RGB <= bulbtype) {
@@ -308,7 +310,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
prev_sat = sat; // store command value
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "sat", sat);
response += buf;
if (LST_RGB <= bulbtype) {
@@ -329,7 +331,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
prev_ct = ct; // store commande value
if (resp) { response += ","; }
snprintf_P(buf, buf_size,
- PSTR("{\"success\":{\"/lights/%d/state/%s\":%d}}"),
+ msg[HUE_RESP_NUM],
device_id, "ct", ct);
response += buf;
if ((LST_COLDWARM == bulbtype) || (LST_RGBW <= bulbtype)) {
@@ -340,11 +342,11 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
response += "]";
if (2 == response.length()) {
- response = FPSTR(HUE_ERROR_JSON);
+ response = msg[HUE_ERROR_JSON];
}
}
else {
- response = FPSTR(HUE_ERROR_JSON);
+ response = msg[HUE_ERROR_JSON];
}
AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str());
WSSend(code, CT_JSON, response);
diff --git a/tasmota/xdrv_42_i2s_audio.ino b/tasmota/xdrv_42_i2s_audio.ino
index 1e468593b..576ba2380 100644
--- a/tasmota/xdrv_42_i2s_audio.ino
+++ b/tasmota/xdrv_42_i2s_audio.ino
@@ -69,6 +69,8 @@ AudioGeneratorMP3 *decoder = NULL;
void *mp3ram = NULL;
+extern FS *ufsp;
+
#ifdef ESP8266
const int preallocateBufferSize = 5*1024;
const int preallocateCodecSize = 29192; // MP3 codec max mem needed
@@ -391,7 +393,7 @@ static const uint8_t wavHTemplate[] PROGMEM = { // Hardcoded simple WAV header w
0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff };
bool SaveWav(char *path, uint8_t *buff, uint32_t size) {
- File fwp = fsp->open(path, FILE_WRITE);
+ File fwp = ufsp->open(path, FILE_WRITE);
uint8_t wavHeader[sizeof(wavHTemplate)];
memcpy_P(wavHeader, wavHTemplate, sizeof(wavHTemplate));
@@ -552,7 +554,7 @@ void I2S_WR_Show(void) {
#ifdef ESP32
void Play_mp3(const char *path) {
-#if defined(USE_SCRIPT) && defined(USE_SCRIPT_FATFS)
+#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(UFILESYSTEM)
if (decoder || mp3) return;
if (!out) return;
@@ -566,7 +568,7 @@ void Play_mp3(const char *path) {
I2S_Task = false;
}
- file = new AudioFileSourceFS(*fsp,path);
+ file = new AudioFileSourceFS(*ufsp,path);
id3 = new AudioFileSourceID3(file);
if (mp3ram) {
diff --git a/tasmota/xdrv_98_filesystem.ino b/tasmota/xdrv_98_filesystem.ino
index 1fadd6427..3aad95a5a 100644
--- a/tasmota/xdrv_98_filesystem.ino
+++ b/tasmota/xdrv_98_filesystem.ino
@@ -70,6 +70,8 @@ The driver enabled by #define USE_UFILESYS
// global file system pointer
FS *ufsp;
+// flash file system pointer on esp32
+FS *ffsp;
char ufs_path[48];
File ufs_upload_file;
@@ -83,6 +85,7 @@ uint8_t ufs_type;
void UFSInit(void) {
ufs_type = 0;
+ ffsp = 0;
// check for fs options,
// 1. check for SD card
// 2. check for littlefs or FAT
@@ -98,12 +101,22 @@ void UFSInit(void) {
if (SD.begin(cs)) {
#ifdef ESP8266
- ufsp = (FS*)&SD;
+ ufsp = &SDFS;
#endif // ESP8266
#ifdef ESP32
ufsp = &SD;
#endif // ESP32
ufs_type = UFS_TSDC;
+ // now detect ffs
+ ffsp = &LITTLEFS;
+ if (!LITTLEFS.begin()) {
+ // ffat is second
+ ffsp = &FFat;
+ if (!FFat.begin(true)) {
+ ffsp = 0;
+ return;
+ }
+ }
return;
}
}
@@ -126,10 +139,12 @@ void UFSInit(void) {
return;
}
ufs_type = UFS_TFAT;
+ ffsp = ufsp;
return;
}
#endif // ESP32
ufs_type = UFS_TLFS;
+ ffsp = ufsp;
return;
}
@@ -267,7 +282,7 @@ void UFS_free(void) {
const char UFS_WEB_DIR[] PROGMEM =
"";
-const char UFS_FILE_UPLOAD[] PROGMEM = D_SDCARD_DIR;
+const char UFS_FILE_UPLOAD[] PROGMEM = D_UFSDIR;
const char UFS_FORM_FILE_UPLOAD[] PROGMEM =
""
"