292 lines
7.9 KiB
C++
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);
|
|
} |