- drobne zmeny v timezone
- prevod do ascii v pocasi - scroller print lines - main, prerobenie do TimeZone vyhodenie DateTime
This commit is contained in:
42
src/Ascifii.h
Normal file
42
src/Ascifii.h
Normal file
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
int GetNumberOfLines();
|
||||
int Scroll(int tick);
|
||||
int TimesScrolled();
|
||||
void PrintSerialLines();
|
||||
void TurnOff();
|
||||
void loop(int tick);
|
||||
~Scroller();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
357
src/main.cpp
357
src/main.cpp
@@ -12,12 +12,15 @@
|
||||
#include <NTP.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <time.h>
|
||||
#include <DateTime.h>
|
||||
|
||||
#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<String>();
|
||||
desc = obj["weather"][0]["description"].as<String>();
|
||||
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; i<ntimers ; i++)
|
||||
{
|
||||
t = &Timers[i];
|
||||
|
||||
tm.tm_sec = 0;
|
||||
tm.tm_min = t->m;
|
||||
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<JsonObject>();
|
||||
for (int i=0;i < obj["data"].size(); i++) {
|
||||
int t = obj["data"][i]["kedy"].as<int>();
|
||||
String c = obj["data"][i]["cas"].as<String>();
|
||||
String datum = obj["data"][i]["datum"].as<String>();
|
||||
|
||||
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<JsonObject>();
|
||||
for (int i=0;i < obj["data"].size(); i++) {
|
||||
int t = obj["data"][i]["kedy"].as<int>();
|
||||
String c = obj["data"][i]["cas"].as<String>();
|
||||
String datum = obj["data"][i]["datum"].as<String>();
|
||||
|
||||
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; i<ntimers ; i++)
|
||||
{
|
||||
t = &Timers[i];
|
||||
|
||||
tm.tm_sec = 0;
|
||||
tm.tm_min = t->m;
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user