From 46a0a0afba4396b26956de47d401bf2648b31a06 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 1 Nov 2018 13:00:05 +0100 Subject: [PATCH] Add minutes to commands Timezone Add minutes to commands Timezone to allow all possible world timezones --- sonoff/_changelog.ino | 3 +- sonoff/settings.h | 4 +-- sonoff/settings.ino | 11 +++++- sonoff/sonoff.ino | 36 +++++++++++++++---- sonoff/support.ino | 76 +++++++++++++++++++++++---------------- sonoff/xdrv_09_timers.ino | 2 +- sonoff/xdrv_interface.ino | 20 +---------- sonoff/xsns_interface.ino | 19 ++-------- 8 files changed, 93 insertions(+), 78 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 648b1faad..c9876ed4d 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,7 +1,8 @@ /* 6.3.0.1 20181031 * Add wifi status to Tuya (#4221) - * Add default sleep 1 to sonoff-basic to lower enrgy consumption (#4217) + * Add default sleep 1 to sonoff-basic to lower energy consumption (#4217) * Fix unintended function overload of WifiState + * Add minutes to commands Timezone to allow all possible world timezones * * 6.3.0 20181030 * Release of v6.3.0 diff --git a/sonoff/settings.h b/sonoff/settings.h index 4d1d61cd4..4af58db81 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -302,9 +302,7 @@ struct SYSCFG { uint16_t pulse_counter_type; // 5D0 uint16_t pulse_counter_debounce; // 5D2 uint8_t rf_code[17][9]; // 5D4 - - byte free_66d[1]; // 66D - + uint8_t timezone_minutes; // 66D uint16_t switch_debounce; // 66E Timer timer[MAX_TIMERS]; // 670 int latitude; // 6B0 diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 4116a1c6d..fc3bf8887 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -607,7 +607,13 @@ void SettingsDefaultSet2() SettingsDefaultSet_5_10_1(); // Display settings // Time - Settings.timezone = APP_TIMEZONE; + if (((APP_TIMEZONE > -14) && (APP_TIMEZONE < 15)) || (99 == APP_TIMEZONE)) { + Settings.timezone = APP_TIMEZONE; + Settings.timezone_minutes = 0; + } else { + Settings.timezone = APP_TIMEZONE / 60; + Settings.timezone_minutes = abs(APP_TIMEZONE % 60); + } strlcpy(Settings.ntp_server[0], NTP_SERVER1, sizeof(Settings.ntp_server[0])); strlcpy(Settings.ntp_server[1], NTP_SERVER2, sizeof(Settings.ntp_server[1])); strlcpy(Settings.ntp_server[2], NTP_SERVER3, sizeof(Settings.ntp_server[2])); @@ -836,6 +842,9 @@ void SettingsDelta() Settings.rgbwwTable[j] = 255; } } + if (Settings.version < 0x06030002) { + Settings.timezone_minutes = 0; + } Settings.version = VERSION; SettingsSave(1); diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 98af3ef9f..dd84fbc47 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1163,10 +1163,29 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) } } else if (CMND_TIMEZONE == command_code) { - if ((data_len > 0) && (((payload >= -13) && (payload <= 14)) || (99 == payload))) { + if ((data_len > 0) && (payload >= -13)) { Settings.timezone = payload; + Settings.timezone_minutes = 0; + if (payload < 15) { + p = strtok (dataBuf, ":"); + if (p) { + p = strtok (NULL, ":"); + if (p) { + Settings.timezone_minutes = strtol(p, NULL, 10); + if (Settings.timezone_minutes > 59) { Settings.timezone_minutes = 59; } + } + } + } else { + Settings.timezone = 99; + } + ntp_force_sync = 1; + } + if (99 == Settings.timezone) { + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.timezone); + } else { + snprintf_P(stemp1, sizeof(stemp1), PSTR("%+03d:%02d"), Settings.timezone, Settings.timezone_minutes); + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, stemp1); } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.timezone); } else if ((CMND_TIMESTD == command_code) || (CMND_TIMEDST == command_code)) { // TimeStd 0/1, 0/1/2/3/4, 1..12, 1..7, 0..23, +/-780 @@ -1491,12 +1510,17 @@ void PublishStatus(uint8_t payload) } if ((0 == payload) || (7 == payload)) { + if (99 == Settings.timezone) { + snprintf_P(stemp, sizeof(stemp), PSTR("%d" ), Settings.timezone); + } else { + snprintf_P(stemp, sizeof(stemp), PSTR("\"%s\"" ), GetTimeZone().c_str()); + } #if defined(USE_TIMERS) && defined(USE_SUNRISE) - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_JSON_UTC_TIME "\":\"%s\",\"" D_JSON_LOCAL_TIME "\":\"%s\",\"" D_JSON_STARTDST "\":\"%s\",\"" D_JSON_ENDDST "\":\"%s\",\"" D_CMND_TIMEZONE "\":%d,\"" D_JSON_SUNRISE "\":\"%s\",\"" D_JSON_SUNSET "\":\"%s\"}}"), - GetTime(0).c_str(), GetTime(1).c_str(), GetTime(2).c_str(), GetTime(3).c_str(), Settings.timezone, GetSun(0).c_str(), GetSun(1).c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_JSON_UTC_TIME "\":\"%s\",\"" D_JSON_LOCAL_TIME "\":\"%s\",\"" D_JSON_STARTDST "\":\"%s\",\"" D_JSON_ENDDST "\":\"%s\",\"" D_CMND_TIMEZONE "\":%s,\"" D_JSON_SUNRISE "\":\"%s\",\"" D_JSON_SUNSET "\":\"%s\"}}"), + GetTime(0).c_str(), GetTime(1).c_str(), GetTime(2).c_str(), GetTime(3).c_str(), stemp, GetSun(0).c_str(), GetSun(1).c_str()); #else - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_JSON_UTC_TIME "\":\"%s\",\"" D_JSON_LOCAL_TIME "\":\"%s\",\"" D_JSON_STARTDST "\":\"%s\",\"" D_JSON_ENDDST "\":\"%s\",\"" D_CMND_TIMEZONE "\":%d}}"), - GetTime(0).c_str(), GetTime(1).c_str(), GetTime(2).c_str(), GetTime(3).c_str(), Settings.timezone); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_JSON_UTC_TIME "\":\"%s\",\"" D_JSON_LOCAL_TIME "\":\"%s\",\"" D_JSON_STARTDST "\":\"%s\",\"" D_JSON_ENDDST "\":\"%s\",\"" D_CMND_TIMEZONE "\":%s}}"), + GetTime(0).c_str(), GetTime(1).c_str(), GetTime(2).c_str(), GetTime(3).c_str(), stemp); #endif // USE_TIMERS and USE_SUNRISE MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "7")); } diff --git a/sonoff/support.ino b/sonoff/support.ino index dcaa64274..59b9a40db 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -1624,6 +1624,7 @@ int WifiState() void WifiConnect() { + WifiSetState(0); WiFi.persistent(false); // Solve possible wifi init errors wifi_status = 0; wifi_retry_init = WIFI_RETRY_OFFSET_SEC + ((ESP.getChipId() & 0xF) * 2); @@ -1881,6 +1882,7 @@ extern "C" { #define SECS_PER_MIN ((uint32_t)(60UL)) #define SECS_PER_HOUR ((uint32_t)(3600UL)) #define SECS_PER_DAY ((uint32_t)(SECS_PER_HOUR * 24UL)) +#define MINS_PER_HOUR ((uint32_t)(60UL)) #define LEAP_YEAR(Y) (((1970+Y)>0) && !((1970+Y)%4) && (((1970+Y)%100) || !((1970+Y)%400))) Ticker TickerRtc; @@ -1895,7 +1897,7 @@ uint32_t standard_time = 0; uint32_t ntp_time = 0; uint32_t midnight = 1451602800; uint32_t restart_time = 0; -int16_t time_timezone = 0; // Timezone * 10 +int32_t time_zone = 0; uint8_t midnight_now = 0; uint8_t ntp_sync_minute = 0; @@ -1925,7 +1927,16 @@ String GetBuildDateAndTime() } int month = (strstr(kMonthNamesEnglish, smonth) -kMonthNamesEnglish) /3 +1; snprintf_P(bdt, sizeof(bdt), PSTR("%d" D_YEAR_MONTH_SEPARATOR "%02d" D_MONTH_DAY_SEPARATOR "%02d" D_DATE_TIME_SEPARATOR "%s"), year, month, day, __TIME__); - return String(bdt); + return String(bdt); // 2017-03-07T11:08:02 +} + +String GetTimeZone() +{ + char tz[7]; + + snprintf_P(tz, sizeof(tz), PSTR("%+03d:%02d"), time_zone / 60, abs(time_zone % 60)); + + return String(tz); // -03:45 } /* @@ -1970,10 +1981,27 @@ String GetDateAndTime(byte time_type) if (Settings.flag3.time_append_timezone && (DT_LOCAL == time_type)) { // if (Settings.flag3.time_append_timezone && ((DT_LOCAL == time_type) || (DT_ENERGY == time_type))) { - snprintf_P(dt, sizeof(dt), PSTR("%s%+03d:%02d"), dt, time_timezone / 10, abs((time_timezone % 10) * 6)); // if timezone = +2:30 then time_timezone = 25 + strncat(dt, GetTimeZone().c_str(), sizeof(dt)); } - return String(dt); + return String(dt); // 2017-03-07T11:08:02-07:00 +} + +String GetTime(int type) +{ + /* type 1 - Local time + * type 2 - Daylight Savings time + * type 3 - Standard time + */ + char stime[25]; // Skip newline + + uint32_t time = utc_time; + if (1 == type) time = local_time; + if (2 == type) time = daylight_saving_time; + if (3 == type) time = standard_time; + snprintf_P(stime, sizeof(stime), sntp_get_real_time(time)); + + return String(stime); // Thu Nov 01 11:41:02 2018 } String GetUptime() @@ -1993,9 +2021,9 @@ String GetUptime() // "128 14:35:44" - OpenVMS // "128T14:35:44" - Tasmota - snprintf_P(dt, sizeof(dt), PSTR("%dT%02d:%02d:%02d"), - ut.days, ut.hour, ut.minute, ut.second); - return String(dt); + snprintf_P(dt, sizeof(dt), PSTR("%dT%02d:%02d:%02d"), ut.days, ut.hour, ut.minute, ut.second); + + return String(dt); // 128T14:35:44 } uint32_t GetMinutesUptime() @@ -2143,18 +2171,6 @@ uint32_t RuleToTime(TimeRule r, int yr) return t; } -String GetTime(int type) -{ - char stime[25]; // Skip newline - - uint32_t time = utc_time; - if (1 == type) time = local_time; - if (2 == type) time = daylight_saving_time; - if (3 == type) time = standard_time; - snprintf_P(stime, sizeof(stime), sntp_get_real_time(time)); - return String(stime); -} - uint32_t LocalTime() { return local_time; @@ -2174,8 +2190,6 @@ boolean MidnightNow() void RtcSecond() { - int32_t stdoffset; - int32_t dstoffset; TIME_T tmpTime; if ((ntp_sync_minute > 59) && (RtcTime.minute > 2)) ntp_sync_minute = 1; // If sync prepare for a new cycle @@ -2208,28 +2222,30 @@ void RtcSecond() utc_time++; local_time = utc_time; if (local_time > 1451602800) { // 2016-01-01 - int32_t time_offset = Settings.timezone * SECS_PER_HOUR; + int16_t timezone_minutes = Settings.timezone_minutes; + if (Settings.timezone < 0) { timezone_minutes *= -1; } + time_zone = (Settings.timezone * SECS_PER_HOUR) + (timezone_minutes * SECS_PER_MIN); if (99 == Settings.timezone) { - dstoffset = Settings.toffset[1] * SECS_PER_MIN; - stdoffset = Settings.toffset[0] * SECS_PER_MIN; + int32_t dstoffset = Settings.toffset[1] * SECS_PER_MIN; + int32_t stdoffset = Settings.toffset[0] * SECS_PER_MIN; if (Settings.tflag[1].hemis) { // Southern hemisphere if ((utc_time >= (standard_time - dstoffset)) && (utc_time < (daylight_saving_time - stdoffset))) { - time_offset = stdoffset; // Standard Time + time_zone = stdoffset; // Standard Time } else { - time_offset = dstoffset; // Daylight Saving Time + time_zone = dstoffset; // Daylight Saving Time } } else { // Northern hemisphere if ((utc_time >= (daylight_saving_time - stdoffset)) && (utc_time < (standard_time - dstoffset))) { - time_offset = dstoffset; // Daylight Saving Time + time_zone = dstoffset; // Daylight Saving Time } else { - time_offset = stdoffset; // Standard Time + time_zone = stdoffset; // Standard Time } } } - local_time += time_offset; - time_timezone = time_offset / 360; // (SECS_PER_HOUR / 10) fails as it is defined as UL + local_time += time_zone; + time_zone /= 60; if (!Settings.energy_kWhtotal_time) { Settings.energy_kWhtotal_time = local_time; } } BreakTime(local_time, RtcTime); diff --git a/sonoff/xdrv_09_timers.ino b/sonoff/xdrv_09_timers.ino index 338a8ddc0..2941ec392 100644 --- a/sonoff/xdrv_09_timers.ino +++ b/sonoff/xdrv_09_timers.ino @@ -131,7 +131,7 @@ void DuskTillDawn(uint8_t *hour_up,uint8_t *minute_up, uint8_t *hour_down, uint8 // double Zeitzone = 0; //Weltzeit // double Zeitzone = 1; //Winterzeit // double Zeitzone = 2.0; //Sommerzeit - double Zeitzone = ((double)time_timezone) / 10; + double Zeitzone = ((double)time_zone) / 60; double Zeitgleichung = BerechneZeitgleichung(&DK, T); double Minuten = Zeitgleichung * 60.0; double Zeitdifferenz = 12.0*acos((sin(h) - sin(B)*sin(DK)) / (cos(B)*cos(DK)))/pi; diff --git a/sonoff/xdrv_interface.ino b/sonoff/xdrv_interface.ino index a6e917a83..a578343b4 100644 --- a/sonoff/xdrv_interface.ino +++ b/sonoff/xdrv_interface.ino @@ -226,22 +226,6 @@ void ShowFreeMem(const char *where) /*********************************************************************************************\ * Function call to all xdrv - * - * FUNC_PRE_INIT - * FUNC_INIT - * FUNC_LOOP - * FUNC_MQTT_SUBSCRIBE - * FUNC_MQTT_INIT - * return FUNC_MQTT_DATA - * return FUNC_COMMAND - * FUNC_SET_POWER - * FUNC_SHOW_SENSOR - * FUNC_EVERY_SECOND - * FUNC_EVERY_50_MSECOND - * FUNC_EVERY_100_MSECOND - * FUNC_EVERY_250_MSECOND - * FUNC_RULES_PROCESS - * FUNC_FREE_MEM \*********************************************************************************************/ boolean XdrvCall(byte Function) @@ -249,9 +233,7 @@ boolean XdrvCall(byte Function) boolean result = false; for (byte x = 0; x < xdrv_present; x++) { - if (!((WL_CONNECTED == WiFi.status()) && (static_cast(WiFi.localIP()) != 0))) { - delay(1); - } + if (global_state.wifi_down) { delay(1); } result = xdrv_func_ptr[x](Function); if (result) break; } diff --git a/sonoff/xsns_interface.ino b/sonoff/xsns_interface.ino index ee3d545da..8132b8c30 100644 --- a/sonoff/xsns_interface.ino +++ b/sonoff/xsns_interface.ino @@ -262,17 +262,6 @@ uint8_t xsns_index = 0; /*********************************************************************************************\ * Function call to all xsns - * - * FUNC_INIT - * FUNC_PREP_BEFORE_TELEPERIOD - * FUNC_SAVE_BEFORE_RESTART - * FUNC_JSON_APPEND - * FUNC_WEB_APPEND - * return FUNC_COMMAND - * FUNC_EVERY_50_MSECOND - * FUNC_EVERY_100_MSECOND - * FUNC_EVERY_250_MSECOND - * FUNC_EVERY_SECOND \*********************************************************************************************/ uint8_t XsnsPresent() @@ -284,9 +273,7 @@ boolean XsnsNextCall(byte Function) { xsns_index++; if (xsns_index == xsns_present) xsns_index = 0; - if (!((WL_CONNECTED == WiFi.status()) && (static_cast(WiFi.localIP()) != 0))) { - delay(1); - } + if (global_state.wifi_down) { delay(1); } return xsns_func_ptr[xsns_index](Function); } @@ -303,9 +290,7 @@ boolean XsnsCall(byte Function) #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND uint32_t profile_start_millis = millis(); #endif // PROFILE_XSNS_SENSOR_EVERY_SECOND - if (!((WL_CONNECTED == WiFi.status()) && (static_cast(WiFi.localIP()) != 0))) { - delay(1); - } + if (global_state.wifi_down) { delay(1); } result = xsns_func_ptr[x](Function); #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND