Version 0.9
This commit is contained in:
140
src/Scroller.cpp
Normal file
140
src/Scroller.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include "Scroller.h"
|
||||
|
||||
Scroller::Scroller(int max_loops)
|
||||
{
|
||||
_max_loops = max_loops;
|
||||
}
|
||||
|
||||
void Scroller::SetMatrix(Adafruit_NeoMatrix *matrix)
|
||||
{
|
||||
this->_matrix = matrix;
|
||||
}
|
||||
|
||||
int Scroller::GetNumberOfLines()
|
||||
{
|
||||
return this->_nlines;
|
||||
}
|
||||
|
||||
int Scroller::AddLine(String line)
|
||||
{
|
||||
this->_Lines[this->_nlines] = line;
|
||||
return _nlines++;
|
||||
}
|
||||
|
||||
int Scroller::AddLines(String* lines,int nlines)
|
||||
{
|
||||
for (int i=0; i < nlines; i++) {
|
||||
_Lines[i] = lines[i];
|
||||
}
|
||||
_nlines = nlines;
|
||||
|
||||
return _nlines;
|
||||
}
|
||||
|
||||
bool Scroller::ReplaceLine(int number,String line)
|
||||
{
|
||||
_Lines[number] = line;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scroller::DeleteLines()
|
||||
{
|
||||
_nlines = 0;
|
||||
}
|
||||
|
||||
int Scroller::Scroll(int tick)
|
||||
{
|
||||
int mx = 32;
|
||||
String line;
|
||||
|
||||
line = _Lines[_lp];
|
||||
|
||||
if (line.length() * 6 > mx)
|
||||
{
|
||||
if (_x < line.length() * 6 - mx)
|
||||
{
|
||||
_matrix->fillScreen(0);
|
||||
_matrix->setCursor(-_x, _y);
|
||||
_matrix->setTextColor(_colors[1]);
|
||||
_matrix->print(line);
|
||||
_matrix->show();
|
||||
if (_x++ == 0) {
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_lp++;
|
||||
_x = 0;
|
||||
return 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
_matrix->fillScreen(0);
|
||||
_matrix->setCursor(_x, _y);
|
||||
_matrix->setTextColor(_colors[1]);
|
||||
_matrix->print(line);
|
||||
_matrix->show();
|
||||
_lp++;
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
bool Scroller::TurnOn()
|
||||
{
|
||||
_off = false;
|
||||
_lp = 0;
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
_nscrolled = 0;
|
||||
_delayTicks = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scroller::TurnOff()
|
||||
{
|
||||
_matrix->fillScreen(0);
|
||||
_matrix->print("");
|
||||
_matrix->show();
|
||||
_off = true;
|
||||
}
|
||||
|
||||
void Scroller::SetColors(uint16_t *colors)
|
||||
{
|
||||
_colors = colors;
|
||||
}
|
||||
|
||||
void Scroller::loop(int tick)
|
||||
{
|
||||
if (_off) return;
|
||||
|
||||
int delta = tick - _tick;
|
||||
|
||||
if (_lp == _nlines) {
|
||||
_lp =0;
|
||||
_nscrolled++;
|
||||
_delayTicks = 50;
|
||||
}
|
||||
|
||||
if (TimesScrolled() == _max_loops) {
|
||||
TurnOff();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_delayTicks - delta <= 0) _delayTicks = Scroll(tick);
|
||||
else _delayTicks -= delta;
|
||||
|
||||
if (_delayTicks < 0) _delayTicks = 0;
|
||||
}
|
||||
|
||||
int Scroller::TimesScrolled()
|
||||
{
|
||||
return _nscrolled;
|
||||
}
|
||||
|
||||
Scroller::~Scroller()
|
||||
{
|
||||
}
|
||||
|
||||
44
src/Scroller.h
Normal file
44
src/Scroller.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef SCROLLER_H
|
||||
#define SCROLLER_H
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_NeoMatrix.h>
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include <Arduino.h>
|
||||
#include <ESP32Ticker.h>
|
||||
|
||||
#define SCROLLER_TICK_TIME 100 //ms
|
||||
|
||||
class Scroller
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
const static int MAX_LINES = 10;
|
||||
String _Lines[MAX_LINES];
|
||||
int _nlines = 0;
|
||||
int _lp = 0;
|
||||
int _tick=0;
|
||||
int _delayTicks = 0;
|
||||
int _nscrolled = 0;
|
||||
int _x = 0, _y = 0;
|
||||
Adafruit_NeoMatrix *_matrix;
|
||||
uint16_t *_colors;
|
||||
int _max_loops;
|
||||
bool _off = true;
|
||||
|
||||
public:
|
||||
Scroller(int max_loops);
|
||||
bool TurnOn();
|
||||
void SetColors(uint16_t *colors);
|
||||
void SetMatrix(Adafruit_NeoMatrix *matrix);
|
||||
int AddLine(String line);
|
||||
int AddLines(String* lines,int nlines);
|
||||
void DeleteLines();
|
||||
bool ReplaceLine(int number,String line);
|
||||
int GetNumberOfLines();
|
||||
int Scroll(int tick);
|
||||
int TimesScrolled();
|
||||
void TurnOff();
|
||||
void loop(int tick);
|
||||
~Scroller();
|
||||
};
|
||||
#endif
|
||||
209
src/TimeZone.cpp
Normal file
209
src/TimeZone.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#include "TimeZone.h"
|
||||
|
||||
void TimeZone::ruleDST(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset) {
|
||||
strcpy(dstStart.tzName, tzName);
|
||||
dstStart.week = week;
|
||||
dstStart.wday = wday;
|
||||
dstStart.month = month;
|
||||
dstStart.hour = hour;
|
||||
dstStart.tzOffset = tzOffset;
|
||||
}
|
||||
|
||||
const char* TimeZone::ruleDST() {
|
||||
if(dstZone) {
|
||||
return ctime(&dstTime);
|
||||
}
|
||||
else return RULE_DST_MESSAGE;
|
||||
}
|
||||
|
||||
void TimeZone::ruleSTD(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset) {
|
||||
strcpy(dstEnd.tzName, tzName);
|
||||
dstEnd.week = week;
|
||||
dstEnd.wday = wday;
|
||||
dstEnd.month = month;
|
||||
dstEnd.hour = hour;
|
||||
dstEnd.tzOffset = tzOffset;
|
||||
}
|
||||
|
||||
const char* TimeZone::ruleSTD() {
|
||||
if(dstZone) {
|
||||
return ctime(&stdTime);
|
||||
}
|
||||
else return RULE_STD_MESSAGE;
|
||||
}
|
||||
|
||||
const char* TimeZone::tzName() {
|
||||
if (dstZone) {
|
||||
if (summerTime()) return dstStart.tzName;
|
||||
else return dstEnd.tzName;
|
||||
}
|
||||
return GMT_MESSAGE; // TODO add timeZoneOffset
|
||||
}
|
||||
|
||||
void TimeZone::timeZone(int8_t tzHours, int8_t tzMinutes) {
|
||||
this->tzHours = tzHours;
|
||||
this->tzMinutes = tzMinutes;
|
||||
timezoneOffset = tzHours * 3600;
|
||||
if (tzHours < 0) {
|
||||
timezoneOffset -= tzMinutes * 60;
|
||||
}
|
||||
else {
|
||||
timezoneOffset += tzMinutes * 60;
|
||||
}
|
||||
}
|
||||
|
||||
void TimeZone::isDST(bool dstZone) {
|
||||
this->dstZone = dstZone;
|
||||
}
|
||||
|
||||
bool TimeZone::isDST() {
|
||||
return summerTime();
|
||||
}
|
||||
|
||||
time_t TimeZone::epoch() {
|
||||
currentTime();
|
||||
return utcCurrent;
|
||||
}
|
||||
|
||||
void TimeZone::currentTime() {
|
||||
utcCurrent = utcTime;
|
||||
if (dstZone) {
|
||||
if (summerTime()) {
|
||||
local = utcCurrent + dstOffset + timezoneOffset;
|
||||
current = gmtime(&local);
|
||||
}
|
||||
else {
|
||||
local = utcCurrent + timezoneOffset;
|
||||
current = gmtime(&local);
|
||||
}
|
||||
if ((current->tm_year + 1900) > yearDST) beginDST();
|
||||
}
|
||||
else {
|
||||
local = utcCurrent + timezoneOffset;
|
||||
current = gmtime(&local);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t TimeZone::year() {
|
||||
currentTime();
|
||||
return current->tm_year + 1900;
|
||||
}
|
||||
|
||||
int8_t TimeZone::month() {
|
||||
currentTime();
|
||||
return current->tm_mon + 1;
|
||||
}
|
||||
|
||||
int8_t TimeZone::day() {
|
||||
currentTime();
|
||||
return current->tm_mday;
|
||||
}
|
||||
|
||||
int8_t TimeZone::weekDay() {
|
||||
currentTime();
|
||||
return current->tm_wday;
|
||||
}
|
||||
|
||||
int8_t TimeZone::hours() {
|
||||
currentTime();
|
||||
return current->tm_hour;
|
||||
}
|
||||
|
||||
int8_t TimeZone::minutes() {
|
||||
currentTime();
|
||||
return current->tm_min;
|
||||
}
|
||||
|
||||
int8_t TimeZone::seconds() {
|
||||
currentTime();
|
||||
return current->tm_sec;
|
||||
}
|
||||
|
||||
void TimeZone::begin() {
|
||||
if (dstZone) {
|
||||
timezoneOffset = dstEnd.tzOffset * SECS_PER_MINUTES;
|
||||
dstOffset = (dstStart.tzOffset - dstEnd.tzOffset) * SECS_PER_MINUTES;
|
||||
currentTime();
|
||||
beginDST();
|
||||
}
|
||||
}
|
||||
|
||||
TimeZone& TimeZone::setUTCTime(time_t t) {
|
||||
utcTime = t;
|
||||
begin();
|
||||
return *this;
|
||||
}
|
||||
|
||||
TimeZone& TimeZone::setLocalTime(time_t t) {
|
||||
utcTime = t;
|
||||
begin();
|
||||
if (dstZone) {
|
||||
if ((t > utcDST) && (t <= utcSTD)) {
|
||||
t -= dstOffset + timezoneOffset;;
|
||||
} else {
|
||||
t -= timezoneOffset;
|
||||
}
|
||||
utcTime = t;
|
||||
currentTime();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
time_t TimeZone::getLocalTime() {
|
||||
currentTime();
|
||||
return local;
|
||||
}
|
||||
|
||||
time_t TimeZone::getUTCTime() {
|
||||
currentTime();
|
||||
return utcTime;
|
||||
}
|
||||
|
||||
char* TimeZone::formattedTime(const char *format) {
|
||||
currentTime();
|
||||
memset(timeString, 0, sizeof(timeString));
|
||||
strftime(timeString, sizeof(timeString), format, current);
|
||||
return timeString;
|
||||
}
|
||||
|
||||
void TimeZone::beginDST() {
|
||||
dstTime = calcDateDST(dstStart, current->tm_year + 1900);
|
||||
utcDST = dstTime - (dstEnd.tzOffset * SECS_PER_MINUTES);
|
||||
stdTime = calcDateDST(dstEnd, current->tm_year + 1900);
|
||||
utcSTD = stdTime - (dstStart.tzOffset * SECS_PER_MINUTES);
|
||||
yearDST = current->tm_year + 1900;
|
||||
}
|
||||
|
||||
time_t TimeZone::calcDateDST(struct ruleDST rule, int year) {
|
||||
uint8_t month = rule.month;
|
||||
uint8_t week = rule.week;
|
||||
if (week == 0) {
|
||||
if (month++ > 11) {
|
||||
month = 0;
|
||||
year++;
|
||||
}
|
||||
week = 1;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
tm.tm_hour = rule.hour;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
tm.tm_mday = 1;
|
||||
tm.tm_mon = month;
|
||||
tm.tm_year = year - 1900;
|
||||
time_t t = mktime(&tm);
|
||||
|
||||
t += ((rule.wday - tm.tm_wday + 7) % 7 + (week - 1) * 7 ) * SECS_PER_DAY;
|
||||
if (rule.week == 0) t -= 7 * SECS_PER_DAY;
|
||||
return t;
|
||||
}
|
||||
|
||||
bool TimeZone::summerTime() {
|
||||
if ((utcCurrent > utcDST) && (utcCurrent <= utcSTD)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
206
src/TimeZone.h
Normal file
206
src/TimeZone.h
Normal file
@@ -0,0 +1,206 @@
|
||||
#ifndef TIMEZONE_H
|
||||
#define TIMEZONE_H
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <time.h>
|
||||
|
||||
#ifndef NTP_H
|
||||
#define SEVENTYYEARS 2208988800UL
|
||||
#define NTP_PACKET_SIZE 48
|
||||
#define NTP_DEFAULT_LOCAL_PORT 123
|
||||
#define SECS_PER_MINUTES 60
|
||||
#define SECS_PER_DAY 86400
|
||||
|
||||
#define GMT_MESSAGE "GMT +/- offset"
|
||||
#define RULE_DST_MESSAGE "no DST rule"
|
||||
#define RULE_STD_MESSAGE "no STD rule"
|
||||
|
||||
enum week_t {Last, First, Second, Third, Fourth};
|
||||
enum dow_t {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
|
||||
enum month_t {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
|
||||
#endif
|
||||
|
||||
class TimeZone {
|
||||
public:
|
||||
|
||||
struct ruleDST {
|
||||
char tzName[6]; // five chars max
|
||||
int8_t week; // First, Second, Third, Fourth, or Last week of the month
|
||||
int8_t wday; // day of week, 0 = Sun, 2 = Mon, ... 6 = Sat
|
||||
int8_t month; // 0 = Jan, 1 = Feb, ... 11=Dec
|
||||
int8_t hour; // 0 - 23
|
||||
int tzOffset; // offset from UTC in minutes
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief set the rule for DST (daylight saving time)
|
||||
* start date of DST
|
||||
*
|
||||
* @param tzName name of the time zone
|
||||
* @param week Last, First, Second, Third, Fourth (0 - 4)
|
||||
* @param wday Sun, Mon, Tue, Wed, Thu, Fri, Sat (0 - 7)
|
||||
* @param month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec (0 -11)
|
||||
* @param hour the local hour when rule chages
|
||||
* @param tzOffset sum of summertime and timezone offset
|
||||
*/
|
||||
void ruleDST(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset);
|
||||
|
||||
/**
|
||||
* @brief get the DST time as a ctime string
|
||||
*
|
||||
* @return char* time string
|
||||
*/
|
||||
const char* ruleDST();
|
||||
|
||||
/**
|
||||
* @brief set the rule for STD (standard day)
|
||||
* end date of DST
|
||||
*
|
||||
* @param tzName name of the time zone
|
||||
* @param week Last, First, Second, Third, Fourth (0 - 4)
|
||||
* @param wday Sun, Mon, Tue, Wed, Thu, Fri, Sat (0 - 7)
|
||||
* @param month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec (0 -11)
|
||||
* @param hour the local hour when rule chages
|
||||
* @param tzOffset timezone offset
|
||||
*/
|
||||
void ruleSTD(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset);
|
||||
|
||||
/**
|
||||
* @brief get the STD time as a ctime string
|
||||
*
|
||||
* @return char* time string
|
||||
*/
|
||||
const char* ruleSTD();
|
||||
|
||||
/**
|
||||
* @brief get the name of the timezone
|
||||
*
|
||||
* @return char* name of the timezone
|
||||
*/
|
||||
const char* tzName();
|
||||
|
||||
/**
|
||||
* @brief set the timezone manually
|
||||
* this should used if there is no DST!
|
||||
*
|
||||
* @param tzHours
|
||||
* @param tzMinutes
|
||||
*/
|
||||
void timeZone(int8_t tzHours, int8_t tzMinutes = 0);
|
||||
|
||||
/**
|
||||
* @brief set daylight saving manually!
|
||||
* use in conjunction with timeZone, when there is no DST!
|
||||
*
|
||||
* @param dstZone
|
||||
*/
|
||||
void isDST(bool dstZone);
|
||||
|
||||
/**
|
||||
* @brief returns the DST state
|
||||
*
|
||||
* @return int 1 if summertime, 0 no summertime
|
||||
*/
|
||||
bool isDST();
|
||||
|
||||
/**
|
||||
* @brief get the Unix epoch timestamp
|
||||
*
|
||||
* @return time_t timestamp
|
||||
*/
|
||||
time_t epoch();
|
||||
|
||||
/**
|
||||
* @brief get the year
|
||||
*
|
||||
* @return int year
|
||||
*/
|
||||
int16_t year();
|
||||
|
||||
/**
|
||||
* @brief get the month
|
||||
*
|
||||
* @return int month, 1 = january
|
||||
*/
|
||||
int8_t month();
|
||||
|
||||
/**
|
||||
* @brief get the day of a month
|
||||
*
|
||||
* @return int day
|
||||
*/
|
||||
int8_t day();
|
||||
|
||||
/**
|
||||
* @brief get the day of a week
|
||||
*
|
||||
* @return int day of the week, 0 = sunday
|
||||
*/
|
||||
int8_t weekDay();
|
||||
|
||||
/**
|
||||
* @brief get the hour of the day
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int8_t hours();
|
||||
|
||||
/**
|
||||
* @brief get the minutes of the hour
|
||||
*
|
||||
* @return int minutes
|
||||
*/
|
||||
int8_t minutes();
|
||||
|
||||
/**
|
||||
* @brief get the seconds of a minute
|
||||
*
|
||||
* @return int seconds
|
||||
*/
|
||||
int8_t seconds();
|
||||
|
||||
/**
|
||||
* @brief returns a formatted string
|
||||
*
|
||||
* @param format for strftime
|
||||
* @return char* formated time string
|
||||
*/
|
||||
|
||||
time_t fromUTC(time_t t);
|
||||
time_t toUTC(time_t t);
|
||||
time_t toLocalTime(time_t t);
|
||||
|
||||
time_t calcDateDST(struct ruleDST rule, int year);
|
||||
bool summerTime(time_t t);
|
||||
bool summerTime();
|
||||
|
||||
TimeZone& setUTCTime(time_t t);
|
||||
TimeZone& setLocalTime(time_t t);
|
||||
time_t getLocalTime();
|
||||
time_t getUTCTime();
|
||||
void begin();
|
||||
char* formattedTime(const char *format);
|
||||
|
||||
private:
|
||||
time_t utcCurrent = 0;
|
||||
time_t local = 0;
|
||||
struct tm *current;
|
||||
uint32_t interval = 60000;
|
||||
uint32_t lastUpdate = 0;
|
||||
uint8_t tzHours = 0;
|
||||
uint8_t tzMinutes = 0;
|
||||
int32_t timezoneOffset;
|
||||
int16_t dstOffset = 0;
|
||||
bool dstZone = true;
|
||||
uint32_t utcTime = 0;
|
||||
time_t utcSTD, utcDST;
|
||||
time_t dstTime, stdTime;
|
||||
uint16_t yearDST;
|
||||
char timeString[64];
|
||||
struct ruleDST dstStart, dstEnd;
|
||||
|
||||
void currentTime();
|
||||
void beginDST();
|
||||
};
|
||||
|
||||
#endif
|
||||
219
src/main.cpp
219
src/main.cpp
@@ -1,4 +1,3 @@
|
||||
// change next line to use with another board/shield
|
||||
#include <WiFi.h>
|
||||
#include <SPI.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
@@ -9,19 +8,22 @@
|
||||
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <DateTime.h>
|
||||
#include <IotWebConf.h>
|
||||
#include <NTP.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <time.h>
|
||||
#include <DateTime.h>
|
||||
|
||||
#include "ESP32TimerInterrupt.h"
|
||||
#include "Scroller.h"
|
||||
#include "calendar.h"
|
||||
#include "TimeZone.h"
|
||||
#ifndef PSTR
|
||||
#define PSTR // Make Arduino Due happy
|
||||
#endif
|
||||
|
||||
#define COMMAND_PARAMETER_LENGTH 30
|
||||
|
||||
#define MAX_TIMES_SCROLLED 5
|
||||
#define PIN 15
|
||||
|
||||
#include <WiFiUdp.h>
|
||||
@@ -49,7 +51,7 @@ enum Lines_names
|
||||
String Lines[LAST_LINE];
|
||||
|
||||
Adafruit_NeoMatrix *matrix;
|
||||
const uint16_t colors[] = {
|
||||
uint16_t colors[] = {
|
||||
Adafruit_NeoMatrix::Color(255, 0, 0), Adafruit_NeoMatrix::Color(0, 255, 0), Adafruit_NeoMatrix::Color(0, 0, 255)};
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
@@ -74,10 +76,53 @@ struct timer_def {
|
||||
int when; int h; int m; int d; int mh; int y;
|
||||
};
|
||||
|
||||
int ntimers;
|
||||
int ntimers,nextTimer = -1;
|
||||
int nts;
|
||||
|
||||
DateTimeClass nextAlarmDateTime;
|
||||
#define MAX_TIMERS 10
|
||||
timer_def Timers[MAX_TIMERS];
|
||||
|
||||
Scroller scroller(MAX_TIMES_SCROLLED);
|
||||
|
||||
unsigned long last_millis;
|
||||
bool showText = false;
|
||||
int scrolledTicker = 0;
|
||||
bool updateNtpTime = false;
|
||||
|
||||
ESP32Timer ITimer0(0);
|
||||
ESP32Timer ITimer1(1);
|
||||
ESP32Timer ITimer2(2);
|
||||
|
||||
#define TIMER0_INTERVAL_MS 1000
|
||||
#define TIMER1_INTERVAL_MS 100
|
||||
#define TIMER2_INTERVAL_MS 60000
|
||||
|
||||
void IRAM_ATTR TimerCheckTime0(void)
|
||||
{
|
||||
unsigned long m = millis(), delta;
|
||||
|
||||
delta = (m - last_millis)/1000;
|
||||
|
||||
DateTime += delta;
|
||||
|
||||
if (nextAlarmDateTime <= DateTime && nextTimer != -1) {
|
||||
showText = true;
|
||||
scroller.TurnOn();
|
||||
}
|
||||
|
||||
last_millis = m;
|
||||
}
|
||||
|
||||
void IRAM_ATTR TimerScrollTime1(void)
|
||||
{
|
||||
scrolledTicker++;
|
||||
}
|
||||
|
||||
void IRAM_ATTR TimerUpdateNTP2(void)
|
||||
{
|
||||
updateNtpTime = true;
|
||||
}
|
||||
|
||||
String getValue(String data, char separator, int index)
|
||||
{
|
||||
@@ -212,7 +257,7 @@ void read_config()
|
||||
{
|
||||
s += (char)file.read();
|
||||
}
|
||||
Serial.print(s);
|
||||
Serial.println(s);
|
||||
|
||||
file.close();
|
||||
|
||||
@@ -258,7 +303,16 @@ void read_config()
|
||||
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];
|
||||
@@ -269,8 +323,8 @@ void calculate_timers()
|
||||
|
||||
if (t->d !=0) {
|
||||
tm.tm_mday = t->d;
|
||||
tm.tm_mon = t->mh;
|
||||
tm.tm_year = t->y;
|
||||
tm.tm_mon = t->mh - 1;
|
||||
tm.tm_year = t->y - 1900;
|
||||
} else {
|
||||
tm.tm_mday = 0;
|
||||
tm.tm_mon = 0;
|
||||
@@ -279,15 +333,67 @@ void calculate_timers()
|
||||
|
||||
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;
|
||||
|
||||
} else if (t->when == TOMOROW ) {
|
||||
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()
|
||||
@@ -304,6 +410,22 @@ void setup()
|
||||
return;
|
||||
}
|
||||
|
||||
if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerCheckTime0))
|
||||
Serial.println("Starting ITimer0 OK, millis() = " + String(millis()));
|
||||
else
|
||||
Serial.println("Can't set ITimer0. Select another freq. or timer");
|
||||
|
||||
// Interval in microsecs
|
||||
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS * 1000, TimerScrollTime1))
|
||||
Serial.println("Starting ITimer1 OK, millis() = " + String(millis()));
|
||||
else
|
||||
Serial.println("Can't set ITimer1. Select another freq. or timer");
|
||||
|
||||
if (ITimer2.attachInterruptInterval(TIMER2_INTERVAL_MS * 1000, TimerUpdateNTP2))
|
||||
Serial.println("Starting ITimer2 OK, millis() = " + String(millis()));
|
||||
else
|
||||
Serial.println("Can't set ITimer2. Select another freq. or timer");
|
||||
|
||||
|
||||
// -- Set up required URL handlers on the web server.
|
||||
server.on("/", handleRoot);
|
||||
@@ -313,42 +435,11 @@ void setup()
|
||||
|
||||
setup_matrix();
|
||||
read_config();
|
||||
|
||||
scroller.SetColors(colors);
|
||||
scroller.SetMatrix(matrix);
|
||||
}
|
||||
|
||||
void scroll_line(String line)
|
||||
{
|
||||
int x = 0, mx = 32;
|
||||
int y = 0;
|
||||
|
||||
if (line.length() * 6 > mx)
|
||||
{
|
||||
for (x = 0; x < line.length() * 6 - mx; x++)
|
||||
{
|
||||
matrix->fillScreen(0);
|
||||
matrix->setCursor(-x, y);
|
||||
matrix->setTextColor(colors[1]);
|
||||
matrix->print(line);
|
||||
matrix->show();
|
||||
if (x == 0)
|
||||
delay(300);
|
||||
else
|
||||
delay(100);
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix->fillScreen(0);
|
||||
matrix->setCursor(x, y);
|
||||
matrix->setTextColor(colors[1]);
|
||||
matrix->print(line);
|
||||
matrix->show();
|
||||
delay(3000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void handleRoot()
|
||||
{
|
||||
// -- Let IotWebConf test and handle captive portal requests.
|
||||
@@ -385,32 +476,48 @@ void loop()
|
||||
unsigned long n = 0;
|
||||
|
||||
// -- doLoop should be called as frequently as possible.
|
||||
iotWebConf.doLoop();
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
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);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
sec = ntp.epoch();
|
||||
DateTime.setTime(sec);
|
||||
|
||||
if (n++ % 25 == 0)
|
||||
Lines[WEATHER_LINE] = get_weather_line();
|
||||
if (updateNtpTime) {
|
||||
Serial.println("---NTP UPDATE---");
|
||||
ntp.update();
|
||||
sec = ntp.epoch();
|
||||
DateTime.setTime(sec);
|
||||
calculate_timers();
|
||||
updateNtpTime = false;
|
||||
|
||||
|
||||
Lines[TIME_LINE] = get_time_line();
|
||||
Lines[DATE_LINE] = get_date_line();
|
||||
Lines[NAMES_LINE] = get_names_line();
|
||||
if (n++ % 10 == 0)
|
||||
Lines[WEATHER_LINE] = get_weather_line();
|
||||
|
||||
for (int i = 0; i < LAST_LINE; i++)
|
||||
{
|
||||
Serial.println(Lines[i]);
|
||||
scroll_line(Lines[i]);
|
||||
iotWebConf.doLoop();
|
||||
Lines[TIME_LINE] = get_time_line();
|
||||
Lines[DATE_LINE] = get_date_line();
|
||||
Lines[NAMES_LINE] = get_names_line();
|
||||
|
||||
scroller.AddLines(Lines,LAST_LINE);
|
||||
|
||||
}
|
||||
|
||||
if (showText) {
|
||||
Serial.println("---SHOW TEXT----");
|
||||
scroller.loop(scrolledTicker);
|
||||
|
||||
if (scroller.TimesScrolled() > MAX_TIMES_SCROLLED) showText = false;
|
||||
}
|
||||
}
|
||||
|
||||
iotWebConf.doLoop();
|
||||
}
|
||||
Reference in New Issue
Block a user