summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/ble/weather/WeatherService.cpp127
-rw-r--r--src/components/ble/weather/WeatherService.h31
2 files changed, 90 insertions, 68 deletions
diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp
index 42302610..4ec57d00 100644
--- a/src/components/ble/weather/WeatherService.cpp
+++ b/src/components/ble/weather/WeatherService.cpp
@@ -28,6 +28,7 @@ namespace Pinetime {
namespace Controllers {
WeatherService::WeatherService(System::SystemTask& system, DateTime& dateTimeController)
: system(system), dateTimeController(dateTimeController) {
+ nullHeader = &nullTimelineheader;
}
void WeatherService::Init() {
@@ -42,7 +43,7 @@ namespace Pinetime {
int WeatherService::OnCommand(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt) {
// TODO: Detect control messages
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
- const auto packetLen = OS_MBUF_PKTLEN(ctxt->om);
+ const uint8_t packetLen = OS_MBUF_PKTLEN(ctxt->om);
if (packetLen <= 0) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
@@ -56,30 +57,28 @@ namespace Pinetime {
// Always encodes to the smallest number of bytes based on the value
int64_t tmpTimestamp = 0;
QCBORDecode_GetInt64InMapSZ(&decodeContext, "Timestamp", &tmpTimestamp);
- if (QCBORDecode_GetError(&decodeContext) != QCBOR_SUCCESS) {
+ uint8_t err = QCBORDecode_GetError(&decodeContext);
+ if (err != QCBOR_SUCCESS) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
int64_t tmpExpires = 0;
QCBORDecode_GetInt64InMapSZ(&decodeContext, "Expires", &tmpExpires);
if (tmpExpires < 0 || tmpExpires > 4294967295) {
- // TODO: Return better error?
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
int64_t tmpEventType = 0;
QCBORDecode_GetInt64InMapSZ(&decodeContext, "EventType", &tmpEventType);
if (tmpEventType < 0 || tmpEventType > static_cast<int64_t>(WeatherData::eventtype::Length)) {
- // TODO: Return better error?
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
switch (static_cast<WeatherData::eventtype>(tmpEventType)) {
- // TODO: Populate
case WeatherData::eventtype::AirQuality: {
std::unique_ptr<WeatherData::AirQuality> airquality = std::make_unique<WeatherData::AirQuality>();
airquality->timestamp = tmpTimestamp;
airquality->eventType = static_cast<WeatherData::eventtype>(tmpEventType);
airquality->expires = tmpExpires;
- UsefulBufC String;
+ UsefulBufC String; // TODO: Everything ok with lifecycle here?
QCBORDecode_GetTextStringInMapSZ(&decodeContext, "Polluter", &String);
if (UsefulBuf_IsNULLOrEmptyC(String) != 0) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
@@ -172,10 +171,9 @@ namespace Pinetime {
}
}
- GetCurrentPressure();
- TidyTimeline();
- GetTimelineLength();
QCBORDecode_ExitMap(&decodeContext);
+ GetTimelineLength();
+ TidyTimeline();
if (QCBORDecode_Finish(&decodeContext) != QCBOR_SUCCESS) {
return BLE_ATT_ERR_INSUFFICIENT_RES;
@@ -205,94 +203,103 @@ namespace Pinetime {
return 0;
}
- WeatherData::Clouds WeatherService::GetCurrentClouds() const {
+ std::unique_ptr<WeatherData::Clouds>& WeatherService::GetCurrentClouds() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Clouds && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Clouds&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Clouds && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Clouds>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Clouds>&>(this->nullHeader);
}
- WeatherData::Obscuration WeatherService::GetCurrentObscuration() const {
+ std::unique_ptr<WeatherData::Obscuration>& WeatherService::GetCurrentObscuration() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Obscuration && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Obscuration&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Obscuration && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Obscuration>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Obscuration>&>(this->nullHeader);
}
- WeatherData::Precipitation WeatherService::GetCurrentPrecipitation() const {
+ std::unique_ptr<WeatherData::Precipitation>& WeatherService::GetCurrentPrecipitation() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Precipitation && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Precipitation&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Precipitation && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Precipitation>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Precipitation>&>(this->nullHeader);
}
- WeatherData::Wind WeatherService::GetCurrentWind() const {
+ std::unique_ptr<WeatherData::Wind>& WeatherService::GetCurrentWind() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Wind && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Wind&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Wind && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Wind>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Wind>&>(this->nullHeader);
}
- WeatherData::Temperature WeatherService::GetCurrentTemperature() const {
+ std::unique_ptr<WeatherData::Temperature>& WeatherService::GetCurrentTemperature() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Temperature && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Temperature&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Temperature && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Temperature>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Temperature>&>(this->nullHeader);
}
- WeatherData::Humidity WeatherService::GetCurrentHumidity() const {
+ std::unique_ptr<WeatherData::Humidity>& WeatherService::GetCurrentHumidity() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Humidity && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Humidity&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Humidity && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Humidity>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Humidity>&>(this->nullHeader);
}
- WeatherData::Pressure WeatherService::GetCurrentPressure() const {
+ std::unique_ptr<WeatherData::Pressure>& WeatherService::GetCurrentPressure() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Pressure && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Pressure&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Pressure && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Pressure>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Pressure>&>(this->nullHeader);
}
- WeatherData::Location WeatherService::GetCurrentLocation() const {
+ std::unique_ptr<WeatherData::Location>& WeatherService::GetCurrentLocation() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::Location && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::Location&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::Location && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::Location>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::Location>&>(this->nullHeader);
}
- WeatherData::AirQuality WeatherService::GetCurrentQuality() const {
+ std::unique_ptr<WeatherData::AirQuality>& WeatherService::GetCurrentQuality() {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
- for (auto&& header : timeline) {
- if (header->eventType == WeatherData::eventtype::AirQuality && header->timestamp + header->expires <= currentTimestamp) {
- return reinterpret_cast<const WeatherData::AirQuality&>(header);
+ for (auto&& header : this->timeline) {
+ if (header->eventType == WeatherData::eventtype::AirQuality && isEventStillValid(header, currentTimestamp)) {
+ return reinterpret_cast<std::unique_ptr<WeatherData::AirQuality>&>(header);
}
}
- return {};
+
+ return reinterpret_cast<std::unique_ptr<WeatherData::AirQuality>&>(this->nullHeader);
}
size_t WeatherService::GetTimelineLength() const {
@@ -311,8 +318,7 @@ namespace Pinetime {
bool WeatherService::HasTimelineEventOfType(const WeatherData::eventtype type) const {
uint64_t currentTimestamp = GetCurrentUnixTimestamp();
for (auto&& header : timeline) {
- if (header->eventType == type && header->timestamp + header->expires <= currentTimestamp) {
- // TODO: Check if its currently valid
+ if (header->eventType == type && isEventStillValid(header, currentTimestamp)) {
return true;
}
}
@@ -320,11 +326,11 @@ namespace Pinetime {
}
void WeatherService::TidyTimeline() {
- uint64_t timeCurrent = 0;
+ uint64_t timeCurrent = GetCurrentUnixTimestamp();
timeline.erase(std::remove_if(std::begin(timeline),
std::end(timeline),
[&](std::unique_ptr<WeatherData::TimelineHeader> const& header) {
- return header->timestamp + header->expires > timeCurrent;
+ return isEventStillValid(header, timeCurrent);
}),
std::end(timeline));
@@ -336,6 +342,11 @@ namespace Pinetime {
return first->timestamp > second->timestamp;
}
+ bool WeatherService::isEventStillValid(const std::unique_ptr<WeatherData::TimelineHeader>& header, const uint64_t currentTimestamp) {
+ // Not getting timestamp in isEventStillValid for more speed
+ return header->timestamp + header->expires <= currentTimestamp;
+ }
+
uint64_t WeatherService::GetCurrentUnixTimestamp() const {
return std::chrono::duration_cast<std::chrono::seconds>(dateTimeController.CurrentDateTime().time_since_epoch()).count();
}
diff --git a/src/components/ble/weather/WeatherService.h b/src/components/ble/weather/WeatherService.h
index 43b2ee28..7accc49e 100644
--- a/src/components/ble/weather/WeatherService.h
+++ b/src/components/ble/weather/WeatherService.h
@@ -51,15 +51,15 @@ namespace Pinetime {
/*
* Helper functions for quick access to currently valid data
*/
- WeatherData::Location GetCurrentLocation() const;
- WeatherData::Clouds GetCurrentClouds() const;
- WeatherData::Obscuration GetCurrentObscuration() const;
- WeatherData::Precipitation GetCurrentPrecipitation() const;
- WeatherData::Wind GetCurrentWind() const;
- WeatherData::Temperature GetCurrentTemperature() const;
- WeatherData::Humidity GetCurrentHumidity() const;
- WeatherData::Pressure GetCurrentPressure() const;
- WeatherData::AirQuality GetCurrentQuality() const;
+ std::unique_ptr<WeatherData::Location>& GetCurrentLocation();
+ std::unique_ptr<WeatherData::Clouds>& GetCurrentClouds();
+ std::unique_ptr<WeatherData::Obscuration>& GetCurrentObscuration();
+ std::unique_ptr<WeatherData::Precipitation>& GetCurrentPrecipitation();
+ std::unique_ptr<WeatherData::Wind>& GetCurrentWind();
+ std::unique_ptr<WeatherData::Temperature>& GetCurrentTemperature();
+ std::unique_ptr<WeatherData::Humidity>& GetCurrentHumidity();
+ std::unique_ptr<WeatherData::Pressure>& GetCurrentPressure();
+ std::unique_ptr<WeatherData::AirQuality>& GetCurrentQuality();
/*
* Management functions
@@ -123,7 +123,6 @@ namespace Pinetime {
/**
* Cleans up the timeline of expired events
- * @return result code
*/
void TidyTimeline();
@@ -137,6 +136,18 @@ namespace Pinetime {
* Returns current UNIX timestamp
*/
uint64_t GetCurrentUnixTimestamp() const;
+
+ /**
+ * Checks if the event hasn't gone past and expired
+ *
+ * @param header timeline event to check
+ * @param currentTimestamp what's the time right now
+ * @return if the event is valid
+ */
+ static bool isEventStillValid(const std::unique_ptr<WeatherData::TimelineHeader>& uniquePtr, const uint64_t timestamp);
+
+ std::unique_ptr<WeatherData::TimelineHeader> nullTimelineheader = std::make_unique<WeatherData::TimelineHeader>();
+ std::unique_ptr<WeatherData::TimelineHeader>* nullHeader;
};
}
}