DS3231 RTC driver embedded in "local clock" (PR#1729) (#1792)

* Try NTP split update to actual source

* fix windows makefiles and timed_events

* fix typo

* Fix sprintf format

* sprintf format - next try to fix for ESP and ESP8266

* sprintf - special case for ESP8266

* Adding GUI button to set clock

* fix

* Add debug output

* fix missing HTTP output
use original obk_config.h - only renaming functions - to see filesizes

* limit functions to NTP ode CLOCK present

* try fix selftests

* Enable simple clock for all platforms, even if NTP is not enabled

* test fixing merge-conflict

* try fixing merge conflicts #1

* try fix merge conflict

* Fix typos
consolidate time display on main page
fix double comments preventing several documentation details ($mday, $month ...) on docs/constants.md
enabling more time stuff for W800 for local testing.

* Fix setDST argument passing

* only test DST if clock is running

* Fix setting epoch time - use atol(<string arg>) instead of Tokenizer_GetArgInteger(0) for epoch
Change user_main.c to use xticks as uptime for g_secondsElapsed

* Fix g_secondsElapesd for Windows - no xTicks there so stick to old way with g_secondsElapesd++ here ...

* Fix simulator build
remove additional defines for W800 used for testing

* Use esp_timer_get_time() instead of xTicks for ESP.
Seems much better, 30 seconds difference in one day
(used to be over 10 minutes off in 12 hours)

* Include DS3231 code

* Include DS3231 RTC driver

* Try simple fix for TXW81X without RTOS

* Second try fix TXW81X

* Fix comments for doc

* fix obk_config (still using "#define ENABLE_NTP_SUNRISE_SUNSET" instead of new "#define ENABLE_CLOCK_SUNRISE_SUNSET")
fix RDA5981
(as already done in branch Split_NTP_new)

* fix deviceclock code for corrected #define

* enable DS3231 driver for all platforms to test compilation and compare sizes

* fix selftest DST and sunrise/sunset (command names are "CLOCK_..." not "NTP...")

* Fix selftest for DST and sunset/sunrise events

* Add debug to try fixing selftest issue

* more debug

* Disable bedug output after fix.

* Disable DS3231 for all platforms. To tes, use previous commit

* Fix comments and handling of year when setting time of DS3231
Switch to internal time functions to reduce flash usage (avoid gmtime and mktime)

* Fix direct acces of NTP-time via g_ntpTime - use function "Clock_GetCurrentTime()"
switch to obktime instead of time.h "gmtime"

* Fix missing include for deviceclock and obktime

* made ds3231 driver dependent on "#define ENABLE_DRIVER_DS3231"
change "deviceclock.c" to set DS3231 RTC on every clock set command if driver is running, so e.g. every NTP update will also adjust RTC time

* fix missing includes for DRV_IsRunning() and DS3231_SetEpoch()

* introducing DS3231_informClockWasSet(bool force) - called by drv_deviceclock whenever clock is set.
so DS3231 driver can ste the clock, if needed - using "force" will force setting (no supprise ;-))

* Fixes to drv_main.c (missing args for onHassDiscovery)
Fixed missing arg "bPreState" in XX_AppendInformationToHTTPIndexPage()
Changed name from CLOCK to TIME
changed some "gmtime" to obktime "calculateComponents()a

* fixes

* fix obk_config.h

* fix missing include

* fix include for drv_txw81x_camera.c

* Directly call TIME "driver" functions, but don't use as real driver - so hiding it's presence in GUI

* fix missing OnEverySecond for TIME

* Prepare for merge: disable DS3231 driver for all platforms

* fix broken obk_config.h

* revert unintended change of src/driver/drv_max72xx_single.c
This commit is contained in:
MaxineMuster
2025-12-04 14:46:51 +01:00
committed by GitHub
parent a23e4183c2
commit a34f90bcbb
37 changed files with 1929 additions and 792 deletions

View File

@ -20,6 +20,7 @@
#include "../cJSON/cJSON.h"
#include <time.h>
#include "../driver/drv_ntp.h"
#include "../driver/drv_deviceclock.h" // to set clock via Javascript in pmntp
#include "../driver/drv_local.h"
#ifdef PLATFORM_BEKEN
#include "start_type_pub.h"
@ -207,6 +208,38 @@ int http_fn_testmsg(http_request_t* request) {
}
#if ENABLE_TIME_PMNTP
// poor mans NTP
int http_fn_pmntp(http_request_t* request) {
char tmpA[128];
uint32_t actepoch=0;
// javascripts "getTime()" should return time since 01.01.1970 (UTC)
if (http_getArg(request->url, "EPOCH", tmpA, sizeof(tmpA))) {
actepoch = (uint32_t)strtoul(tmpA,0,10);
TIME_setDeviceTime(actepoch);
addLogAdv(LOG_DEBUG, LOG_FEATURE_HTTP,"Set clock to %u! \n",actepoch);
}
#if ENABLE_TIME_DST
if (! IsDST_initialized()) {
#endif
if (http_getArg(request->url, "OFFSET", tmpA, sizeof(tmpA)) && actepoch != 0 ) {
// if actual time is during DST period, javascript will return
// an offset including the one additional hour of DST
// if we don't handle DST, simply accept this as "offset"
TIME_setDeviceTimeOffset(atoi(tmpA));
addLogAdv(LOG_DEBUG, LOG_FEATURE_HTTP,"Clock - set g_UTCoffset to %i! \n",
atoi(tmpA));
}
#if ENABLE_TIME_DST
// ignore JS offset, if we can/will calculate DST on our own
} else setDST();
#endif
poststr(request, "HTTP/1.1 302 OK\nLocation: /index\nConnection: close\n\n");
poststr(request, NULL);
return 0;
}
#endif
// bit mask telling which channels are hidden from HTTP
// If given bit is set, then given channel is hidden
extern int g_hiddenChannels;
@ -1142,7 +1175,9 @@ typedef enum {
}
poststr(request, "<form action=\"/app\" target=\"_blank\"><input type=\"submit\" value=\"Launch Web Application\"></form> ");
poststr(request, "<form action=\"about\"><input type=\"submit\" value=\"About\"/></form>");
#if ENABLE_TIME_PMNTP
poststr(request, "<input type='submit' value='Set clock to PC time' onclick='location.href =\"/pmntp?EPOCH=\"+((e=new Date)/1e3|0)+\"&OFFSET=\"+-60*e.getTimezoneOffset()'><p>");
#endif
poststr(request, htmlFooterRefreshLink);
http_html_end(request);
}

View File

@ -33,3 +33,4 @@ int http_fn_startup_command(http_request_t* request);
int http_fn_cfg_generic(http_request_t* request);
int http_fn_cfg_startup(http_request_t* request);
int http_fn_cfg_dgr(http_request_t* request);
int http_fn_pmntp(http_request_t* request);

View File

@ -16,14 +16,17 @@
#include "../mqtt/new_mqtt.h"
#include "hass.h"
#include "../cJSON/cJSON.h"
#include <time.h>
//#include <time.h>
#include "../driver/drv_ntp.h"
#include "../driver/drv_deviceclock.h"
#include "../driver/drv_local.h"
#include "../driver/drv_bl_shared.h"
#include "../driver/drv_ds1820_simple.h"
#include "../driver/drv_ds1820_full.h"
#include "../libraries/obktime/obktime.h" // for time functions
#if ENABLE_TASMOTA_JSON
void JSON_PrintKeyValue_String(void* request, jsonCb_t printer, const char* key, const char* value, bool bComma) {
@ -378,10 +381,12 @@ static int http_tasmota_json_SENSOR(void* request, jsonCb_t printer) {
/*
{"StatusSNS":{"Time":"2023-04-10T10:19:55"}}
*/
static void format_date(char *buffer, int buflength, struct tm *ltm)
/*static void format_date(char *buffer, int buflength, struct tm *ltm)
{
snprintf(buffer, buflength, "%04d-%02d-%02dT%02d:%02d:%02d",ltm->tm_year+1900, ltm->tm_mon+1, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
}
*/
// use obktimes ISO_8601 for this, e.g. TS2STR(TIME_GetCurrentTime(),TIME_FORMAT_ISO_8601)
static int http_tasmota_json_status_SNS(void* request, jsonCb_t printer, bool bAppendHeader) {
char buff[20];
@ -391,9 +396,11 @@ static int http_tasmota_json_status_SNS(void* request, jsonCb_t printer, bool bA
}
printer(request, "{");
time_t localTime = (time_t)NTP_GetCurrentTime();
/* time_t localTime = (time_t)TIME_GetCurrentTime();
format_date(buff, sizeof(buff), gmtime(&localTime));
JSON_PrintKeyValue_String(request, printer, "Time", buff, false);
*/
JSON_PrintKeyValue_String(request, printer, "Time", TS2STR(TIME_GetCurrentTime(),TIME_FORMAT_ISO_8601), false);
#ifndef OBK_DISABLE_ALL_DRIVERS
#ifdef ENABLE_DRIVER_BL0937
@ -466,14 +473,16 @@ void format_time(int total_seconds, char* output, int outLen) {
static int http_tasmota_json_status_STS(void* request, jsonCb_t printer, bool bAppendHeader) {
char buff[20];
time_t localTime = (time_t)NTP_GetCurrentTime();
time_t localTime = (time_t)TIME_GetCurrentTime();
if (bAppendHeader) {
printer(request, "\"StatusSTS\":");
}
printer(request, "{");
format_date(buff, sizeof(buff), gmtime(&localTime));
JSON_PrintKeyValue_String(request, printer, "Time", buff, true);
// format_date(buff, sizeof(buff), gmtime(&localTime));
// JSON_PrintKeyValue_String(request, printer, "Time", buff, true);
JSON_PrintKeyValue_String(request, printer, "Time", TS2STR(TIME_GetCurrentTime(),TIME_FORMAT_ISO_8601), true);
format_time(g_secondsElapsed, buff, sizeof(buff));
JSON_PrintKeyValue_String(request, printer, "Uptime", buff, true);
//JSON_PrintKeyValue_String(request, printer, "Uptime", "30T02:59:30", true);
@ -516,16 +525,29 @@ static int http_tasmota_json_status_STS(void* request, jsonCb_t printer, bool bA
static int http_tasmota_json_status_TIM(void* request, jsonCb_t printer) {
char buff[20];
time_t localTime = (time_t)NTP_GetCurrentTime();
time_t localUTC = (time_t)NTP_GetCurrentTimeWithoutOffset();
// time_t localTime = (time_t)TIME_GetCurrentTime();
// time_t localUTC = (time_t)TIME_GetCurrentTimeWithoutOffset();
printer(request, "\"StatusTIM\":{");
format_date(buff, sizeof(buff), gmtime(&localUTC));
JSON_PrintKeyValue_String(request, printer, "UTC", buff, true);
format_date(buff, sizeof(buff), gmtime(&localTime));
JSON_PrintKeyValue_String(request, printer, "Local", buff, true);
// format_date(buff, sizeof(buff), gmtime(&localUTC));
// JSON_PrintKeyValue_String(request, printer, "UTC", buff, true);
JSON_PrintKeyValue_String(request, printer, "UTC", TS2STR(TIME_GetCurrentTimeWithoutOffset(),TIME_FORMAT_ISO_8601), true);
// format_date(buff, sizeof(buff), gmtime(&localTime));
// JSON_PrintKeyValue_String(request, printer, "Local", buff, true);
JSON_PrintKeyValue_String(request, printer, "Local", TS2STR(TIME_GetCurrentTime(),TIME_FORMAT_ISO_8601), true);
#if ENABLE_TIME_DST
uint32_t DST[2]={0,0};
// only get DST settings, if DST is set
if (getDST_offset() > 0) getDSTtransition(DST);
JSON_PrintKeyValue_String(request, printer, "StartDST", TS2STR(DST[0],TIME_FORMAT_ISO_8601) , true);
JSON_PrintKeyValue_String(request, printer, "EndDST", TS2STR(DST[1],TIME_FORMAT_ISO_8601), true);
#else
JSON_PrintKeyValue_String(request, printer, "StartDST", "2022-03-27T02:00:00", true);
JSON_PrintKeyValue_String(request, printer, "EndDST", "2022-10-30T03:00:00", true);
JSON_PrintKeyValue_String(request, printer, "Timezone", "+01:00", true);
#endif
int TZ=TIME_GetCurrentTime() - TIME_GetCurrentTimeWithoutOffset();
char tmp[8];
sprintf(tmp,"%+03i:%02i",(int8_t)TZ/3600,(uint8_t)abs((TZ%3600)/60));
JSON_PrintKeyValue_String(request, printer, "Timezone", tmp, true);
JSON_PrintKeyValue_String(request, printer, "Sunrise", "07:50", true);
JSON_PrintKeyValue_String(request, printer, "Sunset", "17:17", false);
printer(request, "}");
@ -735,17 +757,20 @@ static int http_tasmota_json_status_generic(void* request, jsonCb_t printer) {
JSON_PrintKeyValue_String(request, printer, "OtaUrl", "https://github.com/openshwprojects/OpenBK7231T_App/releases/latest", true);
JSON_PrintKeyValue_String(request, printer, "RestartReason", "HardwareWatchdog", true);
JSON_PrintKeyValue_Int(request, printer, "Uptime", g_secondsElapsed, true);
struct tm* ltm;
// struct tm* ltm;
time_t ntpTime = 0; // if no NTP_time set, we will not change this value, but just stick to 0 and hence "fake" start of epoch 1970-01-01T00:00:00
if (NTP_GetCurrentTimeWithoutOffset() > g_secondsElapsed) { // would be negative else, leading to unwanted results when converted to (unsigned) time_t
ntpTime = (time_t)NTP_GetCurrentTimeWithoutOffset() - (time_t)g_secondsElapsed;
if (TIME_GetCurrentTimeWithoutOffset() > g_secondsElapsed) { // would be negative else, leading to unwanted results when converted to (unsigned) time_t
ntpTime = (time_t)TIME_GetCurrentTimeWithoutOffset() - (time_t)g_secondsElapsed;
}
/*
ltm = gmtime(&ntpTime);
if (ltm != 0) {
printer(request, "\"StartupUTC\":\"%04d-%02d-%02dT%02d:%02d:%02d\",", ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
}
else {
}
*/
printer(request, "\"StartupUTC\":\"%s\",", TS2STR(TIME_GetCurrentTime(),TIME_FORMAT_ISO_8601));
JSON_PrintKeyValue_Int(request, printer, "Sleep", 50, true);
JSON_PrintKeyValue_Int(request, printer, "CfgHolder", 4617, true);
JSON_PrintKeyValue_Int(request, printer, "BootCount", 22, true);

View File

@ -340,9 +340,9 @@ void http_html_end(http_request_t* request) {
poststr(request, g_build_str);
hprintf255(request, "<br>Online for&nbsp;<span id=\"onlineFor\" data-initial=\"%i\">-</span>", g_secondsElapsed);
WiFI_GetMacAddress((char*)mac);
snprintf(upTimeStr, sizeof(upTimeStr), "<br>Device MAC: %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
poststr(request, upTimeStr);
snprintf(upTimeStr, sizeof(upTimeStr), "<br>Short name: %s, Chipset %s", CFG_GetShortDeviceName(), PLATFORM_MCU_NAME);
@ -912,7 +912,10 @@ int HTTP_ProcessPacket(http_request_t* request) {
if (http_checkUrlBase(urlStr, "ota")) return http_fn_ota(request);
if (http_checkUrlBase(urlStr, "ota_exec")) return http_fn_ota_exec(request);
if (http_checkUrlBase(urlStr, "cm")) return http_fn_cm(request);
#if ENABLE_TIME_PMNTP
if (http_checkUrlBase(urlStr, "pmntp")) return http_fn_pmntp(request); // poor mans NTP
#endif
return http_fn_other(request);
}