From c94a59e7d3e0f9929171263412033a56872c168a Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sat, 9 Dec 2023 20:39:08 +0100 Subject: SimpleWeather service : new weather implementation This new implementation of the weather feature provides a new BLE API and a new weather service. The API uses a single characteristic that allows companion apps to write the weather conditions (current and forecast for the next 5 days). The SimpleWeather service exposes those data as std::optional fields. This new implementation replaces the previous WeahterService. The API is documented in docs/SimpleWeatherService.md. --- src/components/ble/SimpleWeatherService.h | 131 ++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/components/ble/SimpleWeatherService.h (limited to 'src/components/ble/SimpleWeatherService.h') diff --git a/src/components/ble/SimpleWeatherService.h b/src/components/ble/SimpleWeatherService.h new file mode 100644 index 00000000..46d5e187 --- /dev/null +++ b/src/components/ble/SimpleWeatherService.h @@ -0,0 +1,131 @@ +/* Copyright (C) 2023 Jean-François Milants + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#pragma once + +#include +#include +#include +#include + +#define min // workaround: nimble's min/max macros conflict with libstdc++ +#define max +#include +#include +#include +#include +#undef max +#undef min + +#include "components/datetime/DateTimeController.h" + +int WeatherCallback(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt, void* arg); + +namespace Pinetime { + namespace Controllers { + + class SimpleWeatherService { + public: + explicit SimpleWeatherService(const DateTime& dateTimeController); + + void Init(); + + int OnCommand(struct ble_gatt_access_ctxt* ctxt); + + enum class Icons : uint8_t { + Sun = 0, // ClearSky + CloudsSun = 1, // FewClouds + Clouds = 2, // Scattered clouds + BrokenClouds = 3, + CloudShowerHeavy = 4, // shower rain + CloudSunRain = 5, // rain + Thunderstorm = 6, + Snow = 7, + Smog = 8, // Mist + Unknown = 255 + }; + + struct CurrentWeather { + CurrentWeather(uint64_t timestamp, uint8_t temperature, uint8_t minTemperature, uint8_t maxTemperature, + uint8_t iconId, const char* location) + : timestamp{timestamp}, temperature{temperature}, minTemperature{minTemperature}, maxTemperature{maxTemperature}, + iconId{iconId} { + std::memcpy(this->location, location, 32); + this->location[32] = 0; + } + uint64_t timestamp; + uint8_t temperature; + uint8_t minTemperature; + uint8_t maxTemperature; + Icons iconId; + char location[33]; // 32 char + \0 (end of string) + + bool operator==(const CurrentWeather& other) const; + bool operator!=(const CurrentWeather& other) const; + }; + + struct Forecast { + uint64_t timestamp; + uint8_t nbDays; + struct Day { + uint8_t minTemperature; + uint8_t maxTemperature; + uint8_t iconId; + }; + std::array days; + }; + + std::optional Current() const; + std::optional GetForecast() const; + + + private: + // 00050000-78fc-48fe-8e23-433b3a1942d0 + static constexpr ble_uuid128_t BaseUuid() { + return CharUuid(0x00, 0x00); + } + + // 0005yyxx-78fc-48fe-8e23-433b3a1942d0 + static constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) { + return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128}, + .value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, y, x, 0x05, 0x00}}; + } + + ble_uuid128_t weatherUuid {BaseUuid()}; + + ble_uuid128_t weatherDataCharUuid {CharUuid(0x00, 0x01)}; + + const struct ble_gatt_chr_def characteristicDefinition[2] = { + {.uuid = &weatherDataCharUuid.u, + .access_cb = WeatherCallback, + .arg = this, + .flags = BLE_GATT_CHR_F_WRITE, + .val_handle = &eventHandle}, + {0}}; + const struct ble_gatt_svc_def serviceDefinition[2] = { + {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &weatherUuid.u, .characteristics = characteristicDefinition}, + {0}}; + + uint16_t eventHandle {}; + + const Pinetime::Controllers::DateTime& dateTimeController; + + std::optional currentWeather; + std::optional forecast; + }; + } +} -- cgit v1.2.3-70-g09d2