summaryrefslogtreecommitdiff
path: root/libforecastio
diff options
context:
space:
mode:
Diffstat (limited to 'libforecastio')
-rw-r--r--libforecastio/forecast.c151
-rw-r--r--libforecastio/forecast.h101
-rw-r--r--libforecastio/forecastio.c173
-rw-r--r--libforecastio/forecastio.h39
-rw-r--r--libforecastio/forecasts.c120
-rw-r--r--libforecastio/forecasts.h34
-rw-r--r--libforecastio/locator.c54
-rw-r--r--libforecastio/locator.h22
8 files changed, 694 insertions, 0 deletions
diff --git a/libforecastio/forecast.c b/libforecastio/forecast.c
new file mode 100644
index 0000000..db09e36
--- /dev/null
+++ b/libforecastio/forecast.c
@@ -0,0 +1,151 @@
+#include <vdr/plugin.h>
+#include <string>
+#include <sstream>
+#include <jansson.h>
+#include "../tools/jsonhelpers.h"
+#include "forecast.h"
+
+using namespace std;
+
+cForecast::cForecast(void) {
+ type = ftUnknownForecast;
+ forecastTime = 0;
+ summary = "";
+ icon = "";
+ sunriseTime = 0;
+ sunsetTime = 0;
+ moonPhase = 0.0;
+ precipIntensity = 0.0;
+ precipProbability = 0.0;
+ percipType = "";
+ temperature = 0.0;
+ apparentTemperature = 0.0;
+ temperatureMin = 0.0;
+ temperatureMinTime = 0;
+ temperatureMax = 0.0;
+ temperatureMaxTime = 0;
+ humidity = 0.0;
+ windSpeed = 0.0;
+ windBearing = 0;
+ visibility = 0.0;
+ cloudCover = 0.0;
+ pressure = 0.0;
+ ozone = 0.0;
+}
+
+cForecast::~cForecast() {
+}
+
+void cForecast::SetForecast(json_t *forecast) {
+ forecastTime = JsonGetInteger(forecast, "time");
+ summary = JsonGetString(forecast, "summary");
+ icon = JsonGetString(forecast, "icon");
+ sunriseTime = JsonGetInteger(forecast, "sunriseTime");
+ sunsetTime = JsonGetInteger(forecast, "sunsetTime");
+ moonPhase = JsonGetFloat(forecast, "moonPhase");
+ precipIntensity = JsonGetFloat(forecast, "precipIntensity");
+ precipProbability = JsonGetFloat(forecast, "precipProbability");
+ percipType = JsonGetString(forecast, "percipType");
+ temperature = JsonGetFloat(forecast, "temperature");
+ apparentTemperature = JsonGetFloat(forecast, "apparentTemperature");
+ temperatureMin = JsonGetFloat(forecast, "temperatureMin");
+ temperatureMinTime = JsonGetInteger(forecast, "temperatureMinTime");
+ temperatureMax = JsonGetFloat(forecast, "temperatureMax");
+ temperatureMaxTime = JsonGetInteger(forecast, "temperatureMaxTime");
+ humidity = JsonGetFloat(forecast, "humidity");
+ windSpeed = JsonGetFloat(forecast, "windSpeed");
+ windBearing = JsonGetInteger(forecast, "windBearing");
+ visibility = JsonGetFloat(forecast, "visibility");
+ cloudCover = JsonGetFloat(forecast, "cloudCover");
+ pressure = JsonGetFloat(forecast, "pressure");
+ ozone = JsonGetFloat(forecast, "ozone");
+}
+
+bool cForecast::TimeMatch(time_t compare) {
+ //forecast is valid if time of forecast is between 30mins before or after compare time
+ int difference = abs(compare - forecastTime);
+ if (difference <= 1800)
+ return true;
+ return false;
+}
+
+bool cForecast::DayMatch(time_t compare) {
+ int difference = compare - forecastTime;
+ if (difference >= 0 && difference <= 86400)
+ return true;
+ return false;
+}
+
+string cForecast::GetDate(time_t myTime) {
+ struct tm *ts;
+ ts = localtime(&myTime);
+ return *cString::sprintf("%d.%02d", ts->tm_mday, ts->tm_mon+1);
+}
+
+string cForecast::GetTime(time_t myTime) {
+ struct tm *ts;
+ ts = localtime(&myTime);
+ return *cString::sprintf("%02d:%02d", ts->tm_hour, ts->tm_min);
+}
+
+string cForecast::GetDateTime(time_t myTime) {
+ struct tm *ts;
+ ts = localtime(&myTime);
+ return *cString::sprintf("%d.%02d %02d:%02d", ts->tm_mday, ts->tm_mon+1, ts->tm_hour, ts->tm_min);
+}
+
+string cForecast::GetWindBearingString(void) {
+ string sBearing = "";
+ if (windBearing >= 349 || windBearing <= 11) {
+ sBearing = "N";
+ } else if (windBearing > 11 && windBearing <= 34) {
+ sBearing = "NNE";
+ } else if (windBearing > 34 && windBearing <= 56) {
+ sBearing = "NE";
+ } else if (windBearing > 56 && windBearing <= 79) {
+ sBearing = "ENE";
+ } else if (windBearing > 79 && windBearing <= 101) {
+ sBearing = "E";
+ } else if (windBearing > 101 && windBearing <= 123) {
+ sBearing = "ESE";
+ } else if (windBearing > 123 && windBearing <= 145) {
+ sBearing = "SE";
+ } else if (windBearing > 145 && windBearing <= 168) {
+ sBearing = "SSE";
+ } else if (windBearing > 168 && windBearing <= 191) {
+ sBearing = "S";
+ } else if (windBearing > 191 && windBearing <= 213) {
+ sBearing = "SSW";
+ } else if (windBearing > 213 && windBearing <= 235) {
+ sBearing = "SW";
+ } else if (windBearing > 235 && windBearing <= 258) {
+ sBearing = "WSW";
+ } else if (windBearing > 258 && windBearing <= 281) {
+ sBearing = "W";
+ } else if (windBearing > 281 && windBearing <= 303) {
+ sBearing = "WNW";
+ } else if (windBearing > 303 && windBearing <= 325) {
+ sBearing = "NW";
+ } else if (windBearing > 325 && windBearing <= 348) {
+ sBearing = "NNW";
+ }
+ return sBearing;
+}
+
+void cForecast::Debug(bool verbose) {
+ if (type == ftCurrent) {
+ dsyslog("weatherforecast: current weather for %s at %s, summary: \"%s\", icon: \"%s\"", GetDate(forecastTime).c_str(), GetTime(forecastTime).c_str(), summary.c_str(), icon.c_str());
+ } else if (type == ftHourly) {
+ dsyslog("weatherforecast: hourly weather for %s on %s, summary: \"%s\", icon: \"%s\"", GetDate(forecastTime).c_str(), GetTime(forecastTime).c_str(), summary.c_str(), icon.c_str());
+ } else if (type == ftDaily) {
+ dsyslog("weatherforecast: daily weather for %s, summary: \"%s\", icon: \"%s\"", GetDate(forecastTime).c_str(), summary.c_str(), icon.c_str());
+ }
+
+ if (!verbose)
+ return;
+ dsyslog("weatherforecast: sunrise time %ld, sunset time: %ld, moon phase %f", sunriseTime, sunsetTime, moonPhase);
+ dsyslog("weatherforecast: min temp %f at %ld, max temp %f at %ld", temperatureMin, temperatureMinTime, temperatureMax, temperatureMaxTime);
+ dsyslog("weatherforecast: precipInt %f, precipProp: %f, type %s", precipIntensity, precipProbability, percipType.c_str());
+ dsyslog("weatherforecast: temperature %f °C, apparentTemp %f °C, humidity: %f", temperature, apparentTemperature, humidity);
+ dsyslog("weatherforecast: windSpeed %f, windBearing: %d, visibility %f, cloudCover: %f, pressure %f, ozone: %f", windSpeed, windBearing, visibility, cloudCover, pressure, ozone);
+}
diff --git a/libforecastio/forecast.h b/libforecastio/forecast.h
new file mode 100644
index 0000000..ccb250d
--- /dev/null
+++ b/libforecastio/forecast.h
@@ -0,0 +1,101 @@
+#ifndef __FORECAST_H
+#define __FORECAST_H
+
+#include <string>
+#include <jansson.h>
+
+using namespace std;
+
+enum eForecastType {
+ ftUnknownForecast,
+ ftCurrent,
+ ftHourly,
+ ftDaily,
+};
+
+class cForecast {
+private:
+ eForecastType type;
+ time_t forecastTime;
+ string summary;
+ string icon;
+ time_t sunriseTime;
+ time_t sunsetTime;
+ float moonPhase;
+ float precipIntensity;
+ float precipProbability;
+ string percipType;
+ float temperature;
+ float apparentTemperature;
+ float temperatureMin;
+ time_t temperatureMinTime;
+ float temperatureMax;
+ time_t temperatureMaxTime;
+ float humidity;
+ float windSpeed;
+ int windBearing;
+ float visibility;
+ float cloudCover;
+ float pressure;
+ float ozone;
+ string GetDate(time_t myTime);
+ string GetTime(time_t myTime);
+ string GetDateTime(time_t myTime);
+public:
+ cForecast(void);
+ virtual ~cForecast(void);
+ void SetForecast(json_t *forecast);
+ void SetForecastType(eForecastType type) { this->type = type; };
+ bool TimeMatch(time_t compare);
+ bool DayMatch(time_t compare);
+ void Debug(bool verbose = false);
+ //Getter Functions for native access to data
+ time_t GetTime(void) { return forecastTime; };
+ string GetSummary(void) { return summary; };
+ string GetIcon(void) { return icon; };
+ time_t GetSunrise(void) { return sunriseTime; };
+ time_t GetSunset(void) { return sunsetTime; };
+ float GetMoonphase(void) { return moonPhase; };
+ float GetPrecipIntensity(void) { return precipIntensity; };
+ float GetPrecipProbability(void) { return precipProbability; };
+ string GetPercipType(void) { return percipType; };
+ float GetTemperature(void) { return temperature; };
+ float GetTemperatureMin(void) { return temperatureMin; };
+ time_t GetTemperatureMinTime(void) { return temperatureMinTime; };
+ float GetTemperatureMax(void) { return temperatureMax; };
+ time_t GetTemperatureMaxTime(void) { return temperatureMaxTime; };
+ float GetApparentTemperature(void) { return apparentTemperature; };
+ float GetHumidity(void) { return humidity; };
+ float GetWindSpeed(void) { return windSpeed; };
+ int GetWindBearing(void) { return windBearing; };
+ float GetVisibility(void) { return visibility; };
+ float GetCloudCover(void) { return cloudCover; };
+ float GetPressure(void) { return pressure; };
+ float GetOzone(void) { return ozone; };
+ //convenient Getter Functions
+ string GetDateTimeString(void) { return GetDateTime(forecastTime); };
+ string GetDateString(void) { return GetDate(forecastTime); };
+ string GetTimeString(void) { return GetTime(forecastTime); };
+ string GetDayName(void) { return *WeekDayName(forecastTime); };
+ string GetSunriseString(void) { return GetTime(sunriseTime); };
+ string GetSunsetString(void) { return GetTime(sunsetTime); };
+ int GetMoonphasePercent(void) { return (int)(moonPhase*100); };
+ string GetPrecipIntensityString(void) { return *cString::sprintf("%.1f", precipIntensity); };
+ int GetPrecipProbabilityPercent(void) { return (int)(precipProbability*100); };
+ string GetTemperatureString(void) { return *cString::sprintf("%.1f", temperature); };
+ string GetTemperatureMinString(void) { return *cString::sprintf("%.1f", temperatureMin); };
+ string GetTemperatureMinTimeString(void) { return GetTime(temperatureMinTime); };
+ string GetTemperatureMaxString(void) { return *cString::sprintf("%.1f", temperatureMax); };
+ string GetTemperatureMaxTimeString(void) { return GetTime(temperatureMaxTime); };
+ string GetApparentTemperatureString(void) { return *cString::sprintf("%.1f", apparentTemperature); };
+ int GetHumidityPercent(void) { return (int)(humidity*100); };
+ string GetWindSpeedString(void) { return *cString::sprintf("%.1f", windSpeed); };
+ string GetWindBearingString(void);
+ string GetVisibilityString(void) { return *cString::sprintf("%.1f", visibility); };
+ int GetCloudCoverPercent(void) { return (int)(cloudCover*100); };
+ string GetPressureString(void) { return *cString::sprintf("%.1f", pressure); };
+ string GetOzoneString(void) { return *cString::sprintf("%.1f", ozone); };
+};
+
+
+#endif //__FORECASTIO_H \ No newline at end of file
diff --git a/libforecastio/forecastio.c b/libforecastio/forecastio.c
new file mode 100644
index 0000000..1a8db4e
--- /dev/null
+++ b/libforecastio/forecastio.c
@@ -0,0 +1,173 @@
+#include <vdr/plugin.h>
+#include <string>
+#include <sstream>
+#include <jansson.h>
+#include "../config.h"
+#include "../tools/curlfuncs.h"
+#include "../tools/filesystem.h"
+#include "forecastio.h"
+
+using namespace std;
+extern cWeatherforecastConfig weatherConfig;
+
+cForecastIO::cForecastIO(string cacheDir) {
+ this->cacheDir = cacheDir;
+ ok = false;
+ cacheDuration = 60 * 60 * weatherConfig.hoursToUpdate;
+ apiKey = "9830052ef63efbec84ec0639e9a205d2";
+ string osdLanguage = Setup.OSDLanguage;
+ language = osdLanguage.substr(0,2);
+ unit = "si";
+ baseURL = "https://api.forecast.io/forecast";
+ latitude = weatherConfig.lat;
+ longitude = weatherConfig.lon;
+ current = NULL;
+ hourly = NULL;
+ daily = NULL;
+}
+
+cForecastIO::~cForecastIO() {
+ if (current)
+ delete current;
+ if (hourly)
+ delete hourly;
+ if (daily)
+ delete daily;
+}
+
+/*****************************************************************
+* PUBLIC FUNCTIONS
+*****************************************************************/
+void cForecastIO::Action(void) {
+ ok = ReadForecast();
+}
+
+cForecast *cForecastIO::GetCurrentForecast(void) {
+ time_t now = time(0);
+ if (current && current->TimeMatch(now))
+ return current;
+ if (hourly)
+ return hourly->GetCurrent();
+ return NULL;
+}
+
+bool cForecastIO::SetCurrentWeather(cServiceCurrentWeather *call) {
+ cForecast *currentForecast = GetCurrentForecast();
+ if (!currentForecast)
+ return false;
+ call->timeStamp = currentForecast->GetDateTimeString();
+ call->temperature = currentForecast->GetTemperatureString();
+ call->apparentTemperature = currentForecast->GetApparentTemperatureString();
+ call->summary = currentForecast->GetSummary();
+ call->icon = currentForecast->GetIcon();
+ call->precipitationIntensity = currentForecast->GetPrecipIntensityString();
+ call->precipitationProbability = currentForecast->GetPrecipProbabilityPercent();
+ call->precipitationType = currentForecast->GetPercipType();
+ call->humidity = currentForecast->GetHumidityPercent();
+ call->windSpeed = currentForecast->GetWindSpeedString();
+ call->windBearing = currentForecast->GetWindBearing();
+ call->windBearingString = currentForecast->GetWindBearingString();
+ call->visibility = currentForecast->GetVisibilityString();
+ call->cloudCover = currentForecast->GetCloudCoverPercent();
+ call->pressure = currentForecast->GetPressureString();
+ call->ozone = currentForecast->GetOzoneString();
+
+ cForecast *dailyForecast = daily->GetFirstDaily();
+ if (!dailyForecast)
+ return true;
+ call->minTemperature = dailyForecast->GetTemperatureMinString();
+ call->maxTemperature = dailyForecast->GetTemperatureMaxString();
+
+ return true;
+}
+
+/*****************************************************************
+* 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 = "";
+ if (!FileExists(forecastFile)) {
+ //get new from forecast.io
+ dsyslog("weatherforecast: no cached forecast, fetching 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);
+ }
+ }
+ ParseForecast(forecastJson);
+
+ return true;
+}
+
+string cForecastIO::FetchOnlineForecast(void) {
+ stringstream url;
+ url << baseURL << "/" << apiKey;
+ url << "/" << latitude << "," << longitude;
+ url << "?lang=" << language << "&units=" << unit;
+ string outputForecastIO;
+ esyslog("weatherforecast: calling URL %s", url.str().c_str());
+ CurlGetUrl(url.str().c_str(), &outputForecastIO);
+ return outputForecastIO;
+}
+
+bool cForecastIO::ParseForecast(string &jsonForecast) {
+ json_t *root;
+ json_error_t error;
+
+ root = json_loads(jsonForecast.c_str(), 0, &error);
+ if ( !root ) {
+ return false;
+ }
+ if ( !json_is_object(root) ) {
+ return false;
+ }
+
+ //reading current weather
+ json_t *currentWeather = json_object_get(root, "currently");
+ if (!json_is_object(currentWeather)) {
+ return false;
+ }
+ current = new cForecast();
+ current->SetForecastType(ftCurrent);
+ current->SetForecast(currentWeather);
+ //current->Debug();
+
+ //reading 48 hour forecast
+ json_t *hourlyWeather = json_object_get(root, "hourly");
+ if (!json_is_object(hourlyWeather)) {
+ return false;
+ }
+ hourly = new cForecasts();
+ hourly->SetForecastType(ftHourly);
+ hourly->SetForecast(hourlyWeather);
+ //hourly->Debug();
+
+ //reading 7 day forecast
+ json_t *dailyWeather = json_object_get(root, "daily");
+ if (!json_is_object(dailyWeather)) {
+ return false;
+ }
+ daily = new cForecasts();
+ daily->SetForecastType(ftDaily);
+ daily->SetForecast(dailyWeather);
+ //daily->Debug();
+
+ return true;
+}
diff --git a/libforecastio/forecastio.h b/libforecastio/forecastio.h
new file mode 100644
index 0000000..c016fb2
--- /dev/null
+++ b/libforecastio/forecastio.h
@@ -0,0 +1,39 @@
+#ifndef __FORECASTIO_H
+#define __FORECASTIO_H
+
+#include <string>
+#include "forecasts.h"
+#include "forecast.h"
+#include "../services.h"
+
+using namespace std;
+
+class cForecastIO : public cThread {
+private:
+ bool ok;
+ string cacheDir;
+ int cacheDuration;
+ string apiKey;
+ string language;
+ string unit;
+ string baseURL;
+ double latitude;
+ double longitude;
+ cForecast *current;
+ cForecasts *hourly;
+ cForecasts *daily;
+ string FetchOnlineForecast(void);
+ bool ParseForecast(string &jsonForecast);
+ void Action(void);
+ bool ReadForecast(void);
+public:
+ cForecastIO(string cacheDir);
+ virtual ~cForecastIO(void);
+ cForecast *GetCurrentForecast(void);
+ cForecasts *GetHourlyForecast(void) { return hourly; };
+ cForecasts *GetDailyForecast(void) { return daily; };
+ bool SetCurrentWeather(cServiceCurrentWeather *call);
+};
+
+
+#endif //__FORECASTIO_H \ No newline at end of file
diff --git a/libforecastio/forecasts.c b/libforecastio/forecasts.c
new file mode 100644
index 0000000..d7cb908
--- /dev/null
+++ b/libforecastio/forecasts.c
@@ -0,0 +1,120 @@
+#include <vdr/plugin.h>
+#include <string>
+#include <sstream>
+#include <jansson.h>
+#include "../tools/jsonhelpers.h"
+#include "forecasts.h"
+
+using namespace std;
+
+cForecasts::cForecasts(void) {
+ type = ftUnknownForecast;
+ summary = "";
+ icon = "";
+ numDataPoints = 0;
+ dataPointPointer = 0;
+ dataPoints = NULL;
+}
+
+cForecasts::~cForecasts() {
+ if (dataPoints && numDataPoints > 0) {
+ for (int i=0; i<numDataPoints; i++) {
+ if (dataPoints[i])
+ delete dataPoints[i];
+ }
+ delete[] dataPoints;
+ }
+}
+
+void cForecasts::SetForecast(json_t *forecast) {
+
+ summary = JsonGetString(forecast, "summary");
+ icon = JsonGetString(forecast, "icon");
+
+ json_t *data = json_object_get(forecast, "data");
+ if ( !json_is_array(data) ) {
+ return;
+ }
+ numDataPoints = json_array_size(data);
+
+ dataPoints = new cForecast*[numDataPoints];
+
+ for (int i = 0; i < numDataPoints; i++) {
+ json_t *jDataPoint = json_array_get(data, i);
+ cForecast *dataPoint = new cForecast();
+ dataPoint->SetForecast(jDataPoint);
+ dataPoint->SetForecastType(type);
+ dataPoints[i] = dataPoint;
+ }
+}
+
+cForecast *cForecasts::GetForecast(int dataPoint) {
+ if (!dataPoints)
+ return NULL;
+ if (dataPoint < 0 || dataPoint >= numDataPoints)
+ return NULL;
+ return dataPoints[dataPoint];
+}
+
+cForecast *cForecasts::GetCurrent(void) {
+ if (!dataPoints)
+ return NULL;
+ time_t now = time(0);
+ for (int i=0; i<numDataPoints; i++) {
+ if (dataPoints[i] && dataPoints[i]->TimeMatch(now))
+ return dataPoints[i];
+ }
+ return NULL;
+}
+
+cForecast *cForecasts::GetFirstHourly(void) {
+ if (!dataPoints)
+ return NULL;
+ time_t now = time(0);
+ for (int i=0; i<numDataPoints; i++) {
+ if (dataPoints[i] && dataPoints[i]->TimeMatch(now)) {
+ dataPointPointer = i;
+ return dataPoints[dataPointPointer];
+ }
+ }
+ return NULL;
+}
+
+cForecast *cForecasts::GetFirstDaily(void) {
+ if (!dataPoints)
+ return NULL;
+ time_t now = time(0);
+ for (int i=0; i<numDataPoints; i++) {
+ if (dataPoints[i] && dataPoints[i]->DayMatch(now)) {
+ dataPointPointer = i;
+ return dataPoints[dataPointPointer];
+ }
+ }
+ return NULL;
+}
+
+
+cForecast *cForecasts::GetNext(void) {
+ if (!dataPoints)
+ return NULL;
+ dataPointPointer++;
+ if (dataPointPointer < numDataPoints) {
+ return dataPoints[dataPointPointer];
+ }
+ dataPointPointer = 0;
+ return NULL;
+}
+
+void cForecasts::Debug(void) {
+ if (type == ftHourly) {
+ dsyslog("weatherforecast: 48 hour forecast");
+ } else if (type == ftDaily) {
+ dsyslog("weatherforecast: 7 day forecast");
+ }
+ dsyslog("weatherforecast: summary: \"%s\"", summary.c_str());
+ dsyslog("weatherforecast: icon: \"%s\"", icon.c_str());
+ for (int i = 0; i < numDataPoints; i++) {
+ dsyslog("weatherforecast: ------------ %s %d -----------", (type == ftHourly)?"Hour":"Day", i);
+ dataPoints[i]->Debug();
+ }
+}
diff --git a/libforecastio/forecasts.h b/libforecastio/forecasts.h
new file mode 100644
index 0000000..9730823
--- /dev/null
+++ b/libforecastio/forecasts.h
@@ -0,0 +1,34 @@
+#ifndef __FORECASTS_H
+#define __FORECASTS_H
+
+#include <string>
+#include <jansson.h>
+#include "forecast.h"
+
+using namespace std;
+
+class cForecasts {
+private:
+ eForecastType type;
+ string summary;
+ string icon;
+ int numDataPoints;
+ int dataPointPointer;
+ cForecast **dataPoints;
+public:
+ cForecasts(void);
+ virtual ~cForecasts(void);
+ void SetForecast(json_t *forecast);
+ void SetForecastType(eForecastType type) { this->type = type; };
+ string GetSummary(void) { return summary; };
+ string GetIcon(void) { return icon; };
+ cForecast *GetForecast(int dataPoint);
+ cForecast *GetCurrent(void);
+ cForecast *GetFirstHourly(void);
+ cForecast *GetFirstDaily(void);
+ cForecast *GetNext(void);
+ void Debug(void);
+};
+
+
+#endif //__FORECASTS_H \ No newline at end of file
diff --git a/libforecastio/locator.c b/libforecastio/locator.c
new file mode 100644
index 0000000..ef2216d
--- /dev/null
+++ b/libforecastio/locator.c
@@ -0,0 +1,54 @@
+#include <vdr/plugin.h>
+#include <jansson.h>
+#include "../tools/curlfuncs.h"
+#include "../tools/jsonhelpers.h"
+#include "locator.h"
+
+using namespace std;
+
+cForecastLocator::cForecastLocator(void) {
+ urlIPLApi = "http://ip-api.com/json";
+ city = "";
+ lat = 0.0;
+ lon = 0.0;
+}
+
+cForecastLocator::~cForecastLocator() {
+
+}
+
+bool cForecastLocator::ReadLocationByIP(void) {
+ string outputJson;
+ CurlGetUrl(urlIPLApi.c_str(), &outputJson);
+
+ json_t *root;
+ json_error_t error;
+
+ root = json_loads(outputJson.c_str(), 0, &error);
+ if ( !root ) {
+ return false;
+ }
+ if ( !json_is_object(root) ) {
+ return false;
+ }
+
+ city = JsonGetString(root, "city");
+ lat = JsonGetFloat(root, "lat");
+ lon = JsonGetFloat(root, "lon");
+
+ dsyslog("weatherforecast: location read from IP: city \"%s\", latitude: %f, longitude: %f", city.c_str(), lat, lon);
+
+ return true;
+}
+
+void cForecastLocator::WriteToSetup(cPlugin *weatherPlug) {
+ //save to setup
+ weatherPlug->SetupStore("city", city.c_str());
+ weatherPlug->SetupStore("lat", FloatToString(lat).c_str());
+ weatherPlug->SetupStore("lon", FloatToString(lon).c_str());
+ //set values in plugin config
+ weatherPlug->SetupParse("city", city.c_str());
+ weatherPlug->SetupParse("lat", FloatToString(lat).c_str());
+ weatherPlug->SetupParse("lon", FloatToString(lon).c_str());
+}
+
diff --git a/libforecastio/locator.h b/libforecastio/locator.h
new file mode 100644
index 0000000..b29637e
--- /dev/null
+++ b/libforecastio/locator.h
@@ -0,0 +1,22 @@
+#ifndef __FORECASTLOCATOR_H
+#define __FORECASTLOCATOR_H
+
+#include <string>
+
+using namespace std;
+
+class cForecastLocator {
+private:
+ string urlIPLApi;
+ string city;
+ float lat;
+ float lon;
+public:
+ cForecastLocator(void);
+ virtual ~cForecastLocator(void);
+ bool ReadLocationByIP(void);
+ void WriteToSetup(cPlugin *weatherPlug);
+};
+
+
+#endif //__FORECASTLOCATOR_H \ No newline at end of file