diff --git a/CHANGELOG.md b/CHANGELOG.md index a02a1323b..76a9f1b05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,15 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [10.0.0.4] +## [10.1.0.1] + +## [Released] + +## [10.1.0] 20211208 +- Release Noelle + + +## [10.0.0.4] 20211208 ### Added - (Internal) Support for FUNC_BUTTON_MULTI_PRESSED in (light)drivers - Support for GPE Multi color smart light as sold by Action in the Netherlands @@ -18,6 +26,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Tuya dimmer range issue (#13849) - BLE Memory leak with update NimBLE v.1.3.1 to v.1.3.3 +- Compile error BLE EQ3 driver with core 2.0.x (#13948) ## [10.0.0.3] 20211130 ### Added @@ -77,8 +86,6 @@ All notable changes to this project will be documented in this file. - Discovery of shutters (#13572) - ESP32-C3 OneWire as used by DS18x20 (#13583) -## [Released] - ## [10.0.0] 20211019 - Release Norman diff --git a/FIRMWARE.md b/FIRMWARE.md index e2eb172b7..610cc6fba 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -18,7 +18,7 @@ See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/C ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v10.0.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v10.1.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://ota.tasmota.com/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) diff --git a/README.md b/README.md index 111536ba8..b41539308 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Easy initial installation of Tasmota can be performed using the [Tasmota WebInst ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v10.0.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v10.1.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://ota.tasmota.com/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 486b5da33..e7b2dcdb3 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -66,12 +66,12 @@ Latest released binaries can be downloaded from - http://ota.tasmota.com/tasmota/release Historical binaries can be downloaded from -- http://ota.tasmota.com/tasmota/release-10.0.0 +- http://ota.tasmota.com/tasmota/release-10.1.0 The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` ### ESP32 based -The following binary downloads have been compiled with ESP32/Arduino library core version **1.0.7.4**. +The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.1.1**. - **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY** - **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 and 4M+ flash. @@ -90,7 +90,7 @@ Latest released binaries can be downloaded from - http://ota.tasmota.com/tasmota32/release Historical binaries can be downloaded from -- http://ota.tasmota.com/tasmota32/release-10.0.0 +- http://ota.tasmota.com/tasmota32/release-10.1.0 The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota32/release/tasmota32.bin`` @@ -100,49 +100,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v10.0.0.4 +## Changelog v10.1.0.1 ### Added -- One second heartbeat GPIO -- (Internal) Support for FUNC_BUTTON_MULTI_PRESSED in (light)drivers -- Command ``TcpConfig`` for TCPBridge protocol configuration [#13565](https://github.com/arendst/Tasmota/issues/13565) -- Support for HDC2010 temperature/humidity sensor by Luc Boudreau [#13633](https://github.com/arendst/Tasmota/issues/13633) -- WS2812 scheme 13 stairs effect [#13595](https://github.com/arendst/Tasmota/issues/13595) -- Command ``IfxPeriod `` to overrule ``Teleperiod`` for Influx messages [#13750](https://github.com/arendst/Tasmota/issues/13750) -- Support for GPE Multi color smart light as sold by Action in the Netherlands -- Shutter support for venetian blinds with tilt control -- Support for 74xx595 8-bit shift registers [#13921](https://github.com/arendst/Tasmota/issues/13921) -- ESP32 Proof of Concept Sonoff SPM with limited functionality (switching and energy monitoring) [#13447](https://github.com/arendst/Tasmota/issues/13447) -- ESP32 Autoconfiguration -- ESP32 Preliminary support for Tasmota Apps (.tapp extesions) -- ESP32 OTA over HTTPS -- ESP32 HTTPS support to ``WebQuery`` -- ESP32 Berry support for neopixel (WS2812, SK6812) -- ESP32 Berry ``import re`` regex module -- ESP32 Berry add module ``python_compat`` to be closer to Python syntax [#13428](https://github.com/arendst/Tasmota/issues/13428) ### Breaking Changed -- ESP32-S2 TSettings memory usage fixed to 4096 bytes regression from v9.5.0.8 ### Changed -- ESP32 core library from v1.0.7.4 to v2.0.1.1 -- ESP32-C3 core library from v2.0.0-post to ESP32 core library -- IRremoteESP8266 library from v2.7.20 to v2.8.0 -- (Internal) Range conversion edge values -- ESP8266 Gratuitous ARP enabled and set to 60 seconds [#13623](https://github.com/arendst/Tasmota/issues/13623) -- File editor no-wrap [#13427](https://github.com/arendst/Tasmota/issues/13427) -- ESP8266 Gratuitous ARP enabled and set to 60 seconds [#13623](https://github.com/arendst/Tasmota/issues/13623) -- Ethernet hostname ending in ``_eth`` to ``-eth`` according to RFC952 ### Fixed -- Initial reset RTC memory based variables like EnergyToday and EnergyTotal -- ESP32 Telegram compile error [#13435](https://github.com/arendst/Tasmota/issues/13435) -- SML compile error [#13441](https://github.com/arendst/Tasmota/issues/13441) -- GUI checkbox MQTT TLS not saved regression from v9.2.0.3 [#13442](https://github.com/arendst/Tasmota/issues/13442) -- Discovery of shutters [#13572](https://github.com/arendst/Tasmota/issues/13572) -- ESP32-C3 OneWire as used by DS18x20 [#13583](https://github.com/arendst/Tasmota/issues/13583) -- ESP32 analog NTC temperature calculation [#13703](https://github.com/arendst/Tasmota/issues/13703) -- Tuya dimmer range issue [#13849](https://github.com/arendst/Tasmota/issues/13849) ### Removed -- ILI9488 driver in favour of Universal Display driver [#13719](https://github.com/arendst/Tasmota/issues/13719) - diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index 6f48d5796..8414795e0 100755 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -76,6 +76,9 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { uint8_t section = 0; dsp_ncmds = 0; lut_num = 0; + lvgl_param.data = 0; + lvgl_param.fluslines = 40; + for (uint32_t cnt = 0; cnt < 5; cnt++) { lut_cnt[cnt] = 0; lut_cmd[cnt] = 0xff; diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index be18bd75e..d03c4e088 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 = 0x0A000004; +const uint32_t VERSION = 0x0A010001; #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index d5a2c5bdb..f744d850b 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -116,6 +116,9 @@ uint32_t DecodeLightId(uint32_t hue_id); #define UNISHOXRSIZE 2560 #endif +#ifndef MAX_EXT_ARRAYS +#define MAX_EXT_ARRAYS 5 +#endif #ifndef STASK_PRIO #define STASK_PRIO 1 @@ -1163,6 +1166,22 @@ float *Get_MFAddr(uint8_t index, uint16_t *len, uint16_t *ipos) { char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, struct GVARS *gv); +char *get_array_by_name(char *lp, float **fp, uint16_t *alen) { + struct T_INDEX ind; + uint8_t vtype; + lp = isvar(lp, &vtype, &ind, 0, 0, 0); + if (vtype==VAR_NV) return 0; + if (vtype&STYPE) return 0; + uint16_t index = glob_script_mem.type[ind.index].index; + + if (glob_script_mem.type[ind.index].bits.is_filter) { + float *fa = Get_MFAddr(index, alen, 0); + *fp = fa; + return lp; + } + *fp = 0; + return lp; +} float *get_array_by_name(char *name, uint16_t *alen) { struct T_INDEX ind; @@ -1281,6 +1300,133 @@ float DoMedian5(uint8_t index, float in) { return median_array(mf->buffer, MEDIAN_SIZE); } + +#ifdef USE_FEXTRACT +// convert tasmota time stamp to ul seconds +uint32_t tstamp2l(char *ts) { +uint16_t year; +uint8_t month; +uint8_t day; +uint8_t hour; +uint8_t mins; +uint8_t secs; + + if (strchr(ts, 'T')) { + // 2020-12-16T15:36:41 + year = strtol(ts, &ts, 10); + if (year < 2020 || year > 2040) { + year = 2020; + } + year -= 2000; + ts++; + month = strtol(ts, &ts, 10); + ts++; + day = strtol(ts, &ts, 10); + ts++; + hour = strtol(ts, &ts, 10); + ts++; + mins = strtol(ts, &ts, 10); + ts++; + secs = strtol(ts, &ts, 10); + } else { + // german excel fromat 16.12.20 15:36 + day = strtol(ts, &ts, 10); + ts++; + month = strtol(ts, &ts, 10); + ts++; + year = strtol(ts, &ts, 10); + ts++; + hour = strtol(ts, &ts, 10); + ts++; + mins = strtol(ts, &ts, 10); + secs = 0; + } + return (year*365*86400)+(month*31*86400)+(day*86400)+(hour*3600)+(mins*60)+secs; +} + +// assume 1. entry is timestamp, others are tab delimited values until LF +// file refernece, from timestamp, to timestampm, column offset, array pointers, array lenght, number of arrays +int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, uint8_t coffs, float **a_ptr, uint16_t *a_len, uint8_t numa, int16_t accum) { + if (!glob_script_mem.file_flags[fref].is_open) return -1; + char rstr[32]; + uint8_t sindex = 0; + uint8_t colpos = 0; + uint8_t range = 0; + uint32_t tsfrom = tstamp2l(ts_from); + uint32_t tsto = tstamp2l(ts_to); + uint16_t lines = 0; + uint16_t rlines = 0; + float summs[numa]; + uint16_t accnt[numa]; + for (uint8_t cnt = 0; cnt < numa; cnt++) { + summs[cnt] = 0; + accnt[cnt] = 0; + } + uint8_t dflg = 1; + if (accum < 0) { + dflg = 0; + accum = -accum; + } + if (accum == 0) accum = 1; + while (glob_script_mem.files[fref].available()) { + // scan through file + uint8_t buff[2], iob; + glob_script_mem.files[fref].read(buff, 1); + iob = buff[0]; + if (iob == '\t' || iob == ',' || iob == '\n') { + rstr[sindex] = 0; + sindex = 0; + if (colpos == 0) { + // timestamp 2020-12-16T15:36:41 + // decompose timestamps + uint32_t cts = tstamp2l(rstr); + if (cts > tsto) break; + if (cts >= tsfrom && cts <= tsto) { + // we want this range + range = 1; + rlines++; + } else { + range = 0; + } + } else { + // data columns + if (range) { + uint8_t curpos = colpos - coffs; + if (colpos >= coffs && curpos < numa) { + if (a_len[curpos]) { + float fval = CharToFloat(rstr); + //AddLog(LOG_LEVEL_INFO, PSTR("cpos %d colp %d numa %d - %s %d"),curpos, colpos, a_len[curpos], rstr, (uint32_t)fval); + summs[curpos] += fval; + accnt[curpos] += 1; + if (accnt[curpos] == accum) { + if (dflg) { + *a_ptr[curpos]++ = summs[curpos] / accum; + } else { + *a_ptr[curpos]++ = summs[curpos]; + } + summs[curpos] = 0; + accnt[curpos] = 0; + a_len[curpos]--; + } + } else { + break; + } + } + } + } + colpos++; + if (iob == '\n') { + colpos = 0; + lines ++; + } + } + rstr[sindex] = iob; + sindex++; + } + return rlines; +} +#endif // USE_FEXTRACT + #ifdef USE_LIGHT uint32_t HSVToRGB(uint16_t hue, uint8_t saturation, uint8_t value) { float r = 0, g = 0, b = 0; @@ -1782,26 +1928,20 @@ chknext: if (!strncmp(vname, "acos(", 5)) { lp=GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv); fvar = acosf(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif if (!strncmp(vname, "abs(", 4)) { lp=GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); fvar = fabs(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "asc(", 4)) { char str[SCRIPT_MAXSSIZE]; lp = GetStringArgument(lp + 4, OPER_EQU, str, gv); fvar = str[0]; - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "adc(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); @@ -1831,6 +1971,26 @@ chknext: len = 0; goto exit; } + if (!strncmp(vname, "acp(", 4)) { + lp += 4; + SCRIPT_SKIP_SPACES + uint16_t alend; + fvar = -1; + float *fpd; + lp = get_array_by_name(lp, &fpd, &alend); + SCRIPT_SKIP_SPACES + uint16_t alens; + float *fps; + lp = get_array_by_name(lp, &fps, &alens); + SCRIPT_SKIP_SPACES + if (alend != alens) { + fvar = -1; + } else { + memcpy(fpd, fps, alend * sizeof(float)); + fvar = 0; + } + goto nfuncexit; + } break; case 'b': @@ -1887,9 +2047,7 @@ chknext: float fvar1; lp = GetNumericArgument(lp, OPER_EQU, &fvar1, gv); fvar = Core2SetAxpPin(fvar, fvar1); - lp++; - len=0; - goto exit; + goto nfuncexit; } #endif // USE_M5STACK_CORE2 @@ -1906,10 +2064,8 @@ chknext: if (*lp!=')') { lp = GetNumericArgument(lp, OPER_EQU, &prio, gv); } - lp++; fvar = scripter_create_task(fvar, fvar1, fvar2, prio); - len = 0; - goto exit; + goto nfuncexit; } #endif //USE_SCRIPT_TASK #endif //ESP32 @@ -1917,9 +2073,7 @@ chknext: if (!strncmp(vname, "cos(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); fvar = cosf(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif break; @@ -1997,9 +2151,7 @@ chknext: fvar = 99999; break; } - len = 0; - lp++; - goto exit; + goto nfuncexit; } #endif //USE_ENERGY_SENSOR break; @@ -2065,9 +2217,7 @@ chknext: break; } } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "fc(", 3)) { lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv); @@ -2081,9 +2231,7 @@ chknext: glob_script_mem.file_flags[ind].is_open = 0; } fvar = 0; - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "ff(", 3)) { lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv); @@ -2091,9 +2239,7 @@ chknext: if (ind>=SFS_MAX) ind = SFS_MAX - 1; glob_script_mem.files[ind].flush(); fvar = 0; - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "fw(", 3)) { char str[SCRIPT_MAXSSIZE]; @@ -2107,10 +2253,24 @@ chknext: } else { fvar = 0; } - lp++; - len = 0; - goto exit; + goto nfuncexit; } + if (!strncmp(vname, "fwb(", 4)) { + lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); + uint8_t buf[2]; + buf[0] = fvar; + SCRIPT_SKIP_SPACES + lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); + uint8_t ind = fvar; + if (ind>=SFS_MAX) ind = SFS_MAX - 1; + if (glob_script_mem.file_flags[ind].is_open) { + fvar = glob_script_mem.files[ind].write(buf, 1); + } else { + fvar = 0; + } + goto nfuncexit; + } + if (!strncmp(vname, "fr(", 3)) { struct T_INDEX ind; uint8_t vtype; @@ -2184,14 +2344,75 @@ chknext: len = 0; goto exit; } + if (!strncmp(vname, "frb(", 4)) { + lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); + uint8_t ind = fvar; + if (ind>=SFS_MAX) ind = SFS_MAX - 1; + if (glob_script_mem.file_flags[ind].is_open) { + uint8_t buf[2]; + buf[0] = 0; + glob_script_mem.files[ind].read(buf, 1); + fvar = buf[0]; + } else { + fvar = 0; + } + goto nfuncexit; + } + if (!strncmp(vname, "fa(", 3)) { + lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv); + uint8_t ind = fvar; + if (ind>=SFS_MAX) ind = SFS_MAX - 1; + if (glob_script_mem.file_flags[ind].is_open) { + fvar = glob_script_mem.files[ind].available(); + } else { + fvar = -1; + } + goto nfuncexit; + } + if (!strncmp(vname, "fs(", 3)) { + lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv); + uint8_t ind = fvar; + SCRIPT_SKIP_SPACES + lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); + SCRIPT_SKIP_SPACES + if (ind>=SFS_MAX) ind = SFS_MAX - 1; + if (glob_script_mem.file_flags[ind].is_open) { + fvar = glob_script_mem.files[ind].seek(fvar, fs::SeekMode::SeekCur); + } else { + fvar = -1; + } + goto nfuncexit; + } + if (!strncmp(vname, "fz(", 3)) { + lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv); + SCRIPT_SKIP_SPACES + uint8_t ind = fvar; + if (ind>=SFS_MAX) ind = SFS_MAX - 1; + if (glob_script_mem.file_flags[ind].is_open) { + fvar = glob_script_mem.files[ind].size(); + } else { + fvar = -1; + } + goto nfuncexit; + } if (!strncmp(vname, "fd(", 3)) { char str[glob_script_mem.max_ssize + 1]; lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); ufsp->remove(str); - lp++; - len = 0; - goto exit; + goto nfuncexit; } +#ifdef USE_UFILESYS + if (!strncmp(vname, "frw(", 4)) { + // read file from web + lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); + SCRIPT_SKIP_SPACES + char url[SCRIPT_MAXSSIZE]; + lp = ForceStringVar(lp, url); + SCRIPT_SKIP_SPACES + fvar = url2file(fvar, url); + goto nfuncexit; + } +#endif #if defined(ESP32) && defined(USE_WEBCAM) if (!strncmp(vname, "fwp(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); @@ -2215,9 +2436,7 @@ chknext: } else { fvar = 0; } - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //ESP32 && USE_WEBCAM #ifdef USE_SCRIPT_FATFS_EXT @@ -2240,17 +2459,13 @@ chknext: } ef.close(); } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "fmd(", 4)) { char str[glob_script_mem.max_ssize + 1]; lp = GetStringArgument(lp + 4, OPER_EQU, str, 0); fvar = ufsp->mkdir(str); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "fmt(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); @@ -2259,64 +2474,99 @@ chknext: } else { //SD.format(); } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "frd(", 4)) { char str[glob_script_mem.max_ssize + 1]; lp = GetStringArgument(lp + 4, OPER_EQU, str, 0); fvar = ufsp->rmdir(str); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "fx(", 3)) { char str[glob_script_mem.max_ssize + 1]; lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); if (ufsp->exists(str)) fvar = 1; else fvar = 0; - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "fsi(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); fvar = UfsInfo(fvar, 0); - lp++; - len = 0; - goto exit; + goto nfuncexit; } - if (!strncmp(vname, "fwa(", 4)) { - struct T_INDEX ind; - uint8_t vtype; - lp = isvar(lp + 4, &vtype, &ind, 0, 0, gv); - if (vtype!=VAR_NV && (vtype&STYPE)==0 && glob_script_mem.type[ind.index].bits.is_filter) { - // found array as result +#ifdef USE_FEXTRACT + if (!strncmp(vname, "fxt(", 4)) { + // extract from file + lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); + SCRIPT_SKIP_SPACES + uint8_t fref = fvar; - } else { - // error + //2020-12-16T14:30:00 + char ts_from[24]; + lp = GetStringArgument(lp, OPER_EQU, ts_from, 0); + SCRIPT_SKIP_SPACES + + char ts_to[24]; + lp = GetStringArgument(lp, OPER_EQU, ts_to, 0); + SCRIPT_SKIP_SPACES + + lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); + SCRIPT_SKIP_SPACES + uint8_t coffs = fvar; + + lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); + SCRIPT_SKIP_SPACES + int16_t accum = fvar; + + uint16_t a_len[MAX_EXT_ARRAYS]; + float *a_ptr[MAX_EXT_ARRAYS]; + + uint8_t index = 0; + while (index < MAX_EXT_ARRAYS) { + lp = get_array_by_name(lp, &a_ptr[index], &a_len[index]); + SCRIPT_SKIP_SPACES + index++; + if (*lp == ')' || *lp == '\n') { + break; + } + } + fvar = extract_from_file(fref, ts_from, ts_to, coffs, a_ptr, a_len, index, accum); + goto nfuncexit; + } +#endif // USE_FEXTRACT + if (!strncmp(vname, "fwa(", 4)) { + uint16_t alen; + float *fa; + lp = get_array_by_name(lp + 4, &fa, &alen); + if (!fa) { fvar = 0; goto exit; } - - while (*lp==' ') lp++; + SCRIPT_SKIP_SPACES lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); + SCRIPT_SKIP_SPACES + uint8_t append = 0; + if (*lp == 'a') { + lp++; + append = 1; + } uint8_t index = fvar; - if (index>=SFS_MAX) index = SFS_MAX - 1; + if (index >= SFS_MAX) index = SFS_MAX - 1; if (glob_script_mem.file_flags[index].is_open) { - uint16_t len = 0; - float *fa = Get_MFAddr(glob_script_mem.type[ind.index].index, &len, 0); char dstr[24]; - for (uint32_t cnt = 0; cnt=SFS_MAX) find = SFS_MAX - 1; + SCRIPT_SKIP_SPACES + + if (find >= SFS_MAX) find = SFS_MAX - 1; char str[glob_script_mem.max_ssize + 1]; if (glob_script_mem.file_flags[find].is_open) { - uint16_t len = 0; - float *fa = Get_MFAddr(glob_script_mem.type[ind.index].index, &len, 0); - char dstr[24]; - for (uint32_t cnt = 0; cnt=glob_script_mem.max_ssize - 1) break; + first = 1; + slen++; + if (slen >= glob_script_mem.max_ssize - 1) break; } } *cp = 0; @@ -2370,9 +2618,7 @@ chknext: } else { fvar = 0; } - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif // USE_SCRIPT_FATFS_EXT @@ -2382,10 +2628,8 @@ chknext: lp = GetStringArgument(lp + 4, OPER_EQU, str, 0); if (lknum<1 || lknum>2) lknum = 1; strlcpy(glob_script_mem.flink[lknum - 1], str, 14); - lp++; fvar = 0; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "fsm", 3)) { fvar=(uint32_t)ufsp; @@ -2501,9 +2745,7 @@ chknext: char path[SCRIPT_MAXSSIZE]; lp = GetStringArgument(lp, OPER_EQU, path, 0); fvar = call2https(host, path); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //SCRIPT_GET_HTTPS_JP break; @@ -2539,9 +2781,36 @@ chknext: char str[SCRIPT_MAXSSIZE]; lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); fvar = strtol(str, NULL, 16); - lp++; - len = 0; - goto exit; + goto nfuncexit; + } + if (!strncmp(vname, "hf(", 3)) { + char str[SCRIPT_MAXSSIZE]; + lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); + SCRIPT_SKIP_SPACES + if (strlen(str) != 8) { + fvar = -1; + } else { + uint8_t *ucp = (uint8_t*)&fvar; + uint8_t rflg = 0; + if (*lp=='r') { + rflg = 1; + ucp += sizeof(float); + lp++; + } + char substr[3]; + char *cp = str; + for (uint32_t cnt = 0; cnt < 4; cnt++) { + substr[0] = *cp++; + substr[1] = *cp++; + substr[2] = 0; + if (!rflg) { + *ucp++ = strtol(substr, NULL, 16); + } else { + *--ucp = strtol(substr, NULL, 16); + } + } + } + goto nfuncexit; } if (!strncmp(vname, "http(", 5)) { char host[SCRIPT_MAXSSIZE]; @@ -2551,9 +2820,7 @@ chknext: lp = GetStringArgument(lp, OPER_EQU, request, 0); SCRIPT_SKIP_SPACES fvar = http_req(host, request); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #ifdef USE_LIGHT if (!strncmp(vname, "hsvrgb(", 7)) { @@ -2571,9 +2838,7 @@ chknext: if (fvar3<0 || fvar3>100) fvar3 = 0; fvar = HSVToRGB(fvar, fvar2, fvar3); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //USE_LIGHT @@ -2588,9 +2853,7 @@ chknext: glob_script_mem.homekit_running == false; } } - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif break; @@ -2608,16 +2871,12 @@ chknext: } else { fvar = -1; } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "int(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); fvar = floor(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "is(", 3)) { lp = isargs(lp + 3, 0); @@ -2662,9 +2921,7 @@ chknext: } lp = GetNumericArgument(lp + 1, OPER_EQU, &fvar, gv); fvar = script_i2c(0, fvar, bus); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "iw", 2)) { uint8_t bytes = 1; @@ -2681,9 +2938,7 @@ chknext: float fvar2; lp = GetNumericArgument(lp, OPER_EQU, &fvar2, gv); fvar = script_i2c(9 + bytes, fvar, fvar2); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "ir", 2)) { uint8_t bytes = 1; @@ -2696,9 +2951,7 @@ chknext: } lp = GetNumericArgument(lp + 1, OPER_EQU, &fvar, gv); fvar = script_i2c(2, fvar, bytes); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif // USE_SCRIPT_I2C break; @@ -2728,9 +2981,7 @@ chknext: lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv); SCRIPT_SKIP_SPACES fvar = lvgl_test(&lp, fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif // USE_LVGL break; @@ -2743,17 +2994,13 @@ chknext: float fvar2; lp = GetNumericArgument(lp, OPER_EQU, &fvar2, gv); fvar = DoMedian5(fvar1, fvar2); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #ifdef USE_ANGLE_FUNC if (!strncmp(vname, "mpt(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); fvar = MeasurePulseTime(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //USE_ANGLE_FUNC if (!strncmp(vname, "micros", 6)) { @@ -2911,10 +3158,8 @@ chknext: // arg2 float fvar2; lp = GetNumericArgument(lp, OPER_EQU, &fvar2, gv); - lp++; fvar = FastPrecisePowf(fvar1, fvar2); - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "pwr[", 4)) { GetNumericArgument(vname + 4, OPER_EQU, &fvar, gv); @@ -2998,10 +3243,8 @@ chknext: if (!strncmp(vname, "sl(", 3)) { char str[SCRIPT_MAXSSIZE]; lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); - lp++; - len = 0; fvar = strlen(str); - goto exit; + goto nfuncexit; } if (!strncmp(vname, "sb(", 3)) { char str[SCRIPT_MAXSSIZE]; @@ -3081,9 +3324,7 @@ chknext: if (fvar>240) fvar = 240; setCpuFrequencyMhz(fvar); fvar = getCpuFrequencyMhz(); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //ESP32 #ifdef USE_TTGO_WATCH @@ -3091,9 +3332,7 @@ chknext: lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); SCRIPT_SKIP_SPACES TTGO_Sleep(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //USE_TTGO_WATCH #if defined(USE_TIMERS) && defined(USE_SUNRISE) @@ -3124,16 +3363,12 @@ chknext: if (!strncmp(vname, "sin(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); fvar = sinf(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "sqrt(", 5)) { lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv); fvar = sqrtf(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //USE_ANGLE_FUNC @@ -3142,9 +3377,7 @@ chknext: lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); SCRIPT_SKIP_SPACES fvar = SML_GetVal(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "sml(", 4)) { float fvar1; @@ -3177,9 +3410,7 @@ chknext: fvar = 0; #endif //ED300L } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "smlj", 4)) { fvar = sml_json_enable; @@ -3190,16 +3421,12 @@ chknext: lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv); if (fvar < 1) fvar = 1; SML_Decode(fvar - 1); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "smlv[", 5)) { lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv); fvar = sml_getv(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //USE_SML_M @@ -3261,9 +3488,7 @@ chknext: fvar = -2; } } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "sw(", 3)) { char str[SCRIPT_MAXSSIZE]; @@ -3273,9 +3498,7 @@ chknext: glob_script_mem.sp->write(str, strlen(str)); fvar = 0; } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "swb(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0); @@ -3284,18 +3507,14 @@ chknext: glob_script_mem.sp->write((uint8_t)fvar); fvar = 0; } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "sa(", 3)) { fvar = -1; if (glob_script_mem.sp) { fvar = glob_script_mem.sp->available(); } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "srb(", 3)) { fvar = -1; @@ -3305,9 +3524,7 @@ chknext: fvar = glob_script_mem.sp->read(); } } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "sp(", 3)) { fvar = -1; @@ -3317,9 +3534,7 @@ chknext: fvar = glob_script_mem.sp->peek(); } } - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "sr(", 3)) { uint16_t size = glob_script_mem.max_ssize; @@ -3396,33 +3611,25 @@ chknext: lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); if (fvar<10) fvar = 10; Script_ticker1.attach_ms(fvar, Script_ticker1_end); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "ts2(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); if (fvar<10) fvar = 10; Script_ticker2.attach_ms(fvar, Script_ticker2_end); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "ts3(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); if (fvar<10) fvar = 10; Script_ticker3.attach_ms(fvar, Script_ticker3_end); - lp++; - len = 0; - goto exit; + goto nfuncexit; } if (!strncmp(vname, "ts4(", 4)) { lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); if (fvar<10) fvar = 10; Script_ticker4.attach_ms(fvar, Script_ticker4_end); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif // USE_SCRIPT_TIMER @@ -3462,10 +3669,8 @@ chknext: } accu += ESP.getCycleCount()-cycles; } - lp++; - len = 0; fvar = accu / 1000; - goto exit; + goto nfuncexit; } #endif @@ -3478,9 +3683,7 @@ chknext: lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); SCRIPT_SKIP_SPACES fvar = get_tpars(index - 1, fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif break; @@ -3570,9 +3773,7 @@ chknext: default: fvar = 0; } - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif //ESP32, USE_WEBCAM #if defined(USE_TTGO_WATCH) && defined(USE_BMA423) @@ -3589,9 +3790,7 @@ chknext: if (!strncmp(vname, "wtch(", 5)) { lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv); fvar = Touch_Status(fvar); - lp++; - len = 0; - goto exit; + goto nfuncexit; } #endif // USE_FT5206 if (!strncmp(vname, "wm", 2)) { @@ -3638,6 +3837,9 @@ notfound: glob_script_mem.var_not_found = 1; return lp; // return constant numbers +nfuncexit: + lp++; + len = 0; exit: if (fp) *fp = fvar; *vtype = NUM_RES; @@ -6770,6 +6972,7 @@ char buff[512]; if (renderer && renderer->framebuffer) { uint8_t *bp = renderer->framebuffer; uint8_t *lbuf = (uint8_t*)special_malloc(Settings->display_width * 3 + 2); + memset(lbuf, 0, Settings->display_width * 3); if (!lbuf) return; uint8_t dmflg = 0; if (renderer->disp_bpp & 0x40) dmflg = 1; @@ -6808,11 +7011,12 @@ char buff[512]; } else { pixel = *bp & 0xf; } + pixel *= 15; + *--lbp = pixel; + *--lbp = pixel; + *--lbp = pixel; } - pixel *= 15; - *--lbp = pixel; - *--lbp = pixel; - *--lbp = pixel; + } else { for (uint32_t cnt = 0; cnt <= 1; cnt++) { if (!(cnt & 1)) { @@ -7941,18 +8145,20 @@ void script_task2(void *arg) { } } } -uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core, uint32_t prio) { +uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core, int32_t prio) { //return 0; BaseType_t res = 0; if (core > 1) { core = 1; } - if (num == 1) { - if (esp32_tasks[0].task_t) { vTaskDelete(esp32_tasks[0].task_t); } - res = xTaskCreatePinnedToCore(script_task1, "T1", STASK_STACK, NULL, prio, &esp32_tasks[0].task_t, core); - esp32_tasks[0].task_timer = time; - } else { - if (esp32_tasks[1].task_t) { vTaskDelete(esp32_tasks[1].task_t); } - res = xTaskCreatePinnedToCore(script_task2, "T2", STASK_STACK, NULL, prio, &esp32_tasks[1].task_t, core); - esp32_tasks[1].task_timer = time; + if (num < 1) { num = 1; } + if (num > 2) { num = 2; } + num--; + if (esp32_tasks[num].task_t) { + vTaskDelete(esp32_tasks[num].task_t); + esp32_tasks[num].task_t = 0; + } + if (prio >= 0) { + res = xTaskCreatePinnedToCore(script_task1, num==0?"T1":"T2", STASK_STACK, NULL, prio, &esp32_tasks[num].task_t, core); + esp32_tasks[num].task_timer = time; } return res; } @@ -7977,7 +8183,7 @@ void script_task2(void *arg) { } } -uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core, uint32_t prio) { +uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core, int32_t prio) { //return 0; BaseType_t res = 0; if (core > 1) { core = 1; } @@ -7997,6 +8203,42 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core, uint32 #endif // USE_SCRIPT_TASK #endif // ESP32 + +#ifdef USE_UFILESYS +// read http content to file +int32_t url2file(uint8_t fref, char *url) { + WiFiClient http_client; + HTTPClient http; + int32_t httpCode = 0; + char hbuff[128]; + strcpy(hbuff, "http://"); + strcat(hbuff, url); + http.begin(http_client, UrlEncode(hbuff)); + httpCode = http.GET(); + if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { + WiFiClient *stream = http.getStreamPtr(); + int32_t len = http.getSize(); + if (len < 0) len = 99999999; + uint8_t buff[512]; + while (http.connected() && (len > 0)) { + size_t size = stream->available(); + if (size) { + if (size > sizeof(buff)) { + size = sizeof(buff); + } + uint32_t read = stream->readBytes(buff, size); + glob_script_mem.files[fref].write(buff, read); + len -= read; + } + delayMicroseconds(1); + } + } + http.end(); + http_client.stop(); + return httpCode; +} +#endif + int32_t http_req(char *host, char *request) { WiFiClient http_client; HTTPClient http; @@ -8613,6 +8855,10 @@ int32_t retval = 0; case 7: retval = Settings->timer[index].arm; break; + case 8: + retval = Settings->flag3.timers_enable; + break; + } return retval; } diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 4b4a988cf..ffded1fde 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -96,6 +96,11 @@ void Get_display(uint8_t index) { } #endif // USE_MULTI_DISPLAY +#ifndef TXT_MAX_SFAC +#define TXT_MAX_SFAC 4 +#endif // TXT_MAX_SFAC + + const uint8_t DISPLAY_MAX_DRIVERS = 32; // Max number of display drivers/models supported by xdsp_interface.ino const uint8_t DISPLAY_MAX_COLS = 64; // Max number of columns allowed with command DisplayCols const uint8_t DISPLAY_MAX_ROWS = 64; // Max number of lines allowed with command DisplayRows @@ -875,9 +880,11 @@ void DisplayText(void) break; case 's': // size sx - if (renderer) renderer->setTextSize(*cp&7); + var = atoiv(cp, &temp); + if (temp > TXT_MAX_SFAC) temp = TXT_MAX_SFAC; + if (renderer) renderer->setTextSize(temp); //else DisplaySetSize(*cp&3); - cp += 1; + cp+=var; break; case 'f': // font sx @@ -2011,7 +2018,7 @@ void CmndDisplayDimmer(void) { } void CmndDisplaySize(void) { - if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) { + if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= TXT_MAX_SFAC)) { Settings->display_size = XdrvMailbox.payload; if (renderer) renderer->setTextSize(Settings->display_size); //else DisplaySetSize(Settings->display_size); diff --git a/tasmota/xdrv_44_miel_hvac.ino b/tasmota/xdrv_44_miel_hvac.ino index dd7461d8c..66e034fec 100644 --- a/tasmota/xdrv_44_miel_hvac.ino +++ b/tasmota/xdrv_44_miel_hvac.ino @@ -42,6 +42,8 @@ #include /* from hvac */ +bool temp_type = false; + struct miel_hvac_header { uint8_t start; #define MIEL_HVAC_H_START 0xfc @@ -68,11 +70,14 @@ struct miel_hvac_data_settings { uint8_t widevane; #define MIEL_HVAC_SETTTINGS_WIDEVANE_MASK \ 0x0f + uint8_t temp05; }; struct miel_hvac_data_roomtemp { uint8_t _pad1[2]; uint8_t temp; + uint8_t _pad2[2]; + uint8_t temp05; }; struct miel_hvac_data_status { @@ -109,8 +114,10 @@ CTASSERT(offsetof(struct miel_hvac_data, data.settings.temp) == 5); CTASSERT(offsetof(struct miel_hvac_data, data.settings.fan) == 6); CTASSERT(offsetof(struct miel_hvac_data, data.settings.vane) == 7); CTASSERT(offsetof(struct miel_hvac_data, data.settings.widevane) == 10); +CTASSERT(offsetof(struct miel_hvac_data, data.settings.temp05) == 11); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp) == 3); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp05) == 6); /* to hvac */ @@ -180,7 +187,8 @@ struct miel_hvac_msg_update { #define MIEL_HVAC_UPDATE_WIDEVANE_LR 0x08 #define MIEL_HVAC_UPDATE_WIDEVANE_SWING 0x0c #define MIEL_HVAC_UPDATE_WIDEVANE_ADJ 0x80 - uint8_t _pad2[2]; + uint8_t temp05; + uint8_t _pad2[1]; } __packed; CTASSERT(sizeof(struct miel_hvac_msg_update) == 16); @@ -192,23 +200,42 @@ CTASSERT(offsetof(struct miel_hvac_msg_update, temp) == MIEL_HVAC_OFFS(10)); CTASSERT(offsetof(struct miel_hvac_msg_update, fan) == MIEL_HVAC_OFFS(11)); CTASSERT(offsetof(struct miel_hvac_msg_update, vane) == MIEL_HVAC_OFFS(12)); CTASSERT(offsetof(struct miel_hvac_msg_update, widevane) == MIEL_HVAC_OFFS(18)); +CTASSERT(offsetof(struct miel_hvac_msg_update, temp05) == MIEL_HVAC_OFFS(19)); static inline uint8_t -miel_hvac_deg2temp(uint8_t deg) +miel_hvac_deg2temp(float deg) { - return (31 - deg); + if (!temp_type) { + return (31 - deg); + } + else { + deg = 2*deg + 128; + return ((uint8_t) deg); + } } -static inline uint8_t +static inline float miel_hvac_temp2deg(uint8_t temp) { - return (31 - temp); + if (!temp_type) { + return (31 - temp); + } + else { + temp -= 128; + return ((float) temp/2); + } } -static inline unsigned int +static inline float miel_hvac_roomtemp2deg(uint8_t roomtemp) { - return ((unsigned int)roomtemp + 10); + if (!temp_type) { + return ((unsigned int)roomtemp + 10); + } + else { + roomtemp -= 128; + return ((float) roomtemp/2); + } } struct miel_hvac_msg_remotetemp { @@ -682,20 +709,27 @@ miel_hvac_cmnd_settemp(void) { struct miel_hvac_softc *sc = miel_hvac_sc; struct miel_hvac_msg_update *update = &sc->sc_update; - unsigned long degc; + float degc; if (XdrvMailbox.data_len == 0) return; - - degc = strtoul(XdrvMailbox.data, nullptr, 0); + + degc = strtof(XdrvMailbox.data, nullptr); if (degc < MIEL_HVAC_UPDATE_TEMP_MIN || degc > MIEL_HVAC_UPDATE_TEMP_MAX) { miel_hvac_respond_unsupported(); return; } - update->flags |= htons(MIEL_HVAC_UPDATE_F_TEMP); - update->temp = miel_hvac_deg2temp(degc); + if (!temp_type) { + update->temp = miel_hvac_deg2temp(degc); + update->temp05 = 0; + } + + else { + update->temp = 0; + update->temp05 = miel_hvac_deg2temp(degc); + } ResponseCmndNumber(degc); } @@ -871,9 +905,15 @@ miel_hvac_publish_settings(struct miel_hvac_softc *sc) ResponseAppend_P(PSTR(",\"HA" D_JSON_IRHVAC_MODE "\":\"%s\""), set->power ? name : "off"); } - - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), - Settings->flag2.temperature_resolution, temp); + if (set->temp05 == 0) { + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), + Settings->flag2.temperature_resolution, temp); + } + else { + temp_type = true; + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), + Settings->flag2.temperature_resolution, temp); + } ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_TEMP "\":%s"), temp); name = miel_hvac_map_byval(set->fan, @@ -1074,11 +1114,18 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) if (sc->sc_temp.type != 0) { const struct miel_hvac_data_roomtemp *rt = &sc->sc_temp.data.roomtemp; - unsigned int temp = miel_hvac_roomtemp2deg(rt->temp); char room_temp[33]; - - dtostrfd(ConvertTemp(temp), - Settings->flag2.temperature_resolution, room_temp); + if(rt->temp05 == 0) { + unsigned int temp = miel_hvac_roomtemp2deg(rt->temp); + dtostrfd(ConvertTemp(temp), + Settings->flag2.temperature_resolution, room_temp); + } + else { + temp_type = true; + float temp = miel_hvac_roomtemp2deg(rt->temp05); + dtostrfd(ConvertTemp(temp), + Settings->flag2.temperature_resolution, room_temp); + } ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), room_temp); diff --git a/tasmota/xdrv_85_BLE_EQ3_TRV.ino b/tasmota/xdrv_85_BLE_EQ3_TRV.ino index cfe3bb33d..d69368268 100644 --- a/tasmota/xdrv_85_BLE_EQ3_TRV.ino +++ b/tasmota/xdrv_85_BLE_EQ3_TRV.ino @@ -128,7 +128,6 @@ print("".join(pin)) // for testing of BLE_ESP32, we remove xsns_62_MI_ESP32.ino completely, and instead add this modified xsns_52_ibeacon_BLE_ESP32.ino #if CONFIG_IDF_TARGET_ESP32 -#if ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(4, 0, 0) #ifdef USE_EQ3_ESP32 #ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support #ifdef USE_BLE_ESP32 @@ -226,7 +225,7 @@ uint8_t pairing = 0; #define EQ3_NUM_DEVICESLOTS 16 eq3_device_tag EQ3Devices[EQ3_NUM_DEVICESLOTS]; -void *EQ3mutex = nullptr; +SemaphoreHandle_t EQ3mutex = nullptr; int EQ3Period = 300; uint8_t EQ3OnlyAliased = 0; @@ -1765,5 +1764,4 @@ bool Xdrv85(uint8_t function) #endif // ESP32 #endif -#endif // ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(4, 0, 0) #endif // CONFIG_IDF_TARGET_ESP32 diff --git a/tasmota/xdsp_17_universal.ino b/tasmota/xdsp_17_universal.ino index b80205029..a37d5af5e 100644 --- a/tasmota/xdsp_17_universal.ino +++ b/tasmota/xdsp_17_universal.ino @@ -55,7 +55,7 @@ void Core2DisplayDim(uint8_t dim); #ifndef DISP_DESC_FILE //#define DISP_DESC_FILE "/dispdesc.txt" #define DISP_DESC_FILE "/display.ini" -#endif +#endif // DISP_DESC_FILE /*********************************************************************************************/ #ifdef DSP_ROM_DESC @@ -95,7 +95,7 @@ int8_t cs; AddLog(LOG_LEVEL_INFO, PSTR("DSP: File descriptor used")); } } -#endif +#endif // USE_UFILESYS #ifdef USE_SCRIPT @@ -212,8 +212,8 @@ int8_t cs; replacepin(&cp, Pin(GPIO_SPI_CLK, 1)); replacepin(&cp, Pin(GPIO_SPI_MOSI, 1)); replacepin(&cp, Pin(GPIO_SPI_DC, 1)); - replacepin(&cp, Pin(GPIO_BACKLIGHT, 1)); - replacepin(&cp, Pin(GPIO_OLED_RESET, 1)); + replacepin(&cp, Pin(GPIO_BACKLIGHT)); + replacepin(&cp, Pin(GPIO_OLED_RESET)); replacepin(&cp, Pin(GPIO_SPI_MISO, 1)); } else { // soft spi pins @@ -280,9 +280,9 @@ int8_t cs; else FT5206_Touch_Init(Wire1); #else if (!wire_n) FT5206_Touch_Init(Wire); -#endif +#endif // ESP32 } -#endif +#endif // USE_FT5206 #ifdef USE_XPT2046 cp = strstr(ddesc, ":TS,"); @@ -291,7 +291,7 @@ int8_t cs; uint8_t touch_cs = replacepin(&cp, Pin(GPIO_XPT2046_CS)); XPT2046_Touch_Init(touch_cs); } -#endif +#endif // USE_XPT2046 uint8_t inirot = Settings->display_rotate; @@ -314,18 +314,18 @@ int8_t cs; #ifdef USE_M5STACK_CORE2 renderer->SetPwrCB(Core2DisplayPower); renderer->SetDimCB(Core2DisplayDim); -#endif +#endif // USE_M5STACK_CORE2 renderer->DisplayInit(DISPLAY_INIT_MODE, Settings->display_size, inirot, Settings->display_font); Settings->display_width = renderer->width(); Settings->display_height = renderer->height(); - + ApplyDisplayDimmer(); #ifdef SHOW_SPLASH renderer->Splash(); -#endif +#endif // SHOW_SPLASH udisp_init_done = true; AddLog(LOG_LEVEL_INFO, PSTR("DSP: %s!"), renderer->devname()); diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 7674f5cf0..d001af112 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -1555,16 +1555,22 @@ void SML_Decode(uint8_t index) { double vdiff = meter_vars[ind - 1] - dvalues[dindex]; dvalues[dindex] = meter_vars[ind - 1]; double dres = (double)360000.0 * vdiff / ((double)dtime / 10000.0); -#ifdef USE_SML_MEDIAN_FILTER - if (meter_desc_p[mindex].flag & 16) { - meter_vars[vindex] = sml_median(&sml_mf[vindex], dres); - } else { - meter_vars[vindex] = dres; - } -#else - meter_vars[vindex] = dres; -#endif + dvalid[vindex] += 1; + + if (dvalid[vindex] >= 2) { + // differece is only valid after 2. calculation + dvalid[vindex] = 2; +#ifdef USE_SML_MEDIAN_FILTER + if (meter_desc_p[mindex].flag & 16) { + meter_vars[vindex] = sml_median(&sml_mf[vindex], dres); + } else { + meter_vars[vindex] = dres; + } +#else + meter_vars[vindex] = dres; +#endif + } mp=strchr(mp,'@'); if (mp) { mp++; @@ -1573,7 +1579,7 @@ void SML_Decode(uint8_t index) { SML_Immediate_MQTT((const char*)mp, vindex, mindex); } } - dvalid[vindex] = 1; + //dvalid[vindex] = 1; dindex++; } } else if (*mp == 'h') { @@ -2212,7 +2218,9 @@ uint8_t *script_meter; #ifdef SML_REPLACE_VARS +#ifndef SML_SRCBSIZE #define SML_SRCBSIZE 256 +#endif uint32_t SML_getlinelen(char *lp) { uint32_t cnt; @@ -2404,10 +2412,53 @@ dddef_exit: script_meter_desc[index].tsecs = strtol(lp, &lp, 10); if (*lp == ',') { lp++; - char txbuff[256]; +#if 1 + // look ahead + uint16_t txlen = 0; + uint16_t tx_entries = 1; + char *txp = lp; + while (*txp) { + if (*txp == ',') tx_entries++; + if (*txp == SCRIPT_EOL) { + if (tx_entries > 1) { + if (*(txp - 1) != ',' ) { + break; + } + // line ends with , + } else { + // single entry + break; + } + } + txp++; + txlen++; + } + if (txlen) { + script_meter_desc[index].txmem = (char*)calloc(txlen + 2, 1); + if (script_meter_desc[index].txmem) { + // now copy send blocks + char *txp = lp; + uint16_t tind = 0; + for (uint32_t cnt = 0; cnt < txlen; cnt++) { + if (*txp == SCRIPT_EOL) { + txp++; + } else { + script_meter_desc[index].txmem[tind] = *txp++; + tind++; + } + } + } + //AddLog(LOG_LEVEL_INFO, PSTR(">>> %s - %d"), script_meter_desc[index].txmem, txlen); + script_meter_desc[index].index = 0; + script_meter_desc[index].max_index = tx_entries; + sml_send_blocks++; + lp += txlen; + } +#else + char txbuff[SML_SRCBSIZE]; uint32_t txlen = 0, tx_entries = 1; for (uint32_t cnt = 0; cnt < sizeof(txbuff); cnt++) { - if (*lp == SCRIPT_EOL) { + if (*lp == SCRIPT_EOL && *(lp - 1) != ',' ) { txbuff[cnt] = 0; txlen = cnt; break; @@ -2424,6 +2475,7 @@ dddef_exit: script_meter_desc[index].max_index = tx_entries; sml_send_blocks++; } +#endif } } if (*lp == SCRIPT_EOL) lp--; diff --git a/tasmota/xsns_62_esp32_mi_ble.ino b/tasmota/xsns_62_esp32_mi_ble.ino index 92fdf4de0..a1627cebe 100644 --- a/tasmota/xsns_62_esp32_mi_ble.ino +++ b/tasmota/xsns_62_esp32_mi_ble.ino @@ -2741,9 +2741,8 @@ void MI32ShowOneMISensor(){ kMI32DeviceType[p->type-1], p->MAC[3], p->MAC[4], p->MAC[5]); } - char SensorTopic[60]; - sprintf(SensorTopic, "tele/tasmota_ble/%s", - id); + char SensorTopic[TOPSZ]; + GetTopic_P(SensorTopic, TELE, (char*)"tasmota_ble", id); MqttPublish(SensorTopic, Settings->flag.mqtt_sensor_retain); //AddLog(LOG_LEVEL_DEBUG,PSTR("M32: %s: show some %d %s"),D_CMND_MI32, MI32.mqttCurrentSlot, ResponseData()); @@ -2868,10 +2867,8 @@ void MI32DiscoveryOneMISensor(){ p->MAC[3], p->MAC[4], p->MAC[5]); } - char SensorTopic[60]; - sprintf(SensorTopic, "tele/tasmota_ble/%s", - id); - + char SensorTopic[TOPSZ]; + GetTopic_P(SensorTopic, TELE, (char*)"tasmota_ble", id); //int i = p->nextDiscoveryData*3; for (int i = 0; i < datacount*3; i += 3){ @@ -3063,7 +3060,7 @@ void MI32ShowTriggeredSensors(){ #endif //USE_HOME_ASSISTANT MI32.option.MQTTType == 1 ){ - char SensorTopic[60]; + char SensorTopic[TOPSZ]; char idstr[32]; const char *alias = BLE_ESP32::getAlias(p->MAC); const char *id = idstr; @@ -3074,7 +3071,7 @@ void MI32ShowTriggeredSensors(){ kMI32DeviceType[p->type-1], p->MAC[3], p->MAC[4], p->MAC[5]); } - snprintf_P(SensorTopic, sizeof(SensorTopic), PSTR("tele/tasmota_ble/%s"), id); + GetTopic_P(SensorTopic, TELE, (char*)"tasmota_ble", id); MqttPublish(SensorTopic, Settings->flag.mqtt_sensor_retain); AddLog(LOG_LEVEL_DEBUG, PSTR("M32: triggered %d %s"), sensor, ResponseData()); XdrvRulesProcess(0);