Add support for internal RTC and NTP for OBP40

This commit is contained in:
Thomas Hooge 2025-02-06 13:05:56 +01:00
parent e398c7bdce
commit 2a4c351c58
7 changed files with 76 additions and 30 deletions

View File

@ -423,19 +423,25 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
// Date and time
String fmttype = commonData.config->getString(commonData.config->dateFormat);
String timesource = commonData.config->getString(commonData.config->timeSource);
int tz = commonData.config->getInt(commonData.config->timeZone);
double tz = commonData.config->getString(commonData.config->timeZone).toDouble();
getdisplay().setTextColor(commonData.fgcolor);
getdisplay().setFont(&Ubuntu_Bold8pt7b);
getdisplay().setCursor(230, 15);
if (timesource == "RTC") {
time_t tv = mktime(&commonData.data.rtcTime) + tz * 3600;
struct tm *local_tm = localtime(&tv);
getdisplay().print(formatTime('m', local_tm->tm_hour, local_tm->tm_min, 0));
getdisplay().print(" ");
getdisplay().print(formatDate(fmttype, local_tm->tm_year + 1900, local_tm->tm_mon + 1, local_tm->tm_mday));
getdisplay().print(" ");
if (timesource == "RTC" or timesource == "iRTC") {
// TODO take DST into account
if (commonData.data.rtcValid) {
time_t tv = mktime(&commonData.data.rtcTime) + (int)(tz * 3600);
struct tm *local_tm = localtime(&tv);
getdisplay().print(formatTime('m', local_tm->tm_hour, local_tm->tm_min, 0));
getdisplay().print(" ");
getdisplay().print(formatDate(fmttype, local_tm->tm_year + 1900, local_tm->tm_mon + 1, local_tm->tm_mday));
getdisplay().print(" ");
getdisplay().print(tz == 0 ? "UTC" : "LOT");
} else {
getdisplay().print("RTC invalid");
}
}
else { // timesource == "GPS"
else if (timesource == "GPS") {
// Show date and time if date present
if(date->valid == true){
String acttime = formatValue(time, commonData).svalue;
@ -445,6 +451,7 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
getdisplay().print(" ");
getdisplay().print(actdate);
getdisplay().print(" ");
getdisplay().print(tz == 0 ? "UTC" : "LOT");
}
else{
if(commonData.config->getBool(commonData.config->useSimuData) == true){
@ -455,11 +462,8 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
}
}
} // timesource == "GPS"
if (tz == 0) {
getdisplay().print("UTC");
}
else {
getdisplay().print("LOT");
getdisplay().print("No time source");
}
}
}

View File

@ -17,6 +17,8 @@
#include "ObpNmea0183.h" // Check NMEA0183 sentence for uncorrect content
#include "OBP60Extensions.h" // Lib for hardware extensions
#include "movingAvg.h" // Lib for moving average building
#include "time.h" // For getting NTP time
#include <ESP32Time.h> // Internal ESP32 RTC clock
// Timer for hardware functions
Ticker Timer1(blinkingFlashLED, 500); // Start Timer1 for flash LED all 500ms
@ -150,6 +152,7 @@ void sensorTask(void *param){
// ds1388.adjust(DateTime(__DATE__, __TIME__)); // Set date and time from PC file time
}
RTC_ready = true;
sensors.rtcValid = true;
}
}
@ -366,6 +369,28 @@ void sensorTask(void *param){
GwApi::BoatValue *hdop=new GwApi::BoatValue(GwBoatData::_HDOP);
GwApi::BoatValue *valueList[]={gpsdays, gpsseconds, hdop};
// Internal RTC with NTP init
ESP32Time rtc(0);
if (api->getConfig()->getString(api->getConfig()->timeSource) == "iRTC") {
GwApi::Status status;
api->getStatus(status);
if (status.wifiClientConnected) {
const char *ntpServer = api->getConfig()->getCString(api->getConfig()->timeServer);
api->getLogger()->logDebug(GwLog::LOG,"Fetching date and time from NTP server '%s'.", ntpServer);
configTime(0, 0, ntpServer); // get time in UTC
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
api->getLogger()->logDebug(GwLog::LOG,"NTP time: %04d-%02d-%02d %02d:%02d:%02d UTC", timeinfo.tm_year+1900, timeinfo.tm_mon+1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
rtc.setTimeStruct(timeinfo);
sensors.rtcValid = true;
} else {
api->getLogger()->logDebug(GwLog::LOG,"NTP time fetch failed!");
}
} else {
api->getLogger()->logDebug(GwLog::LOG,"Wifi client not connected, NTP not available.");
}
}
// Sensor task loop runs with 100ms
//####################################################################################
@ -464,6 +489,9 @@ void sensorTask(void *param){
api->sendN2kMessage(N2kMsg);
// }
}
} else if (sensors.rtcValid) {
// use internal rtc feature
sensors.rtcTime = rtc.getTimeStruct();
}
}

View File

@ -119,7 +119,7 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
if(valid1 == true){
svalue1old = svalue1; // Save old value
svalue1old = svalue1; // Save old value
unit1old = unit1; // Save old unit
}
@ -132,7 +132,7 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
if(valid2 == true){
svalue2old = svalue2; // Save old value
svalue2old = svalue2; // Save old value
unit2old = unit2; // Save old unit
}
@ -145,7 +145,7 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
if(valid3 == true){
svalue3old = svalue3; // Save old value
svalue3old = svalue3; // Save old value
unit3old = unit3; // Save old unit
}
@ -177,7 +177,7 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
if (source == 'G') {
// GPS value
getdisplay().print(svalue2);
} else {
} else if (commonData->data.rtcValid) {
// RTC value
if (tz == 'L') {
getdisplay().print(formatDate(dateformat, local_tm->tm_year + 1900, local_tm->tm_mon + 1, local_tm->tm_mday));
@ -185,6 +185,8 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
else {
getdisplay().print(formatDate(dateformat, commonData->data.rtcTime.tm_year + 1900, commonData->data.rtcTime.tm_mon + 1, commonData->data.rtcTime.tm_mday));
}
} else {
getdisplay().print("---");
}
} else {
getdisplay().print(svalue2old);
@ -203,13 +205,15 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
if (source == 'G') {
getdisplay().print(svalue1); // Value
}
else {
else if (commonData->data.rtcValid) {
if (tz == 'L') {
getdisplay().print(formatTime('s', local_tm->tm_hour, local_tm->tm_min, local_tm->tm_sec));
}
else {
getdisplay().print(formatTime('s', commonData->data.rtcTime.tm_hour, commonData->data.rtcTime.tm_min, commonData->data.rtcTime.tm_sec));
}
} else {
getdisplay().print("---");
}
}
else {
@ -329,14 +333,10 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
getdisplay().setFont(&Ubuntu_Bold12pt7b);
getdisplay().setCursor(175, 110);
if(holdvalues == false){
if (tz == 'L') {
getdisplay().print(unit2); // Unit
} else {
getdisplay().print("UTC");
}
getdisplay().print(tz == 'L' ? "LOT" : "UTC");
}
else{
getdisplay().print(unit2old); // Unit
getdisplay().print(unit2old); // date unit
}
getdisplay().setFont(&Ubuntu_Bold8pt7b);
@ -378,7 +378,7 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
// Draw hour pointer
float startwidth = 8; // Start width of pointer
if(valid1 == true || holdvalues == true || simulation == true){
if(valid1 == true || commonData->data.rtcValid || holdvalues == true || simulation == true){
float sinx=sin(hour * 30.0 * pi / 180); // Hour
float cosx=cos(hour * 30.0 * pi / 180);
// Normal pointer
@ -404,7 +404,7 @@ double timezone = 0; // there are timezones with non int offsets, e.g. 5.5 or 5.
// Draw minute pointer
startwidth = 8; // Start width of pointer
if(valid1 == true || holdvalues == true || simulation == true){
if(valid1 == true || commonData->data.rtcValid || holdvalues == true || simulation == true){
float sinx=sin(minute * 6.0 * pi / 180); // Minute
float cosx=cos(minute * 6.0 * pi / 180);
// Normal pointer

View File

@ -46,6 +46,7 @@ typedef struct{
double rotationAngle = 0; // Rotation angle in radiant
bool validRotAngle = false; // Valid flag magnet present for rotation sensor
struct tm rtcTime; // UTC time from internal RTC
bool rtcValid = false;
int sunsetHour = 0;
int sunsetMinute = 0;
int sunriseHour = 0;

View File

@ -697,8 +697,8 @@
"default": "GPS",
"description": "Data source for date and time display in status line [RTC|GPS]",
"list": [
{"l":"Internal real time clock (RTC)","v":"RTC"},
{"l":"External time via bus (GPS)","v":"GPS"}
{"l":"Real time clock (RTC)","v":"RTC"},
{"l":"Time via bus (GPS)","v":"GPS"}
],
"category": "OBP60 Display",
"capabilities": {

View File

@ -8,6 +8,17 @@
"description": "system name, used for the access point and for services",
"category": "system"
},
{
"name": "timeServer",
"label": "time server",
"type": "string",
"default": "pool.ntp.org",
"description": "NTP time server. Use only one hostname or IP address",
"category": "wifi client",
"capabilities": {
"obp40": "true"
}
},
{
"name": "timeZone",
"label": "Time Zone",
@ -710,9 +721,10 @@
"label": "Status Time Source",
"type": "list",
"default": "GPS",
"description": "Data source for date and time display in status line [RTC|GPS]",
"description": "Data source for date and time display in status line [RTC|iRTC|GPS]",
"list": [
{"l":"Internal real time clock (RTC)","v":"RTC"},
{"l":"Internal real time clock (iRTC)","v":"iRTC"},
{"l":"External real time clock (RTC)","v":"RTC"},
{"l":"External time via bus (GPS)","v":"GPS"}
],
"category": "OBP40 Display",

View File

@ -71,6 +71,7 @@ lib_deps =
Wire
SPI
SD
ESP32time
esphome/AsyncTCP-esphome@2.0.1
robtillaart/PCF8574@0.3.9
adafruit/Adafruit Unified Sensor @ 1.1.13