BigW Consortium Gitlab

Commit 06e84ac8 by David Frey

update OpenWeatherMap ambient temp in background

Update in the background instead of on demand to prevent blocking for long periods of time.
parent f8424710
...@@ -16,11 +16,14 @@ static char ApiKey[32 + 1]; ...@@ -16,11 +16,14 @@ static char ApiKey[32 + 1];
static struct static struct
{ {
// Must hold this lock to read/write the other values
le_mutex_Ref_t lock;
int64_t timestampNs; int64_t timestampNs;
double temperature; double temperature;
} LastResult; } LastResult;
static le_data_RequestObjRef_t DataRequest = NULL; static le_data_RequestObjRef_t DataRequest = NULL;
static bool AmbientTemperatureServiceAdvertised = false; static le_thread_Ref_t HttpThread = NULL;
static le_timer_Ref_t UpdateTimer;
static int64_t GetTimestampNs(void) static int64_t GetTimestampNs(void)
{ {
...@@ -31,35 +34,63 @@ static int64_t GetTimestampNs(void) ...@@ -31,35 +34,63 @@ static int64_t GetTimestampNs(void)
le_result_t mangOH_ambientTemperature_Read(double *temperature) le_result_t mangOH_ambientTemperature_Read(double *temperature)
{ {
// Use a cached value if the temperature was requested recently le_mutex_Lock(LastResult.lock);
const int64_t now = GetTimestampNs(); *temperature = LastResult.temperature;
const int64_t minDelay = 60LL * 1000LL * 1000LL * 1000LL; le_mutex_Unlock(LastResult.lock);
if (LastResult.timestampNs && ((now - LastResult.timestampNs) < minDelay)) return LE_OK;
{ }
*temperature = LastResult.temperature;
return LE_OK;
}
static le_result_t UpdateAmbientTemperature(void)
{
json_t *response = OpenWeatherMapGet(Location.latitude, Location.longitude, ApiKey); json_t *response = OpenWeatherMapGet(Location.latitude, Location.longitude, ApiKey);
if (!response) if (!response)
{ {
return LE_FAULT; return LE_FAULT;
} }
const int unpackRes = json_unpack(response, "{s:{s:f}}", "main", "temp", temperature); double temperature;
const int unpackRes = json_unpack(response, "{s:{s:f}}", "main", "temp", &temperature);
json_decref(response); json_decref(response);
if (unpackRes != 0) if (unpackRes != 0)
{ {
return LE_FAULT; return LE_FAULT;
} }
LE_DEBUG("Received ambient temperature reading: %f", *temperature); LE_DEBUG("Received OpenWeatherMap temperature: %f", temperature);
le_mutex_Lock(LastResult.lock);
LastResult.timestampNs = GetTimestampNs();
LastResult.temperature = temperature;
le_mutex_Unlock(LastResult.lock);
LastResult.timestampNs = now;
LastResult.temperature = *temperature;
return LE_OK; return LE_OK;
} }
void UpdateTimerHandler(le_timer_Ref_t timer)
{
UpdateAmbientTemperature();
}
void *HttpThreadFunc(void *context)
{
while (UpdateAmbientTemperature() != LE_OK)
{
sleep(20);
}
// A temperature is available, so advertise the service
mangOH_ambientTemperature_AdvertiseService();
UpdateTimer = le_timer_Create("owm ambient");
LE_ASSERT_OK(le_timer_SetHandler(UpdateTimer, UpdateTimerHandler));
LE_ASSERT_OK(le_timer_SetMsInterval(UpdateTimer, 1000 * 60 * 1));
LE_ASSERT_OK(le_timer_SetRepeat(UpdateTimer, 0));
LE_ASSERT_OK(le_timer_Start(UpdateTimer));
le_event_RunLoop();
return NULL;
}
static void DcsStateHandler static void DcsStateHandler
( (
const char *intfName, const char *intfName,
...@@ -70,11 +101,11 @@ static void DcsStateHandler ...@@ -70,11 +101,11 @@ static void DcsStateHandler
if (isConnected) if (isConnected)
{ {
LE_INFO("Data connection established using interface %s", intfName); LE_INFO("Data connection established using interface %s", intfName);
// Now that we have a connection, advertise the ambient temperature service // Now that we have a connection, start the thread which updates the temperature
if (!AmbientTemperatureServiceAdvertised) if (!HttpThread)
{ {
AmbientTemperatureServiceAdvertised = true; HttpThread = le_thread_Create("owm http", HttpThreadFunc, NULL);
mangOH_ambientTemperature_AdvertiseService(); le_thread_Start(HttpThread);
} }
} }
else else
...@@ -91,6 +122,8 @@ COMPONENT_INIT ...@@ -91,6 +122,8 @@ COMPONENT_INIT
cfgRes != LE_OK || ApiKey[0] == '\0', cfgRes != LE_OK || ApiKey[0] == '\0',
"Failed to read OpenWeatherMap API Key from config tree"); "Failed to read OpenWeatherMap API Key from config tree");
LastResult.lock = le_mutex_CreateNonRecursive("owm LastResult");
le_data_AddConnectionStateHandler(DcsStateHandler, NULL); le_data_AddConnectionStateHandler(DcsStateHandler, NULL);
LE_DEBUG("Requesting data connection"); LE_DEBUG("Requesting data connection");
DataRequest = le_data_Request(); DataRequest = le_data_Request();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment