diff --git a/esp32_partition_app1984k_spiffs60k.csv b/esp32_partition_app1984k_spiffs60k.csv new file mode 100644 index 000000000..9c5f895a0 --- /dev/null +++ b/esp32_partition_app1984k_spiffs60k.csv @@ -0,0 +1,8 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x9000,20K, +otadata,data,ota,0xe000,8K, +app0,app,ota_0,0x10000,1984K, +app1,app,ota_1,0x200000,1984K, +spiffs,data,spiffs,0x3f0000,60K, +eeprom,data,nvs,0x3ff000,4K, diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 050c2e390..466a8991e 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -394,11 +394,14 @@ // -- Ping ---------------------------------------- // #define USE_PING // Enable Ping command (+2k code) +#define USE_UNISHOX_COMPRESSION // add support for string compression for RULES or SCRIPT + // -- Rules or Script ---------------------------- // Select none or only one of the below defines USE_RULES or USE_SCRIPT #define USE_RULES // Add support for rules (+8k code) - #define USE_RULES_COMPRESSION // Compresses rules in Flash at about ~50% (+3.3k code) + // with USE_UNISHOX_COMPRESSION // Compresses rules in Flash at about ~50% (+3.3k code) //#define USE_SCRIPT // Add support for script (+17k code) + // supports USE_UNISHOX_COMPRESSION //#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support // #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) diff --git a/tasmota/support.ino b/tasmota/support.ino index 839e126f6..8d915cf05 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1882,7 +1882,7 @@ void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32 * Uncompress static PROGMEM strings \*********************************************************************************************/ -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION #include @@ -1908,4 +1908,4 @@ String Decompress(const char * compressed, size_t uncompressed_size) { return content; } -#endif // defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) \ No newline at end of file +#endif // USE_UNISHOX_COMPRESSION \ No newline at end of file diff --git a/tasmota/support_eeprom.ino b/tasmota/support_eeprom.ino new file mode 100644 index 000000000..b990aa242 --- /dev/null +++ b/tasmota/support_eeprom.ino @@ -0,0 +1,89 @@ +/* + support_eeprom.ino - eeprom support for Sonoff-Tasmota + + Copyright (C) 2020 Theo Arends & Gerhard Mutz + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + supports hardware i2c eeprom 24c256 and flash eeprom simulation on ESP8266 and ESP32 + all ESP8266 linker files contain 4k eeprom partition + ESP32 requires esp32_partition_app1984k_spiffs60k.csv for 4k eeprom +*/ + + +#ifdef USE_EEPROM + +#ifdef USE_24C256 + // i2c eeprom +#include +#define EEPROM_ADDRESS 0x50 +static Eeprom24C128_256 m_eeprom(EEPROM_ADDRESS); + +void eeprom_writeBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + m_eeprom.writeBytes(addr,len,(uint8_t*)buff); +} +void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + m_eeprom.readBytes(addr,len,(uint8_t*)buff); +} + +uint32_t eeprom_init(uint32_t size) { + if (i2c_flg) { + if (I2cActive(EEPROM_ADDRESS) || I2cSetDevice(EEPROM_ADDRESS)) { + // eeprom is present + I2cSetActiveFound(EEPROM_ADDRESS, "24C256"); + return 1; + } + } + return 0; +} + +#else // USE_24C256 + +#ifdef ESP32 + +// esp32 uses eeprom section +uint32_t eeprom_init(uint32_t size) { + return EEPROM.begin(size); +} +void eeprom_writeBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + EEPROM.writeBytes(addr, buff, len); + EEPROM.commit(); +} +void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + EEPROM.readBytes(addr, buff, len); +} + +#else +// esp8266 uses eeprom section +uint32_t eeprom_init(uint32_t size) { + EEPROM.begin(size); + return 1; +} +void eeprom_writeBytes(uint32_t adr, uint32_t len, uint8_t *buf) { + for (uint32_t cnt=0; cnt= 0 : the actual stored size @@ -343,7 +343,7 @@ int32_t SetRule(uint32_t idx, const char *content, bool append = false) { Settings.rules[idx][1] = 0; } -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION if (0 != len_in + offset) { // do a dry-run compression to display how much it would be compressed int32_t len_compressed, len_uncompressed; @@ -353,11 +353,11 @@ int32_t SetRule(uint32_t idx, const char *content, bool append = false) { AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Stored uncompressed, would compress from %d to %d (-%d%%)"), len_uncompressed, len_compressed, 100 - changeUIntScale(len_compressed, 0, len_uncompressed, 0, 100)); } -#endif // USE_RULES_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION return len_in + offset; } else { -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION int32_t len_compressed; // allocate temp buffer so we don't nuke the rule if it's too big to fit char *buf_out = (char*) malloc(MAX_RULE_SIZE + 8); // take some margin @@ -390,9 +390,9 @@ int32_t SetRule(uint32_t idx, const char *content, bool append = false) { free(buf_out); return len_compressed; -#else // USE_RULES_COMPRESSION +#else // USE_UNISHOX_COMPRESSION return -1; // the rule does not fit and we can't compress -#endif // USE_RULES_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION } } diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 0edfad516..888fa3cb8 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -26,6 +26,7 @@ uses about 17 k of flash to do optimize code for space +g:var gloabal vars (via udp broadcast) remarks @@ -67,28 +68,70 @@ keywords if then else endif, or, and are better readable for beginners (others m uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); -#ifdef USE_SCRIPT_COMPRESSION +// solve conficting defines +// highest priority +#ifdef USE_SCRIPT_FATFS +#undef LITTLEFS_SCRIPT_SIZE +#undef EEP_SCRIPT_SIZE +#undef USE_UNISHOX_COMPRESSION +#if USE_SCRIPT_FATFS==-1 +#ifdef ESP32 +#error "script fat file option -1 currently not supported for ESP32" +#else +#pragma message "script fat file option -1 used" +#endif +#else +#pragma message "script fat file SDC option used" +#endif +#endif // USE_SCRIPT_FATFS + +// lfs on esp8266 spiffs on esp32 +#ifdef LITTLEFS_SCRIPT_SIZE +#undef EEP_SCRIPT_SIZE +#undef USE_UNISHOX_COMPRESSION +#pragma message "script little file system option used" +#endif // LITTLEFS_SCRIPT_SIZE + +// eeprom script +#ifdef EEP_SCRIPT_SIZE +#undef USE_UNISHOX_COMPRESSION +#ifdef USE_24C256 +#pragma message "script 24c256 file option used" +#else +#warning "EEP_SCRIPT_SIZE also needs USE_24C256" +#define USE_24C256 +#endif +#endif // EEP_SCRIPT_SIZE + +// compression last option before default +#ifdef USE_UNISHOX_COMPRESSION +#pragma message "script compression option used" +#endif // USE_UNISHOX_COMPRESSION + + +#ifdef USE_UNISHOX_COMPRESSION #include -//Unishox compressor; // singleton #define SCRIPT_COMPRESS compressor.unishox_compress #define SCRIPT_DECOMPRESS compressor.unishox_decompress #ifndef UNISHOXRSIZE #define UNISHOXRSIZE 2560 #endif -#endif // USE_SCRIPT_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION -#if (defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)) || (USE_SCRIPT_FATFS==-1) +#if defined(LITTLEFS_SCRIPT_SIZE) || (USE_SCRIPT_FATFS==-1) #ifdef ESP32 #include "FS.h" #include "SPIFFS.h" #else #include #endif - FS *fsp; +#endif // LITTLEFS_SCRIPT_SIZE + +#ifdef LITTLEFS_SCRIPT_SIZE void SaveFile(const char *name,const uint8_t *buf,uint32_t len) { File file = fsp->open(name, "w"); if (!file) return; @@ -116,7 +159,7 @@ void LoadFile(const char *name,uint8_t *buf,uint32_t len) { file.read(buf, len); file.close(); } -#endif +#endif // LITTLEFS_SCRIPT_SIZE // offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution #define EPOCH_OFFSET 1546300800 @@ -317,23 +360,10 @@ void RulesTeleperiod(void) { } // EEPROM MACROS -#ifdef USE_24C256 -#ifndef USE_SCRIPT_FATFS // i2c eeprom -#include -#define EEPROM_ADDRESS 0x50 -// strange bug, crashes with powers of 2 ??? 4096 crashes -#ifndef EEP_SCRIPT_SIZE -#define EEP_SCRIPT_SIZE 4095 -#endif +#define EEP_WRITE(A,B,C) eeprom_writeBytes(A,B,(uint8_t*)C); +#define EEP_READ(A,B,C) eeprom_readBytes(A,B,(uint8_t*)C); -static Eeprom24C128_256 eeprom(EEPROM_ADDRESS); -// eeprom.writeBytes(address, length, buffer); -#define EEP_WRITE(A,B,C) eeprom.writeBytes(A,B,(uint8_t*)C); -// eeprom.readBytes(address, length, buffer); -#define EEP_READ(A,B,C) eeprom.readBytes(A,B,(uint8_t*)C); -#endif -#endif #define SCRIPT_SKIP_SPACES while (*lp==' ' || *lp=='\t') lp++; #define SCRIPT_SKIP_EOL while (*lp==SCRIPT_EOL) lp++; @@ -651,13 +681,7 @@ char *script; #if USE_SCRIPT_FATFS>=0 fsp=&SD; - -#ifdef USE_MMC - if (fsp->begin()) { -#else if (SD.begin(USE_SCRIPT_FATFS)) { -#endif - #else if (fsp->begin()) { #endif @@ -738,13 +762,14 @@ float median_array(float *array,uint8_t len) { } -float *Get_MFAddr(uint8_t index,uint8_t *len) { +float *Get_MFAddr(uint8_t index,uint8_t *len,uint8_t *ipos) { *len=0; uint8_t *mp=(uint8_t*)glob_script_mem.mfilt; for (uint8_t count=0; countnumvals&0x7f; + if (ipos) *ipos=mflp->index; return mflp->rbuff; } mp+=sizeof(struct M_FILT)+((mflp->numvals&0x7f)-1)*sizeof(float); @@ -936,6 +961,56 @@ if (hsv.S == 0) { #endif //#endif +#ifdef USE_ANGLE_FUNC +uint32_t pulse_time_hl; +uint32_t pulse_time_lh; +uint32_t pulse_ltime_hl; +uint32_t pulse_ltime_lh; +uint8_t pt_pin; + +void MP_Timer(void) ICACHE_RAM_ATTR; + +#define MPT_DEBOUNCE 10 + +void MP_Timer(void) { + uint32_t level = digitalRead(pt_pin&0x3f); + uint32_t ms = millis(); + uint32_t time; + if (level) { + // rising edge + pulse_ltime_lh = ms; + time = ms - pulse_ltime_hl; + if (time>MPT_DEBOUNCE) pulse_time_hl = time; + } else { + // falling edge + pulse_ltime_hl = ms; + time = ms - pulse_ltime_lh; + if (time>MPT_DEBOUNCE) pulse_time_lh = time; + } +} + +uint32_t MeasurePulseTime(int32_t in) { + if (in >= 0) { + // define pin; + pt_pin = in; + pinMode(pt_pin&0x3f,INPUT_PULLUP); + attachInterrupt(pt_pin&0x3f, MP_Timer, CHANGE); + pulse_ltime_lh = millis(); + pulse_ltime_hl = millis(); + return 0; + } + uint32_t ptime; + if (in==-1) { + ptime = pulse_time_lh; + pulse_time_lh = 0; + } else { + ptime = pulse_time_hl; + pulse_time_hl = 0; + } + return ptime; +} +#endif // USE_ANGLE_FUNC + // vtype => ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number // no flash strings here for performance reasons!!! char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) { @@ -1720,6 +1795,15 @@ chknext: len=0; goto exit; } +#ifdef USE_ANGLE_FUNC + if (!strncmp(vname,"mpt(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + fvar=MeasurePulseTime(fvar); + lp++; + len=0; + goto exit; + } +#endif if (!strncmp(vname,"micros",6)) { fvar=micros(); goto exit; @@ -3159,7 +3243,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { // numeric result if (glob_script_mem.type[ind.index].bits.is_filter) { uint8_t len=0; - float *fa=Get_MFAddr(index,&len); + float *fa=Get_MFAddr(index,&len,0); //Serial.printf(">> 2 %d\n",(uint32_t)*fa); if (fa && len) ws2812_set_array(fa,len,fvar); } @@ -4065,26 +4149,26 @@ void ScriptSaveSettings(void) { } -#if defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#ifdef EEP_SCRIPT_SIZE if (glob_script_mem.flags&1) { EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram); } -#endif +#endif // EEP_SCRIPT_SIZE -#if !defined(USE_24C256) && defined(USE_SCRIPT_FATFS) +#ifdef USE_SCRIPT_FATFS if (glob_script_mem.flags&1) { fsp->remove(FAT_SCRIPT_NAME); File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE); file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE); file.close(); } -#endif +#endif // USE_SCRIPT_FATFS -#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#ifdef LITTLEFS_SCRIPT_SIZE if (glob_script_mem.flags&1) { SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE); } -#endif +#endif // LITTLEFS_SCRIPT_SIZE } if (glob_script_mem.script_mem) { @@ -4094,11 +4178,7 @@ void ScriptSaveSettings(void) { glob_script_mem.script_mem_size=0; } -#ifdef USE_SCRIPT_COMPRESSION -#ifndef USE_24C256 -#ifndef USE_SCRIPT_FATFS -#ifndef LITTLEFS_SCRIPT_SIZE - +#ifdef USE_UNISHOX_COMPRESSION //AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1); if (len_compressed > 0) { @@ -4107,11 +4187,7 @@ void ScriptSaveSettings(void) { } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); } - -#endif -#endif -#endif -#endif // USE_SCRIPT_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION if (bitRead(Settings.rule_enabled, 0)) { int16_t res=Init_Scripter(); @@ -5068,10 +5144,11 @@ const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'"; #define MAX_GARRAY 4 -char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries) { +char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries, uint8_t *ipos) { struct T_INDEX ind; uint8_t vtype; uint8 entries=0; +uint8_t cipos=0; uint8_t anum=0; while (anum> 2 %d\n",(uint32_t)*fa); if (fa && len>=entries) { - if (!entries) {entries = len;} + if (!entries) { + entries = len; + } // add array to list arrays[anum]=fa; anum++; @@ -5111,6 +5190,7 @@ uint8 entries=0; //Serial.printf(">> %d - %d - %d\n",anum,entries,(uint32_t)*arrays[0]); *ranum=anum; *rentries=entries; + *ipos=cipos; return lp; } @@ -5409,7 +5489,8 @@ void ScriptWebShow(char mc) { float *arrays[MAX_GARRAY]; uint8_t anum=0; uint8 entries=0; - lp=gc_get_arrays(lp, &arrays[0], &anum, &entries); + uint8 ipos=0; + lp=gc_get_arrays(lp, &arrays[0], &anum, &entries, &ipos); if (anum>nanum) { goto nextwebline; @@ -5456,28 +5537,38 @@ void ScriptWebShow(char mc) { int8_t todflg=-1; if (!strncmp(label,"cnt",3)) { todflg=atoi(&label[3]); + if (todflg>=entries) todflg=entries-1; } + uint32_t aind=ipos; + if (aind>=entries) aind=entries-1; for (uint32_t cnt=0; cnt=0) { sprintf(lbl,"%d",todflg); todflg++; + if (todflg>=entries) { + todflg=0; + } } else { - GetTextIndexed(lbl, sizeof(lbl), cnt, label); + GetTextIndexed(lbl, sizeof(lbl), aind, label); } WSContentSend_PD(lbl); WSContentSend_PD("',"); for (uint32_t ind=0; ind=entries) { + aind=0; + } } // get header @@ -5722,7 +5813,7 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { /*********************************************************************************************\ * Interface \*********************************************************************************************/ - +//const esp_partition_t *esp32_part; bool Xdrv10(uint8_t function) { @@ -5739,10 +5830,7 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram=(uint8_t*)Settings.script_pram[0]; glob_script_mem.script_pram_size=PMEM_SIZE; -#ifdef USE_SCRIPT_COMPRESSION -#ifndef USE_24C256 -#ifndef USE_SCRIPT_FATFS -#ifndef LITTLEFS_SCRIPT_SIZE +#ifdef USE_UNISHOX_COMPRESSION int32_t len_decompressed; sprt=(char*)calloc(UNISHOXRSIZE+8,1); if (!sprt) { break; } @@ -5751,10 +5839,7 @@ bool Xdrv10(uint8_t function) len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size); if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed]=0; //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); -#endif -#endif -#endif -#endif // USE_SCRIPT_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION #ifdef USE_BUTTON_EVENT for (uint32_t cnt=0;cnt=0 - fsp = &SD; - -#ifdef USE_MMC - if (fsp->begin()) { -#else - + // fs on SD card #ifdef ESP32 if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1); + SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1); } -#endif +#endif // ESP32 + fsp = &SD; if (SD.begin(USE_SCRIPT_FATFS)) { -#endif - #else - fsp = &LittleFS; - if (fsp->begin()) { -#endif + // fs on flash + fsp = &LittleFS; + if (fsp->begin()) { +#endif // USE_SCRIPT_FATFS>=0 //fsp->dateTimeCallback(dateTime); @@ -5834,14 +5909,18 @@ bool Xdrv10(uint8_t function) } else { glob_script_mem.script_sd_found=0; } -#endif +#endif // USE_SCRIPT_FATFS -#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#ifdef LITTLEFS_SCRIPT_SIZE #ifdef ESP32 + // spiffs on esp32 fsp = &SPIFFS; + //esp32_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_DATA_SPIFFS,NULL); + //Serial.printf("address %d - %d - %s\n",esp32_part->address,esp32_part->size, esp32_part->label); #else + // lfs on esp8266 fsp = &LittleFS; #endif char *script; @@ -5856,7 +5935,7 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram=(uint8_t*)Settings.rules[0]; glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE; glob_script_mem.flags=1; -#endif +#endif // LITTLEFS_SCRIPT_SIZE // a valid script MUST start with >D if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino index 86022b084..5376d4248 100644 --- a/tasmota/xdrv_21_wemo.ino +++ b/tasmota/xdrv_21_wemo.ino @@ -85,7 +85,7 @@ void WemoRespondToMSearch(int echo_type) * Wemo web server additions \*********************************************************************************************/ -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION //SetBinaryStateBinaryStateBinaryStateinGetBinaryStateBinaryStateBinaryStateoutBinaryStatebool0levelstring0\r\n\r\n //Successfully compressed from 779 to 249 bytes (-68%) @@ -293,7 +293,7 @@ void HandleUpnpEvent(void) } } -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION snprintf_P(event, sizeof(event), Decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_SIZE).c_str(), state, bitRead(power, devices_present -1), state); #else snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state); @@ -305,7 +305,7 @@ void HandleUpnpService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_EVENT_SERVICE)); -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION WSSend(200, CT_PLAIN, Decompress(WEMO_EVENTSERVICE_XML, WEMO_EVENTSERVICE_XML_SIZE)); #else WSSend(200, CT_PLAIN, FPSTR(WEMO_EVENTSERVICE_XML)); @@ -316,7 +316,7 @@ void HandleUpnpMetaService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_META_SERVICE)); -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION WSSend(200, CT_PLAIN, Decompress(WEMO_METASERVICE_XML, WEMO_METASERVICE_XML_SIZE)); #else WSSend(200, CT_PLAIN, FPSTR(WEMO_METASERVICE_XML)); @@ -327,7 +327,7 @@ void HandleUpnpSetupWemo(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP)); -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION String setup_xml = Decompress(WEMO_SETUP_XML, WEMO_SETUP_XML_SIZE); #else String setup_xml = FPSTR(WEMO_SETUP_XML); diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index bf508d9c2..7494715f3 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -136,7 +136,7 @@ ZF(MainsVoltage) ZF(MainsFrequency) ZF(BatteryVoltage) ZF(BatteryPercentage) ZF(CurrentTemperature) ZF(MinTempExperienced) ZF(MaxTempExperienced) ZF(OverTempTotalDwell) ZF(SceneCount) ZF(CurrentScene) ZF(CurrentGroup) ZF(SceneValid) ZF(AlarmCount) ZF(Time) ZF(TimeStatus) ZF(TimeZone) ZF(DstStart) ZF(DstEnd) -ZF(DstShift) ZF(StandardTime) ZF(LocalTime) ZF(LastSetTime) ZF(ValidUntilTime) +ZF(DstShift) ZF(StandardTime) ZF(LocalTime) ZF(LastSetTime) ZF(ValidUntilTime) ZF(TimeEpoch) ZF(LocationType) ZF(LocationMethod) ZF(LocationAge) ZF(QualityMeasure) ZF(NumberOfDevices) @@ -283,6 +283,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint32, Cx000A, 0x0007, Z(LocalTime), 1, Z_Nop }, { ZUTC, Cx000A, 0x0008, Z(LastSetTime), 1, Z_Nop }, { ZUTC, Cx000A, 0x0009, Z(ValidUntilTime), 1, Z_Nop }, + { ZUTC, Cx000A, 0xFF00, Z(TimeEpoch), 1, Z_Nop }, // Tasmota specific, epoch // RSSI Location cluster { Zdata8, Cx000B, 0x0000, Z(LocationType), 1, Z_Nop }, @@ -1397,7 +1398,7 @@ int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje if (multiplier > 0) { json[new_name] = ((float)value) * multiplier; } else { - json[new_name] = ((float)value) / multiplier; + json[new_name] = ((float)value) / (-multiplier); } } diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 996103fe5..aad2732ca 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -866,7 +866,8 @@ void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const break; #endif case 0x000A: // Time - if (HasKeyCaseInsensitive(json, PSTR("Time"))) { json_out[F("Time")] = Rtc.utc_time; } + if (HasKeyCaseInsensitive(json, PSTR("Time"))) { json_out[F("Time")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? Rtc.utc_time - 946684800 : Rtc.utc_time; } + if (HasKeyCaseInsensitive(json, PSTR("TimeEpoch"))) { json_out[F("TimeEpoch")] = Rtc.utc_time; } if (HasKeyCaseInsensitive(json, PSTR("TimeStatus"))) { json_out[F("TimeStatus")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? 0x02 : 0x00; } // if time is beyond 2010 then we are synchronized if (HasKeyCaseInsensitive(json, PSTR("TimeZone"))) { json_out[F("TimeZone")] = Settings.toffset[0] * 60; } // seconds break; diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino index 0ea39c194..4da0a48f6 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_9_impl.ino @@ -483,7 +483,7 @@ void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t if (multiplier > 0) { // inverse of decoding val_f = val_f / multiplier; } else { - val_f = val_f * multiplier; + val_f = val_f * (-multiplier); } use_val = false; } diff --git a/tasmota/xsns_68_windmeter.ino b/tasmota/xsns_68_windmeter.ino index 3faa7ecb7..5487c898c 100644 --- a/tasmota/xsns_68_windmeter.ino +++ b/tasmota/xsns_68_windmeter.ino @@ -58,8 +58,8 @@ float const windmeter_pi = 3.1415926535897932384626433; // Pi float const windmeter_2pi = windmeter_pi * 2; struct WINDMETER { - uint32_t counter_time; - unsigned long counter = 0; + volatile uint32_t counter_time; + volatile unsigned long counter = 0; //uint32_t speed_time; float speed = 0; float last_tele_speed = 0;