Added methods to calculate and show sunrise and sunset times
This commit is contained in:
parent
19a1c0aa54
commit
b319c78dc1
30
include/SunPosition.h
Normal file
30
include/SunPosition.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sunset.h>
|
||||||
|
|
||||||
|
#define SUNPOS_UPDATE_INTERVAL 60000l
|
||||||
|
|
||||||
|
class SunPositionClass {
|
||||||
|
public:
|
||||||
|
SunPositionClass();
|
||||||
|
void init();
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
bool isDayPeriod();
|
||||||
|
bool sunsetTime(struct tm* info);
|
||||||
|
bool sunriseTime(struct tm* info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateSunData();
|
||||||
|
|
||||||
|
SunSet _sun;
|
||||||
|
bool _isDayPeriod = true;
|
||||||
|
uint _sunriseMinutes = 0;
|
||||||
|
uint _sunsetMinutes = 0;
|
||||||
|
|
||||||
|
uint32_t _lastUpdate = 0;
|
||||||
|
bool _isValidInfo = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SunPositionClass SunPosition;
|
||||||
@ -7,4 +7,5 @@ class Utils {
|
|||||||
public:
|
public:
|
||||||
static uint32_t getChipId();
|
static uint32_t getChipId();
|
||||||
static uint64_t generateDtuSerial();
|
static uint64_t generateDtuSerial();
|
||||||
|
static int getTimezoneOffset();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -27,6 +27,7 @@ lib_deps =
|
|||||||
https://github.com/bertmelis/espMqttClient.git#v1.3.3
|
https://github.com/bertmelis/espMqttClient.git#v1.3.3
|
||||||
nrf24/RF24 @ ^1.4.5
|
nrf24/RF24 @ ^1.4.5
|
||||||
olikraus/U8g2 @ ^2.34.13
|
olikraus/U8g2 @ ^2.34.13
|
||||||
|
buelowp/sunset @ ^1.1.3
|
||||||
|
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
pre:auto_firmware_version.py
|
pre:auto_firmware_version.py
|
||||||
|
|||||||
88
src/SunPosition.cpp
Normal file
88
src/SunPosition.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Thomas Basler and others
|
||||||
|
*/
|
||||||
|
#include "SunPosition.h"
|
||||||
|
#include "Configuration.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
SunPositionClass SunPosition;
|
||||||
|
|
||||||
|
SunPositionClass::SunPositionClass()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SunPositionClass::init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SunPositionClass::loop()
|
||||||
|
{
|
||||||
|
if (millis() - _lastUpdate > SUNPOS_UPDATE_INTERVAL) {
|
||||||
|
updateSunData();
|
||||||
|
_lastUpdate = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SunPositionClass::isDayPeriod()
|
||||||
|
{
|
||||||
|
return _isDayPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SunPositionClass::updateSunData()
|
||||||
|
{
|
||||||
|
CONFIG_T const& config = Configuration.get();
|
||||||
|
int offset = Utils::getTimezoneOffset() / 3600;
|
||||||
|
_sun.setPosition(config.Ntp_Latitude, config.Ntp_Longitude, offset);
|
||||||
|
|
||||||
|
struct tm timeinfo;
|
||||||
|
if (!getLocalTime(&timeinfo, 5)) {
|
||||||
|
_isDayPeriod = false;
|
||||||
|
_sunriseMinutes = 0;
|
||||||
|
_sunsetMinutes = 0;
|
||||||
|
_isValidInfo = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_sun.setCurrentDate(1900 + timeinfo.tm_year, timeinfo.tm_mon + 1, timeinfo.tm_mday);
|
||||||
|
_sunriseMinutes = (int)_sun.calcCustomSunrise(SunSet::SUNSET_NAUTICAL);
|
||||||
|
_sunsetMinutes = (int)_sun.calcCustomSunset(SunSet::SUNSET_NAUTICAL);
|
||||||
|
uint minutesPastMidnight = timeinfo.tm_hour * 60 + timeinfo.tm_min;
|
||||||
|
|
||||||
|
_isDayPeriod = (minutesPastMidnight >= _sunriseMinutes) && (minutesPastMidnight < _sunsetMinutes);
|
||||||
|
_isValidInfo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SunPositionClass::sunsetTime(struct tm* info)
|
||||||
|
{
|
||||||
|
// Get today's date
|
||||||
|
time_t aTime = time(NULL);
|
||||||
|
|
||||||
|
// Set the time to midnight
|
||||||
|
struct tm* tm = localtime(&aTime);
|
||||||
|
tm->tm_sec = 0;
|
||||||
|
tm->tm_min = _sunsetMinutes;
|
||||||
|
tm->tm_hour = 0;
|
||||||
|
tm->tm_isdst = -1;
|
||||||
|
time_t midnight = mktime(tm);
|
||||||
|
|
||||||
|
localtime_r(&midnight, info);
|
||||||
|
return _isValidInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SunPositionClass::sunriseTime(struct tm* info)
|
||||||
|
{
|
||||||
|
// Get today's date
|
||||||
|
time_t aTime = time(NULL);
|
||||||
|
|
||||||
|
// Set the time to midnight
|
||||||
|
struct tm* tm = localtime(&aTime);
|
||||||
|
tm->tm_sec = 0;
|
||||||
|
tm->tm_min = _sunriseMinutes;
|
||||||
|
tm->tm_hour = 0;
|
||||||
|
tm->tm_isdst = -1;
|
||||||
|
time_t midnight = mktime(tm);
|
||||||
|
|
||||||
|
localtime_r(&midnight, info);
|
||||||
|
return _isValidInfo;
|
||||||
|
}
|
||||||
@ -36,3 +36,20 @@ uint64_t Utils::generateDtuSerial()
|
|||||||
|
|
||||||
return dtuId;
|
return dtuId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Utils::getTimezoneOffset()
|
||||||
|
{
|
||||||
|
// see: https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c/44063597#44063597
|
||||||
|
|
||||||
|
time_t gmt, rawtime = time(NULL);
|
||||||
|
struct tm* ptm;
|
||||||
|
|
||||||
|
struct tm gbuf;
|
||||||
|
ptm = gmtime_r(&rawtime, &gbuf);
|
||||||
|
|
||||||
|
// Request that mktime() looksup dst in timezone database
|
||||||
|
ptm->tm_isdst = -1;
|
||||||
|
gmt = mktime(ptm);
|
||||||
|
|
||||||
|
return static_cast<int>(difftime(rawtime, gmt));
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@
|
|||||||
#include "WebApi_ntp.h"
|
#include "WebApi_ntp.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "NtpSettings.h"
|
#include "NtpSettings.h"
|
||||||
|
#include "SunPosition.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "WebApi_errors.h"
|
#include "WebApi_errors.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
@ -51,6 +52,16 @@ void WebApiNtpClass::onNtpStatus(AsyncWebServerRequest* request)
|
|||||||
strftime(timeStringBuff, sizeof(timeStringBuff), "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
strftime(timeStringBuff, sizeof(timeStringBuff), "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||||
root[F("ntp_localtime")] = timeStringBuff;
|
root[F("ntp_localtime")] = timeStringBuff;
|
||||||
|
|
||||||
|
SunPosition.sunriseTime(&timeinfo);
|
||||||
|
strftime(timeStringBuff, sizeof(timeStringBuff), "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||||
|
root[F("sun_risetime")] = timeStringBuff;
|
||||||
|
|
||||||
|
SunPosition.sunsetTime(&timeinfo);
|
||||||
|
strftime(timeStringBuff, sizeof(timeStringBuff), "%A, %B %d %Y %H:%M:%S", &timeinfo);
|
||||||
|
root[F("sun_settime")] = timeStringBuff;
|
||||||
|
|
||||||
|
root[F("sun_isDayPeriod")] = SunPosition.isDayPeriod();
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "NetworkSettings.h"
|
#include "NetworkSettings.h"
|
||||||
#include "NtpSettings.h"
|
#include "NtpSettings.h"
|
||||||
#include "PinMapping.h"
|
#include "PinMapping.h"
|
||||||
|
#include "SunPosition.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
@ -80,6 +81,11 @@ void setup()
|
|||||||
NtpSettings.init();
|
NtpSettings.init();
|
||||||
MessageOutput.println(F("done"));
|
MessageOutput.println(F("done"));
|
||||||
|
|
||||||
|
// Initialize SunPosition
|
||||||
|
MessageOutput.print(F("Initialize SunPosition... "));
|
||||||
|
SunPosition.init();
|
||||||
|
MessageOutput.println(F("done"));
|
||||||
|
|
||||||
// Initialize MqTT
|
// Initialize MqTT
|
||||||
MessageOutput.print(F("Initialize MqTT... "));
|
MessageOutput.print(F("Initialize MqTT... "));
|
||||||
MqttSettings.init();
|
MqttSettings.init();
|
||||||
@ -178,6 +184,8 @@ void loop()
|
|||||||
yield();
|
yield();
|
||||||
Display.loop();
|
Display.loop();
|
||||||
yield();
|
yield();
|
||||||
|
SunPosition.loop();
|
||||||
|
yield();
|
||||||
MessageOutput.loop();
|
MessageOutput.loop();
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
@ -228,7 +228,12 @@
|
|||||||
"Status": "Status",
|
"Status": "Status",
|
||||||
"Synced": "synchronisiert",
|
"Synced": "synchronisiert",
|
||||||
"NotSynced": "nicht synchronisiert",
|
"NotSynced": "nicht synchronisiert",
|
||||||
"LocalTime": "Lokale Uhrzeit"
|
"LocalTime": "Lokale Uhrzeit",
|
||||||
|
"Sunrise": "Nautische Morgendämmerung",
|
||||||
|
"Sunset": "Nautische Abenddämmerung",
|
||||||
|
"Mode": "Modus",
|
||||||
|
"Day": "Tag",
|
||||||
|
"Night": "Nacht"
|
||||||
},
|
},
|
||||||
"mqttinfo": {
|
"mqttinfo": {
|
||||||
"MqttInformation": "MQTT Informationen",
|
"MqttInformation": "MQTT Informationen",
|
||||||
|
|||||||
@ -228,7 +228,12 @@
|
|||||||
"Status": "Status",
|
"Status": "Status",
|
||||||
"Synced": "synced",
|
"Synced": "synced",
|
||||||
"NotSynced": "not synced",
|
"NotSynced": "not synced",
|
||||||
"LocalTime": "Local Time"
|
"LocalTime": "Local Time",
|
||||||
|
"Sunrise": "Nautical Sunrise",
|
||||||
|
"Sunset": "Nautical Sunset",
|
||||||
|
"Mode": "Mode",
|
||||||
|
"Day": "Day",
|
||||||
|
"Night": "Night"
|
||||||
},
|
},
|
||||||
"mqttinfo": {
|
"mqttinfo": {
|
||||||
"MqttInformation": "MQTT Information",
|
"MqttInformation": "MQTT Information",
|
||||||
|
|||||||
@ -228,7 +228,12 @@
|
|||||||
"Status": "Statut",
|
"Status": "Statut",
|
||||||
"Synced": "synchronisée",
|
"Synced": "synchronisée",
|
||||||
"NotSynced": "pas synchronisée",
|
"NotSynced": "pas synchronisée",
|
||||||
"LocalTime": "Heure locale"
|
"LocalTime": "Heure locale",
|
||||||
|
"Sunrise": "Nautical Sunrise",
|
||||||
|
"Sunset": "Nautical Sunset",
|
||||||
|
"Mode": "Mode",
|
||||||
|
"Day": "Day",
|
||||||
|
"Night": "Night"
|
||||||
},
|
},
|
||||||
"mqttinfo": {
|
"mqttinfo": {
|
||||||
"MqttInformation": "MQTT Information",
|
"MqttInformation": "MQTT Information",
|
||||||
|
|||||||
@ -4,4 +4,7 @@ export interface NtpStatus {
|
|||||||
ntp_timezone_descr: string
|
ntp_timezone_descr: string
|
||||||
ntp_status: boolean;
|
ntp_status: boolean;
|
||||||
ntp_localtime: string;
|
ntp_localtime: string;
|
||||||
|
sun_risetime: string;
|
||||||
|
sun_settime: string;
|
||||||
|
sun_isDayPeriod: boolean;
|
||||||
}
|
}
|
||||||
@ -39,6 +39,25 @@
|
|||||||
<th>{{ $t('ntpinfo.LocalTime') }}</th>
|
<th>{{ $t('ntpinfo.LocalTime') }}</th>
|
||||||
<td>{{ ntpDataList.ntp_localtime }}</td>
|
<td>{{ ntpDataList.ntp_localtime }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>{{ $t('ntpinfo.Sunrise') }}</th>
|
||||||
|
<td>{{ ntpDataList.sun_risetime }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{ $t('ntpinfo.Sunset') }}</th>
|
||||||
|
<td>{{ ntpDataList.sun_settime }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{ $t('ntpinfo.Mode') }}</th>
|
||||||
|
<td class="badge" :class="{
|
||||||
|
'text-bg-dark': !ntpDataList.sun_isDayPeriod,
|
||||||
|
'text-bg-warning': ntpDataList.sun_isDayPeriod,
|
||||||
|
}">
|
||||||
|
<span v-if="ntpDataList.sun_isDayPeriod">{{ $t('ntpinfo.Day') }}</span>
|
||||||
|
<span v-else>{{ $t('ntpinfo.Night') }}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user