From 233a07ce5af6e05763754ae2eadccdc8b1b8a2fd Mon Sep 17 00:00:00 2001 From: Jaro Date: Sun, 7 Jun 2020 12:34:07 +0200 Subject: [PATCH] - drobne zmeny v timezone - prevod do ascii v pocasi - scroller print lines - main, prerobenie do TimeZone vyhodenie DateTime --- src/Ascifii.h | 42 ++++++ src/Scroller.cpp | 8 ++ src/Scroller.h | 1 + src/TimeZone.cpp | 4 + src/TimeZone.h | 28 ++++ src/main.cpp | 357 +++++++++++++++++++++++------------------------ 6 files changed, 259 insertions(+), 181 deletions(-) create mode 100644 src/Ascifii.h diff --git a/src/Ascifii.h b/src/Ascifii.h new file mode 100644 index 0000000..fbb172f --- /dev/null +++ b/src/Ascifii.h @@ -0,0 +1,42 @@ +#ifndef ASCIFII_H +#define ASCIFII_H + +#include "Arduino.h" + +const char *conversion[] = { + "á","ä","č","ď","é","í","ĺ","ľ","ň","ó","ô","ŕ","ř","š","ť","ú","ý","ž", + "Á","Ä","Č","Ď","É","Í","Ĺ","Ľ","Ň","Ó","Ô","Ŕ","Ř","Š","Ť","Ú","Ý","Ž" +}; + +const char *conversion2[] = { + "a","a","c","d","e","i","l","l","n","o","o","r","r","s","t","u","y","z", + "A","A","C","D","E","I","L","L","N","O","O","R","R","S","T","U","Y","Z" +}; + +class Ascifii +{ + public: + static String ToAscii(String s); +}; + + +String Ascifii::ToAscii(String s) +{ + const char *c = s.c_str(); + String rs; + + for (int j=0;j < strlen(c); j++) { + if (c[j] > 128) { + for (int i=0;i < sizeof(conversion)/sizeof(conversion[0]); i++) { + if (strncmp(c+j,conversion[i],strlen(conversion[i])) == 0) { + rs += String(conversion2[i]); + }; + } + } else { + rs += String(c[j]); + } + } + + return rs; +} +#endif \ No newline at end of file diff --git a/src/Scroller.cpp b/src/Scroller.cpp index e6a2453..3359bd6 100644 --- a/src/Scroller.cpp +++ b/src/Scroller.cpp @@ -81,6 +81,14 @@ int Scroller::Scroll(int tick) } } +void Scroller::PrintSerialLines() +{ + for (int i=0; i < _nlines; i++) + { + Serial.println(_Lines[i]); + } +} + bool Scroller::TurnOn() { _off = false; diff --git a/src/Scroller.h b/src/Scroller.h index b89211a..da31a38 100644 --- a/src/Scroller.h +++ b/src/Scroller.h @@ -37,6 +37,7 @@ public: int GetNumberOfLines(); int Scroll(int tick); int TimesScrolled(); + void PrintSerialLines(); void TurnOff(); void loop(int tick); ~Scroller(); diff --git a/src/TimeZone.cpp b/src/TimeZone.cpp index d3b04ad..d04870e 100644 --- a/src/TimeZone.cpp +++ b/src/TimeZone.cpp @@ -166,6 +166,10 @@ char* TimeZone::formattedTime(const char *format) { return timeString; } +String TimeZone::toString() { + return String(formattedTime(TimeZone::ISO8601)); +} + void TimeZone::beginDST() { dstTime = calcDateDST(dstStart, current->tm_year + 1900); utcDST = dstTime - (dstEnd.tzOffset * SECS_PER_MINUTES); diff --git a/src/TimeZone.h b/src/TimeZone.h index aab1ce0..2b4e80d 100644 --- a/src/TimeZone.h +++ b/src/TimeZone.h @@ -21,6 +21,7 @@ enum month_t {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; #endif class TimeZone { + constexpr static const char* ISO8601 = "%FT%T"; public: struct ruleDST { @@ -32,6 +33,32 @@ class TimeZone { int tzOffset; // offset from UTC in minutes }; + TimeZone& operator-=(const time_t timeDeltaSecs) { + setUTCTime(utcTime - timeDeltaSecs); + return *this; + } + + TimeZone& operator+=(const time_t timeDeltaSecs) { + setUTCTime(utcTime + timeDeltaSecs); + return *this; + } + + friend bool operator<(const TimeZone& lhs, const TimeZone& rhs) { + return lhs.utcTime < rhs.utcTime; + } + + friend bool operator>(const TimeZone& lhs, const TimeZone& rhs) { + return lhs.utcTime > rhs.utcTime; + } + + friend bool operator<=(const TimeZone& lhs, const TimeZone& rhs) { + return !(lhs.utcTime > rhs.utcTime); + } + + friend bool operator>=(const TimeZone& lhs, const TimeZone& rhs) { + return !(lhs.utcTime < rhs.utcTime); + } + /** * @brief set the rule for DST (daylight saving time) * start date of DST @@ -180,6 +207,7 @@ class TimeZone { time_t getUTCTime(); void begin(); char* formattedTime(const char *format); + String toString(); private: time_t utcCurrent = 0; diff --git a/src/main.cpp b/src/main.cpp index 2f17aec..38eb49b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,12 +12,15 @@ #include #include #include -#include +#include "StringSplitter.h" #include "ESP32TimerInterrupt.h" + #include "Scroller.h" #include "calendar.h" #include "TimeZone.h" +#include "Ascifii.h" + #ifndef PSTR #define PSTR // Make Arduino Due happy #endif @@ -79,7 +82,8 @@ struct timer_def { int ntimers,nextTimer = -1; int nts; -DateTimeClass nextAlarmDateTime; +TimeZone DateTime; +TimeZone nextAlarmDateTime; #define MAX_TIMERS 10 timer_def Timers[MAX_TIMERS]; @@ -106,7 +110,7 @@ void IRAM_ATTR TimerCheckTime0(void) DateTime += delta; - if (nextAlarmDateTime <= DateTime && nextTimer != -1) { + if (nextAlarmDateTime.epoch() <= DateTime.epoch() && nextTimer != -1) { showText = true; scroller.TurnOn(); } @@ -124,22 +128,6 @@ void IRAM_ATTR TimerUpdateNTP2(void) updateNtpTime = true; } -String getValue(String data, char separator, int index) -{ - int found = 0; - int strIndex[] = { 0, -1 }; - int maxIndex = data.length() - 1; - - for (int i = 0; i <= maxIndex && found <= index; i++) { - if (data.charAt(i) == separator || i == maxIndex) { - found++; - strIndex[0] = strIndex[1] + 1; - strIndex[1] = (i == maxIndex) ? i+1 : i; - } - } - return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; -} - String get_name_of_day(int m, int d) { for (int i = 0; i < sizeof(cal_names) / sizeof(cal_names[0]); i++) @@ -170,7 +158,7 @@ String get_weather_line() w = obj["weather"][0]["main"].as(); desc = obj["weather"][0]["description"].as(); temp -= 273.15; - return String(temp) + String("C ") + desc; + return String(temp) + String("C ") + Ascifii::ToAscii(desc); } } @@ -189,12 +177,164 @@ String get_date_line() String get_names_line() { - int d = DateTime.getParts().getMonthDay(); - int m = DateTime.getParts().getMonth(); + int d = DateTime.month(); + int m = DateTime.day(); m++; return get_name_of_day(m, d); } +void calculate_timers() +{ + timer_def *t; + int timer = -1; + struct tm tm; + time_t alarm; + TimeZone TZ,NextAlarm; + + Serial.println("---CALC TIMERS---"); + TZ = DateTime; + + for (int i=0; im; + tm.tm_hour = t->h; + + if (t->d !=0) { + tm.tm_mday = t->d; + tm.tm_mon = t->mh - 1; + tm.tm_year = t->y - 1900; + } else { + tm.tm_mday = 0; + tm.tm_mon = 0; + tm.tm_year = 0; + } + + if (t->d == 0) { + if (t->when == WORK_DAYS) { + int offset=24*3600; + int wday; + + tm.tm_mday = DateTime.day(); + tm.tm_mon = DateTime.month() - 1; + tm.tm_year = DateTime.year() - 1900; + wday = DateTime.weekDay(); + + if (wday == 0) offset = 3600*24; + if (wday == 6) offset = 2*3600*24; + + alarm = mktime(&tm); + TZ.setLocalTime(alarm); + + if (TZ.epoch() < DateTime.epoch() && wday == 5 ) offset = 3*3600*24; + if (TZ.epoch() > DateTime.epoch() && (wday >=1 && wday <=5)) offset=0; + + TZ += offset; + + } else if (t->when == WEEKENDS) { + int offset=24*3600; + int wday; + + tm.tm_mday = DateTime.day(); + tm.tm_mon = DateTime.month() - 1; + tm.tm_year = DateTime.year() - 1900; + wday = DateTime.weekDay(); + + if (wday >= 1 && wday <= 5) offset = (7-wday) *3600*24; + + alarm = mktime(&tm); + TZ.setLocalTime(alarm); + + if (TZ.epoch() > DateTime.epoch() && (wday == 6 || wday == 0 )) offset = 0; + + TZ += offset; + + } else if (t->when == ONCE ) { + alarm = mktime(&tm); + TZ.setLocalTime(alarm); + } + + if (TZ.epoch() > DateTime.epoch() && (TZ.epoch() < NextAlarm.epoch() || timer == -1)) { + Serial.println("TZ:" + TZ.toString()); + timer = i; + NextAlarm = TZ; + } + } + + } + + if (timer != -1) { + nextTimer = timer; + nextAlarmDateTime = NextAlarm; + Serial.println(DateTime.toString()); + Serial.println(nextAlarmDateTime.toString()); + } +} + +void read_config() +{ + File file = SPIFFS.open("/settings.json", "r"); + if (!file) + { + Serial.println("Failed to open settings file for reading"); + return; + } + + Serial.println("====File Content SETTINGS===="); + String s; + while (file.available()) + { + s += (char)file.read(); + } + Serial.println(s); + + file.close(); + + ntimers = 0; + settings = s; + Serial.println("SETTINGS: " + settings); + + deserializeJson(doc, settings); + JsonObject obj = doc.as(); + for (int i=0;i < obj["data"].size(); i++) { + int t = obj["data"][i]["kedy"].as(); + String c = obj["data"][i]["cas"].as(); + String datum = obj["data"][i]["datum"].as(); + + StringSplitter *splitter = new StringSplitter(c, ':', 2); + + int h = splitter->getItemAtIndex(0).toInt(); + int m = splitter->getItemAtIndex(1).toInt(); + int d = 0; + int mh = 0; + int y = 0; + + Serial.println(t); + Serial.println(c); + Serial.println(datum); + + if (datum != NULL) { + StringSplitter *splitter = new StringSplitter(datum, '.', 3); + + d = splitter->getItemAtIndex(0).toInt(); + mh = splitter->getItemAtIndex(1).toInt(); + y = splitter->getItemAtIndex(2).toInt(); + } + + Timers[ntimers].when = t; + Timers[ntimers].h = h; + Timers[ntimers].m = m; + Timers[ntimers].d = d; + Timers[ntimers].mh = mh; + Timers[ntimers].y = y; + + ntimers++; + } +} + + void setup_matrix() { matrix = new Adafruit_NeoMatrix(32, 8, PIN, @@ -239,166 +379,17 @@ void handleSave() { file.close(); server.send(200, "text/plain", ""); - + read_config(); + calculate_timers(); } -void read_config() -{ - File file = SPIFFS.open("/settings.json", "r"); - if (!file) - { - Serial.println("Failed to open settings file for reading"); - return; - } - - Serial.println("====File Content SETTINGS===="); - String s; - while (file.available()) - { - s += (char)file.read(); - } - Serial.println(s); - - file.close(); - - ntimers = 0; - settings = s; - Serial.println("SETTINGS: " + settings); - - deserializeJson(doc, settings); - JsonObject obj = doc.as(); - for (int i=0;i < obj["data"].size(); i++) { - int t = obj["data"][i]["kedy"].as(); - String c = obj["data"][i]["cas"].as(); - String datum = obj["data"][i]["datum"].as(); - - int h = getValue(c,':',0).toInt(); - int m = getValue(c,':',1).toInt(); - int d = 0; - int mh = 0; - int y = 0; - - Serial.println(t); - Serial.println(c); - Serial.println(datum); - - if (datum != NULL) { - d = getValue(datum,'.',0).toInt(); - mh = getValue(datum,'.',1).toInt(); - y = getValue(datum,'.',2).toInt(); - } - - Timers[ntimers].when = t; - Timers[ntimers].h = h; - Timers[ntimers].m = m; - Timers[ntimers].d = d; - Timers[ntimers].mh = mh; - Timers[ntimers].y = y; - - ntimers++; - } - Serial.println("N timers:" + ntimers); -} - -void calculate_timers() -{ - timer_def *t; - int timer = -1; - struct tm tm; - DateTimeClass AlarmTime,NextAlarm; - time_t alarm; - TimeZone TZ; - - Serial.println("---CALC TIMERS---"); - TZ.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) - TZ.ruleSTD("CET", Last, Sun, Oct, 3, 60); // last sunday in october 3:00, timezone +60min (+1 GMT) - - for (int i=0; im; - tm.tm_hour = t->h; - - if (t->d !=0) { - tm.tm_mday = t->d; - tm.tm_mon = t->mh - 1; - tm.tm_year = t->y - 1900; - } else { - tm.tm_mday = 0; - tm.tm_mon = 0; - tm.tm_year = 0; - } - - if (t->d == 0) { - if (t->when == WORK_DAYS) { - int offset=24*3600; - int wday; - - tm.tm_mday = DateTime.getParts().getMonthDay(); - tm.tm_mon = DateTime.getParts().getMonth(); - tm.tm_year = DateTime.getParts().getYear() - 1900; - wday = DateTime.getParts().getWeekDay(); - - if (wday == 0) offset = 3600*24; - if (wday == 6) offset = 2*3600*24; - - alarm = mktime(&tm); - TZ.setLocalTime(alarm); - - AlarmTime.setTime(TZ.getUTCTime()); - - if (AlarmTime > DateTime && wday == 5 ) offset = 3*3600*24; - - TZ.setLocalTime(alarm + offset); - AlarmTime.setTime(TZ.getUTCTime()); - - } else if (t->when == WEEKENDS) { - int offset=24*3600; - int wday; - - tm.tm_mday = DateTime.getParts().getMonthDay(); - tm.tm_mon = DateTime.getParts().getMonth(); - tm.tm_year = DateTime.getParts().getYear() - 1900; - wday = DateTime.getParts().getWeekDay(); - - if (wday >= 1 && wday <= 5) offset = (7-wday) *3600*24; - - alarm = mktime(&tm); - TZ.setLocalTime(alarm); - AlarmTime.setTime(TZ.getUTCTime()); - - if (AlarmTime > DateTime && wday == 5 ) offset = 3*3600*24; - - TZ.setLocalTime(alarm + offset); - AlarmTime.setTime(TZ.getUTCTime()); - - } else if (t->when == ONCE ) { - alarm = mktime(&tm); - TZ.setLocalTime(alarm); - AlarmTime.setTime(TZ.getUTCTime()); - } - - if (AlarmTime > DateTime && (AlarmTime < NextAlarm || timer == -1)) { - timer = i; - NextAlarm = AlarmTime; - } - } - - } - - if (timer != -1) { - nextTimer = timer; - nextAlarmDateTime = NextAlarm; - Serial.println(DateTime.toString()); - Serial.println(nextAlarmDateTime.toString()); - } -} void setup() { Serial.begin(115200); + DateTime.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) + DateTime.ruleSTD("CET", Last, Sun, Oct, 3, 60); // last sunday in october 3:00, timezone +60min (+1 GMT) + //iotWebConf.setStatusPin(PIN); iotWebConf.init(); @@ -472,7 +463,6 @@ void handleRoot() void loop() { - unsigned long sec; unsigned long n = 0; // -- doLoop should be called as frequently as possible. @@ -482,20 +472,24 @@ void loop() if (initialized == false) { Serial.println("---INIT---"); + ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60); // last sunday in october 3:00, timezone +60min (+1 GMT) ntp.begin(); - sec = ntp.epoch(); - DateTime.setTime(sec); + unsigned long sec = ntp.epoch(); + DateTime.setUTCTime(sec); + nextAlarmDateTime = DateTime; initialized = true; } if (updateNtpTime) { Serial.println("---NTP UPDATE---"); + ntp.update(); - sec = ntp.epoch(); - DateTime.setTime(sec); + unsigned long sec = ntp.epoch(); + DateTime.setUTCTime(sec); + last_millis = millis(); calculate_timers(); updateNtpTime = false; @@ -508,6 +502,7 @@ void loop() Lines[NAMES_LINE] = get_names_line(); scroller.AddLines(Lines,LAST_LINE); + scroller.PrintSerialLines(); }