aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/ble/SimpleWeatherService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/ble/SimpleWeatherService.cpp')
-rw-r--r--src/components/ble/SimpleWeatherService.cpp71
1 files changed, 68 insertions, 3 deletions
diff --git a/src/components/ble/SimpleWeatherService.cpp b/src/components/ble/SimpleWeatherService.cpp
index 51baf543..c2da9305 100644
--- a/src/components/ble/SimpleWeatherService.cpp
+++ b/src/components/ble/SimpleWeatherService.cpp
@@ -41,12 +41,48 @@ namespace {
SimpleWeatherService::Location cityName;
std::memcpy(cityName.data(), &dataBuffer[16], 32);
cityName[32] = '\0';
+ int16_t sunrise = -1;
+ int16_t sunset = -1;
+ if (dataBuffer[1] > 0) {
+ int16_t bufferSunrise = ToInt16(&dataBuffer[49]);
+ int16_t bufferSunset = ToInt16(&dataBuffer[51]);
+
+ // Sunrise/sunset format
+
+ // Assume sun is down at minute 0 / midnight
+
+ // 0<=x<1440 sunrise happens this many minutes into the day
+ // (0 day starts with sun up)
+ // -1 unknown
+ // -2 sun not rising today
+
+ // 0<x<1440 sunset happens this many minutes into the day
+ // -1 unknown
+ // -2 sun not setting today
+
+ // Check if the weather data is well formed
+ // Disable boolean simplification suggestion, as simplifying it makes it unreadable
+ if (!( // NOLINT(readability-simplify-boolean-expr)
+ // Fail if either unknown
+ (bufferSunrise == -1 || bufferSunset == -1)
+ // Cannot be out of range
+ || (bufferSunrise < -2 || bufferSunrise > 1439 || bufferSunset < -2 || bufferSunset > 1439)
+ // Cannot have sunset without sunrise
+ || (bufferSunrise == -2 && bufferSunset != -2)
+ // Cannot have sunset before sunrise
+ || (bufferSunrise >= bufferSunset && bufferSunrise >= 0 && bufferSunset >= 0))) {
+ sunrise = bufferSunrise;
+ sunset = bufferSunset;
+ }
+ }
return SimpleWeatherService::CurrentWeather(ToUInt64(&dataBuffer[2]),
SimpleWeatherService::Temperature(ToInt16(&dataBuffer[10])),
SimpleWeatherService::Temperature(ToInt16(&dataBuffer[12])),
SimpleWeatherService::Temperature(ToInt16(&dataBuffer[14])),
SimpleWeatherService::Icons {dataBuffer[16 + 32]},
- std::move(cityName));
+ std::move(cityName),
+ sunrise,
+ sunset);
}
SimpleWeatherService::Forecast CreateForecast(const uint8_t* dataBuffer) {
@@ -94,7 +130,7 @@ int SimpleWeatherService::OnCommand(struct ble_gatt_access_ctxt* ctxt) {
switch (GetMessageType(dataBuffer)) {
case MessageType::CurrentWeather:
- if (GetVersion(dataBuffer) == 0) {
+ if (GetVersion(dataBuffer) <= 1) {
currentWeather = CreateCurrentWeather(dataBuffer);
NRF_LOG_INFO("Current weather :\n\tTimestamp : %d\n\tTemperature:%d\n\tMin:%d\n\tMax:%d\n\tIcon:%d\n\tLocation:%s",
currentWeather->timestamp,
@@ -103,6 +139,9 @@ int SimpleWeatherService::OnCommand(struct ble_gatt_access_ctxt* ctxt) {
currentWeather->maxTemperature.PreciseCelsius(),
currentWeather->iconId,
currentWeather->location.data());
+ if (GetVersion(dataBuffer) == 1) {
+ NRF_LOG_INFO("Sunrise: %d\n\tSunset: %d", currentWeather->sunrise, currentWeather->sunset);
+ }
}
break;
case MessageType::Forecast:
@@ -153,10 +192,36 @@ std::optional<SimpleWeatherService::Forecast> SimpleWeatherService::GetForecast(
return {};
}
+bool SimpleWeatherService::IsNight() const {
+ if (currentWeather && currentWeather->sunrise != -1 && currentWeather->sunset != -1) {
+ auto currentTime = dateTimeController.CurrentDateTime().time_since_epoch();
+
+ // Get timestamp for last midnight
+ auto midnight = std::chrono::floor<std::chrono::days>(currentTime);
+
+ // Calculate minutes since midnight
+ auto currentMinutes = std::chrono::duration_cast<std::chrono::minutes>(currentTime - midnight).count();
+
+ // Sun not rising today => night all hours
+ if (currentWeather->sunrise == -2) {
+ return true;
+ }
+ // Sun not setting today => check before sunrise
+ if (currentWeather->sunset == -2) {
+ return currentMinutes < currentWeather->sunrise;
+ }
+
+ // Before sunrise or after sunset
+ return currentMinutes < currentWeather->sunrise || currentMinutes >= currentWeather->sunset;
+ }
+
+ return false;
+}
+
bool SimpleWeatherService::CurrentWeather::operator==(const SimpleWeatherService::CurrentWeather& other) const {
return this->iconId == other.iconId && this->temperature == other.temperature && this->timestamp == other.timestamp &&
this->maxTemperature == other.maxTemperature && this->minTemperature == other.maxTemperature &&
- std::strcmp(this->location.data(), other.location.data()) == 0;
+ std::strcmp(this->location.data(), other.location.data()) == 0 && this->sunrise == other.sunrise && this->sunset == other.sunset;
}
bool SimpleWeatherService::Forecast::Day::operator==(const SimpleWeatherService::Forecast::Day& other) const {