mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 19:56:30 +00:00
Merge branch 'development' of github.com:arendst/Tasmota into pr2_tm1637
This commit is contained in:
commit
dce391f3ee
@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Support for Frysk language translations by Christiaan Heerze
|
- Support for Frysk language translations by Christiaan Heerze
|
||||||
- ESP8266 Fallback to ``*.bin.gz`` binary when OTA upload of ``*.bin`` binary fails
|
- ESP8266 Fallback to ``*.bin.gz`` binary when OTA upload of ``*.bin`` binary fails
|
||||||
- Berry language improved Tasmota integration
|
- Berry language improved Tasmota integration
|
||||||
|
- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete`` and ``UfsRename``
|
||||||
|
- Basic support for filesystem ``autoexec.bat``
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- IRremoteESP8266 library from v2.7.14 to v2.7.15
|
- IRremoteESP8266 library from v2.7.14 to v2.7.15
|
||||||
|
@ -95,6 +95,8 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
|||||||
- Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind`` and ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110`` and ``112``
|
- Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind`` and ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110`` and ``112``
|
||||||
- Commands ``ZbNoAutoBind``, ``ZbReceivedTopic`` and ``ZbOmitDevice`` as synonyms for ``SetOption116, 118`` and ``119``
|
- Commands ``ZbNoAutoBind``, ``ZbReceivedTopic`` and ``ZbOmitDevice`` as synonyms for ``SetOption116, 118`` and ``119``
|
||||||
- Commands ``BuzzerActive`` and ``BuzzerPwm`` as synonyms for ``SetOption67`` and ``111``
|
- Commands ``BuzzerActive`` and ``BuzzerPwm`` as synonyms for ``SetOption67`` and ``111``
|
||||||
|
- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete`` and ``UfsRename``
|
||||||
|
- Basic support for filesystem ``autoexec.bat``
|
||||||
- Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152)
|
- 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)
|
- 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)
|
- Rotary No Pullup GPIO selection ``Rotary A/B_n`` [#10407](https://github.com/arendst/Tasmota/issues/10407)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
name=Waveshare esp 2.9 inch e-paper display driver
|
name=Display renderer
|
||||||
version=1.0
|
version=1.0
|
||||||
author=Gerhard Mutz
|
author=Gerhard Mutz
|
||||||
maintainer=Gerhard Mutz
|
maintainer=Gerhard Mutz
|
||||||
sentence=ESP8266 library for Waveshare e-paper display.
|
sentence=ESP8266 ESP32 library for Tasmota displays
|
||||||
paragraph=
|
paragraph=
|
||||||
category=Display
|
category=Display
|
||||||
url=https://github.com/gemu2015/Sonoff-Tasmota/tree/displays/lib/esp-epaper-29-ws-20171230-gemu-1.0#
|
url=https://github.com/arendst/Tasmota
|
||||||
architectures=*
|
architectures=*
|
||||||
|
9
lib/lib_display/Epaper_29-gemu-1.0/library.properties
Normal file
9
lib/lib_display/Epaper_29-gemu-1.0/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=Waveshare esp 2.9 inch e-paper display driver
|
||||||
|
version=1.0
|
||||||
|
author=Gerhard Mutz
|
||||||
|
maintainer=Gerhard Mutz
|
||||||
|
sentence=ESP8266 ESP32 library for Waveshare 2.9 inch e-paper display
|
||||||
|
paragraph=
|
||||||
|
category=Display
|
||||||
|
url=https://github.com/arendst/Tasmota
|
||||||
|
architectures=*
|
9
lib/lib_display/Epaper_42-gemu-1.0/library.properties
Normal file
9
lib/lib_display/Epaper_42-gemu-1.0/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=Waveshare esp 4.2 inch e-paper display driver
|
||||||
|
version=1.0
|
||||||
|
author=Gerhard Mutz
|
||||||
|
maintainer=Gerhard Mutz
|
||||||
|
sentence=ESP8266 ESP32 library for Waveshare e-paper display.
|
||||||
|
paragraph=
|
||||||
|
category=Display
|
||||||
|
url=https://github.com/arendst/Tasmota
|
||||||
|
architectures=*
|
9
lib/lib_display/ILI9341-gemu-1.0/library.properties
Normal file
9
lib/lib_display/ILI9341-gemu-1.0/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=ILI9341
|
||||||
|
version=1.0.0
|
||||||
|
author=Gerhard Mutz
|
||||||
|
maintainer=Gerhard Mutz
|
||||||
|
sentence=ILI9341 ESP8266 ESP32 display driver for Tasmota
|
||||||
|
paragraph=ILI9341 ESP8266 ESP32 display driver for Tasmota
|
||||||
|
category=Display
|
||||||
|
url=https://github.com/arendst/Tasmota
|
||||||
|
architectures=*
|
@ -1,9 +1,9 @@
|
|||||||
name=RA8876
|
name=RA8876
|
||||||
version=1.0.2
|
version=1.0.0
|
||||||
author=Jaret Burkett
|
author=Jaret Burkett / Gerhard Mutz
|
||||||
maintainer=Jaret Burkett <jaretburkett@gmail.com>
|
maintainer=Gerhard Mutz
|
||||||
sentence=Library for RA8876 displays
|
sentence=Tasmota Library for RA8876 displays
|
||||||
paragraph=Library for RA8876 displays
|
paragraph=Tasmota Library for RA8876 displays
|
||||||
category=Display
|
category=Display
|
||||||
url=https://github.com/jaretburkett/ILI9488
|
url=https://github.com/arendst/Tasmota
|
||||||
architectures=*
|
architectures=*
|
||||||
|
9
lib/lib_div/ProcessControl/library.properties
Normal file
9
lib/lib_div/ProcessControl/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=Process_control
|
||||||
|
version=1.0.0
|
||||||
|
author=Colin Law
|
||||||
|
maintainer=Colin Law
|
||||||
|
sentence=C++ library of process control algorithms
|
||||||
|
paragraph=C++ library of process control algorithms
|
||||||
|
category=Heating
|
||||||
|
url=https://github.com/colinl/process-control.git
|
||||||
|
architectures=*
|
9
lib/lib_div/stm32flash-1.0-tasmota/library.properties
Normal file
9
lib/lib_div/stm32flash-1.0-tasmota/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=stm32_flash
|
||||||
|
version=1.0.0
|
||||||
|
author=Tormod Volden
|
||||||
|
maintainer=Tormod Volden
|
||||||
|
sentence=STM32 Flasher
|
||||||
|
paragraph=STM32 Flaher
|
||||||
|
category=Tools
|
||||||
|
url=
|
||||||
|
architectures=esp8266
|
@ -2,7 +2,7 @@
|
|||||||
"name": "NimBLE-Arduino",
|
"name": "NimBLE-Arduino",
|
||||||
"keywords": "esp32, bluetooth",
|
"keywords": "esp32, bluetooth",
|
||||||
"description": "Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE",
|
"description": "Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE",
|
||||||
"version": "1.0.2",
|
"version": "1.1.0",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "espressif32"
|
"platforms": "espressif32"
|
||||||
}
|
}
|
||||||
|
@ -1667,6 +1667,92 @@ void TemplateJson(void)
|
|||||||
ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1);
|
ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ( defined(USE_SCRIPT) && defined(SUPPORT_MQTT_EVENT) ) || defined (USE_DT_VARS)
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Parse json paylod with path
|
||||||
|
\*********************************************************************************************/
|
||||||
|
// parser object, source keys, delimiter, float result or NULL, string result or NULL, string size
|
||||||
|
// return 1 if numeric 2 if string, else 0 = not found
|
||||||
|
uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, float *nres, char *sres, uint32_t slen) {
|
||||||
|
uint32_t res = 0;
|
||||||
|
const char *cp = spath;
|
||||||
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: parsing json key: %s from json: %s"), cp, jpath);
|
||||||
|
#endif
|
||||||
|
JsonParserObject obj = *jobj;
|
||||||
|
JsonParserObject lastobj = obj;
|
||||||
|
char selem[32];
|
||||||
|
uint8_t aindex = 0;
|
||||||
|
String value = "";
|
||||||
|
while (1) {
|
||||||
|
// read next element
|
||||||
|
for (uint32_t sp=0; sp<sizeof(selem)-1; sp++) {
|
||||||
|
if (!*cp || *cp==delim) {
|
||||||
|
selem[sp] = 0;
|
||||||
|
cp++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
selem[sp] = *cp++;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: cmp current key: %s"), selem);
|
||||||
|
#endif
|
||||||
|
// check for array
|
||||||
|
char *sp = strchr(selem,'[');
|
||||||
|
if (sp) {
|
||||||
|
*sp = 0;
|
||||||
|
aindex = atoi(sp+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check element
|
||||||
|
obj = obj[selem];
|
||||||
|
if (!obj.isValid()) {
|
||||||
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: obj invalid: %s"), selem);
|
||||||
|
#endif
|
||||||
|
JsonParserToken tok = lastobj[selem];
|
||||||
|
if (tok.isValid()) {
|
||||||
|
if (tok.isArray()) {
|
||||||
|
JsonParserArray array = JsonParserArray(tok);
|
||||||
|
value = array[aindex].getStr();
|
||||||
|
if (array.isNum()) {
|
||||||
|
if (nres) *nres=tok.getFloat();
|
||||||
|
res = 1;
|
||||||
|
} else {
|
||||||
|
res = 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = tok.getStr();
|
||||||
|
if (tok.isNum()) {
|
||||||
|
if (nres) *nres=tok.getFloat();
|
||||||
|
res = 1;
|
||||||
|
} else {
|
||||||
|
res = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: token invalid: %s"), selem);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (obj.isObject()) {
|
||||||
|
lastobj = obj;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!*cp) break;
|
||||||
|
}
|
||||||
|
if (sres) {
|
||||||
|
strlcpy(sres,value.c_str(), slen);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_SCRIPT
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Sleep aware time scheduler functions borrowed from ESPEasy
|
* Sleep aware time scheduler functions borrowed from ESPEasy
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
@ -2237,6 +2323,9 @@ void AddLogSpi(bool hardware, uint32_t clk, uint32_t mosi, uint32_t miso) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Uncompress static PROGMEM strings
|
* Uncompress static PROGMEM strings
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -716,6 +716,11 @@ void MqttPublishTeleState(void)
|
|||||||
ResponseClear();
|
ResponseClear();
|
||||||
MqttShowState();
|
MqttShowState();
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN);
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN);
|
||||||
|
|
||||||
|
#ifdef USE_DT_VARS
|
||||||
|
DTVarsTeleperiod();
|
||||||
|
#endif // USE_DT_VARS
|
||||||
|
|
||||||
#if defined(USE_RULES) || defined(USE_SCRIPT)
|
#if defined(USE_RULES) || defined(USE_SCRIPT)
|
||||||
RulesTeleperiod(); // Allow rule based HA messages
|
RulesTeleperiod(); // Allow rule based HA messages
|
||||||
#endif // USE_SCRIPT
|
#endif // USE_SCRIPT
|
||||||
|
@ -370,10 +370,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
|
|||||||
|
|
||||||
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
||||||
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
||||||
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_MAX };
|
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_AUTOEXEC, SRC_MAX };
|
||||||
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
||||||
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
||||||
"Thermostat|Chat|TCL|Berry";
|
"Thermostat|Chat|TCL|Berry|Autoexec";
|
||||||
|
|
||||||
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
||||||
|
|
||||||
|
@ -146,6 +146,7 @@ struct {
|
|||||||
bool restart_halt; // Do not restart but stay in wait loop
|
bool restart_halt; // Do not restart but stay in wait loop
|
||||||
bool module_changed; // Indicate module changed since last restart
|
bool module_changed; // Indicate module changed since last restart
|
||||||
bool wifi_stay_asleep; // Allow sleep only incase of ESP32 BLE
|
bool wifi_stay_asleep; // Allow sleep only incase of ESP32 BLE
|
||||||
|
bool no_autoexec; // Disable autoexec
|
||||||
|
|
||||||
StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits)
|
StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits)
|
||||||
uint8_t spi_enabled; // SPI configured
|
uint8_t spi_enabled; // SPI configured
|
||||||
@ -303,6 +304,7 @@ void setup(void) {
|
|||||||
}
|
}
|
||||||
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +2) { // Restarted 4 times
|
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +2) { // Restarted 4 times
|
||||||
Settings.rule_enabled = 0; // Disable all rules
|
Settings.rule_enabled = 0; // Disable all rules
|
||||||
|
TasmotaGlobal.no_autoexec = true;
|
||||||
}
|
}
|
||||||
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +3) { // Restarted 5 times
|
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +3) { // Restarted 5 times
|
||||||
for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) {
|
for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) {
|
||||||
|
@ -261,6 +261,8 @@ const uint16_t LOG_BUFFER_SIZE = 4000; // Max number of characters in lo
|
|||||||
#define TASM_FILE_DRIVER "/.drvset%03d"
|
#define TASM_FILE_DRIVER "/.drvset%03d"
|
||||||
#define TASM_FILE_SENSOR "/.snsset%03d"
|
#define TASM_FILE_SENSOR "/.snsset%03d"
|
||||||
#define TASM_FILE_ZIGBEE "/zb" // Zigbee settings blob as used by CC2530 on ESP32
|
#define TASM_FILE_ZIGBEE "/zb" // Zigbee settings blob as used by CC2530 on ESP32
|
||||||
|
#define TASM_FILE_AUTOEXEC "/autoexec.bat" // Commands executed after restart
|
||||||
|
#define TASM_FILE_CONFIG "/config.sys" // Settings executed after restart
|
||||||
|
|
||||||
#ifndef MQTT_MAX_PACKET_SIZE
|
#ifndef MQTT_MAX_PACKET_SIZE
|
||||||
#define MQTT_MAX_PACKET_SIZE 1200 // Bytes
|
#define MQTT_MAX_PACKET_SIZE 1200 // Bytes
|
||||||
|
@ -501,7 +501,7 @@ void EnergyEverySecond(void)
|
|||||||
{
|
{
|
||||||
// Overtemp check
|
// Overtemp check
|
||||||
if (TasmotaGlobal.global_update) {
|
if (TasmotaGlobal.global_update) {
|
||||||
if (TasmotaGlobal.power && !isnan(TasmotaGlobal.temperature_celsius) && (TasmotaGlobal.temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays
|
if (TasmotaGlobal.power && !isnan(TasmotaGlobal.temperature_celsius) && (TasmotaGlobal.temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // SetOption42 Device overtemp, turn off relays
|
||||||
|
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %1_f"), &TasmotaGlobal.temperature_celsius);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %1_f"), &TasmotaGlobal.temperature_celsius);
|
||||||
|
|
||||||
|
@ -4326,14 +4326,13 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
|
|||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
#ifdef USE_SENDMAIL
|
#ifdef USE_SENDMAIL
|
||||||
/*
|
else if (!strncmp(lp, "mail", 4)) {
|
||||||
else if (!strncmp(lp, "sm", 2)) {
|
lp+=5;
|
||||||
lp+=3;
|
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
Replace_Cmd_Vars(lp ,1 , tmp, sizeof(tmp));
|
Replace_Cmd_Vars(lp ,1 , tmp, sizeof(tmp));
|
||||||
SendMail(tmp);
|
SendMail(tmp);
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}*/
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) {
|
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) {
|
||||||
// execute cmd
|
// execute cmd
|
||||||
@ -5819,14 +5818,14 @@ void dateTime(uint16_t* date, uint16_t* time) {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef SUPPORT_MQTT_EVENT
|
#ifdef SUPPORT_MQTT_EVENT
|
||||||
|
/*
|
||||||
//#define DEBUG_MQTT_EVENT
|
//#define DEBUG_MQTT_EVENT
|
||||||
|
// parser object, source keys, delimiter, float result or NULL, string result or NULL, string size
|
||||||
uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, float *nres, char *sres, uint32_t slen) {
|
uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, float *nres, char *sres, uint32_t slen) {
|
||||||
uint32_t res = 0;
|
uint32_t res = 0;
|
||||||
const char *cp = spath;
|
const char *cp = spath;
|
||||||
#ifdef DEBUG_MQTT_EVENT
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
// AddLog(LOG_LEVEL_INFO, PSTR("Script: parsing json key: %s from json: %s"), cp, jpath);
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: parsing json key: %s from json: %s"), cp, jpath);
|
||||||
#endif
|
#endif
|
||||||
JsonParserObject obj = *jobj;
|
JsonParserObject obj = *jobj;
|
||||||
JsonParserObject lastobj = obj;
|
JsonParserObject lastobj = obj;
|
||||||
@ -5843,8 +5842,8 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl
|
|||||||
}
|
}
|
||||||
selem[sp] = *cp++;
|
selem[sp] = *cp++;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MQTT_EVENT
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("Script: cmp current key: %s"), selem);
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: cmp current key: %s"), selem);
|
||||||
#endif
|
#endif
|
||||||
// check for array
|
// check for array
|
||||||
char *sp = strchr(selem,'[');
|
char *sp = strchr(selem,'[');
|
||||||
@ -5856,8 +5855,8 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl
|
|||||||
// now check element
|
// now check element
|
||||||
obj = obj[selem];
|
obj = obj[selem];
|
||||||
if (!obj.isValid()) {
|
if (!obj.isValid()) {
|
||||||
#ifdef DEBUG_MQTT_EVENT
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("Script: obj invalid: %s"), selem);
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: obj invalid: %s"), selem);
|
||||||
#endif
|
#endif
|
||||||
JsonParserToken tok = lastobj[selem];
|
JsonParserToken tok = lastobj[selem];
|
||||||
if (tok.isValid()) {
|
if (tok.isValid()) {
|
||||||
@ -5881,8 +5880,8 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MQTT_EVENT
|
#ifdef DEBUG_JSON_PARSE_PATH
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("Script: token invalid: %s"), selem);
|
AddLog(LOG_LEVEL_INFO, PSTR("JSON: token invalid: %s"), selem);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5892,11 +5891,13 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl
|
|||||||
}
|
}
|
||||||
if (!*cp) break;
|
if (!*cp) break;
|
||||||
}
|
}
|
||||||
strlcpy(sres,value.c_str(),slen);
|
if (sres) {
|
||||||
|
strlcpy(sres,value.c_str(), slen);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
#ifndef MQTT_EVENT_MSIZE
|
#ifndef MQTT_EVENT_MSIZE
|
||||||
#define MQTT_EVENT_MSIZE 256
|
#define MQTT_EVENT_MSIZE 256
|
||||||
#endif // MQTT_EVENT_MSIZE
|
#endif // MQTT_EVENT_MSIZE
|
||||||
|
@ -180,95 +180,6 @@ void DisplayClear(void)
|
|||||||
XdspCall(FUNC_DISPLAY_CLEAR);
|
XdspCall(FUNC_DISPLAY_CLEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayDrawHLine(uint16_t x, uint16_t y, int16_t len, uint16_t color)
|
|
||||||
{
|
|
||||||
dsp_x = x;
|
|
||||||
dsp_y = y;
|
|
||||||
dsp_len = len;
|
|
||||||
dsp_color = color;
|
|
||||||
XdspCall(FUNC_DISPLAY_DRAW_HLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawVLine(uint16_t x, uint16_t y, int16_t len, uint16_t color)
|
|
||||||
{
|
|
||||||
dsp_x = x;
|
|
||||||
dsp_y = y;
|
|
||||||
dsp_len = len;
|
|
||||||
dsp_color = color;
|
|
||||||
XdspCall(FUNC_DISPLAY_DRAW_VLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawLine(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2, uint16_t color)
|
|
||||||
{
|
|
||||||
dsp_x = x;
|
|
||||||
dsp_y = y;
|
|
||||||
dsp_x2 = x2;
|
|
||||||
dsp_y2 = y2;
|
|
||||||
dsp_color = color;
|
|
||||||
XdspCall(FUNC_DISPLAY_DRAW_LINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color)
|
|
||||||
{
|
|
||||||
dsp_x = x;
|
|
||||||
dsp_y = y;
|
|
||||||
dsp_rad = rad;
|
|
||||||
dsp_color = color;
|
|
||||||
XdspCall(FUNC_DISPLAY_DRAW_CIRCLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawFilledCircle(uint16_t x, uint16_t y, uint16_t rad, uint16_t color)
|
|
||||||
{
|
|
||||||
dsp_x = x;
|
|
||||||
dsp_y = y;
|
|
||||||
dsp_rad = rad;
|
|
||||||
dsp_color = color;
|
|
||||||
XdspCall(FUNC_DISPLAY_FILL_CIRCLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawRectangle(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2, uint16_t color)
|
|
||||||
{
|
|
||||||
dsp_x = x;
|
|
||||||
dsp_y = y;
|
|
||||||
dsp_x2 = x2;
|
|
||||||
dsp_y2 = y2;
|
|
||||||
dsp_color = color;
|
|
||||||
XdspCall(FUNC_DISPLAY_DRAW_RECTANGLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawFilledRectangle(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2, uint16_t color)
|
|
||||||
{
|
|
||||||
dsp_x = x;
|
|
||||||
dsp_y = y;
|
|
||||||
dsp_x2 = x2;
|
|
||||||
dsp_y2 = y2;
|
|
||||||
dsp_color = color;
|
|
||||||
XdspCall(FUNC_DISPLAY_FILL_RECTANGLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawFrame(void)
|
|
||||||
{
|
|
||||||
XdspCall(FUNC_DISPLAY_DRAW_FRAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplaySetSize(uint8_t size)
|
|
||||||
{
|
|
||||||
Settings.display_size = size &3;
|
|
||||||
XdspCall(FUNC_DISPLAY_TEXT_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplaySetFont(uint8_t font)
|
|
||||||
{
|
|
||||||
Settings.display_font = font &3;
|
|
||||||
XdspCall(FUNC_DISPLAY_FONT_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplaySetRotation(uint8_t rotation)
|
|
||||||
{
|
|
||||||
Settings.display_rotate = rotation &3;
|
|
||||||
XdspCall(FUNC_DISPLAY_ROTATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag)
|
void DisplayDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag)
|
||||||
{
|
{
|
||||||
dsp_x = x;
|
dsp_x = x;
|
||||||
@ -559,10 +470,10 @@ void DisplayText(void)
|
|||||||
cp += var;
|
cp += var;
|
||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
if (renderer) renderer->writeFastHLine(disp_xpos + temp, disp_ypos, -temp, fg_color);
|
if (renderer) renderer->writeFastHLine(disp_xpos + temp, disp_ypos, -temp, fg_color);
|
||||||
else DisplayDrawHLine(disp_xpos + temp, disp_ypos, -temp, fg_color);
|
//else DisplayDrawHLine(disp_xpos + temp, disp_ypos, -temp, fg_color);
|
||||||
} else {
|
} else {
|
||||||
if (renderer) renderer->writeFastHLine(disp_xpos, disp_ypos, temp, fg_color);
|
if (renderer) renderer->writeFastHLine(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
else DisplayDrawHLine(disp_xpos, disp_ypos, temp, fg_color);
|
//else DisplayDrawHLine(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
}
|
}
|
||||||
disp_xpos += temp;
|
disp_xpos += temp;
|
||||||
break;
|
break;
|
||||||
@ -572,10 +483,10 @@ void DisplayText(void)
|
|||||||
cp += var;
|
cp += var;
|
||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
if (renderer) renderer->writeFastVLine(disp_xpos, disp_ypos + temp, -temp, fg_color);
|
if (renderer) renderer->writeFastVLine(disp_xpos, disp_ypos + temp, -temp, fg_color);
|
||||||
else DisplayDrawVLine(disp_xpos, disp_ypos + temp, -temp, fg_color);
|
//else DisplayDrawVLine(disp_xpos, disp_ypos + temp, -temp, fg_color);
|
||||||
} else {
|
} else {
|
||||||
if (renderer) renderer->writeFastVLine(disp_xpos, disp_ypos, temp, fg_color);
|
if (renderer) renderer->writeFastVLine(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
else DisplayDrawVLine(disp_xpos, disp_ypos, temp, fg_color);
|
//else DisplayDrawVLine(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
}
|
}
|
||||||
disp_ypos += temp;
|
disp_ypos += temp;
|
||||||
break;
|
break;
|
||||||
@ -587,7 +498,7 @@ void DisplayText(void)
|
|||||||
var = atoiv(cp, &temp1);
|
var = atoiv(cp, &temp1);
|
||||||
cp += var;
|
cp += var;
|
||||||
if (renderer) renderer->writeLine(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
if (renderer) renderer->writeLine(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
||||||
else DisplayDrawLine(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
//else DisplayDrawLine(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
||||||
disp_xpos += temp;
|
disp_xpos += temp;
|
||||||
disp_ypos += temp1;
|
disp_ypos += temp1;
|
||||||
break;
|
break;
|
||||||
@ -596,14 +507,14 @@ void DisplayText(void)
|
|||||||
var = atoiv(cp, &temp);
|
var = atoiv(cp, &temp);
|
||||||
cp += var;
|
cp += var;
|
||||||
if (renderer) renderer->drawCircle(disp_xpos, disp_ypos, temp, fg_color);
|
if (renderer) renderer->drawCircle(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
else DisplayDrawCircle(disp_xpos, disp_ypos, temp, fg_color);
|
//else DisplayDrawCircle(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
break;
|
break;
|
||||||
case 'K':
|
case 'K':
|
||||||
// filled circle
|
// filled circle
|
||||||
var = atoiv(cp, &temp);
|
var = atoiv(cp, &temp);
|
||||||
cp += var;
|
cp += var;
|
||||||
if (renderer) renderer->fillCircle(disp_xpos, disp_ypos, temp, fg_color);
|
if (renderer) renderer->fillCircle(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
else DisplayDrawFilledCircle(disp_xpos, disp_ypos, temp, fg_color);
|
//else DisplayDrawFilledCircle(disp_xpos, disp_ypos, temp, fg_color);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
// rectangle
|
// rectangle
|
||||||
@ -613,7 +524,7 @@ void DisplayText(void)
|
|||||||
var = atoiv(cp, &temp1);
|
var = atoiv(cp, &temp1);
|
||||||
cp += var;
|
cp += var;
|
||||||
if (renderer) renderer->drawRect(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
if (renderer) renderer->drawRect(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
||||||
else DisplayDrawRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
//else DisplayDrawRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
// filled rectangle
|
// filled rectangle
|
||||||
@ -623,7 +534,7 @@ void DisplayText(void)
|
|||||||
var = atoiv(cp, &temp1);
|
var = atoiv(cp, &temp1);
|
||||||
cp += var;
|
cp += var;
|
||||||
if (renderer) renderer->fillRect(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
if (renderer) renderer->fillRect(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
||||||
else DisplayDrawFilledRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
//else DisplayDrawFilledRectangle(disp_xpos, disp_ypos, temp, temp1, fg_color);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
// rounded rectangle
|
// rounded rectangle
|
||||||
@ -696,9 +607,49 @@ void DisplayText(void)
|
|||||||
index_colors[temp] = ftemp;
|
index_colors[temp] = ftemp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef USE_DT_VARS
|
||||||
|
if (*cp == 'v') {
|
||||||
|
cp++;
|
||||||
|
{ int16_t num, gxp, gyp, textbcol, textfcol, font, textsize, txlen, dp;
|
||||||
|
var=atoiv(cp,&num);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&gxp);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&gyp);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&textbcol);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&textfcol);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&font);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&textsize);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&txlen);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
var=atoiv(cp,&dp);
|
||||||
|
cp+=var;
|
||||||
|
cp++;
|
||||||
|
// text itself
|
||||||
|
char bbuff[32];
|
||||||
|
cp = get_string(bbuff, sizeof(bbuff), cp);
|
||||||
|
char unit[4];
|
||||||
|
cp = get_string(unit, sizeof(unit), cp);
|
||||||
|
define_dt_var(num, gxp, gyp, textbcol, textfcol, font, textsize, txlen, dp, bbuff, unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // USE_DT_VARS
|
||||||
// force draw grafics buffer
|
// force draw grafics buffer
|
||||||
if (renderer) renderer->Updateframe();
|
if (renderer) renderer->Updateframe();
|
||||||
else DisplayDrawFrame();
|
//else DisplayDrawFrame();
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
// set auto draw mode
|
// set auto draw mode
|
||||||
@ -709,18 +660,18 @@ void DisplayText(void)
|
|||||||
case 's':
|
case 's':
|
||||||
// size sx
|
// size sx
|
||||||
if (renderer) renderer->setTextSize(*cp&7);
|
if (renderer) renderer->setTextSize(*cp&7);
|
||||||
else DisplaySetSize(*cp&3);
|
//else DisplaySetSize(*cp&3);
|
||||||
cp += 1;
|
cp += 1;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
// font sx
|
// font sx
|
||||||
{ uint8_t font = *cp&7;
|
{ uint8_t font = *cp&7;
|
||||||
if (renderer) renderer->setTextFont(font);
|
if (renderer) renderer->setTextFont(font);
|
||||||
else DisplaySetFont(font);
|
//else DisplaySetFont(font);
|
||||||
if (font) {
|
if (font) {
|
||||||
// for backward compatibility set size to 1 on non GFX fonts
|
// for backward compatibility set size to 1 on non GFX fonts
|
||||||
if (renderer) renderer->setTextSize(1);
|
if (renderer) renderer->setTextSize(1);
|
||||||
else DisplaySetSize(1);
|
//else DisplaySetSize(1);
|
||||||
}
|
}
|
||||||
cp += 1;
|
cp += 1;
|
||||||
}
|
}
|
||||||
@ -728,7 +679,7 @@ void DisplayText(void)
|
|||||||
case 'a':
|
case 'a':
|
||||||
// rotation angle
|
// rotation angle
|
||||||
if (renderer) renderer->setRotation(*cp&3);
|
if (renderer) renderer->setRotation(*cp&3);
|
||||||
else DisplaySetRotation(*cp&3);
|
//else DisplaySetRotation(*cp&3);
|
||||||
cp+=1;
|
cp+=1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -976,7 +927,7 @@ void DisplayText(void)
|
|||||||
// draw buffer
|
// draw buffer
|
||||||
if (auto_draw&1) {
|
if (auto_draw&1) {
|
||||||
if (renderer) renderer->Updateframe();
|
if (renderer) renderer->Updateframe();
|
||||||
else DisplayDrawFrame();
|
//else DisplayDrawFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,6 +970,167 @@ void Display_Text_From_File(const char *file) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_DT_VARS
|
||||||
|
|
||||||
|
#ifndef MAX_DT_VARS
|
||||||
|
#define MAX_DT_VARS 8
|
||||||
|
#endif // MAX_DT_VARS
|
||||||
|
|
||||||
|
#define MAX_DVTSIZE 24
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t xp;
|
||||||
|
uint16_t yp;
|
||||||
|
uint8_t txtbcol;
|
||||||
|
uint8_t txtfcol;
|
||||||
|
int8_t txtsiz;
|
||||||
|
int8_t txtlen;
|
||||||
|
int8_t dp;
|
||||||
|
int8_t font;
|
||||||
|
char unit[6];
|
||||||
|
char *jstrbuf;
|
||||||
|
char rstr[32];
|
||||||
|
} DT_VARS;
|
||||||
|
|
||||||
|
DT_VARS *dt_vars[MAX_DT_VARS];
|
||||||
|
|
||||||
|
void define_dt_var(uint32_t num, uint32_t xp, uint32_t yp, uint32_t txtbcol, uint32_t txtfcol, int32_t font, int32_t txtsiz, int32_t txtlen, int32_t dp, char *jstr, char *unit) {
|
||||||
|
if (num >= MAX_DT_VARS) return;
|
||||||
|
|
||||||
|
if (dt_vars[num]) {
|
||||||
|
if (dt_vars[num]->jstrbuf) free(dt_vars[num]->jstrbuf);
|
||||||
|
free(dt_vars[num]);
|
||||||
|
}
|
||||||
|
//dt [dv0:100:100:0:3:2:1:10:2:WLAN#ID:uV:]
|
||||||
|
|
||||||
|
DT_VARS *dtp = (DT_VARS*)malloc(sizeof(DT_VARS));
|
||||||
|
if (!dtp) return;
|
||||||
|
|
||||||
|
dt_vars[num] = dtp;
|
||||||
|
|
||||||
|
dtp->xp = xp;
|
||||||
|
dtp->yp = yp;
|
||||||
|
dtp->txtbcol = txtbcol;
|
||||||
|
dtp->txtfcol = txtfcol;
|
||||||
|
dtp->font = font;
|
||||||
|
dtp->txtsiz = txtsiz;
|
||||||
|
if (txtlen > MAX_DVTSIZE) {txtlen = MAX_DVTSIZE;}
|
||||||
|
dtp->txtlen = txtlen;
|
||||||
|
dtp->dp = dp;
|
||||||
|
dtp->jstrbuf = (char*)malloc(strlen(jstr + 1));
|
||||||
|
if (!dtp->jstrbuf) {
|
||||||
|
free (dtp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strcpy(dtp->jstrbuf, jstr);
|
||||||
|
strcpy(dtp->unit,unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_dt_vars(void) {
|
||||||
|
if (!renderer) return;
|
||||||
|
|
||||||
|
for (uint32_t cnt = 0; cnt < MAX_DT_VARS; cnt++) {
|
||||||
|
if (dt_vars[cnt]) {
|
||||||
|
if (dt_vars[cnt]->jstrbuf) {
|
||||||
|
// draw
|
||||||
|
char vstr[MAX_DVTSIZE + 7];
|
||||||
|
memset(vstr, ' ', sizeof(vstr));
|
||||||
|
strcpy(vstr, dt_vars[cnt]->rstr);
|
||||||
|
strcat(vstr, " ");
|
||||||
|
strcat(vstr, dt_vars[cnt]->unit);
|
||||||
|
uint16_t slen = strlen(vstr);
|
||||||
|
vstr[slen] = ' ';
|
||||||
|
|
||||||
|
if (!dt_vars[cnt]->txtlen) {
|
||||||
|
vstr[slen] = 0;
|
||||||
|
} else {
|
||||||
|
vstr[abs(int(dt_vars[cnt]->txtlen))] = 0;
|
||||||
|
}
|
||||||
|
if (dt_vars[cnt]->txtlen < 0) {
|
||||||
|
// right align
|
||||||
|
alignright(vstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dt_vars[cnt]->txtsiz > 0) {
|
||||||
|
renderer->setDrawMode(0);
|
||||||
|
} else {
|
||||||
|
renderer->setDrawMode(2);
|
||||||
|
}
|
||||||
|
renderer->setTextColor(GetColorFromIndex(dt_vars[cnt]->txtfcol),GetColorFromIndex(dt_vars[cnt]->txtbcol));
|
||||||
|
renderer->setTextFont(dt_vars[cnt]->font);
|
||||||
|
renderer->setTextSize(abs(dt_vars[cnt]->txtsiz));
|
||||||
|
renderer->DrawStringAt(dt_vars[cnt]->xp, dt_vars[cnt]->yp, vstr, GetColorFromIndex(dt_vars[cnt]->txtfcol), 0);
|
||||||
|
|
||||||
|
// reset display vars
|
||||||
|
renderer->setTextColor(fg_color, bg_color);
|
||||||
|
renderer->setDrawMode(auto_draw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DTV_JSON_SIZE 1024
|
||||||
|
|
||||||
|
void DTVarsTeleperiod(void) {
|
||||||
|
char *json = (char*)malloc(DTV_JSON_SIZE);
|
||||||
|
if (json) {
|
||||||
|
strlcpy(json, TasmotaGlobal.mqtt_data, DTV_JSON_SIZE);
|
||||||
|
get_dt_vars(json);
|
||||||
|
free(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_dt_mqtt(void) {
|
||||||
|
ResponseClear();
|
||||||
|
uint16_t script_tele_period_save = TasmotaGlobal.tele_period;
|
||||||
|
TasmotaGlobal.tele_period = 2;
|
||||||
|
XsnsNextCall(FUNC_JSON_APPEND, script_xsns_index);
|
||||||
|
TasmotaGlobal.tele_period = script_tele_period_save;
|
||||||
|
if (strlen(TasmotaGlobal.mqtt_data)) {
|
||||||
|
TasmotaGlobal.mqtt_data[0] = '{';
|
||||||
|
snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("%s}"), TasmotaGlobal.mqtt_data);
|
||||||
|
}
|
||||||
|
get_dt_vars(TasmotaGlobal.mqtt_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_dt_vars(char *json) {
|
||||||
|
if (strlen(json)) {
|
||||||
|
JsonParser parser(json);
|
||||||
|
JsonParserObject obj = parser.getRootObject();
|
||||||
|
|
||||||
|
for (uint32_t cnt = 0; cnt < MAX_DT_VARS; cnt++) {
|
||||||
|
if (dt_vars[cnt]) {
|
||||||
|
if (dt_vars[cnt]->jstrbuf) {
|
||||||
|
char sbuf[32];
|
||||||
|
uint32_t res = JsonParsePath(&obj, dt_vars[cnt]->jstrbuf, '#', NULL, sbuf, sizeof(sbuf));
|
||||||
|
if (res) {
|
||||||
|
if (dt_vars[cnt]->dp < 0) {
|
||||||
|
// use string
|
||||||
|
strcpy(dt_vars[cnt]->rstr, sbuf);
|
||||||
|
} else {
|
||||||
|
// convert back and forth
|
||||||
|
dtostrfd(CharToFloat(sbuf), dt_vars[cnt]->dp, dt_vars[cnt]->rstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_dt_vars(void) {
|
||||||
|
for (uint32_t cnt = 0; cnt < MAX_DT_VARS; cnt++) {
|
||||||
|
if (dt_vars[cnt]) {
|
||||||
|
if (dt_vars[cnt]->jstrbuf) free(dt_vars[cnt]->jstrbuf);
|
||||||
|
free(dt_vars[cnt]);
|
||||||
|
dt_vars[cnt] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_DT_VARS
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
#ifdef USE_DISPLAY_MODES1TO5
|
#ifdef USE_DISPLAY_MODES1TO5
|
||||||
@ -1423,6 +1535,10 @@ void DisplayInitDriver(void)
|
|||||||
Display_Text_From_File("/display.ini");
|
Display_Text_From_File("/display.ini");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_DT_VARS
|
||||||
|
free_dt_vars();
|
||||||
|
#endif
|
||||||
|
|
||||||
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings.display_model);
|
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings.display_model);
|
||||||
|
|
||||||
if (Settings.display_model) {
|
if (Settings.display_model) {
|
||||||
@ -1688,7 +1804,7 @@ void CmndDisplaySize(void)
|
|||||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) {
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) {
|
||||||
Settings.display_size = XdrvMailbox.payload;
|
Settings.display_size = XdrvMailbox.payload;
|
||||||
if (renderer) renderer->setTextSize(Settings.display_size);
|
if (renderer) renderer->setTextSize(Settings.display_size);
|
||||||
else DisplaySetSize(Settings.display_size);
|
//else DisplaySetSize(Settings.display_size);
|
||||||
}
|
}
|
||||||
ResponseCmndNumber(Settings.display_size);
|
ResponseCmndNumber(Settings.display_size);
|
||||||
}
|
}
|
||||||
@ -1698,7 +1814,7 @@ void CmndDisplayFont(void)
|
|||||||
if ((XdrvMailbox.payload >=0) && (XdrvMailbox.payload <= 4)) {
|
if ((XdrvMailbox.payload >=0) && (XdrvMailbox.payload <= 4)) {
|
||||||
Settings.display_font = XdrvMailbox.payload;
|
Settings.display_font = XdrvMailbox.payload;
|
||||||
if (renderer) renderer->setTextFont(Settings.display_font);
|
if (renderer) renderer->setTextFont(Settings.display_font);
|
||||||
else DisplaySetFont(Settings.display_font);
|
//else DisplaySetFont(Settings.display_font);
|
||||||
}
|
}
|
||||||
ResponseCmndNumber(Settings.display_font);
|
ResponseCmndNumber(Settings.display_font);
|
||||||
}
|
}
|
||||||
@ -2547,9 +2663,7 @@ bool Xdrv13(uint8_t function)
|
|||||||
case FUNC_PRE_INIT:
|
case FUNC_PRE_INIT:
|
||||||
DisplayInitDriver();
|
DisplayInitDriver();
|
||||||
#ifdef USE_GRAPH
|
#ifdef USE_GRAPH
|
||||||
for (uint8_t count=0;count<NUM_GRAPHS;count++) {
|
for (uint8_t count = 0; count < NUM_GRAPHS; count++) { graph[count] = 0; }
|
||||||
graph[count]=0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case FUNC_EVERY_50_MSECOND:
|
case FUNC_EVERY_50_MSECOND:
|
||||||
@ -2562,11 +2676,16 @@ bool Xdrv13(uint8_t function)
|
|||||||
#ifdef USE_GRAPH
|
#ifdef USE_GRAPH
|
||||||
DisplayCheckGraph();
|
DisplayCheckGraph();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_DT_VARS
|
||||||
|
get_dt_mqtt();
|
||||||
|
draw_dt_vars();
|
||||||
|
#endif // USE_DT_VARS
|
||||||
|
|
||||||
#ifdef USE_DISPLAY_MODES1TO5
|
#ifdef USE_DISPLAY_MODES1TO5
|
||||||
if (Settings.display_model && Settings.display_mode) { XdspCall(FUNC_DISPLAY_EVERY_SECOND); }
|
if (Settings.display_model && Settings.display_mode) { XdspCall(FUNC_DISPLAY_EVERY_SECOND); }
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef USE_DISPLAY_MODES1TO5
|
#ifdef USE_DISPLAY_MODES1TO5
|
||||||
case FUNC_MQTT_SUBSCRIBE:
|
case FUNC_MQTT_SUBSCRIBE:
|
||||||
DisplayMqttSubscribe();
|
DisplayMqttSubscribe();
|
||||||
|
@ -83,7 +83,11 @@ uint8_t ufs_dir;
|
|||||||
// 0 = None, 1 = SD, 2 = ffat, 3 = littlefs
|
// 0 = None, 1 = SD, 2 = ffat, 3 = littlefs
|
||||||
uint8_t ufs_type;
|
uint8_t ufs_type;
|
||||||
uint8_t ffs_type;
|
uint8_t ffs_type;
|
||||||
bool download_busy;
|
|
||||||
|
struct {
|
||||||
|
bool download_busy;
|
||||||
|
bool autoexec = false;
|
||||||
|
} UfsData;
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
@ -332,15 +336,67 @@ bool TfsDeleteFile(const char *fname) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TfsRenameFile(const char *fname1, const char *fname2) {
|
||||||
|
if (!ffs_type) { return false; }
|
||||||
|
|
||||||
|
if (!ffsp->rename(fname1, fname2)) {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("TFS: Rename failed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Autoexec support
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
void UfsAutoexec(void) {
|
||||||
|
if (!ffs_type) { return; }
|
||||||
|
File file = ffsp->open(TASM_FILE_AUTOEXEC, "r");
|
||||||
|
if (!file) { return; }
|
||||||
|
|
||||||
|
char cmd_line[512];
|
||||||
|
while (file.available()) {
|
||||||
|
uint16_t index = 0;
|
||||||
|
while (file.available()) {
|
||||||
|
uint8_t buf[1];
|
||||||
|
file.read(buf, 1);
|
||||||
|
if ((buf[0] == '\n') || (buf[0] == '\r')) {
|
||||||
|
// Line terminated with linefeed or carriage return
|
||||||
|
if (index < sizeof(cmd_line) - 1) {
|
||||||
|
// Process line
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// Discard too long line and start with next line
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((0 == index) && isspace(buf[0])) {
|
||||||
|
// Skip leading spaces (' ','\t','\n','\v','\f','\r')
|
||||||
|
}
|
||||||
|
else if (index < sizeof(cmd_line) - 2) {
|
||||||
|
cmd_line[index++] = buf[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((index > 0) && (cmd_line[0] != ';')) { // Information but no comment
|
||||||
|
cmd_line[index] = 0;
|
||||||
|
ExecuteCommand(cmd_line, SRC_AUTOEXEC);
|
||||||
|
}
|
||||||
|
delay(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Commands
|
* Commands
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix
|
const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix
|
||||||
"|Type|Size|Free|Delete";
|
"|Type|Size|Free|Delete|Rename";
|
||||||
|
|
||||||
void (* const kUFSCommand[])(void) PROGMEM = {
|
void (* const kUFSCommand[])(void) PROGMEM = {
|
||||||
&UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete};
|
&UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete, &UFSRename};
|
||||||
|
|
||||||
void UFSInfo(void) {
|
void UFSInfo(void) {
|
||||||
Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}"), ufs_type, UfsInfo(0, 0), UfsInfo(1, 0));
|
Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}"), ufs_type, UfsInfo(0, 0), UfsInfo(1, 0));
|
||||||
@ -392,11 +448,32 @@ void UFSDelete(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UFSRename(void) {
|
||||||
|
// UfsRename sdcard or flashfs file if only one of them available
|
||||||
|
// UfsRename2 flashfs file if available
|
||||||
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
bool result = false;
|
||||||
|
const char *fname1 = strtok(XdrvMailbox.data, ",");
|
||||||
|
const char *fname2 = strtok(nullptr, ",");
|
||||||
|
if (fname1 && fname2) {
|
||||||
|
if (ffs_type && (ffs_type != ufs_type) && (2 == XdrvMailbox.index)) {
|
||||||
|
result = TfsRenameFile(fname1, fname2);
|
||||||
|
} else {
|
||||||
|
result = (ufs_type && ufsp->rename(fname1, fname2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!result) {
|
||||||
|
ResponseCmndChar(PSTR(D_JSON_FAILED));
|
||||||
|
} else {
|
||||||
|
ResponseCmndDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Web support
|
* Web support
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
|
|
||||||
const char UFS_WEB_DIR[] PROGMEM =
|
const char UFS_WEB_DIR[] PROGMEM =
|
||||||
@ -654,12 +731,12 @@ uint8_t UfsDownloadFile(char *file) {
|
|||||||
#ifdef ESP32_DOWNLOAD_TASK
|
#ifdef ESP32_DOWNLOAD_TASK
|
||||||
download_file.close();
|
download_file.close();
|
||||||
|
|
||||||
if (download_busy == true) {
|
if (UfsData.download_busy == true) {
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("UFS: Download is busy"));
|
AddLog(LOG_LEVEL_INFO, PSTR("UFS: Download is busy"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
download_busy = true;
|
UfsData.download_busy = true;
|
||||||
char *path = (char*)malloc(128);
|
char *path = (char*)malloc(128);
|
||||||
strcpy(path,file);
|
strcpy(path,file);
|
||||||
xTaskCreatePinnedToCore(donload_task, "DT", 6000, (void*)path, 3, NULL, 1);
|
xTaskCreatePinnedToCore(donload_task, "DT", 6000, (void*)path, 3, NULL, 1);
|
||||||
@ -710,7 +787,7 @@ void donload_task(void *path) {
|
|||||||
}
|
}
|
||||||
download_file.close();
|
download_file.close();
|
||||||
download_Client.stop();
|
download_Client.stop();
|
||||||
download_busy = false;
|
UfsData.download_busy = false;
|
||||||
vTaskDelete( NULL );
|
vTaskDelete( NULL );
|
||||||
}
|
}
|
||||||
#endif // ESP32_DOWNLOAD_TASK
|
#endif // ESP32_DOWNLOAD_TASK
|
||||||
@ -752,6 +829,17 @@ bool Xdrv50(uint8_t function) {
|
|||||||
UfsCheckSDCardInit();
|
UfsCheckSDCardInit();
|
||||||
break;
|
break;
|
||||||
#endif // USE_SDCARD
|
#endif // USE_SDCARD
|
||||||
|
case FUNC_EVERY_SECOND:
|
||||||
|
if (UfsData.autoexec) {
|
||||||
|
// Safe to execute autoexec commands here
|
||||||
|
UfsData.autoexec = false;
|
||||||
|
if (!TasmotaGlobal.no_autoexec) { UfsAutoexec(); }
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FUNC_MQTT_INIT:
|
||||||
|
// Do not execute autoexec commands here
|
||||||
|
UfsData.autoexec = true;
|
||||||
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = DecodeCommand(kUFSCommands, kUFSCommand);
|
result = DecodeCommand(kUFSCommands, kUFSCommand);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user