-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integration of Simple Weather Service
Replace the old WeatherService by the new Simple Weather Service.
- Loading branch information
Showing
8 changed files
with
235 additions
and
785 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
#include "components/ble/SimpleWeatherService.h" | ||
|
||
#include <algorithm> | ||
#include <cstring> | ||
#include <nrf_log.h> | ||
|
||
using namespace Pinetime::Controllers; | ||
|
||
namespace { | ||
enum class MessageType : uint8_t { CurrentWeather, Forecast, Unknown }; | ||
|
||
uint64_t ToUInt64(const uint8_t* data) { | ||
return *(reinterpret_cast<const uint64_t*>(data)); | ||
} | ||
|
||
SimpleWeatherService::CurrentWeather CreateCurrentWeather(const uint8_t* dataBuffer) { | ||
char cityName[33]; | ||
std::memcpy(&cityName[0], &dataBuffer[13], 32); | ||
cityName[32] = '\0'; | ||
return SimpleWeatherService::CurrentWeather {ToUInt64(&dataBuffer[2]), | ||
dataBuffer[10], | ||
dataBuffer[11], | ||
dataBuffer[12], | ||
dataBuffer[13 + 32], | ||
cityName}; | ||
} | ||
|
||
SimpleWeatherService::Forecast CreateForecast(const uint8_t* dataBuffer) { | ||
auto timestamp = static_cast<uint64_t>(ToUInt64(&dataBuffer[2])); | ||
|
||
std::array<SimpleWeatherService::Forecast::Day, SimpleWeatherService::MaxNbForecastDays> days; | ||
const uint8_t nbDaysInBuffer = dataBuffer[10]; | ||
const uint8_t nbDays = std::min(SimpleWeatherService::MaxNbForecastDays, nbDaysInBuffer); | ||
for (int i = 0; i < nbDays; i++) { | ||
days[i] = SimpleWeatherService::Forecast::Day {dataBuffer[11 + (i * 3)], dataBuffer[12 + (i * 3)], dataBuffer[13 + (i * 3)]}; | ||
} | ||
return SimpleWeatherService::Forecast {timestamp, nbDays, days}; | ||
} | ||
|
||
MessageType GetMessageType(const uint8_t* data) { | ||
auto messageType = static_cast<MessageType>(*data); | ||
if (messageType > MessageType::Unknown) { | ||
return MessageType::Unknown; | ||
} | ||
return messageType; | ||
} | ||
|
||
uint8_t GetVersion(const uint8_t* dataBuffer) { | ||
return dataBuffer[1]; | ||
} | ||
} | ||
|
||
int WeatherCallback(uint16_t /*connHandle*/, uint16_t /*attrHandle*/, struct ble_gatt_access_ctxt* ctxt, void* arg) { | ||
return static_cast<Pinetime::Controllers::SimpleWeatherService*>(arg)->OnCommand(ctxt); | ||
} | ||
|
||
SimpleWeatherService::SimpleWeatherService(const DateTime& dateTimeController) : dateTimeController(dateTimeController) { | ||
} | ||
|
||
void SimpleWeatherService::Init() { | ||
//ble_gatts_count_cfg(serviceDefinition); | ||
//ble_gatts_add_svcs(serviceDefinition); | ||
} | ||
|
||
int SimpleWeatherService::OnCommand(struct ble_gatt_access_ctxt* ctxt) { | ||
|
||
return 0; | ||
} | ||
|
||
std::optional<SimpleWeatherService::CurrentWeather> SimpleWeatherService::Current() const { | ||
if (currentWeather) { | ||
auto currentTime = dateTimeController.UTCDateTime().time_since_epoch(); | ||
auto weatherTpSecond = std::chrono::seconds {currentWeather->timestamp}; | ||
auto weatherTp = std::chrono::duration_cast<std::chrono::seconds>(weatherTpSecond); | ||
auto delta = currentTime - weatherTp; | ||
|
||
if (delta < std::chrono::hours {24}) { | ||
return currentWeather; | ||
} | ||
} | ||
return {}; | ||
} | ||
|
||
std::optional<SimpleWeatherService::Forecast> SimpleWeatherService::GetForecast() const { | ||
if (forecast) { | ||
auto currentTime = dateTimeController.UTCDateTime().time_since_epoch(); | ||
auto weatherTpSecond = std::chrono::seconds {forecast->timestamp}; | ||
auto weatherTp = std::chrono::duration_cast<std::chrono::seconds>(weatherTpSecond); | ||
auto delta = currentTime - weatherTp; | ||
|
||
if (delta < std::chrono::hours {24}) { | ||
return this->forecast; | ||
} | ||
} | ||
return {}; | ||
} | ||
|
||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#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> | ||
#include <array> | ||
//#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); | ||
|
||
static constexpr uint8_t MaxNbForecastDays = 5; | ||
|
||
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; | ||
}; | ||
|
||
struct Forecast { | ||
uint64_t timestamp; | ||
uint8_t nbDays; | ||
|
||
struct Day { | ||
uint8_t minTemperature; | ||
uint8_t maxTemperature; | ||
uint8_t iconId; | ||
}; | ||
|
||
std::array<Day, MaxNbForecastDays> 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; | ||
}; | ||
} | ||
} |
Oops, something went wrong.