SimpleWeather service : new weather implementation
Fix recovery firmware and code formatting.
This commit is contained in:
parent
c94a59e7d3
commit
50c679023f
|
@ -22,45 +22,45 @@
|
||||||
using namespace Pinetime::Controllers;
|
using namespace Pinetime::Controllers;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
enum class MessageType {
|
enum class MessageType { CurrentWeather, Forecast, Unknown };
|
||||||
CurrentWeather,
|
|
||||||
Forecast,
|
|
||||||
Unknown
|
|
||||||
};
|
|
||||||
|
|
||||||
SimpleWeatherService::CurrentWeather CreateCurrentWeather(const uint8_t* dataBuffer) {
|
SimpleWeatherService::CurrentWeather CreateCurrentWeather(const uint8_t* dataBuffer) {
|
||||||
char cityName[33];
|
char cityName[33];
|
||||||
std::memcpy(&cityName[0], &dataBuffer[13], 32);
|
std::memcpy(&cityName[0], &dataBuffer[13], 32);
|
||||||
cityName[32] = '\0';
|
cityName[32] = '\0';
|
||||||
return SimpleWeatherService::CurrentWeather{dataBuffer[2] + (dataBuffer[3] << 8) + (dataBuffer[4] << 16) + (dataBuffer[5] << 24) +
|
return SimpleWeatherService::CurrentWeather {dataBuffer[2] + (dataBuffer[3] << 8) + (dataBuffer[4] << 16) + (dataBuffer[5] << 24) +
|
||||||
((uint64_t) dataBuffer[6] << 32) + ((uint64_t) dataBuffer[7] << 40) + ((uint64_t) dataBuffer[8] << 48) +
|
((uint64_t) dataBuffer[6] << 32) + ((uint64_t) dataBuffer[7] << 40) +
|
||||||
((uint64_t) dataBuffer[9] << 54),
|
((uint64_t) dataBuffer[8] << 48) + ((uint64_t) dataBuffer[9] << 54),
|
||||||
dataBuffer[10],
|
dataBuffer[10],
|
||||||
dataBuffer[11],
|
dataBuffer[11],
|
||||||
dataBuffer[12],
|
dataBuffer[12],
|
||||||
dataBuffer[13 + 32],
|
dataBuffer[13 + 32],
|
||||||
cityName};
|
cityName};
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleWeatherService::Forecast CreateForecast(const uint8_t* dataBuffer) {
|
SimpleWeatherService::Forecast CreateForecast(const uint8_t* dataBuffer) {
|
||||||
uint64_t timestamp = static_cast<uint64_t>(dataBuffer[2] + (dataBuffer[3] << 8) + (dataBuffer[4] << 16) + (dataBuffer[5] << 24) +
|
uint64_t timestamp = static_cast<uint64_t>(dataBuffer[2] + (dataBuffer[3] << 8) + (dataBuffer[4] << 16) + (dataBuffer[5] << 24) +
|
||||||
((uint64_t) dataBuffer[6] << 32) + ((uint64_t) dataBuffer[7] << 40) + ((uint64_t) dataBuffer[8] << 48) +
|
((uint64_t) dataBuffer[6] << 32) + ((uint64_t) dataBuffer[7] << 40) +
|
||||||
((uint64_t) dataBuffer[9] << 54));
|
((uint64_t) dataBuffer[8] << 48) + ((uint64_t) dataBuffer[9] << 54));
|
||||||
uint8_t nbDays = dataBuffer[10];
|
uint8_t nbDays = dataBuffer[10];
|
||||||
std::array<SimpleWeatherService::Forecast::Day, 5> days;
|
std::array<SimpleWeatherService::Forecast::Day, 5> days;
|
||||||
for (int i = 0; i < nbDays; i++) {
|
for (int i = 0; i < nbDays; i++) {
|
||||||
days[i] = SimpleWeatherService::Forecast::Day {dataBuffer[11 + (i * 3)],
|
days[i] = SimpleWeatherService::Forecast::Day {dataBuffer[11 + (i * 3)], dataBuffer[12 + (i * 3)], dataBuffer[13 + (i * 3)]};
|
||||||
dataBuffer[12 + (i * 3)],
|
|
||||||
dataBuffer[13 + (i * 3)]};
|
|
||||||
}
|
}
|
||||||
return SimpleWeatherService::Forecast {timestamp, nbDays, days};
|
return SimpleWeatherService::Forecast {timestamp, nbDays, days};
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageType GetMessageType(const uint8_t* dataBuffer) {
|
MessageType GetMessageType(const uint8_t* dataBuffer) {
|
||||||
switch(dataBuffer[0]) {
|
switch (dataBuffer[0]) {
|
||||||
case 0: return MessageType::CurrentWeather; break;
|
case 0:
|
||||||
case 1: return MessageType::Forecast; break;
|
return MessageType::CurrentWeather;
|
||||||
default: return MessageType::Unknown; break;
|
break;
|
||||||
|
case 1:
|
||||||
|
return MessageType::Forecast;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return MessageType::Unknown;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ int WeatherCallback(uint16_t /*connHandle*/, uint16_t /*attrHandle*/, struct ble
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleWeatherService::SimpleWeatherService(const DateTime& dateTimeController) : dateTimeController(dateTimeController) {
|
SimpleWeatherService::SimpleWeatherService(const DateTime& dateTimeController) : dateTimeController(dateTimeController) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleWeatherService::Init() {
|
void SimpleWeatherService::Init() {
|
||||||
|
@ -86,9 +85,9 @@ int SimpleWeatherService::OnCommand(struct ble_gatt_access_ctxt* ctxt) {
|
||||||
const auto* buffer = ctxt->om;
|
const auto* buffer = ctxt->om;
|
||||||
const auto* dataBuffer = buffer->om_data;
|
const auto* dataBuffer = buffer->om_data;
|
||||||
|
|
||||||
switch(GetMessageType(dataBuffer)) {
|
switch (GetMessageType(dataBuffer)) {
|
||||||
case MessageType::CurrentWeather:
|
case MessageType::CurrentWeather:
|
||||||
if(GetVersion(dataBuffer) == 0) {
|
if (GetVersion(dataBuffer) == 0) {
|
||||||
currentWeather = CreateCurrentWeather(dataBuffer);
|
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",
|
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,
|
currentWeather->timestamp,
|
||||||
|
@ -100,11 +99,15 @@ int SimpleWeatherService::OnCommand(struct ble_gatt_access_ctxt* ctxt) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MessageType::Forecast:
|
case MessageType::Forecast:
|
||||||
if(GetVersion(dataBuffer) == 0) {
|
if (GetVersion(dataBuffer) == 0) {
|
||||||
forecast = CreateForecast(dataBuffer);
|
forecast = CreateForecast(dataBuffer);
|
||||||
NRF_LOG_INFO("Forecast : Timestamp : %d", forecast->timestamp);
|
NRF_LOG_INFO("Forecast : Timestamp : %d", forecast->timestamp);
|
||||||
for(int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
NRF_LOG_INFO("\t[%d] Min: %d - Max : %d - Icon : %d", i, forecast->days[i].minTemperature, forecast->days[i].maxTemperature, forecast->days[i].iconId);
|
NRF_LOG_INFO("\t[%d] Min: %d - Max : %d - Icon : %d",
|
||||||
|
i,
|
||||||
|
forecast->days[i].minTemperature,
|
||||||
|
forecast->days[i].maxTemperature,
|
||||||
|
forecast->days[i].iconId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -116,13 +119,13 @@ int SimpleWeatherService::OnCommand(struct ble_gatt_access_ctxt* ctxt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<SimpleWeatherService::CurrentWeather> SimpleWeatherService::Current() const {
|
std::optional<SimpleWeatherService::CurrentWeather> SimpleWeatherService::Current() const {
|
||||||
if(currentWeather) {
|
if (currentWeather) {
|
||||||
auto currentTime = dateTimeController.UTCDateTime().time_since_epoch();
|
auto currentTime = dateTimeController.UTCDateTime().time_since_epoch();
|
||||||
auto weatherTpSecond = std::chrono::seconds{currentWeather->timestamp};
|
auto weatherTpSecond = std::chrono::seconds {currentWeather->timestamp};
|
||||||
auto weatherTp = std::chrono::duration_cast<std::chrono::seconds>(weatherTpSecond);
|
auto weatherTp = std::chrono::duration_cast<std::chrono::seconds>(weatherTpSecond);
|
||||||
auto delta = currentTime - weatherTp;
|
auto delta = currentTime - weatherTp;
|
||||||
|
|
||||||
if(delta < std::chrono::hours{24}) {
|
if (delta < std::chrono::hours {24}) {
|
||||||
return currentWeather;
|
return currentWeather;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,13 +133,13 @@ std::optional<SimpleWeatherService::CurrentWeather> SimpleWeatherService::Curren
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<SimpleWeatherService::Forecast> SimpleWeatherService::GetForecast() const {
|
std::optional<SimpleWeatherService::Forecast> SimpleWeatherService::GetForecast() const {
|
||||||
if(forecast) {
|
if (forecast) {
|
||||||
auto currentTime = dateTimeController.UTCDateTime().time_since_epoch();
|
auto currentTime = dateTimeController.UTCDateTime().time_since_epoch();
|
||||||
auto weatherTpSecond = std::chrono::seconds{forecast->timestamp};
|
auto weatherTpSecond = std::chrono::seconds {forecast->timestamp};
|
||||||
auto weatherTp = std::chrono::duration_cast<std::chrono::seconds>(weatherTpSecond);
|
auto weatherTp = std::chrono::duration_cast<std::chrono::seconds>(weatherTpSecond);
|
||||||
auto delta = currentTime - weatherTp;
|
auto delta = currentTime - weatherTp;
|
||||||
|
|
||||||
if(delta < std::chrono::hours{24}) {
|
if (delta < std::chrono::hours {24}) {
|
||||||
return this->forecast;
|
return this->forecast;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,12 +47,12 @@ namespace Pinetime {
|
||||||
int OnCommand(struct ble_gatt_access_ctxt* ctxt);
|
int OnCommand(struct ble_gatt_access_ctxt* ctxt);
|
||||||
|
|
||||||
enum class Icons : uint8_t {
|
enum class Icons : uint8_t {
|
||||||
Sun = 0, // ClearSky
|
Sun = 0, // ClearSky
|
||||||
CloudsSun = 1, // FewClouds
|
CloudsSun = 1, // FewClouds
|
||||||
Clouds = 2, // Scattered clouds
|
Clouds = 2, // Scattered clouds
|
||||||
BrokenClouds = 3,
|
BrokenClouds = 3,
|
||||||
CloudShowerHeavy = 4, // shower rain
|
CloudShowerHeavy = 4, // shower rain
|
||||||
CloudSunRain = 5, // rain
|
CloudSunRain = 5, // rain
|
||||||
Thunderstorm = 6,
|
Thunderstorm = 6,
|
||||||
Snow = 7,
|
Snow = 7,
|
||||||
Smog = 8, // Mist
|
Smog = 8, // Mist
|
||||||
|
@ -60,13 +60,21 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CurrentWeather {
|
struct CurrentWeather {
|
||||||
CurrentWeather(uint64_t timestamp, uint8_t temperature, uint8_t minTemperature, uint8_t maxTemperature,
|
CurrentWeather(uint64_t timestamp,
|
||||||
uint8_t iconId, const char* location)
|
uint8_t temperature,
|
||||||
: timestamp{timestamp}, temperature{temperature}, minTemperature{minTemperature}, maxTemperature{maxTemperature},
|
uint8_t minTemperature,
|
||||||
iconId{iconId} {
|
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);
|
std::memcpy(this->location, location, 32);
|
||||||
this->location[32] = 0;
|
this->location[32] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
uint8_t temperature;
|
uint8_t temperature;
|
||||||
uint8_t minTemperature;
|
uint8_t minTemperature;
|
||||||
|
@ -81,18 +89,19 @@ namespace Pinetime {
|
||||||
struct Forecast {
|
struct Forecast {
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
uint8_t nbDays;
|
uint8_t nbDays;
|
||||||
|
|
||||||
struct Day {
|
struct Day {
|
||||||
uint8_t minTemperature;
|
uint8_t minTemperature;
|
||||||
uint8_t maxTemperature;
|
uint8_t maxTemperature;
|
||||||
uint8_t iconId;
|
uint8_t iconId;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<Day, 5> days;
|
std::array<Day, 5> days;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::optional<CurrentWeather> Current() const;
|
std::optional<CurrentWeather> Current() const;
|
||||||
std::optional<Forecast> GetForecast() const;
|
std::optional<Forecast> GetForecast() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 00050000-78fc-48fe-8e23-433b3a1942d0
|
// 00050000-78fc-48fe-8e23-433b3a1942d0
|
||||||
static constexpr ble_uuid128_t BaseUuid() {
|
static constexpr ble_uuid128_t BaseUuid() {
|
||||||
|
@ -109,13 +118,12 @@ namespace Pinetime {
|
||||||
|
|
||||||
ble_uuid128_t weatherDataCharUuid {CharUuid(0x00, 0x01)};
|
ble_uuid128_t weatherDataCharUuid {CharUuid(0x00, 0x01)};
|
||||||
|
|
||||||
const struct ble_gatt_chr_def characteristicDefinition[2] = {
|
const struct ble_gatt_chr_def characteristicDefinition[2] = {{.uuid = &weatherDataCharUuid.u,
|
||||||
{.uuid = &weatherDataCharUuid.u,
|
.access_cb = WeatherCallback,
|
||||||
.access_cb = WeatherCallback,
|
.arg = this,
|
||||||
.arg = this,
|
.flags = BLE_GATT_CHR_F_WRITE,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE,
|
.val_handle = &eventHandle},
|
||||||
.val_handle = &eventHandle},
|
{0}};
|
||||||
{0}};
|
|
||||||
const struct ble_gatt_svc_def serviceDefinition[2] = {
|
const struct ble_gatt_svc_def serviceDefinition[2] = {
|
||||||
{.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &weatherUuid.u, .characteristics = characteristicDefinition},
|
{.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &weatherUuid.u, .characteristics = characteristicDefinition},
|
||||||
{0}};
|
{0}};
|
||||||
|
|
|
@ -122,7 +122,7 @@ void DisplayApp::PushMessage(Display::Messages msg) {
|
||||||
void DisplayApp::Register(Pinetime::System::SystemTask* /*systemTask*/) {
|
void DisplayApp::Register(Pinetime::System::SystemTask* /*systemTask*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayApp::Register(Pinetime::Controllers::WeatherService* /*weatherService*/) {
|
void DisplayApp::Register(Pinetime::Controllers::SimpleWeatherService* /*weatherService*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayApp::Register(Pinetime::Controllers::MusicService* /*musicService*/) {
|
void DisplayApp::Register(Pinetime::Controllers::MusicService* /*musicService*/) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Pinetime {
|
||||||
class AlarmController;
|
class AlarmController;
|
||||||
class BrightnessController;
|
class BrightnessController;
|
||||||
class FS;
|
class FS;
|
||||||
class WeatherService;
|
class SimpleWeatherService;
|
||||||
class MusicService;
|
class MusicService;
|
||||||
class NavigationService;
|
class NavigationService;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ namespace Pinetime {
|
||||||
|
|
||||||
void PushMessage(Pinetime::Applications::Display::Messages msg);
|
void PushMessage(Pinetime::Applications::Display::Messages msg);
|
||||||
void Register(Pinetime::System::SystemTask* systemTask);
|
void Register(Pinetime::System::SystemTask* systemTask);
|
||||||
void Register(Pinetime::Controllers::WeatherService* weatherService);
|
void Register(Pinetime::Controllers::SimpleWeatherService* weatherService);
|
||||||
void Register(Pinetime::Controllers::MusicService* musicService);
|
void Register(Pinetime::Controllers::MusicService* musicService);
|
||||||
void Register(Pinetime::Controllers::NavigationService* NavigationService);
|
void Register(Pinetime::Controllers::NavigationService* NavigationService);
|
||||||
|
|
||||||
|
|
|
@ -45,16 +45,36 @@ namespace {
|
||||||
|
|
||||||
const char* GetIcon(const Pinetime::Controllers::SimpleWeatherService::Icons icon) {
|
const char* GetIcon(const Pinetime::Controllers::SimpleWeatherService::Icons icon) {
|
||||||
switch (icon) {
|
switch (icon) {
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::Sun: return Symbols::sun; break;
|
case Pinetime::Controllers::SimpleWeatherService::Icons::Sun:
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::CloudsSun: return Symbols::cloudSun; break;
|
return Symbols::sun;
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::Clouds: return Symbols::cloud; break;
|
break;
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::BrokenClouds: return Symbols::cloud; break; // TODO missing symbol
|
case Pinetime::Controllers::SimpleWeatherService::Icons::CloudsSun:
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::Thunderstorm: return Symbols::cloud; break; // TODO missing symbol
|
return Symbols::cloudSun;
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::Snow: return Symbols::cloud; break; // TODO missing symbol
|
break;
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::CloudShowerHeavy: return Symbols::cloudShowersHeavy; break;
|
case Pinetime::Controllers::SimpleWeatherService::Icons::Clouds:
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::CloudSunRain: return Symbols::cloudSunRain; break;
|
return Symbols::cloud;
|
||||||
case Pinetime::Controllers::SimpleWeatherService::Icons::Smog: return Symbols::smog; break;
|
break;
|
||||||
default: return Symbols::ban; break;
|
case Pinetime::Controllers::SimpleWeatherService::Icons::BrokenClouds:
|
||||||
|
return Symbols::cloud;
|
||||||
|
break; // TODO missing symbol
|
||||||
|
case Pinetime::Controllers::SimpleWeatherService::Icons::Thunderstorm:
|
||||||
|
return Symbols::cloud;
|
||||||
|
break; // TODO missing symbol
|
||||||
|
case Pinetime::Controllers::SimpleWeatherService::Icons::Snow:
|
||||||
|
return Symbols::cloud;
|
||||||
|
break; // TODO missing symbol
|
||||||
|
case Pinetime::Controllers::SimpleWeatherService::Icons::CloudShowerHeavy:
|
||||||
|
return Symbols::cloudShowersHeavy;
|
||||||
|
break;
|
||||||
|
case Pinetime::Controllers::SimpleWeatherService::Icons::CloudSunRain:
|
||||||
|
return Symbols::cloudSunRain;
|
||||||
|
break;
|
||||||
|
case Pinetime::Controllers::SimpleWeatherService::Icons::Smog:
|
||||||
|
return Symbols::smog;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return Symbols::ban;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue