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];
static struct
{
// Must hold this lock to read/write the other values
le_mutex_Ref_t lock;
int64_t timestampNs;
double temperature;
} LastResult;
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)
{
......@@ -31,35 +34,63 @@ static int64_t GetTimestampNs(void)
le_result_t mangOH_ambientTemperature_Read(double *temperature)
{
// Use a cached value if the temperature was requested recently
const int64_t now = GetTimestampNs();
const int64_t minDelay = 60LL * 1000LL * 1000LL * 1000LL;
if (LastResult.timestampNs && ((now - LastResult.timestampNs) < minDelay))
{
le_mutex_Lock(LastResult.lock);
*temperature = LastResult.temperature;
le_mutex_Unlock(LastResult.lock);
return LE_OK;
}
}
static le_result_t UpdateAmbientTemperature(void)
{
json_t *response = OpenWeatherMapGet(Location.latitude, Location.longitude, ApiKey);
if (!response)
{
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);
if (unpackRes != 0)
{
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;
}
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
(
const char *intfName,
......@@ -70,11 +101,11 @@ static void DcsStateHandler
if (isConnected)
{
LE_INFO("Data connection established using interface %s", intfName);
// Now that we have a connection, advertise the ambient temperature service
if (!AmbientTemperatureServiceAdvertised)
// Now that we have a connection, start the thread which updates the temperature
if (!HttpThread)
{
AmbientTemperatureServiceAdvertised = true;
mangOH_ambientTemperature_AdvertiseService();
HttpThread = le_thread_Create("owm http", HttpThreadFunc, NULL);
le_thread_Start(HttpThread);
}
}
else
......@@ -91,6 +122,8 @@ COMPONENT_INIT
cfgRes != LE_OK || ApiKey[0] == '\0',
"Failed to read OpenWeatherMap API Key from config tree");
LastResult.lock = le_mutex_CreateNonRecursive("owm LastResult");
le_data_AddConnectionStateHandler(DcsStateHandler, NULL);
LE_DEBUG("Requesting data connection");
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