summaryrefslogtreecommitdiff
path: root/libforecastio
diff options
context:
space:
mode:
authorlouis <louis.braun@gmx.de>2015-01-17 10:23:39 +0100
committerlouis <louis.braun@gmx.de>2015-01-17 10:23:39 +0100
commita5aa281e337f148e27b17c287e04d8a023856667 (patch)
tree6ff69709bfd9815ece9b29a31ae8397653ff8848 /libforecastio
parentc7f71f3f2b580714bd9e5a5c773bc2179c0e8567 (diff)
downloadvdr-plugin-weatherforecast-a5aa281e337f148e27b17c287e04d8a023856667.tar.gz
vdr-plugin-weatherforecast-a5aa281e337f148e27b17c287e04d8a023856667.tar.bz2
added possibility to use own api key0.0.2
Diffstat (limited to 'libforecastio')
-rw-r--r--libforecastio/forecastio.c138
-rw-r--r--libforecastio/forecastio.h18
2 files changed, 117 insertions, 39 deletions
diff --git a/libforecastio/forecastio.c b/libforecastio/forecastio.c
index 1a8db4e..83b9df9 100644
--- a/libforecastio/forecastio.c
+++ b/libforecastio/forecastio.c
@@ -11,9 +11,8 @@ using namespace std;
extern cWeatherforecastConfig weatherConfig;
cForecastIO::cForecastIO(string cacheDir) {
- this->cacheDir = cacheDir;
- ok = false;
- cacheDuration = 60 * 60 * weatherConfig.hoursToUpdate;
+ forecastFile = *cString::sprintf("%s/%s", cacheDir.c_str(), "weather.json");
+ cacheDurationDefault = 60 * 60 * weatherConfig.hoursToUpdate;
apiKey = "9830052ef63efbec84ec0639e9a205d2";
string osdLanguage = Setup.OSDLanguage;
language = osdLanguage.substr(0,2);
@@ -27,27 +26,42 @@ cForecastIO::cForecastIO(string cacheDir) {
}
cForecastIO::~cForecastIO() {
- if (current)
- delete current;
- if (hourly)
- delete hourly;
- if (daily)
- delete daily;
+ Clear();
}
/*****************************************************************
* PUBLIC FUNCTIONS
*****************************************************************/
void cForecastIO::Action(void) {
- ok = ReadForecast();
+ loopActive = true;
+ ReadForecastInitial();
+ waitMutex.Lock();
+ while (loopActive && Running()) {
+ waitCondition.TimedWait(waitMutex, 1000 * 60);
+ if (!loopActive)
+ return;
+ if (!CacheFileValid()) {
+ ReadForecast();
+ }
+ }
+}
+
+void cForecastIO::Stop() {
+ loopActive = false;
+ waitCondition.Broadcast();
+ Cancel(1);
+ while (Active())
+ cCondWait::SleepMs(10);
}
cForecast *cForecastIO::GetCurrentForecast(void) {
time_t now = time(0);
- if (current && current->TimeMatch(now))
+ if (current && current->TimeMatch(now)) {
return current;
- if (hourly)
+ }
+ if (hourly) {
return hourly->GetCurrent();
+ }
return NULL;
}
@@ -55,6 +69,7 @@ bool cForecastIO::SetCurrentWeather(cServiceCurrentWeather *call) {
cForecast *currentForecast = GetCurrentForecast();
if (!currentForecast)
return false;
+
call->timeStamp = currentForecast->GetDateTimeString();
call->temperature = currentForecast->GetTemperatureString();
call->apparentTemperature = currentForecast->GetApparentTemperatureString();
@@ -75,6 +90,7 @@ bool cForecastIO::SetCurrentWeather(cServiceCurrentWeather *call) {
cForecast *dailyForecast = daily->GetFirstDaily();
if (!dailyForecast)
return true;
+
call->minTemperature = dailyForecast->GetTemperatureMinString();
call->maxTemperature = dailyForecast->GetTemperatureMaxString();
@@ -84,41 +100,93 @@ bool cForecastIO::SetCurrentWeather(cServiceCurrentWeather *call) {
/*****************************************************************
* PRIVATE FUNCTIONS
*****************************************************************/
-bool cForecastIO::ReadForecast(void) {
- string forecastFile = *cString::sprintf("%s/%s", cacheDir.c_str(), "weather.json");
- dsyslog("weatherforecast: trying to read cached forecast from %s", forecastFile.c_str());
- string forecastJson = "";
+
+void cForecastIO::Clear(void) {
+ if (current) {
+ delete current;
+ current = NULL;
+ }
+ if (hourly) {
+ delete hourly;
+ hourly = NULL;
+ }
+ if (daily) {
+ delete daily;
+ daily = NULL;
+ }
+}
+
+bool cForecastIO::CheckUserApiKey(void) {
+ if (weatherConfig.userApiKey.size() == 0)
+ return false;
+ if (weatherConfig.userApiKey.compare(apiKey) == 0) {
+ return false;
+ }
+ return true;
+}
+
+int cForecastIO::CalculateCachDuration(void) {
+ if (!CheckUserApiKey())
+ return cacheDurationDefault;
+ if (weatherConfig.userHoursToUpdate > 0 && weatherConfig.userHoursToUpdate <= 24) {
+ return weatherConfig.userHoursToUpdate * 60 * 60;
+ }
+ return cacheDurationDefault;
+}
+
+bool cForecastIO::CacheFileValid(void) {
if (!FileExists(forecastFile)) {
+ dsyslog("weatherforecast: no cached forecast available");
+ return false;
+ }
+ int cacheDuration = CalculateCachDuration();
+ time_t fileCreation = FileCreationTime(forecastFile);
+ time_t now = time(0);
+ int age = now - fileCreation;
+ int ageHours = age / 3600;
+ int ageMinutes = (age%3600) / 60;
+ if (age > cacheDuration) {
+ dsyslog("weatherforecast: cached forecast is outdated (age %dh %dmin, cache duration %dh)", ageHours, ageMinutes, cacheDuration / 3600);
+ return false;
+ }
+ return true;
+}
+
+void cForecastIO::ReadForecastInitial(void) {
+ string forecastJson = "";
+ if (!CacheFileValid()) {
//get new from forecast.io
- dsyslog("weatherforecast: no cached forecast, fetching newly from forecast.io");
+ dsyslog("weatherforecast: fetching forecast newly from forecast.io");
forecastJson = FetchOnlineForecast();
WriteIntoFile(forecastFile, forecastJson);
} else {
- //check if cached file is too old
- time_t fileCreation = FileCreationTime(forecastFile);
- time_t now = time(0);
- int age = now - fileCreation;
- int ageHours = age / 3600;
- int ageMinutes = (age%3600) / 60;
- if (age > cacheDuration) {
- //get new from forecast.io
- dsyslog("weatherforecast: cached forecast is with %dh %dmin too old, fetching newly from forecast.io", ageHours, ageMinutes);
- forecastJson = FetchOnlineForecast();
- WriteIntoFile(forecastFile, forecastJson);
- } else {
- //using cached data
- dsyslog("weatherforecast: cached forecast is only %dh %dmin old, using cached forecast", ageHours, ageMinutes);
- forecastJson = ReadFromFile(forecastFile);
- }
+ //using cached data
+ dsyslog("weatherforecast: using cached forecast");
+ forecastJson = ReadFromFile(forecastFile);
}
ParseForecast(forecastJson);
- return true;
+}
+
+void cForecastIO::ReadForecast(void) {
+ dsyslog("weatherforecast: updating forecast from forecast.io");
+ string forecastJson = "";
+ forecastJson = FetchOnlineForecast();
+ if (forecastJson.size() > 0) {
+ WriteIntoFile(forecastFile, forecastJson);
+ Lock();
+ Clear();
+ ParseForecast(forecastJson);
+ Unlock();
+ }
}
string cForecastIO::FetchOnlineForecast(void) {
+ string myApiKey = apiKey;
+ if (CheckUserApiKey())
+ myApiKey = weatherConfig.userApiKey;
stringstream url;
- url << baseURL << "/" << apiKey;
+ url << baseURL << "/" << myApiKey;
url << "/" << latitude << "," << longitude;
url << "?lang=" << language << "&units=" << unit;
string outputForecastIO;
diff --git a/libforecastio/forecastio.h b/libforecastio/forecastio.h
index c016fb2..bc45e2c 100644
--- a/libforecastio/forecastio.h
+++ b/libforecastio/forecastio.h
@@ -10,9 +10,8 @@ using namespace std;
class cForecastIO : public cThread {
private:
- bool ok;
- string cacheDir;
- int cacheDuration;
+ string forecastFile;
+ int cacheDurationDefault;
string apiKey;
string language;
string unit;
@@ -22,13 +21,24 @@ private:
cForecast *current;
cForecasts *hourly;
cForecasts *daily;
+ bool loopActive;
+ cCondVar waitCondition;
+ cMutex waitMutex;
+ bool CheckUserApiKey(void);
+ int CalculateCachDuration(void);
+ bool CacheFileValid(void);
string FetchOnlineForecast(void);
bool ParseForecast(string &jsonForecast);
void Action(void);
- bool ReadForecast(void);
+ void Clear(void);
+ void ReadForecastInitial(void);
+ void ReadForecast(void);
public:
cForecastIO(string cacheDir);
virtual ~cForecastIO(void);
+ void Stop(void);
+ void LockForecasts(void) { Lock(); };
+ void UnlockForecasts(void) { Unlock(); };
cForecast *GetCurrentForecast(void);
cForecasts *GetHourlyForecast(void) { return hourly; };
cForecasts *GetDailyForecast(void) { return daily; };