Simple Weather Service
Store temperatures as int16_t (instead of uint8_t previously). The temperature is expressed in °C * 100.
This commit is contained in:
parent
ad090ab188
commit
e5b73212f6
|
@ -28,11 +28,11 @@ The byte array must contain the following data:
|
||||||
- [0] : Message type = `0`
|
- [0] : Message type = `0`
|
||||||
- [1] : Message version = `0`
|
- [1] : Message version = `0`
|
||||||
- [2][3][4][5][6][7][8][9] : Timestamp (64 bits UNIX timestamp, number of nanoseconds elapsed since 1 JAN 1970)
|
- [2][3][4][5][6][7][8][9] : Timestamp (64 bits UNIX timestamp, number of nanoseconds elapsed since 1 JAN 1970)
|
||||||
- [10] : Current temperature (°C)
|
- [10, 11] : Current temperature (°C * 100)
|
||||||
- [11] : Minimum temperature (°C)
|
- [12, 13] : Minimum temperature (°C * 100)
|
||||||
- [12] : Maximum temperature (°C)
|
- [14, 15] : Maximum temperature (°C * 100)
|
||||||
- [13]..[44] : location (string, unused characters should be set to `0`)
|
- [16]..[47] : location (string, unused characters should be set to `0`)
|
||||||
- [45] : icon ID
|
- [48] : icon ID
|
||||||
- 0 = Sun, clear sky
|
- 0 = Sun, clear sky
|
||||||
- 1 = Few clouds
|
- 1 = Few clouds
|
||||||
- 2 = Clouds
|
- 2 = Clouds
|
||||||
|
@ -48,21 +48,21 @@ The byte array must contain the following data:
|
||||||
The byte array must contain the following data:
|
The byte array must contain the following data:
|
||||||
|
|
||||||
- [0] : Message type = `0`
|
- [0] : Message type = `0`
|
||||||
- [0] : Message version = `0`
|
- [1] : Message version = `0`
|
||||||
- [2][3][4][5][6][7][8][9] : Timestamp (64 bits UNIX timestamp, number of nanoseconds elapsed since 1 JAN 1970)
|
- [2][3][4][5][6][7][8][9] : Timestamp (64 bits UNIX timestamp, number of nanoseconds elapsed since 1 JAN 1970)
|
||||||
- [10] Number of days (Max 5, fields for unused days should be set to `0`)
|
- [10] Number of days (Max 5, fields for unused days should be set to `0`)
|
||||||
- [11] Day 0 Minimum temperature
|
- [11,12] Day 0 Minimum temperature (°C * 100)
|
||||||
- [12] Day 0 Maximum temperature
|
- [13,14] Day 0 Maximum temperature (°C * 100)
|
||||||
- [13] Day 0 Icon ID
|
- [15] Day 0 Icon ID
|
||||||
- [14] Day 1 Minimum temperature
|
- [16,17] Day 1 Minimum temperature (°C * 100)
|
||||||
- [15] Day 1 Maximum temperature
|
- [18,19] Day 1 Maximum temperature (°C * 100)
|
||||||
- [16] Day 1 Icon ID
|
- [20] Day 1 Icon ID
|
||||||
- [17] Day 2 Minimum temperature
|
- [21,22] Day 2 Minimum temperature (°C * 100)
|
||||||
- [18] Day 2 Maximum temperature
|
- [23,24] Day 2 Maximum temperature (°C * 100)
|
||||||
- [19] Day 2 Icon ID
|
- [25] Day 2 Icon ID
|
||||||
- [20] Day 3 Minimum temperature
|
- [26,27] Day 3 Minimum temperature (°C * 100)
|
||||||
- [21] Day 3 Maximum temperature
|
- [28,29] Day 3 Maximum temperature (°C * 100)
|
||||||
- [22] Day 3 Icon ID
|
- [30] Day 3 Icon ID
|
||||||
- [23] Day 4 Minimum temperature
|
- [31,32] Day 4 Minimum temperature (°C * 100)
|
||||||
- [24] Day 4 Maximum temperature
|
- [33,34] Day 4 Maximum temperature (°C * 100)
|
||||||
- [25] Day 4 Icon ID
|
- [35] Day 4 Icon ID
|
|
@ -29,18 +29,30 @@ namespace {
|
||||||
enum class MessageType : uint8_t { CurrentWeather, Forecast, Unknown };
|
enum class MessageType : uint8_t { CurrentWeather, Forecast, Unknown };
|
||||||
|
|
||||||
uint64_t ToUInt64(const uint8_t* data) {
|
uint64_t ToUInt64(const uint8_t* data) {
|
||||||
return *(reinterpret_cast<const uint64_t*>(data));
|
return data[0] +
|
||||||
|
(data[1] << 8) +
|
||||||
|
(data[2] << 16) +
|
||||||
|
(data[3] << 24) +
|
||||||
|
(static_cast<uint64_t>(data[4]) << 32) +
|
||||||
|
(static_cast<uint64_t>(data[5]) << 48) +
|
||||||
|
(static_cast<uint64_t>(data[6]) << 48) +
|
||||||
|
(static_cast<uint64_t>(data[7]) << 56);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t ToInt16(const uint8_t* data) {
|
||||||
|
return data[0] +
|
||||||
|
(data[1] << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleWeatherService::CurrentWeather CreateCurrentWeather(const uint8_t* dataBuffer) {
|
SimpleWeatherService::CurrentWeather CreateCurrentWeather(const uint8_t* dataBuffer) {
|
||||||
SimpleWeatherService::Location cityName;
|
SimpleWeatherService::Location cityName;
|
||||||
std::memcpy(cityName.data(), &dataBuffer[13], 32);
|
std::memcpy(cityName.data(), &dataBuffer[16], 32);
|
||||||
cityName[32] = '\0';
|
cityName[32] = '\0';
|
||||||
return SimpleWeatherService::CurrentWeather (ToUInt64(&dataBuffer[2]),
|
return SimpleWeatherService::CurrentWeather (ToUInt64(&dataBuffer[2]),
|
||||||
dataBuffer[10],
|
ToInt16(&dataBuffer[10]),
|
||||||
dataBuffer[11],
|
ToInt16(&dataBuffer[12]),
|
||||||
dataBuffer[12],
|
ToInt16(&dataBuffer[14]),
|
||||||
SimpleWeatherService::Icons{dataBuffer[13 + 32]},
|
SimpleWeatherService::Icons{dataBuffer[16 + 32]},
|
||||||
std::move(cityName));
|
std::move(cityName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +63,10 @@ namespace {
|
||||||
const uint8_t nbDaysInBuffer = dataBuffer[10];
|
const uint8_t nbDaysInBuffer = dataBuffer[10];
|
||||||
const uint8_t nbDays = std::min(SimpleWeatherService::MaxNbForecastDays, nbDaysInBuffer);
|
const uint8_t nbDays = std::min(SimpleWeatherService::MaxNbForecastDays, nbDaysInBuffer);
|
||||||
for (int i = 0; i < nbDays; i++) {
|
for (int i = 0; i < nbDays; i++) {
|
||||||
days[i] = SimpleWeatherService::Forecast::Day {dataBuffer[11 + (i * 3)], dataBuffer[12 + (i * 3)], SimpleWeatherService::Icons{dataBuffer[13 + (i * 3)]}};
|
days[i] = SimpleWeatherService::Forecast::Day {
|
||||||
|
ToInt16(&dataBuffer[11 + (i * 5)]),
|
||||||
|
ToInt16(&dataBuffer[13 + (i * 5)]),
|
||||||
|
SimpleWeatherService::Icons{dataBuffer[15 + (i * 5)]}};
|
||||||
}
|
}
|
||||||
return SimpleWeatherService::Forecast {timestamp, nbDays, days};
|
return SimpleWeatherService::Forecast {timestamp, nbDays, days};
|
||||||
}
|
}
|
||||||
|
@ -95,7 +110,7 @@ int SimpleWeatherService::OnCommand(struct ble_gatt_access_ctxt* ctxt) {
|
||||||
currentWeather->minTemperature,
|
currentWeather->minTemperature,
|
||||||
currentWeather->maxTemperature,
|
currentWeather->maxTemperature,
|
||||||
currentWeather->iconId,
|
currentWeather->iconId,
|
||||||
currentWeather->location);
|
currentWeather->location.data());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MessageType::Forecast:
|
case MessageType::Forecast:
|
||||||
|
|
|
@ -64,9 +64,9 @@ namespace Pinetime {
|
||||||
using Location = std::array<char, 33>; // 32 char + \0 (end of string)
|
using Location = std::array<char, 33>; // 32 char + \0 (end of string)
|
||||||
struct CurrentWeather {
|
struct CurrentWeather {
|
||||||
CurrentWeather(uint64_t timestamp,
|
CurrentWeather(uint64_t timestamp,
|
||||||
uint8_t temperature,
|
int16_t temperature,
|
||||||
uint8_t minTemperature,
|
int16_t minTemperature,
|
||||||
uint8_t maxTemperature,
|
int16_t maxTemperature,
|
||||||
Icons iconId,
|
Icons iconId,
|
||||||
Location&& location)
|
Location&& location)
|
||||||
: timestamp {timestamp},
|
: timestamp {timestamp},
|
||||||
|
@ -78,9 +78,9 @@ namespace Pinetime {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
uint8_t temperature;
|
int16_t temperature;
|
||||||
uint8_t minTemperature;
|
int16_t minTemperature;
|
||||||
uint8_t maxTemperature;
|
int16_t maxTemperature;
|
||||||
Icons iconId;
|
Icons iconId;
|
||||||
Location location;
|
Location location;
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ namespace Pinetime {
|
||||||
uint8_t nbDays;
|
uint8_t nbDays;
|
||||||
|
|
||||||
struct Day {
|
struct Day {
|
||||||
uint8_t minTemperature;
|
int16_t minTemperature;
|
||||||
uint8_t maxTemperature;
|
int16_t maxTemperature;
|
||||||
Icons iconId;
|
Icons iconId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -543,7 +543,7 @@ void WatchFacePineTimeStyle::Refresh() {
|
||||||
if (currentWeather.IsUpdated()) {
|
if (currentWeather.IsUpdated()) {
|
||||||
auto optCurrentWeather = currentWeather.Get();
|
auto optCurrentWeather = currentWeather.Get();
|
||||||
if (optCurrentWeather) {
|
if (optCurrentWeather) {
|
||||||
lv_label_set_text_fmt(temperature, "%d°", optCurrentWeather->temperature);
|
lv_label_set_text_fmt(temperature, "%d°", (optCurrentWeather->temperature)/100);
|
||||||
lv_label_set_text(weatherIcon, Symbols::GetSymbol(optCurrentWeather->iconId));
|
lv_label_set_text(weatherIcon, Symbols::GetSymbol(optCurrentWeather->iconId));
|
||||||
lv_obj_realign(temperature);
|
lv_obj_realign(temperature);
|
||||||
lv_obj_realign(weatherIcon);
|
lv_obj_realign(weatherIcon);
|
||||||
|
|
Loading…
Reference in a new issue