infinityledclock/vscode/infclock/src/led_clock_time.cpp

292 lines
7.9 KiB
C++

#include "led_clock_time.hpp"
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Time
Timezone CE(CEST, CET);
void led_clock_time::init(bool debug)
{
Serial.println();
http = new HTTPClient();
timedebug = debug;
Serial.println("Try to connect to wifi first time ... maybe captive portal will b started ...");
connectWifi(); // isconnected should be true after here if not in debug mode ...
Serial.printf("Connection status : %s\n", isconnected == true?"connected":"not connected");
wasalreadyconnected = isconnected;
rtc_ready = rtc_init(); // at least timeisvalid should be true after here ...
if(timeisvalid == false)
{
if(isconnected == false)
{
//nothing to show ... keep waiting forever in the captive portal ...
captivepotal_timeout = 0;
Serial.println("RTC time is not valid and there is no connection to Wifi - will go into cpative portal mode and wait for valid config. Please connect via Wifi to 'BlueLedclock'.");
connectWifi();
}
}
}
bool led_clock_time::rtc_init()
{
bool rc = true;
Rtc = new RtcDS3231<TwoWire>(Wire);
Rtc->Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
Serial.println();
Serial.println("RTC init ...");
if (!Rtc->IsDateTimeValid())
{
if (Rtc->LastError() != 0)
{
Serial.print("RTC communications error = ");
Serial.println(Rtc->LastError());
return(false);
}
else
{
Serial.println("RTC lost confidence in the DateTime!");
if(false == rtc_settime(compiled))
{
return(false);
}
}
}
if (!Rtc->GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc->SetIsRunning(true);
}
Serial.println("Check RTC time - set to accurate time if needed and possible.");
if(false == syncTime())
{
RtcDateTime now = Rtc->GetDateTime();
if (now.TotalSeconds() < compiled.TotalSeconds())
{
rc = rtc_settime(compiled);
}
}
Rtc->Enable32kHzPin(false);
Rtc->SetSquareWavePin(DS3231SquareWavePin_ModeNone);
rc = rtc_gettime();
Serial.printf("RTC time is: %d:%d:%d . Valid time bit is set to '%s'\n", int_hour, int_minute, int_second, timeisvalid==true?"true":"false");
if(rc == false)
{
Serial.println("RTC setup finished with a failure! Time couldn't set to actual value!");
}
else
{
Serial.println("RTC setup finished with success!");
}
return(rc);
}
bool led_clock_time::rtc_settime(RtcDateTime newtime)
{
bool rc = false;
if((millis() - lastwrittentortc > WAITBEFOREWRITERTCAGAIN_MS) || (lastwrittentortc ==0))
{
lastwrittentortc = millis();
//Serial.println("Try to write time to RTC.");
Rtc->SetDateTime(newtime);
RtcDateTime gettime = Rtc->GetDateTime();
if (newtime.TotalSeconds() <= gettime.TotalSeconds())
{
rc = true;
}
else
{
Serial.printf("Current RTC read time (%d) is smaller than the provided time (%d) that was written before to RTC. This is not correct!", gettime.TotalSeconds(), newtime.TotalSeconds());
}
}
else
{
rc = true;
}
if(rc == false)
{
Serial.println("RTC set time finished with a failure! Time couldn't set to actual value!");
timeisvalid = false;
}
else
{
timeisvalid = true;
}
return(rc);
}
bool led_clock_time::gettime(uint32_t *hour, uint32_t *minute, uint32_t *second)
{
if(0 == timedebug)
{
syncTime();
rtc_gettime();
}
else
{
dbg_gettime();
}
*hour = int_hour;
*second = int_second;
*minute = int_minute;
return(timeisvalid);
}
bool led_clock_time::rtc_gettime(void)
{
bool rc = true;
RtcDateTime now = Rtc->GetDateTime();
int_second = now.Second();
int_minute = now.Minute();
int_hour = now.Hour();
if((int_hour == 0) && (int_minute == 0) && (int_second == 0) && (now.Year() == 2000))
{
rc = false;
timeisvalid = false;
Serial.printf("RTC is stucked at %02d:%02d:%02d %02d.%02d.%04d this is a failure! Time couldn't set to actual value!\n", int_hour, int_minute, int_second, now.Day(), now.Month(), now.Year());
}
return(rc);
}
void led_clock_time::dbg_gettime(void)
{
timeisvalid = 0;
timesynced = false;
int_second = int_second + 1;
if(int_second > 59)
{
int_second = 0;
int_minute++;
if(int_minute > 59)
{
int_minute = 0;
int_hour++;
if(int_hour > 11)
{
int_hour = 0;
}
}
}
}
bool led_clock_time::connectWifi()
{
if(timedebug == false)
{
if ((WiFi.status() != WL_CONNECTED))
{
isconnected = false;
Serial.printf("Looking for Wifi: captive portal is open for about %ld seconds.\n",captivepotal_timeout );
wifiManager.setDebugOutput(false);
//sets timeout until configuration portal gets turned off
wifiManager.setTimeout(captivepotal_timeout); //in seconds
captivepotal_timeout = 30;
//and goes into a blocking loop awaiting configuration
if(false == wifiManager.autoConnect("BlueLedClock")) {
Serial.println("Failed to connect to WiFi and hit timeout ... (reset clock to retry). ");
}
else
{
Serial.println("Connect to WiFi. ");
isconnected = true;
}
}
else
{
isconnected = true;
}
}
else
{
isconnected = false;
}
return isconnected;
}
bool led_clock_time::isConnectedToWifi()
{
if ((WiFi.status() != WL_CONNECTED))
{
if(wasalreadyconnected == true)
{
connectWifi();
}
else
{
isconnected = false;
}
}
else{
isconnected = true;
}
return isconnected;
}
bool led_clock_time::isTimenSynced()
{
return timesynced;
}
bool led_clock_time::syncTime()
{
TimeChangeRule *tcr; // pointer to the time change rule, use to get the TZ abbrev
int httpCode = -1;
if((timelastsync == 0) || (((millis()/1000)- timelastsync) > NTP_SYNC_CYCLE_SECS))
{
if(true == isConnectedToWifi())
{
http->begin(TIMEURL);
// start connection and send HTTP header
httpCode = http->GET();
// httpCode will be negative on error
if (httpCode == HTTP_CODE_OK) {
String epoch_str = http->getString();
epoch = epoch_str.toInt();
epoch = CE.toLocal(epoch, &tcr);
if(epoch > 0)
{
struct tm * timeinfo = localtime(&epoch);
char timestr[9] = "";
char datestr[12] = "";
sprintf(timestr, "%02d:%02d:%02d",timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
sprintf(datestr, "%s %d %d", MONTH_STR[timeinfo->tm_mon].c_str(), timeinfo->tm_mday, 1900+timeinfo->tm_year);
RtcDateTime rtctime = RtcDateTime(datestr, timestr);
if(rtc_settime(rtctime) == true)
{
timelastsync = millis()/1000;
//Serial.printf("Synced time: %s %s\n", datestr, timestr );
timesynced = true;
}
}
}
}
}
if( HTTP_CODE_OK != httpCode )
{
if(((millis()/1000)- timelastsync) > (NTP_SYNC_MAX_TRIES * NTP_SYNC_CYCLE_SECS))
timesynced = false;
}
return(timesynced);
}