summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY3
-rw-r--r--config.c35
-rw-r--r--config.h6
-rw-r--r--displaymenu.c165
-rw-r--r--displaymenu.h1
-rw-r--r--icons/default/widgets/clear-day.pngbin0 -> 4980 bytes
-rw-r--r--icons/default/widgets/clear-night.pngbin0 -> 3115 bytes
-rw-r--r--icons/default/widgets/cloudy.pngbin0 -> 6433 bytes
-rw-r--r--icons/default/widgets/fog.pngbin0 -> 3652 bytes
-rw-r--r--icons/default/widgets/partly-cloudy-day.pngbin0 -> 7028 bytes
-rw-r--r--icons/default/widgets/partly-cloudy-night.pngbin0 -> 6409 bytes
-rw-r--r--icons/default/widgets/rain.pngbin0 -> 6021 bytes
-rw-r--r--icons/default/widgets/sleet.pngbin0 -> 5681 bytes
-rw-r--r--icons/default/widgets/snow.pngbin0 -> 7660 bytes
-rw-r--r--icons/default/widgets/thunderstorm.pngbin0 -> 6644 bytes
-rw-r--r--icons/default/widgets/umbrella.pngbin0 -> 2290 bytes
-rw-r--r--icons/default/widgets/weather.pngbin0 -> 2290 bytes
-rw-r--r--icons/default/widgets/wind.pngbin0 -> 2568 bytes
-rw-r--r--po/de_DE.po47
-rw-r--r--preview/Zitrone.pngbin0 -> 31595 bytes
-rw-r--r--setup.c41
-rw-r--r--widgets/weather/lib/forecast.io.php431
-rw-r--r--widgets/weather/update_weather.php117
23 files changed, 805 insertions, 41 deletions
diff --git a/HISTORY b/HISTORY
index 3fb24bcb..45ac4eb7 100644
--- a/HISTORY
+++ b/HISTORY
@@ -4,6 +4,7 @@ VDR Plugin 'skinflatplus' Revision History
2014-MM-DD: Version 0.5.0
- [add] main menu widgets
- there are several widgets that can be displayed in the main menu
+ - Widget weather
- Widget dvb devices
- Widget active timer
- Widget timer conflicts
@@ -20,6 +21,8 @@ VDR Plugin 'skinflatplus' Revision History
- add more default themes: DeepOrange, DeepPurple, Indigo, Red, Teal
- [update] icons
- update many icons with android material design icons
+- [update] MV-Themes
+ - see MV_Themes.HISTORY
2014-10-29: Version 0.4.3
- [add] option to draw the menu background over the entire height
diff --git a/config.c b/config.c
index acd27cfe..71a393ea 100644
--- a/config.c
+++ b/config.c
@@ -79,33 +79,38 @@ cFlatConfig::cFlatConfig(void) {
MainMenuItemScale = 0.5;
MainMenuWidgetDVBDevicesShow = true;
- MainMenuWidgetDVBDevicesPosition = 1;
+ MainMenuWidgetDVBDevicesPosition = 2;
MainMenuWidgetActiveTimerShow = true;
- MainMenuWidgetActiveTimerPosition = 2;
+ MainMenuWidgetActiveTimerPosition = 3;
MainMenuWidgetActiveTimerMaxCount = 2;
MainMenuWidgetActiveTimerHideEmpty = false;
MainMenuWidgetLastRecShow = false;
- MainMenuWidgetLastRecPosition = 3;
+ MainMenuWidgetLastRecPosition = 4;
MainMenuWidgetLastRecMaxCount = 3;
MainMenuWidgetTimerConflictsShow = false;
- MainMenuWidgetTimerConflictsPosition = 4;
+ MainMenuWidgetTimerConflictsPosition = 5;
MainMenuWidgetTimerConflictsHideEmpty = false;
MainMenuWidgetSystemInfoShow = true;
- MainMenuWidgetSystemInfoPosition = 5;
+ MainMenuWidgetSystemInfoPosition = 6;
MainMenuWidgetSystemUpdatesShow = true;
- MainMenuWidgetSystemUpdatesPosition = 6;
+ MainMenuWidgetSystemUpdatesPosition = 7;
MainMenuWidgetSystemUpdatesHideIfZero = 0;
MainMenuWidgetTemperaturesShow = true;
- MainMenuWidgetTemperaturesPosition = 7;
+ MainMenuWidgetTemperaturesPosition = 8;
MainMenuWidgetCommandShow = true;
- MainMenuWidgetCommandPosition = 8;
+ MainMenuWidgetCommandPosition = 9;
+
+ MainMenuWidgetWeatherShow = true;
+ MainMenuWidgetWeatherPosition = 1;
+ MainMenuWidgetWeatherDays = 5;
+ MainMenuWidgetWeatherType = 0;
TopBarFontClockScale = 0.01;
TopBarHideClockText = 0;
@@ -327,6 +332,10 @@ bool cFlatConfig::SetupParse(const char *Name, const char *Value) {
else if (strcmp(Name, "MainMenuWidgetTemperaturesPosition") == 0) MainMenuWidgetTemperaturesPosition = atoi(Value);
else if (strcmp(Name, "MainMenuWidgetCommandShow") == 0) MainMenuWidgetCommandShow = atoi(Value);
else if (strcmp(Name, "MainMenuWidgetCommandPosition") == 0) MainMenuWidgetCommandPosition = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherShow") == 0) MainMenuWidgetWeatherShow = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherPosition") == 0) MainMenuWidgetWeatherPosition = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherDays") == 0) MainMenuWidgetWeatherDays = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherType") == 0) MainMenuWidgetWeatherType = atoi(Value);
else return false;
@@ -607,6 +616,16 @@ bool pairCompareIntString(const std::pair<int, std::string>&i, const std::pair<i
return i.first > j.first;
}
+int roundUp(int numToRound, int multiple)
+{
+ if(multiple == 0)
+ return numToRound;
+ int remainder = numToRound % multiple;
+ if (remainder == 0)
+ return numToRound;
+ return numToRound + multiple - remainder;
+}
+
void cFlatConfig::DecorDescriptions(cStringList &Decors) {
cString decorPath = cString::sprintf("%s/decors", PLUGINRESOURCEPATH);
std::vector<std::string> files;
diff --git a/config.h b/config.h
index 68bbf478..2dc7b0e0 100644
--- a/config.h
+++ b/config.h
@@ -12,6 +12,7 @@
bool stringCompare( const std::string &left, const std::string &right );
bool pairCompareTimeStringDesc(const std::pair<time_t, std::string>&i, const std::pair<time_t, std::string>&j);
bool pairCompareIntString(const std::pair<int, std::string>&i, const std::pair<int, std::string>&j);
+int roundUp(int numToRound, int multiple);
class cFlatConfig
{
@@ -279,6 +280,11 @@ class cFlatConfig
int MainMenuWidgetCommandShow;
int MainMenuWidgetCommandPosition;
+ int MainMenuWidgetWeatherShow;
+ int MainMenuWidgetWeatherPosition;
+ int MainMenuWidgetWeatherType;
+ int MainMenuWidgetWeatherDays;
+
// TVScraper
int TVScraperChanInfoShowPoster;
double TVScraperChanInfoPosterSize;
diff --git a/displaymenu.c b/displaymenu.c
index 83b7174a..a0cdb4b6 100644
--- a/displaymenu.c
+++ b/displaymenu.c
@@ -3907,6 +3907,8 @@ void cFlatDisplayMenu::DrawMainMenuWidgets(void) {
widgets.push_back(std::make_pair(Config.MainMenuWidgetTimerConflictsPosition, "timer_conflicts"));
if( Config.MainMenuWidgetCommandShow )
widgets.push_back(std::make_pair(Config.MainMenuWidgetCommandPosition, "custom_command"));
+ if( Config.MainMenuWidgetWeatherShow )
+ widgets.push_back(std::make_pair(Config.MainMenuWidgetWeatherPosition, "weather"));
std::sort(widgets.begin(), widgets.end(), pairCompareIntString);
@@ -3947,6 +3949,10 @@ void cFlatDisplayMenu::DrawMainMenuWidgets(void) {
int addHeight = DrawMainMenuWidgetCommand(wLeft, wWidth, ContentTop);
if( addHeight > 0 )
ContentTop = addHeight + marginItem;
+ } else if( widget.compare("weather") == 0 ) {
+ int addHeight = DrawMainMenuWidgetWeather(wLeft, wWidth, ContentTop);
+ if( addHeight > 0 )
+ ContentTop = addHeight + marginItem;
}
}
@@ -4610,6 +4616,165 @@ int cFlatDisplayMenu::DrawMainMenuWidgetCommand(int wLeft, int wWidth, int Conte
return contentWidget.ContentHeight(false);
}
+int cFlatDisplayMenu::DrawMainMenuWidgetWeather(int wLeft, int wWidth, int ContentTop) {
+ if( ContentTop + fontHeight + 6 + fontSmlHeight > menuPixmap->ViewPort().Height() )
+ return -1;
+
+ cFont *fontTempSml = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize/2.0 );
+
+ std::string Location;
+ cString locationFilename = cString::sprintf("%s/widgets/weather/weather.location", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N) );
+ std::ifstream file(*locationFilename, std::ifstream::in);
+ if( file.is_open() ) {
+ std::getline(file, Location);
+ file.close();
+ } else {
+ Location = tr("Unknown");
+ }
+ cString Title = cString::sprintf("%s - %s", tr("Weather"), Location.c_str());
+
+ cImage *img = imgLoader.LoadIcon("widgets/weather", fontHeight, fontHeight - marginItem*2);
+ if( img ) {
+ contentWidget.AddImage(img, cRect(marginItem, ContentTop + marginItem, fontHeight, fontHeight));
+ }
+ contentWidget.AddText(*Title, false, cRect(marginItem*2 + fontHeight, ContentTop, 0, 0), Theme.Color(clrMenuEventFontTitle), Theme.Color(clrMenuEventBg), font);
+ ContentTop += fontHeight;
+ contentWidget.AddRect(cRect(0, ContentTop, wWidth, 3), Theme.Color(clrMenuEventTitleLine));
+ ContentTop += 6;
+
+ int left = marginItem;
+ for( int index = 0; index < Config.MainMenuWidgetWeatherDays; index++ ) {
+ std::string icon;
+ cString iconFilename = cString::sprintf("%s/widgets/weather/weather.%d.icon", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index );
+ std::ifstream file(*iconFilename, std::ifstream::in);
+ if( file.is_open() ) {
+ std::getline(file, icon);
+ file.close();
+ } else
+ continue;
+
+ std::string summary;
+ cString summaryFilename = cString::sprintf("%s/widgets/weather/weather.%d.summary", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index );
+ std::ifstream file2(*summaryFilename, std::ifstream::in);
+ if( file2.is_open() ) {
+ std::getline(file2, summary);
+ file2.close();
+ } else
+ continue;
+
+ std::string tempMax;
+ cString tempMaxFilename = cString::sprintf("%s/widgets/weather/weather.%d.tempMax", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index );
+ std::ifstream file3(*tempMaxFilename, std::ifstream::in);
+ if( file3.is_open() ) {
+ std::getline(file3, tempMax);
+ file3.close();
+ } else
+ continue;
+
+ std::string tempMin;
+ cString tempMinFilename = cString::sprintf("%s/widgets/weather/weather.%d.tempMin", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index );
+ std::ifstream file4(*tempMinFilename, std::ifstream::in);
+ if( file4.is_open() ) {
+ std::getline(file4, tempMin);
+ file4.close();
+ } else
+ continue;
+
+ std::string prec;
+ double p = 0.0;
+ cString precString = "0%";
+ cString precFilename = cString::sprintf("%s/widgets/weather/weather.%d.precipitation", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index );
+ std::ifstream file5(*precFilename, std::ifstream::in);
+ if( file5.is_open() ) {
+ std::getline(file5, prec);
+ std::replace( prec.begin(), prec.end(), '.', ',');
+ file5.close();
+ p = atof(prec.c_str()) * 100.0;
+ p = roundUp(p, 10);
+ precString = cString::sprintf("%.0f%%", p);
+ dsyslog("WEATHER: %s %f %s", prec.c_str(), p, *precString);
+ } else
+ continue;
+
+ std::string precType;
+ cString precTypeFilename = cString::sprintf("%s/widgets/weather/weather.%d.precipitationType", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index );
+ std::ifstream file6(*precTypeFilename, std::ifstream::in);
+ if( file6.is_open() ) {
+ std::getline(file6, precType);
+ file6.close();
+ } else
+ continue;
+
+ cString weekDayName = "";
+ time_t t;
+ time(&t);
+ struct tm* tm = localtime(&t);
+ tm->tm_mday += index;
+ time_t t2 = mktime(tm);
+ weekDayName = WeekDayName(t2);
+
+ if( Config.MainMenuWidgetWeatherType == 0 ) { // short
+ if( left + fontHeight*2 + font->Width("XXX") + font->Width("XXXX") + marginItem*6 > wWidth )
+ break;
+ if( index > 0 ) {
+ contentWidget.AddText("|", false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font);
+ left += font->Width("|") + marginItem*2;
+ }
+
+ cString weatherIcon = cString::sprintf("widgets/%s", icon.c_str());
+ cImage *img = imgLoader.LoadIcon(*weatherIcon, fontHeight, fontHeight - marginItem*2);
+ if( img ) {
+ contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight));
+ left += fontHeight + marginItem;
+ }
+ contentWidget.AddText(tempMax.c_str(), false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml);
+ contentWidget.AddText(tempMin.c_str(), false, cRect(left, ContentTop + fontTempSml->Height(), 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml);
+ left += font->Width("XXX") + marginItem;
+
+ img = imgLoader.LoadIcon("widgets/umbrella", fontHeight, fontHeight - marginItem*2);
+ if( img ) {
+ contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight));
+ left += fontHeight - marginItem;
+ }
+ contentWidget.AddText(*precString, false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font);
+ left += font->Width(*precString) + marginItem*2;
+ } else { // long
+ if( ContentTop + marginItem > menuPixmap->ViewPort().Height() )
+ break;
+
+ left = marginItem;
+
+ cString dayname = cString::sprintf("%s ", *weekDayName);
+ contentWidget.AddText(*dayname, false, cRect(left, ContentTop, wWidth - marginItem*2, fontHeight), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font, wWidth - marginItem*2);
+ left += font->Width("XXXX") + marginItem;
+
+ cString weatherIcon = cString::sprintf("widgets/%s", icon.c_str());
+ cImage *img = imgLoader.LoadIcon(*weatherIcon, fontHeight, fontHeight - marginItem*2);
+ if( img ) {
+ contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight));
+ left += fontHeight + marginItem;
+ }
+ contentWidget.AddText(tempMax.c_str(), false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml);
+ contentWidget.AddText(tempMin.c_str(), false, cRect(left, ContentTop + fontTempSml->Height(), 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml);
+ left += font->Width("XXX") + marginItem;
+
+ img = imgLoader.LoadIcon("widgets/umbrella", fontHeight, fontHeight - marginItem*2);
+ if( img ) {
+ contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight));
+ left += fontHeight - marginItem;
+ }
+ contentWidget.AddText(*precString, false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font);
+ left += font->Width("XXXX") + marginItem;
+
+ contentWidget.AddText(summary.c_str(), true, cRect(left, ContentTop, wWidth - left, fontHeight), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml, wWidth - left, fontHeight);
+
+ ContentTop += fontHeight;
+ }
+
+ }
+ return contentWidget.ContentHeight(false);
+}
+
/*
int cFlatDisplayMenu::DrawMainMenuWidgetTimerConflicts(int wLeft, int wTop, int wWidth) {
int wHeight = fontHeight + 6 + (Config.MainMenuWidgetLastRecMaxCount * fontSmlHeight) + Config.decorBorderMenuContentSize*2;
diff --git a/displaymenu.h b/displaymenu.h
index 3d803820..adca16c6 100644
--- a/displaymenu.h
+++ b/displaymenu.h
@@ -99,6 +99,7 @@ class cFlatDisplayMenu : public cFlatBaseRender, public cSkinDisplayMenu {
int DrawMainMenuWidgetSystemUpdates(int wLeft, int wWidth, int ContentTop);
int DrawMainMenuWidgetTemperaturs(int wLeft, int wWidth, int ContentTop);
int DrawMainMenuWidgetCommand(int wLeft, int wWidth, int ContentTop);
+ int DrawMainMenuWidgetWeather(int wLeft, int wWidth, int ContentTop);
public:
cFlatDisplayMenu(void);
diff --git a/icons/default/widgets/clear-day.png b/icons/default/widgets/clear-day.png
new file mode 100644
index 00000000..2b06a14e
--- /dev/null
+++ b/icons/default/widgets/clear-day.png
Binary files differ
diff --git a/icons/default/widgets/clear-night.png b/icons/default/widgets/clear-night.png
new file mode 100644
index 00000000..9bbe49f6
--- /dev/null
+++ b/icons/default/widgets/clear-night.png
Binary files differ
diff --git a/icons/default/widgets/cloudy.png b/icons/default/widgets/cloudy.png
new file mode 100644
index 00000000..9870c7f4
--- /dev/null
+++ b/icons/default/widgets/cloudy.png
Binary files differ
diff --git a/icons/default/widgets/fog.png b/icons/default/widgets/fog.png
new file mode 100644
index 00000000..9bc88d2a
--- /dev/null
+++ b/icons/default/widgets/fog.png
Binary files differ
diff --git a/icons/default/widgets/partly-cloudy-day.png b/icons/default/widgets/partly-cloudy-day.png
new file mode 100644
index 00000000..b6df1798
--- /dev/null
+++ b/icons/default/widgets/partly-cloudy-day.png
Binary files differ
diff --git a/icons/default/widgets/partly-cloudy-night.png b/icons/default/widgets/partly-cloudy-night.png
new file mode 100644
index 00000000..aa358fb7
--- /dev/null
+++ b/icons/default/widgets/partly-cloudy-night.png
Binary files differ
diff --git a/icons/default/widgets/rain.png b/icons/default/widgets/rain.png
new file mode 100644
index 00000000..1d99ae00
--- /dev/null
+++ b/icons/default/widgets/rain.png
Binary files differ
diff --git a/icons/default/widgets/sleet.png b/icons/default/widgets/sleet.png
new file mode 100644
index 00000000..de3761bc
--- /dev/null
+++ b/icons/default/widgets/sleet.png
Binary files differ
diff --git a/icons/default/widgets/snow.png b/icons/default/widgets/snow.png
new file mode 100644
index 00000000..939e22f3
--- /dev/null
+++ b/icons/default/widgets/snow.png
Binary files differ
diff --git a/icons/default/widgets/thunderstorm.png b/icons/default/widgets/thunderstorm.png
new file mode 100644
index 00000000..4abf3717
--- /dev/null
+++ b/icons/default/widgets/thunderstorm.png
Binary files differ
diff --git a/icons/default/widgets/umbrella.png b/icons/default/widgets/umbrella.png
new file mode 100644
index 00000000..18deac14
--- /dev/null
+++ b/icons/default/widgets/umbrella.png
Binary files differ
diff --git a/icons/default/widgets/weather.png b/icons/default/widgets/weather.png
new file mode 100644
index 00000000..18deac14
--- /dev/null
+++ b/icons/default/widgets/weather.png
Binary files differ
diff --git a/icons/default/widgets/wind.png b/icons/default/widgets/wind.png
new file mode 100644
index 00000000..d92ec154
--- /dev/null
+++ b/icons/default/widgets/wind.png
Binary files differ
diff --git a/po/de_DE.po b/po/de_DE.po
index 2e136543..18483ec4 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-skinflat 0.4.3\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2014-11-09 14:53+0100\n"
+"POT-Creation-Date: 2014-11-15 15:41+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -246,6 +246,9 @@ msgstr ""
msgid "no output available"
msgstr ""
+msgid "Weather"
+msgstr ""
+
msgid "Audio Tracks"
msgstr "Audio Spuren"
@@ -378,6 +381,12 @@ msgstr "vergangen"
msgid "remaining"
msgstr "verbleibend"
+msgid "short"
+msgstr ""
+
+msgid "long"
+msgstr ""
+
msgid "General settings"
msgstr "Allgemeine Einstellungen"
@@ -738,6 +747,18 @@ msgstr ""
msgid "Main menu item scale"
msgstr ""
+msgid "Widget DVB weather: enable"
+msgstr ""
+
+msgid "Widget DVB weather: position"
+msgstr ""
+
+msgid "Widget DVB weather: show days"
+msgstr ""
+
+msgid "Widget DVB weather: type"
+msgstr ""
+
msgid "Widget DVB devices: enable"
msgstr ""
@@ -800,27 +821,3 @@ msgstr ""
msgid "Widget custom commands: position"
msgstr ""
-
-msgid "Enable widget: DVB devices"
-msgstr ""
-
-msgid "Enable widget: active timer"
-msgstr ""
-
-msgid "Enable widget: last recordings"
-msgstr ""
-
-msgid "Enable widget: timer conflicts"
-msgstr ""
-
-msgid "Enable widget: system information"
-msgstr ""
-
-msgid "Enable widget: system updates"
-msgstr ""
-
-msgid "Enable widget: temperatures"
-msgstr ""
-
-msgid "Enable widget: custom commands"
-msgstr ""
diff --git a/preview/Zitrone.png b/preview/Zitrone.png
new file mode 100644
index 00000000..8788e59f
--- /dev/null
+++ b/preview/Zitrone.png
Binary files differ
diff --git a/setup.c b/setup.c
index f3a867a1..3285d37b 100644
--- a/setup.c
+++ b/setup.c
@@ -14,6 +14,7 @@ cStringList ScrollerTypes;
cStringList ScrollBarTypes;
cStringList DiskUsageFree;
cStringList ChannelTimeLefts;
+cStringList WeatherTypes;
int ConfigFileSelection;
@@ -111,6 +112,9 @@ void cFlatSetup::Setup(void) {
ChannelTimeLefts.Append( strdup( tr("past")) );
ChannelTimeLefts.Append( strdup( tr("remaining")) );
+ WeatherTypes.Clear();
+ WeatherTypes.Append( strdup( tr("short")) );
+ WeatherTypes.Append( strdup( tr("long")) );
Add(new cOsdItem(tr("General settings"), osUnknown, true));
Add(new cOsdItem(tr("Channelinfo settings"), osUnknown, true));
@@ -300,6 +304,10 @@ void cFlatSetup::Store(void) {
SetupStore("MainMenuWidgetTemperaturesPosition", Config.MainMenuWidgetTemperaturesPosition);
SetupStore("MainMenuWidgetCommandShow", Config.MainMenuWidgetCommandShow);
SetupStore("MainMenuWidgetCommandPosition", Config.MainMenuWidgetCommandPosition);
+ SetupStore("MainMenuWidgetWeatherShow", Config.MainMenuWidgetWeatherShow);
+ SetupStore("MainMenuWidgetWeatherPosition", Config.MainMenuWidgetWeatherPosition);
+ SetupStore("MainMenuWidgetWeatherDays", Config.MainMenuWidgetWeatherDays);
+ SetupStore("MainMenuWidgetWeatherType", Config.MainMenuWidgetWeatherType);
Config.Init();
}
@@ -469,6 +477,10 @@ bool cFlatSetupGeneral::SetupParse(const char *Name, const char *Value) {
else if (strcmp(Name, "MainMenuWidgetTemperaturesPosition") == 0) SetupConfig->MainMenuWidgetTemperaturesPosition = atoi(Value);
else if (strcmp(Name, "MainMenuWidgetCommandShow") == 0) SetupConfig->MainMenuWidgetCommandShow = atoi(Value);
else if (strcmp(Name, "MainMenuWidgetCommandPosition") == 0) SetupConfig->MainMenuWidgetCommandPosition = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherShow") == 0) SetupConfig->MainMenuWidgetWeatherShow = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherPosition") == 0) SetupConfig->MainMenuWidgetWeatherPosition = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherDays") == 0) SetupConfig->MainMenuWidgetWeatherDays = atoi(Value);
+ else if (strcmp(Name, "MainMenuWidgetWeatherType") == 0) SetupConfig->MainMenuWidgetWeatherType = atoi(Value);
else return false;
return true;
@@ -620,6 +632,10 @@ void cFlatSetupGeneral::SaveCurrentSettings(void) {
Config.Store("MainMenuWidgetTemperaturesPosition", SetupConfig->MainMenuWidgetTemperaturesPosition, *Filename);
Config.Store("MainMenuWidgetCommandShow", SetupConfig->MainMenuWidgetCommandShow, *Filename);
Config.Store("MainMenuWidgetCommandPosition", SetupConfig->MainMenuWidgetCommandPosition, *Filename);
+ Config.Store("MainMenuWidgetWeatherShow", SetupConfig->MainMenuWidgetWeatherShow, *Filename);
+ Config.Store("MainMenuWidgetWeatherPosition", SetupConfig->MainMenuWidgetWeatherPosition, *Filename);
+ Config.Store("MainMenuWidgetWeatherDays", SetupConfig->MainMenuWidgetWeatherDays, *Filename);
+ Config.Store("MainMenuWidgetWeatherType", SetupConfig->MainMenuWidgetWeatherType, *Filename);
cString msg = cString::sprintf("%s %s", tr("saved settings in file:"), *File);
Skins.Message(mtInfo, msg);
@@ -1205,6 +1221,14 @@ void cFlatSetupMMWidget::Setup(void) {
if( SetupConfig->MainMenuWidgetsEnable ) {
Add(new cMenuEditPrcItem(tr("Main menu item scale"), &SetupConfig->MainMenuItemScale, 0.3, 0.7, 0));
+ Add(new cOsdItem("Widget DVB weather", osUnknown, false));
+ Add(new cMenuEditBoolItem(tr("Widget DVB weather: enable"), &SetupConfig->MainMenuWidgetWeatherShow));
+ if( SetupConfig->MainMenuWidgetWeatherShow ) {
+ Add(new cMenuEditIntItem(tr("Widget DVB weather: position"), &SetupConfig->MainMenuWidgetWeatherPosition));
+ Add(new cMenuEditIntItem(tr("Widget DVB weather: show days"), &SetupConfig->MainMenuWidgetWeatherDays));
+ Add(new cMenuEditStraItem(tr("Widget DVB weather: type"), &SetupConfig->MainMenuWidgetWeatherType, WeatherTypes.Size(), &WeatherTypes[0]));
+ }
+
Add(new cOsdItem("Widget DVB devices", osUnknown, false));
Add(new cMenuEditBoolItem(tr("Widget DVB devices: enable"), &SetupConfig->MainMenuWidgetDVBDevicesShow));
if( SetupConfig->MainMenuWidgetDVBDevicesShow ) {
@@ -1280,14 +1304,15 @@ eOSState cFlatSetupMMWidget::ProcessKey(eKeys Key) {
if( Key == kLeft || Key == kRight ) {
const char* ItemText = Get(Current())->Text();
if( strstr(ItemText, tr("Enable main menu widgets")) != NULL ||
- strstr(ItemText, tr("Enable widget: DVB devices")) != NULL ||
- strstr(ItemText, tr("Enable widget: active timer")) != NULL ||
- strstr(ItemText, tr("Enable widget: last recordings")) != NULL ||
- strstr(ItemText, tr("Enable widget: timer conflicts")) != NULL ||
- strstr(ItemText, tr("Enable widget: system information")) != NULL ||
- strstr(ItemText, tr("Enable widget: system updates")) != NULL ||
- strstr(ItemText, tr("Enable widget: temperatures")) != NULL ||
- strstr(ItemText, tr("Enable widget: custom commands")) != NULL
+ strstr(ItemText, tr("Widget DVB weather: enable")) != NULL ||
+ strstr(ItemText, tr("Widget DVB devices: enable")) != NULL ||
+ strstr(ItemText, tr("Widget active timer: enable")) != NULL ||
+ strstr(ItemText, tr("Widget last recordings: enable")) != NULL ||
+ strstr(ItemText, tr("Widget timer conflicts: enable")) != NULL ||
+ strstr(ItemText, tr("Widget system information: enable")) != NULL ||
+ strstr(ItemText, tr("Widget system updates: enable")) != NULL ||
+ strstr(ItemText, tr("Widget temperatures: enable")) != NULL ||
+ strstr(ItemText, tr("Widget custom commands: enable")) != NULL
) {
ItemLastSel = Current();
Setup();
diff --git a/widgets/weather/lib/forecast.io.php b/widgets/weather/lib/forecast.io.php
new file mode 100644
index 00000000..a3fdd0b2
--- /dev/null
+++ b/widgets/weather/lib/forecast.io.php
@@ -0,0 +1,431 @@
+<?php
+/**
+ * Helper Class for forecast.io webservice
+ */
+
+class ForecastIO{
+
+ private $api_key;
+ const API_ENDPOINT = 'https://api.forecast.io/forecast/';
+
+ /**
+ * Create a new instance
+ *
+ * @param String $api_key
+ */
+ function __construct($api_key) {
+
+ $this->api_key = $api_key;
+
+ }
+
+
+ private function requestData($latitude, $longitude, $units, $language = 'en', $timestamp = false, $exclusions = false) {
+
+ $validUnits = array('auto', 'us', 'si', 'ca', 'uk');
+
+ if (in_array($units, $validUnits)) {
+
+ $request_url = self::API_ENDPOINT .
+ $this->api_key . '/' .
+ $latitude . ',' . $longitude .
+ '?units=' . $units . '&lang=' . $language .
+ ( $timestamp ? ',' . $timestamp : '' ) .
+ ( $exclusions ? '&exclude=' . $exclusions : '' );
+
+ /**
+ * Use Buffer to cache API-requests if initialized
+ * (if not, just get the latest data)
+ *
+ * More info: http://git.io/FoO2Qw
+ */
+
+ if(class_exists('Buffer')) {
+ $cache = new Buffer();
+ $content = $cache->data($request_url);
+ } else {
+ $content = file_get_contents($request_url);
+ }
+
+ } else {
+
+ return false;
+
+ }
+
+ if (!empty($content)) {
+
+ return json_decode($content);
+
+ } else {
+
+ return false;
+
+ }
+
+
+ }
+
+ /**
+ * Will return the current conditions
+ *
+ * @param float $latitude
+ * @param float $longitude
+ * @return \ForecastIOConditions|boolean
+ */
+ function getCurrentConditions($latitude, $longitude, $units = 'auto', $language) {
+
+ $data = $this->requestData($latitude, $longitude, $units, $language);
+
+ if ($data !== false) {
+
+ return new ForecastIOConditions($data->currently);
+
+ } else {
+
+ return false;
+
+ }
+
+ }
+
+ /**
+ * Will return historical conditions for day of given timestamp
+ *
+ * @param float $latitude
+ * @param float $longitude
+ * @param int $timestamp
+ * @return \ForecastIOConditions|boolean
+ */
+ function getHistoricalConditions($latitude, $longitude, $units = 'auto', $language, $timestamp) {
+
+ $exclusions = 'currently,minutely,hourly,alerts,flags';
+
+ $data = $this->requestData($latitude, $longitude, $units, $language, $timestamp, $exclusions);
+
+ if ($data !== false) {
+
+ return new ForecastIOConditions($data->daily->data[0]);
+
+ } else {
+
+ return false;
+
+ }
+
+ }
+
+ /**
+ * Will return conditions on hourly basis for today
+ *
+ * @param type $latitude
+ * @param type $longitude
+ * @return \ForecastIOConditions|boolean
+ */
+ function getForecastToday($latitude, $longitude, $units = 'auto', $language) {
+
+ $data = $this->requestData($latitude, $longitude, $units, $language);
+
+ if ($data !== false) {
+
+ $conditions = array();
+
+ $today = date('Y-m-d');
+
+ foreach ($data->hourly->data as $raw_data) {
+
+ if (date('Y-m-d', $raw_data->time) == $today) {
+
+ $conditions[] = new ForecastIOConditions($raw_data);
+
+ }
+
+ }
+
+ return $conditions;
+
+ } else {
+
+ return false;
+
+ }
+
+ }
+
+
+ /**
+ * Will return daily conditions for next seven days
+ *
+ * @param float $latitude
+ * @param float $longitude
+ * @return \ForecastIOConditions|boolean
+ */
+ function getForecastWeek($latitude, $longitude, $units = 'auto', $language) {
+
+ $data = $this->requestData($latitude, $longitude, $units, $language);
+
+ if ($data !== false) {
+
+ $conditions = array();
+
+ foreach ($data->daily->data as $raw_data) {
+
+ $conditions[] = new ForecastIOConditions($raw_data);
+
+ }
+
+ return $conditions;
+
+ } else {
+
+ return false;
+
+ }
+
+ }
+
+
+}
+
+
+/**
+ * Wrapper for get data by getters
+ */
+class ForecastIOConditions{
+
+ private $raw_data;
+
+ function __construct($raw_data) {
+
+ $this->raw_data = $raw_data;
+
+ }
+
+ /**
+ * Will return the temperature
+ *
+ * @return String
+ */
+ function getTemperature() {
+
+ return $this->raw_data->temperature;
+
+ }
+
+ /**
+ * get the min temperature
+ *
+ * only available for week forecast
+ *
+ * @return type
+ */
+ function getMinTemperature() {
+
+ return $this->raw_data->temperatureMin;
+
+ }
+
+ /**
+ * get max temperature
+ *
+ * only available for week forecast
+ *
+ * @return type
+ */
+ function getMaxTemperature() {
+
+ return $this->raw_data->temperatureMax;
+
+ }
+
+ /**
+ * get apparent temperature (heat index/wind chill)
+ *
+ * only available for current conditions
+ *
+ * @return type
+ */
+ function getApparentTemperature() {
+
+ return $this->raw_data->apparentTemperature;
+
+ }
+
+ /**
+ * Get the summary of the conditions
+ *
+ * @return String
+ */
+ function getSummary() {
+
+ return $this->raw_data->summary;
+
+ }
+
+ /**
+ * Get the icon of the conditions
+ *
+ * @return String
+ */
+ function getIcon() {
+
+ return $this->raw_data->icon;
+
+ }
+
+ /**
+ * Get the time, when $format not set timestamp else formatted time
+ *
+ * @param String $format
+ * @return String
+ */
+ function getTime($format = null) {
+
+ if (!isset($format)) {
+
+ return $this->raw_data->time;
+
+ } else {
+
+ return date($format, $this->raw_data->time);
+
+ }
+
+ }
+
+ /**
+ * Get the pressure
+ *
+ * @return String
+ */
+ function getPressure() {
+
+ return $this->raw_data->pressure;
+
+ }
+
+ /**
+ * Get the dew point
+ *
+ * Available in the current conditions
+ *
+ * @return String
+ */
+ function getDewPoint() {
+
+ return $this->raw_data->dewPoint;
+
+ }
+
+ /**
+ * get humidity
+ *
+ * @return String
+ */
+ function getHumidity() {
+
+ return $this->raw_data->humidity;
+
+ }
+
+ /**
+ * Get the wind speed
+ *
+ * @return String
+ */
+ function getWindSpeed() {
+
+ return $this->raw_data->windSpeed;
+
+ }
+
+ /**
+ * Get wind direction
+ *
+ * @return type
+ */
+ function getWindBearing() {
+
+ return $this->raw_data->windBearing;
+
+ }
+
+ /**
+ * get precipitation type
+ *
+ * @return type
+ */
+ function getPrecipitationType() {
+
+ return $this->raw_data->precipType;
+
+ }
+
+ /**
+ * get the probability 0..1 of precipitation type
+ *
+ * @return type
+ */
+ function getPrecipitationProbability() {
+
+ return $this->raw_data->precipProbability;
+
+ }
+
+ /**
+ * Get the cloud cover
+ *
+ * @return type
+ */
+ function getCloudCover() {
+
+ return $this->raw_data->cloudCover;
+
+ }
+
+
+
+ /**
+ * get sunrise time
+ *
+ * only available for week forecast
+ *
+ * @return type
+ */
+ function getSunrise($format=null) {
+
+ if (!isset($format)) {
+
+ return $this->raw_data->sunriseTime;
+
+ } else {
+
+ return date($format, $this->raw_data->sunriseTime);
+
+ }
+
+ }
+
+ /**
+ * get sunset time
+ *
+ * only available for week forecast
+ *
+ * @return type
+ */
+ function getSunset($format=null) {
+
+ if (!isset($format)) {
+
+ return $this->raw_data->sunsetTime;
+
+ } else {
+
+ return date($format, $this->raw_data->sunsetTime);
+
+ }
+
+ }
+
+}
+?>
diff --git a/widgets/weather/update_weather.php b/widgets/weather/update_weather.php
new file mode 100644
index 00000000..8d2d8be9
--- /dev/null
+++ b/widgets/weather/update_weather.php
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * USER CONFIG
+ */
+$city = "Berlin";
+$country = "DE";
+$locationSkin = "Berlin"; // location shown in skin
+$units = 'si'; // Can be set to 'us', 'si', 'ca', 'uk' or 'auto' (see forecast.io API); default is auto
+$degree_sign = "°C";
+$lang = 'de'; // Can be set to 'en', 'de', 'pl', 'es', 'fr', 'it', 'tet' or 'x-pig-latin' (see forecast.io API); default is 'en'
+// We have only 1000 api calls per day, so please only do one update per day!
+// Or request an own key for free at forecast.io
+$api_key = '137f2d85a1f1db5762e5e073103541d2';
+
+/*
+ * DO NOT CHANGE ANYTHING FROM HERE
+ */
+include('lib/forecast.io.php');
+
+// delete old files
+array_map('unlink', glob("weather.*"));
+
+// get lat & long from google maps
+$MAPSURL = "http://maps.googleapis.com/maps/api/geocode/json?address=".$city.",".$country."&sensor=false";
+$json = file_get_contents($MAPSURL);
+$data = json_decode($json, true);
+
+if( !isset($data['results'][0]) ) {
+ echo "no latitude and longitude find for: ".$city.",".$country." !\n";
+ exit;
+}
+$latitude = $data['results'][0]['geometry']['location']['lat'];
+$longitude = $data['results'][0]['geometry']['location']['lng'];
+
+// forecast query
+$forecast = new ForecastIO($api_key);
+
+// get daily conditions for next 7 days
+$conditions_week = $forecast->getForecastWeek($latitude, $longitude, $units, $lang);
+
+if( !$handle = fopen("weather.location", "w") ) {
+ print "can't create file!\n";
+} else {
+ fwrite($handle, $locationSkin);
+ fclose($handle);
+}
+
+
+$index = -1;
+foreach($conditions_week as $conditions) {
+ $index++;
+
+ if( !$handle = fopen("weather.".$index.".summary", "w") ) {
+ print "can't create file!\n";
+ continue;
+ }
+ fwrite($handle, $conditions->getSummary());
+ fclose($handle);
+
+/*
+ if( !$handle = fopen("weather.".$index.".temp", "w") ) {
+ print "can't create file!\n";
+ continue;
+ }
+ // we only have min & max so we must calc
+ $temp = round(($conditions->getMinTemperature() + $conditions->getMaxTemperature()) / 2.0, 1);
+ fwrite($handle, $temp);
+ fwrite($handle, $degree_sign);
+ fclose($handle);
+ */
+ if( !$handle = fopen("weather.".$index.".tempMin", "w") ) {
+ print "can't create file!\n";
+ continue;
+ }
+ // we only have min & max so we must calc
+ $temp = round($conditions->getMinTemperature(), 1);
+ fwrite($handle, $temp);
+ fwrite($handle, $degree_sign);
+ fclose($handle);
+
+ if( !$handle = fopen("weather.".$index.".tempMax", "w") ) {
+ print "can't create file!\n";
+ continue;
+ }
+ // we only have min & max so we must calc
+ $temp = round($conditions->getMaxTemperature(), 1);
+ fwrite($handle, $temp);
+ fwrite($handle, $degree_sign);
+ fclose($handle);
+
+
+ if( !$handle = fopen("weather.".$index.".precipitation", "w") ) {
+ print "can't create file!\n";
+ continue;
+ }
+ fwrite($handle, $conditions->getPrecipitationProbability());
+ fclose($handle);
+
+ if( !$handle = fopen("weather.".$index.".precipitationType", "w") ) {
+ print "can't create file!\n";
+ continue;
+ }
+ if( $conditions->getPrecipitationProbability() > 0 )
+ fwrite($handle, $conditions->getPrecipitationType());
+ else
+ fwrite($handle, "none");
+ fclose($handle);
+
+ if( !$handle = fopen("weather.".$index.".icon", "w") ) {
+ print "can't create file!\n";
+ continue;
+ }
+ fwrite($handle, $conditions->getIcon());
+ fclose($handle);
+}
+?>