diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 5e041384e..81d9f850b 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -4,8 +4,9 @@ * Change defines USE_TX20_WIND_SENSOR and USE_RC_SWITCH in my_user_config.h to disable to lower iram usage enabling latest core compilation (#6060, #6062) * Add blend RGB leds with White leds for better whites (#5895, #5704) * Add command SetOption41 0..8 to control number of Tuya switches (#6039) - * Add AZ7798 automatic setting of clock display (#6034) * Add command SetOption42 0..255 to set overtemperature (Celsius only) threshold resulting in power off all on energy monitoring devices. Default setting is 90 (#6036) + * Add command Time to disable NTP and set UTC time as Epoch value if above 1451602800 (=20160101). Time 0 re-enables NTP (#5279) + * Add AZ7798 automatic setting of clock display (#6034) * Add Epoch and UptimeSec to JSON messages (#6068) * * 6.6.0 20190707 diff --git a/sonoff/i18n.h b/sonoff/i18n.h index e4342f5ea..b049966f6 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -262,6 +262,7 @@ #define D_CMND_RESET "Reset" #define D_JSON_RESET_AND_RESTARTING "Reset and Restarting" #define D_JSON_ONE_TO_RESET "1 to reset" +#define D_CMND_TIME "Time" #define D_CMND_TIMEZONE "Timezone" #define D_CMND_TIMESTD "TimeStd" #define D_CMND_TIMEDST "TimeDst" diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 719ff812d..04521ae00 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -80,7 +80,7 @@ enum TasmotaCommands { CMND_COUNTERDEBOUNCE, CMND_BUTTONDEBOUNCE, CMND_SWITCHDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG, CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME, CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_INTERLOCK, CMND_TEMPLATE, - CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_TIMESTD, CMND_TIMEDST, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE, CMND_LEDMASK, + CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIME, CMND_TIMEZONE, CMND_TIMESTD, CMND_TIMEDST, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE, CMND_LEDMASK, CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER, CMND_DRIVER }; const char kTasmotaCommands[] PROGMEM = D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_FANSPEED "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" @@ -90,7 +90,7 @@ const char kTasmotaCommands[] PROGMEM = D_CMND_COUNTERDEBOUNCE "|" D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TEMPLATE "|" - D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" + D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER "|" D_CMND_DRIVER; const char kSleepMode[] PROGMEM = "Dynamic|Normal"; @@ -1408,6 +1408,13 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len) Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_ONE_TO_RESET); } } + else if (CMND_TIME == command_code) { + if (data_len > 0) { + RtcSetTime(payload32); + } + ResponseBeginTime(); + ResponseJsonEnd(); + } else if (CMND_TIMEZONE == command_code) { if ((data_len > 0) && (payload >= -13)) { Settings.timezone = payload; diff --git a/sonoff/support_rtc.ino b/sonoff/support_rtc.ino index e55bff4c5..62f11bd2c 100644 --- a/sonoff/support_rtc.ino +++ b/sonoff/support_rtc.ino @@ -50,6 +50,7 @@ int32_t drift_time = 0; int32_t time_timezone = 0; uint8_t midnight_now = 0; uint8_t ntp_sync_minute = 0; +bool user_time_entry = false; // Override NTP by user setting int32_t DriftTime(void) { @@ -356,34 +357,36 @@ void RtcSecond(void) { TIME_T tmpTime; - if ((ntp_sync_minute > 59) && (RtcTime.minute > 2)) 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 (!global_state.wifi_down && (offset == RtcTime.second) && ((RtcTime.year < 2016) || (ntp_sync_minute == RtcTime.minute) || ntp_force_sync)) { - ntp_time = sntp_get_current_timestamp(); - if (ntp_time > 1451602800) { // Fix NTP bug in core 2.4.1/SDK 2.2.1 (returns Thu Jan 01 08:00:10 1970 after power on) - ntp_force_sync = false; - if (utc_time > 1451602800) { drift_time = ntp_time - utc_time; } - utc_time = ntp_time; - ntp_sync_minute = 60; // Sync so block further requests - if (restart_time == 0) { - restart_time = utc_time - uptime; // save first ntp time as restart time - } - BreakTime(utc_time, tmpTime); - RtcTime.year = tmpTime.year + 1970; - daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); - standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); + if (!user_time_entry) { + if ((ntp_sync_minute > 59) && (RtcTime.minute > 2)) 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 (!global_state.wifi_down && (offset == RtcTime.second) && ((RtcTime.year < 2016) || (ntp_sync_minute == RtcTime.minute) || ntp_force_sync)) { + ntp_time = sntp_get_current_timestamp(); + if (ntp_time > 1451602800) { // Fix NTP bug in core 2.4.1/SDK 2.2.1 (returns Thu Jan 01 08:00:10 1970 after power on) + ntp_force_sync = false; + if (utc_time > 1451602800) { drift_time = ntp_time - utc_time; } + utc_time = ntp_time; + ntp_sync_minute = 60; // Sync so block further requests + if (restart_time == 0) { + restart_time = utc_time - uptime; // save first ntp time as restart time + } + BreakTime(utc_time, tmpTime); + RtcTime.year = tmpTime.year + 1970; + daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); + standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); - // Do not use AddLog here if syslog is enabled. UDP will force exception 9 -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"), GetTime(0).c_str(), GetTime(2).c_str(), GetTime(3).c_str()); - ntp_synced_message = true; + // Do not use AddLog here if syslog is enabled. UDP will force exception 9 + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"), GetTime(0).c_str(), GetTime(2).c_str(), GetTime(3).c_str()); + ntp_synced_message = true; - if (local_time < 1451602800) { // 2016-01-01 - rules_flag.time_init = 1; + if (local_time < 1451602800) { // 2016-01-01 + rules_flag.time_init = 1; + } else { + rules_flag.time_set = 1; + } } else { - rules_flag.time_set = 1; + ntp_sync_minute++; // Try again in next minute } - } else { - ntp_sync_minute++; // Try again in next minute } } utc_time++; @@ -430,6 +433,18 @@ void RtcSecond(void) RtcTime.year += 1970; } +void RtcSetTime(uint32_t epoch) +{ + if (epoch < 1451602800) { // 2016-01-01 + user_time_entry = false; + ntp_force_sync = true; + } else { + user_time_entry = true; + utc_time = epoch -1; + } + RtcSecond(); +} + void RtcInit(void) { sntp_setservername(0, Settings.ntp_server[0]);