From aaf16b4a2369e72e7f1319e5de525ce0ced08ef2 Mon Sep 17 00:00:00 2001 From: betateilchen Date: Sat, 10 Oct 2015 23:28:47 +0000 Subject: [PATCH] contrib/55_GDS.2015/GDSweblink.pm: added git-svn-id: https://svn.fhem.de/fhem/trunk@9423 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/55_GDS.2015/GDSweblink.pm | 325 +++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 fhem/contrib/55_GDS.2015/GDSweblink.pm diff --git a/fhem/contrib/55_GDS.2015/GDSweblink.pm b/fhem/contrib/55_GDS.2015/GDSweblink.pm new file mode 100644 index 000000000..a07c84768 --- /dev/null +++ b/fhem/contrib/55_GDS.2015/GDSweblink.pm @@ -0,0 +1,325 @@ +# $Id: 99_GDSweblink.pm 9418 2015-10-10 09:32:35Z betateilchen $ +package main; + +use strict; +use warnings; +use POSIX; + +#################################################################################################### +# +# create weblinks +# provided by jensb +# +#################################################################################################### + +#sub +#gdsUtils_Initialize($$) +#{ +# my ($hash) = @_; +#} + +# weather description to icon name mapping +my %GDSDayWeatherIconMap = ( + 'bedeckt' => 'overcast', + 'bewölkt' => 'mostlycloudy', + 'Dunst oder flacher Nebel' => 'haze', + 'gefrierender Nebel' => 'icy', + 'gering bewölkt' => 'partlycloudy', + 'Gewitter' => 'thunderstorm', + 'Glatteisbildung' => 'icy', + 'Graupelschauer' => 'snow', + 'Hagelschauer' => 'snow', + 'heiter' => 'partlycloudy', + 'in Wolken' => 'mostlycloudy', + 'kein signifikantes Wetter' => 'na', + 'kräftiger Graupelschauer' => 'heavysnow', + 'kräftiger Hagelschauer' => 'heavysnow', + 'kräftiger Regen' => 'heavyrain', + 'kräftiger Regenschauer' => 'scatteredshowers', + 'kräftiger Schneefall' => 'heavysnow', + 'kräftiger Schneeregen' => 'rainsnow', + 'kräftiger Schneeregenschauer' => 'rainsnow', + 'kräftiger Schneeschauer' => 'heavysnow', + 'leicht bewölkt' => 'partlycloudy', + 'leichter Regen' => 'mist', + 'leichter Schneefall' => 'snow', + 'leichter Schneeregen' => 'rainsnow', + 'Nebel' => 'fog', + 'Regen' => 'rain', + 'Regenschauer' => 'scatteredshowers', + 'Sandsturm' => 'dust', + 'Schneefall' => 'snow', + 'Schneefegen' => 'snow', + 'Schneeregen' => 'rainsnow', + 'Schneeregenschauer' => 'rainsnow', + 'Schneeschauer' => 'snow', + 'schweres Gewitter' => 'thunderstorm', + 'stark bewölkt' => 'mostlycloudy', + 'starkes Gewitter' => 'thunderstorm', + 'wolkenlos' => 'sunny', + '---' => 'mostlycloudy', + ); + +my %GDSNightWeatherIconMap = ( + 'bedeckt' => 'overcast', + 'bewölkt' => 'mostlycloudy_night', + 'Dunst oder flacher Nebel' => 'haze_night', + 'gefrierender Nebel' => 'icy', + 'gering bewölkt' => 'partlycloudy_night', + 'Gewitter' => 'thunderstorm', + 'Glatteisbildung' => 'icy', + 'Graupelschauer' => 'snow', + 'Hagelschauer' => 'snow', + 'heiter' => 'partlycloudy_night', + 'in Wolken' => 'mostlycloudy_night', + 'kein signifikantes Wetter' => 'na', + 'kräftiger Graupelschauer' => 'heavysnow', + 'kräftiger Hagelschauer' => 'heavysnow', + 'kräftiger Regen' => 'heavyrain', + 'kräftiger Regenschauer' => 'scatteredshowers_night', + 'kräftiger Schneefall' => 'heavysnow', + 'kräftiger Schneeregen' => 'rainsnow', + 'kräftiger Schneeregenschauer' => 'rainsnow', + 'kräftiger Schneeschauer' => 'heavysnow', + 'leicht bewölkt' => 'partlycloudy_night', + 'leichter Regen' => 'mist', + 'leichter Schneefall' => 'snow', + 'leichter Schneeregen' => 'rainsnow', + 'Nebel' => 'fog', + 'Regen' => 'rain', + 'Regenschauer' => 'scatteredshowers_night', + 'Sandsturm' => 'dust', + 'Schneefall' => 'snow', + 'Schneefegen' => 'snow', + 'Schneeregen' => 'rainsnow', + 'Schneeregenschauer' => 'rainsnow', + 'Schneeschauer' => 'snow', + 'schweres Gewitter' => 'thunderstorm', + 'stark bewölkt' => 'mostlycloudy_night', + 'starkes Gewitter' => 'thunderstorm', + 'wolkenlos' => 'sunny_night', + '---' => 'mostlycloudy_night', + ); + +# icon parameters +use constant ICONHIGHT => 120; +use constant ICONWIDTH => 175; +use constant ICONSCALE => 0.5; + +sub GDSIsDay($$) { +# check if it is day at given time +# +# @param: time +# @param: altitude, see documentation of module SUNRISE_EL + my ($time, $altitude) = @_; + + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time); + my $t = ($hour*60 + $min) + $sec; + + my (undef, $srHour, $srMin, $srSec, undef) = GetTimeSpec(sunrise_abs_dat($time, $altitude)); + my $sunrise = ($srHour*60 + $srMin) + $srSec; + + my (undef, $ssHour, $ssMin, $ssSec, undef) = GetTimeSpec(sunset_abs_dat($time, $altitude)); + my $sunset = ($ssHour*60 + $ssMin) + $ssSec; + + return $t >= $sunrise && $t <= $sunset; +} + +sub GDSIconIMGTag($;$) { +# get FHEM weather icon +# +# @param: weather description +# @param: time of weather description or 1 for night, optional, defaults to daytime icons + my $width = int(ICONSCALE*ICONWIDTH); + my ($weather, $time) = @_; + my $icon; + if (!defined($time) || (defined($time) && $time > 1 && GDSIsDay($time, "REAL"))) { + $icon = $GDSDayWeatherIconMap{$weather}; + } else { + $icon = $GDSNightWeatherIconMap{$weather}; + } + if (defined($icon)) { + my $url= FW_IconURL("weather/$icon"); + my $style= " width=$width"; + return "\"$icon\""; + } else { + return ""; + } +} + +sub GDSAsHtmlV($;$) { +# create forecast in a vertical HTML table +# +# @param: device name +# @param: number of icons, optional, default 8 + my ($d,$items) = @_; + $d = "" if(!$d); + $items = $items? $items - 1 : 7; + return "$d is not a GDS instance
" + if(!$defs{$d} || $defs{$d}{TYPE} ne "GDS"); + + my $width = int(ICONSCALE*ICONWIDTH); + + my $ret = sprintf('', $width); + $ret .= sprintf('', + $width, + GDSIconIMGTag(ReadingsVal($d, "c_weather", "?"), time_str2num(ReadingsTimestamp($d, "c_weather", TimeNow()))), + ReadingsVal($d, "c_weather", "?"), + ReadingsVal($d, "c_temperature", "?"), + ReadingsVal($d, "c_windSpeed", "?"), ReadingsVal($d, "c_windDir", "?")); + + # get time of last forecast + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time_str2num(ReadingsTimestamp($d, "fc3_weather24", TimeNow()))); + + for(my $i=0; $i<$items; $i++) { + my $day = int(($i + 1)/2); + my $timeLabel = $i == 0? ($hour < 17? '18' : '24') : ($i - 1)%2 == 0? '12' : '24'; + my $weekday = $i == 0? ($hour < 17? 'Spät' : 'Nachts') : ($i - 1)%2 == 0? ReadingsVal($d, "fc".$day."_weekday", "?").' früh' : ReadingsVal($d, "fc".$day."_weekday", "?").' spät'; + + if (($i - 1)%2 == 0) { + $ret .= sprintf('', + $width, + GDSIconIMGTag(ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?")), + $weekday, + ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?"), + ReadingsVal($d, "fc".$day."_tMinAir", "?"), + ReadingsVal($d, "fc".$day."_windGust".$timeLabel, "")); + } else { + if ($i == 0 && $hour >= 17) { + $ret .= sprintf('', + $width, + GDSIconIMGTag(ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?"), 1), + $weekday, + ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?"), + ReadingsVal($d, "fc".$day."_tAvgAir".$timeLabel, "?"), + ReadingsVal($d, "fc".$day."_windGust".$timeLabel, "")); + } else { + $ret .= sprintf('', + $width, + GDSIconIMGTag(ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?")), + $weekday, + ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?"), + ReadingsVal($d, "fc".$day."_tMaxAir", "?"), + ReadingsVal($d, "fc".$day."_windGust".$timeLabel, "")); + } + } + } + + $ret .= "
%sAktuell: %s
%s°C
Wind %s km/h %s
%s%s: %s
min %s°C
%s
%s%s: %s
%s°C
%s
%s%s: %s
max %s°C
%s
"; + return $ret; +} + +sub GDSAsHtmlH($;$) { +# create forecast in a horizontal HTML table +# +# @param: device name +# @param: number of icons, optional, default 8 + my ($d, $items) = @_; + $d = "" if(!$d); + $items = $items? $items - 1 : 7; + return "$d is not a GDS instance
" + if(!$defs{$d} || $defs{$d}{TYPE} ne "GDS"); + + my $width = 110; + + my $ret = ''; + + # get time of last forecast + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time_str2num(ReadingsTimestamp($d, "fc3_weather24", TimeNow()))); + + # weekday / time + $ret .= sprintf(''); + for(my $i=0; $i<$items; $i++) { + my $day = int(($i + 1)/2); + my $timeLabel = $i == 0? ($hour < 17? '18' : '24') : ($i - 1)%2 == 0? '12' : '24'; + my $weekday = $i == 0? ($hour < 17? 'Spät' : 'Nachts') : ($i - 1)%2 == 0? ReadingsVal($d, "fc".$day."_weekday", "?").' früh' : ReadingsVal($d, "fc".$day."_weekday", "?").' spät'; + $ret .= sprintf('', $weekday); + } + $ret .= ''; + + # condition icon + $ret .= sprintf('', $width, GDSIconIMGTag(ReadingsVal($d, "c_weather", "?"), time_str2num(ReadingsTimestamp($d, "c_weather", TimeNow())))); + for(my $i=0; $i<$items; $i++) { + my $day = int(($i + 1)/2); + my $timeLabel = $i == 0? ($hour < 17? '18' : '24') : ($i - 1)%2 == 0? '12' : '24'; + $ret .= sprintf('', $width, GDSIconIMGTag(ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?"), $i==0 && $hour >= 17? 1 : undef)); + } + $ret .= ''; + + # condition text + $ret .= sprintf('', ReadingsVal($d, "c_weather", "?")); + for(my $i=0; $i<$items; $i++) { + my $day = int(($i + 1)/2); + my $timeLabel = $i == 0? ($hour < 17? '18' : '24') : ($i - 1)%2 == 0? '12' : '24'; + $ret .= sprintf('', ReadingsVal($d, "fc".$day."_weather".$timeLabel, "?")); + } + $ret .= ''; + + # temperature / min temperature + $ret .= sprintf('', ReadingsVal($d, "c_temperature", "?")); + for(my $i=0; $i<$items; $i++) { + my $day = int(($i + 1)/2); + my $timeLabel = $i == 0? ($hour < 17? '18' : '24') : ($i - 1)%2 == 0? '12' : '24'; + if (($i - 1)%2 == 0) { + $ret .= sprintf('', ReadingsVal($d, "fc".$day."_tMinAir", "?")); + } else { + if ($i == 0 && $hour >= 17) { + $ret .= sprintf('', ReadingsVal($d, "fc".$day."_tAvgAir".$timeLabel, "?")); + } else { + $ret .= sprintf('', ReadingsVal($d, "fc".$day."_tMaxAir", "?")); + } + } + } + $ret .= ''; + + # wind + $ret .= sprintf('', ReadingsVal($d, "c_windSpeed", "?"), ReadingsVal($d, "c_windDir", "?")); + for(my $i=0; $i<$items; $i++) { + my $day = int(($i + 1)/2); + my $timeLabel = $i == 0? ($hour < 17? '18' : '24') : ($i - 1)%2 == 0? '12' : '24'; + $ret .= sprintf('', ReadingsVal($d, "fc".$day."_windGust".$timeLabel, "")); + } + $ret .= "
Aktuell%s
%s%s
%s%s
%s°Cmin %s°C%s°Cmax %s°C
%s km/h %s%s
"; + + return $ret; +} + +sub GDSAsHtmlD($;$) { +# create forecast in a horizontal or vertical HTML table +# depending on the display orientation +# @param: device name +# @param: number of icons, optional, default 8 + + my ($d,$i) = @_; + if(defined($FW_ss) && $FW_ss) { + GDSAsHtmlV($d,$i); + } else { + GDSAsHtmlH($d,$i); + } +} + +1; + +=pod +=begin html + + +

gdsUtils

+
    +
  • This module provides three additional functions:
    + GDSAsHtmlV, GDSAsHtmlH and GDSAsHtmlD.
    + The first function returns the HTML code for a vertically arranged weather forecast.
    + The second function returns the HTML code for a horizontally arranged weather forecast.
    + The third function dynamically picks the orientation depending on whether a
    + smallscreen style is set (vertical layout) or not (horizontal layout).
    + The attributes gdsSetCond and gdsSetForecast must be configured for the functions to work.
    + Each of these functions accepts an additional parameter to limit the number of icons to display (1...8).
    + If the attribute gdsSetForecast is not configured this parameter should be set to 1.
    +
    + Example: define MyForecastWeblink weblink htmlCode { GDSAsHtml("MyWeather") }
    + where "MyWeather" is the name of your GDS device.
    +
  • +
+ +=end html +=cut