From eebf7935d6ea44c96c998314ffe7f8e1aefcbbdf Mon Sep 17 00:00:00 2001 From: FintasticMan Date: Fri, 6 Oct 2023 20:31:11 +0200 Subject: [PATCH] weather: Add some heuristics to GetCurrent* This means that there is a higher likelihood that the returned event is the most up-to-date current event. It chooses the event with the lowest expiry, and between events with the same expiry, it chooses the one with the latest timestamp. --- src/components/ble/weather/WeatherService.cpp | 72 ++++++++++++++----- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index b9a6af556c..fa5c63a1d2 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -403,110 +403,146 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentClouds() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Clouds && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentObscuration() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Obscuration && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentPrecipitation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Precipitation && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentWind() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Wind && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentTemperature() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Temperature && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentHumidity() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Humidity && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentPressure() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Pressure && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentLocation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::Location && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } std::unique_ptr& WeatherService::GetCurrentQuality() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); + auto* best = this->nullHeader; for (auto&& header : this->timeline) { if (header->eventType == WeatherData::eventtype::AirQuality && currentTimestamp >= header->timestamp && IsEventStillValid(header, currentTimestamp)) { - return reinterpret_cast&>(header); + if ((*best)->timestamp == 0 || header->expires < (*best)->expires || + (header->expires == (*best)->expires && header->timestamp > (*best)->timestamp)) { + best = &header; + } } } - return reinterpret_cast&>(*this->nullHeader); + return reinterpret_cast&>(*best); } size_t WeatherService::GetTimelineLength() const {