Optimize Sun data calculation

This commit is contained in:
Thomas Basler 2023-11-18 22:34:55 +01:00
parent 859b902ef9
commit d3f95000e2
2 changed files with 23 additions and 40 deletions

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#include <mutex> #include <atomic>
#include <sunset.h> #include <sunset.h>
class SunPositionClass { class SunPositionClass {
@ -19,16 +19,14 @@ public:
private: private:
void updateSunData(); void updateSunData();
bool checkRecalcDayChanged(); bool checkRecalcDayChanged();
bool getDoRecalc(); bool getSunTime(struct tm* info, uint32_t offset);
SunSet _sun;
bool _isSunsetAvailable = true; bool _isSunsetAvailable = true;
uint32_t _sunriseMinutes = 0; uint32_t _sunriseMinutes = 0;
uint32_t _sunsetMinutes = 0; uint32_t _sunsetMinutes = 0;
bool _isValidInfo = false; bool _isValidInfo = false;
bool _doRecalc = true; std::atomic_bool _doRecalc = true;
std::mutex _recalcLock;
uint32_t _lastSunPositionCalculatedYMD = 0; uint32_t _lastSunPositionCalculatedYMD = 0;
}; };

View File

@ -19,7 +19,7 @@ void SunPositionClass::init()
void SunPositionClass::loop() void SunPositionClass::loop()
{ {
if (getDoRecalc() || checkRecalcDayChanged()) { if (_doRecalc || checkRecalcDayChanged()) {
updateSunData(); updateSunData();
} }
} }
@ -43,16 +43,9 @@ bool SunPositionClass::isSunsetAvailable()
void SunPositionClass::setDoRecalc(bool doRecalc) void SunPositionClass::setDoRecalc(bool doRecalc)
{ {
std::lock_guard<std::mutex> lock(_recalcLock);
_doRecalc = doRecalc; _doRecalc = doRecalc;
} }
bool SunPositionClass::getDoRecalc()
{
std::lock_guard<std::mutex> lock(_recalcLock);
return _doRecalc;
}
bool SunPositionClass::checkRecalcDayChanged() bool SunPositionClass::checkRecalcDayChanged()
{ {
time_t now; time_t now;
@ -64,10 +57,7 @@ bool SunPositionClass::checkRecalcDayChanged()
uint32_t ymd; uint32_t ymd;
ymd = (timeinfo.tm_year << 9) | (timeinfo.tm_mon << 5) | timeinfo.tm_mday; ymd = (timeinfo.tm_year << 9) | (timeinfo.tm_mon << 5) | timeinfo.tm_mday;
if (_lastSunPositionCalculatedYMD != ymd) { return _lastSunPositionCalculatedYMD != ymd;
return true;
}
return false;
} }
void SunPositionClass::updateSunData() void SunPositionClass::updateSunData()
@ -82,15 +72,12 @@ void SunPositionClass::updateSunData()
if (!gotLocalTime) { if (!gotLocalTime) {
_sunriseMinutes = 0; _sunriseMinutes = 0;
_sunsetMinutes = 0; _sunsetMinutes = 0;
_isSunsetAvailable = true;
_isValidInfo = false; _isValidInfo = false;
return; return;
} }
CONFIG_T const& config = Configuration.get(); CONFIG_T const& config = Configuration.get();
int offset = Utils::getTimezoneOffset() / 3600;
_sun.setPosition(config.Ntp_Latitude, config.Ntp_Longitude, offset);
_sun.setCurrentDate(1900 + timeinfo.tm_year, timeinfo.tm_mon + 1, timeinfo.tm_mday);
double sunset_type; double sunset_type;
switch (config.Ntp_SunsetType) { switch (config.Ntp_SunsetType) {
@ -108,15 +95,21 @@ void SunPositionClass::updateSunData()
break; break;
} }
double sunriseRaw = _sun.calcCustomSunrise(sunset_type); int offset = Utils::getTimezoneOffset() / 3600;
double sunsetRaw = _sun.calcCustomSunset(sunset_type);
SunSet sun;
sun.setPosition(config.Ntp_Latitude, config.Ntp_Longitude, offset);
sun.setCurrentDate(1900 + timeinfo.tm_year, timeinfo.tm_mon + 1, timeinfo.tm_mday);
double sunriseRaw = sun.calcCustomSunrise(sunset_type);
double sunsetRaw = sun.calcCustomSunset(sunset_type);
// If no sunset/sunrise exists (e.g. astronomical calculation in summer) // If no sunset/sunrise exists (e.g. astronomical calculation in summer)
// assume it's day period // assume it's day period
if (std::isnan(sunriseRaw) || std::isnan(sunsetRaw)) { if (std::isnan(sunriseRaw) || std::isnan(sunsetRaw)) {
_isSunsetAvailable = false;
_sunriseMinutes = 0; _sunriseMinutes = 0;
_sunsetMinutes = 0; _sunsetMinutes = 0;
_isSunsetAvailable = false;
_isValidInfo = false; _isValidInfo = false;
return; return;
} }
@ -128,7 +121,7 @@ void SunPositionClass::updateSunData()
_isValidInfo = true; _isValidInfo = true;
} }
bool SunPositionClass::sunsetTime(struct tm* info) bool SunPositionClass::getSunTime(struct tm* info, uint32_t offset)
{ {
// Get today's date // Get today's date
time_t aTime = time(NULL); time_t aTime = time(NULL);
@ -137,7 +130,7 @@ bool SunPositionClass::sunsetTime(struct tm* info)
struct tm tm; struct tm tm;
localtime_r(&aTime, &tm); localtime_r(&aTime, &tm);
tm.tm_sec = 0; tm.tm_sec = 0;
tm.tm_min = _sunsetMinutes; tm.tm_min = offset;
tm.tm_hour = 0; tm.tm_hour = 0;
tm.tm_isdst = -1; tm.tm_isdst = -1;
time_t midnight = mktime(&tm); time_t midnight = mktime(&tm);
@ -146,20 +139,12 @@ bool SunPositionClass::sunsetTime(struct tm* info)
return _isValidInfo; return _isValidInfo;
} }
bool SunPositionClass::sunsetTime(struct tm* info)
{
return getSunTime(info, _sunsetMinutes);
}
bool SunPositionClass::sunriseTime(struct tm* info) bool SunPositionClass::sunriseTime(struct tm* info)
{ {
// Get today's date return getSunTime(info, _sunriseMinutes);
time_t aTime = time(NULL);
// Set the time to midnight
struct tm tm;
localtime_r(&aTime, &tm);
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;
} }