diff options
| author | Jean-François Milants <jf@codingfield.com> | 2023-12-09 20:39:08 +0100 |
|---|---|---|
| committer | JF <JF002@users.noreply.github.com> | 2023-12-23 21:12:25 +0100 |
| commit | c94a59e7d3e0f9929171263412033a56872c168a (patch) | |
| tree | f9e3d4c1915b91f57ff8d96b18e10f0fbb998aa4 /src/components/ble/SimpleWeatherService.h | |
| parent | 088082d32db483ac5326bed09d5d47847fb5bf9b (diff) | |
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.
Diffstat (limited to 'src/components/ble/SimpleWeatherService.h')
| -rw-r--r-- | src/components/ble/SimpleWeatherService.h | 131 |
1 files changed, 131 insertions, 0 deletions
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 <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include <cstdint> +#include <string> +#include <vector> +#include <memory> + +#define min // workaround: nimble's min/max macros conflict with libstdc++ +#define max +#include <host/ble_gap.h> +#include <host/ble_uuid.h> +#include <optional> +#include <cstring> +#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<Day, 5> days; + }; + + std::optional<CurrentWeather> Current() const; + std::optional<Forecast> 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> currentWeather; + std::optional<Forecast> forecast; + }; + } +} |
