From f88c69a31aadb0fdfe6555db626ba8f05e756272 Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Mon, 5 Jan 2026 07:12:08 -0500 Subject: SimpleWeatherService: Add sunrise and sunset data (#2100) * SimpleWeatherService: Add sunrise and sunset data --------- Co-authored-by: mark9064 <30447455+mark9064@users.noreply.github.com> --- src/components/ble/SimpleWeatherService.cpp | 71 +++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) (limited to 'src/components/ble/SimpleWeatherService.cpp') 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 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::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(currentTime); + + // Calculate minutes since midnight + auto currentMinutes = std::chrono::duration_cast(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 { -- cgit v1.2.3-70-g09d2