diff --git a/README.md b/README.md index 15a13ba22..6c8e77762 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.11.1i** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. +Current version is **5.11.1j** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 42635ea3a..f2cd88ad7 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,10 @@ -/* 5.11.1i +/* 5.11.1j + * Prep for release + * Change uptime from hour to second resulting in a display of 123T13:45:21 where 123 is days + * Fix Arilux RF induced exception by moving interrupt handler to iram on non esp/arduino lib v2.3.0 + * Add NTP sync based on chip id (#1773) + * + * 5.11.1i * Update TasmotaSerial library to 1.1.0 * Rename commands HlwPCal, HlwUCal and HlwICal to PowerCal, VoltageCal and CurrentCal to be used for both Pow and S31 calibration * Rename commands HlwPSet, HlwUSet and HlwISet to PowerSet, VoltageSet and CurrentSet to be used for both Pow and S31 calibration diff --git a/sonoff/settings.h b/sonoff/settings.h index cfcd49df1..4fe5f77d5 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -270,6 +270,7 @@ struct TIME_T { char name_of_month[4]; uint16_t day_of_year; uint16_t year; + unsigned long days; unsigned long valid; } RtcTime; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index c21b31a49..569b5dc85 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x050B0109 // 5.11.1i +#define VERSION 0x050B010A // 5.11.1j // Location specific includes #include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) @@ -126,7 +126,8 @@ byte ota_retry_counter = OTA_ATTEMPTS; // OTA retry counter char *ota_url; // OTA url string int restart_flag = 0; // Sonoff restart flag int wifi_state_flag = WIFI_RESTART; // Wifi state flag -int uptime = 0; // Current uptime in hours +//int uptime = 0; // Current uptime in hours +uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year boolean latest_uptime_flag = true; // Signal latest uptime int tele_period = 0; // Tele period timer byte web_log_index = 1; // Index in Web log buffer (should never be 0) @@ -1714,8 +1715,8 @@ void PublishStatus(uint8_t payload) } if ((0 == payload) || (1 == payload)) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_UPTIME "\":%d,\"" D_CMND_SLEEP "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"), - baudrate, Settings.mqtt_grptopic, Settings.ota_url, uptime, Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"), + baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetUptime().c_str(), Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress()); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1")); } @@ -1788,7 +1789,7 @@ void MqttShowState() { char stemp1[33]; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":%d"), mqtt_data, GetDateAndTime().c_str(), uptime); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\""), mqtt_data, GetDateAndTime().c_str(), GetUptime().c_str()); #ifdef USE_ADC_VCC dtostrfd((double)ESP.getVcc()/1000, 3, stemp1); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1); @@ -1833,6 +1834,8 @@ boolean MqttShowSensor() void PerformEverySecond() { + uptime++; + if (blockgpio0) { blockgpio0--; } @@ -1897,8 +1900,7 @@ void PerformEverySecond() if ((2 == RtcTime.minute) && latest_uptime_flag) { latest_uptime_flag = false; - uptime++; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":%d}"), GetDateAndTime().c_str(), uptime); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\"}"), GetDateAndTime().c_str(), GetUptime().c_str()); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_UPTIME)); } if ((3 == RtcTime.minute) && !latest_uptime_flag) { diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index bb0e2392d..18e603ea8 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -82,9 +82,21 @@ void WifiWpsStatusCallback(wps_cb_status status); #ifdef USE_DHT #undef USE_DHT // Disable internal DHT sensor #endif +#ifdef USE_DISPLAY +#undef USE_DISPLAY // Disable Display support +#endif +#ifdef USE_MHZ19 +#undef USE_MHZ19 // Disable support for MH-Z19 CO2 sensor +#endif +#ifdef USE_SENSEAIR +#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor +#endif #ifdef USE_IR_REMOTE #undef USE_IR_REMOTE // Disable IR driver #endif +#ifdef USE_ARILUX_RF +#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller +#endif #ifdef DEBUG_THEO #undef DEBUG_THEO // Disable debug code #endif diff --git a/sonoff/support.ino b/sonoff/support.ino index d3a597d48..d34cbefe6 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -993,6 +993,7 @@ uint32_t standard_time = 0; uint32_t ntp_time = 0; uint32_t midnight = 1451602800; uint8_t midnight_now = 0; +uint8_t ntp_sync_minute = 0; String GetBuildDateAndTime() { @@ -1047,6 +1048,22 @@ String GetUtcDateAndTime() return String(dt); } +String GetUptime() +{ + char dt[16]; + + TIME_T ut; + BreakTime(uptime, ut); + + // "P128DT14H35M44S" - ISO8601:2004 - https://en.wikipedia.org/wiki/ISO_8601 Durations +// snprintf_P(dt, sizeof(dt), PSTR("P%dDT%02dH%02dM%02dS"), ut.days, ut.hour, ut.minute, ut.second); + + // "128 14:35:44" - OpenVMS + // "128T14:35:44" - Tasmota + snprintf_P(dt, sizeof(dt), PSTR("%d" D_DATE_TIME_SEPARATOR "%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), ut.days, ut.hour, ut.minute, ut.second); + return String(dt); +} + void BreakTime(uint32_t time_input, TIME_T &tm) { // break the given time_input into time components @@ -1066,6 +1083,7 @@ void BreakTime(uint32_t time_input, TIME_T &tm) time /= 60; // now it is hours tm.hour = time % 24; time /= 24; // now it is days + tm.days = time; tm.day_of_week = ((time + 4) % 7) + 1; // Sunday is day 1 year = 0; @@ -1201,22 +1219,13 @@ boolean MidnightNow() void RtcSecond() { - byte ntpsync; uint32_t stdoffset; uint32_t dstoffset; TIME_T tmpTime; - ntpsync = 0; - if (RtcTime.year < 2016) { - if (WL_CONNECTED == WiFi.status()) { - ntpsync = 1; // Initial NTP sync - } - } else { - if ((1 == RtcTime.minute) && (1 == RtcTime.second)) { - ntpsync = 1; // Hourly NTP sync at xx:01:01 - } - } - if (ntpsync) { + if ((ntp_sync_minute > 59) && (3 == RtcTime.minute)) ntp_sync_minute = 1; // If sync prepare for a new cycle + uint8_t offset = (uptime < 30) ? RtcTime.second : (((ESP.getChipId() & 0xF) * 3) + 3) ; // First try ASAP to sync. If fails try once every 60 seconds based on chip id + if ((WL_CONNECTED == WiFi.status()) && (offset == RtcTime.second) && ((RtcTime.year < 2016) || (ntp_sync_minute == RtcTime.minute))) { ntp_time = sntp_get_current_timestamp(); if (ntp_time) { utc_time = ntp_time; @@ -1230,6 +1239,9 @@ void RtcSecond() AddLog(LOG_LEVEL_DEBUG); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_STD_TIME ") %s"), GetTime(3).c_str()); AddLog(LOG_LEVEL_DEBUG); + ntp_sync_minute = 60; // Sync so block further requests + } else { + ntp_sync_minute++; // Try again in next minute } } utc_time++; diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 1cf1d788b..fde332a2c 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -169,11 +169,10 @@ #define PRESSURE_RESOLUTION 1 // [PressRes] Maximum number of decimals (0 - 3) showing sensor Pressure #define ENERGY_RESOLUTION 3 // [EnergyRes] Maximum number of decimals (0 - 5) showing energy usage in kWh -// -- Sensor code selection ----------------------- +// -- Internal Analog input ----------------------- #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices -#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) - +// -- One wire sensors ---------------------------- // WARNING: Select none for default one DS18B20 sensor or enable one of the following two options for multiple sensors //#define USE_DS18x20 // Optional for more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code) //#define USE_DS18x20_LEGACY // Optional for more than one DS18x20 sensors with dynamic scan using library OneWire (+1k5 code) @@ -185,39 +184,24 @@ #define USE_SHT3X // Add I2C code for SHT3x sensor (+0k6 code) #define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code) #define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code) - #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code) +// #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code) #define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code) // #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code) // #define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Adafruit TSL2561 Arduino (+1k2 code) // #define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (no library needed) (+0k7 code) // #define USE_ADS1115_I2CDEV // Add I2C code for ADS1115 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code) // #define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code) -// #define USE_DISPLAY // Add I2C Display Support for LCD, Oled and up to eigth Matrices (+19k code) - #define MTX_ADDRESS1 0x71 // [DisplayAddress[1]] I2C address of first 8x8 matrix module - #define MTX_ADDRESS2 0x74 // [DisplayAddress[2]] I2C address of second 8x8 matrix module - #define MTX_ADDRESS3 0x75 // [DisplayAddress[3]] I2C address of third 8x8 matrix module - #define MTX_ADDRESS4 0x72 // [DisplayAddress[4]] I2C address of fourth 8x8 matrix module - #define MTX_ADDRESS5 0x73 // [DisplayAddress[5]] I2C address of fifth 8x8 matrix module - #define MTX_ADDRESS6 0x76 // [DisplayAddress[6]] I2C address of sixth 8x8 matrix module - #define MTX_ADDRESS7 0x00 // [DisplayAddress[7]] I2C address of seventh 8x8 matrix module - #define MTX_ADDRESS8 0x00 // [DisplayAddress[8]] I2C address of eigth 8x8 matrix module #endif // USE_I2C -//#define USE_SPI // SPI using library TasmotaTFT -#ifdef USE_SPI - #ifndef USE_DISPLAY - #define USE_DISPLAY // Add SPI Display support for 320x240 and 480x320 TFT - #endif -#endif // USE_SPI - -// -- Carbon dioxide (CO2) sensors ---------------- +// -- Serial sensors ------------------------------ #define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code) #define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code) #define CO2_LOW 800 // Below this CO2 value show green light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1) #define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1) - #define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code) +#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) +// -- Low level interface devices ----------------- #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram) // #define USE_IR_HVAC // Support for HVAC system using IR (+2k code) #define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram) @@ -226,7 +210,7 @@ #define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB, 2 - RGBW, 3 - GRBW) // #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow -#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code) +#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code, 252 iram (non 2.3.0)) /*********************************************************************************************\ * Compile a minimal version if upgrade memory gets tight ONLY TO BE USED FOR UPGRADE STEP 1! diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index 40861f557..9af2d74be 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -1328,6 +1328,9 @@ void HandleUploadLoop() #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION +#ifdef USE_ARILUX_RF + AriluxRfDisable(); // Prevent restart exception on Arilux Interrupt routine +#endif // USE_ARILUX_RF if (Settings.flag.mqtt_enabled) { MqttClient.disconnect(); } @@ -1593,7 +1596,8 @@ void HandleInformation() func += F(D_PROGRAM_VERSION "}2"); func += my_version; func += F("}1" D_BUILD_DATE_AND_TIME "}2"); func += GetBuildDateAndTime(); func += F("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_ESP8266_RELEASE "/"); func += String(ESP.getSdkVersion()); - func += F("}1" D_UPTIME "}2"); func += String(uptime); func += F(" Hours"); +// func += F("}1" D_UPTIME "}2"); func += String(uptime); func += F(" Seconds"); + func += F("}1" D_UPTIME "}2"); func += GetUptime(); snprintf_P(stopic, sizeof(stopic), PSTR(" at %X"), GetSettingsAddress()); func += F("}1" D_FLASH_WRITE_COUNT "}2"); func += String(Settings.save_flag); func += stopic; func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount); diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_01_light.ino index a4d242985..432788878 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_01_light.ino @@ -108,7 +108,7 @@ uint16_t light_wakeup_counter = 0; uint8_t light_fixed_color_index = 1; -unsigned long strip_timer_counter = 0; // Bars and Gradient +unsigned long strip_timer_counter = 0; // Bars and Gradient #ifdef USE_ARILUX_RF /*********************************************************************************************\ @@ -133,9 +133,12 @@ unsigned int arilux_rf_repeat_count = 0; uint8_t arilux_rf_toggle = 0; + +#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 #ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves RF misses -//void AriluxRfInterrupt() ICACHE_RAM_ATTR; // As iram is tight and it works this way too +void AriluxRfInterrupt() ICACHE_RAM_ATTR; // As iram is tight and it works this way too #endif // USE_WS2812_DMA +#endif // ARDUINO_ESP8266_RELEASE_2_3_0 void AriluxRfInterrupt() { @@ -366,13 +369,9 @@ void LightInit() } } if (pin[GPIO_ARIRFRCV] < 99) { -#ifdef USE_ARILUX_RF - AriluxRfInit(); -#else if (pin[GPIO_LED2] < 99) { digitalWrite(pin[GPIO_LED2], bitRead(led_inverted, 1)); // Turn off RF } -#endif // USE_ARILUX_RF } } #ifdef USE_WS2812 // ************************************************************************ @@ -1225,11 +1224,14 @@ boolean Xdrv01(byte function) case FUNC_EVERY_50_MSECOND: LightAnimate(); #ifdef USE_ARILUX_RF - if (pin[GPIO_ARIRFRCV] < 99) { - AriluxRfHandler(); - } + if (pin[GPIO_ARIRFRCV] < 99) AriluxRfHandler(); #endif // USE_ARILUX_RF break; +#ifdef USE_ARILUX_RF + case FUNC_EVERY_SECOND: + if (10 == uptime) AriluxRfInit(); // Needs rest before enabling RF interrupts + break; +#endif // USE_ARILUX_RF case FUNC_COMMAND: result = LightCommand(); break;