59_OPENWEATHER.pm 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. ###############################################################
  2. # $Id: 59_OPENWEATHER.pm 11198 2016-04-07 15:24:09Z grompo $
  3. #
  4. # 59_OPENWEATHER.pm
  5. #
  6. # (c) 2014 Torsten Poitzsch
  7. # (c) 2014-2016 tupol http://forum.fhem.de/index.php?action=profile;u=5432
  8. #
  9. # This module reads weather forecast data via the openweather-api of www.wetter.com
  10. #
  11. # Copyright notice
  12. #
  13. # This script is free software; you can redistribute it and/or modify
  14. # it under the terms of the GNU General Public License as published by
  15. # the Free Software Foundation; either version 2 of the License, or
  16. # (at your option) any later version.
  17. #
  18. # The GNU General Public License can be found at
  19. # http://www.gnu.org/copyleft/gpl.html.
  20. # A copy is found in the text file GPL.txt and important notices to the license
  21. # from the author is found in LICENSE.txt distributed with these scripts.
  22. #
  23. # This script is distributed in the hope that it will be useful,
  24. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. # GNU General Public License for more details.
  27. #
  28. # This copyright notice MUST APPEAR in all copies of the script!
  29. #
  30. ##############################################################################
  31. #
  32. # define <name> OPENWEATHER <project> <cityCode> <apikey>
  33. #
  34. ##############################################################################
  35. ###############################################
  36. # parser for the weather data
  37. package MyOPENWEATHERParser;
  38. use base qw(HTML::Parser);
  39. our %fcReadings = ();
  40. my $curTag = "";
  41. our $day = -2;
  42. our $time = "";
  43. # here HTML::text/start/end are overridden
  44. %knownTags = ( tn => "tempMin"
  45. , tx => "tempMax"
  46. , w => "weatherCode"
  47. , w_txt => "weather"
  48. , ws => "wind"
  49. , wd => "windDir"
  50. , wd_txt => "windDirTxt"
  51. , pc => "chOfRain"
  52. , p => "valHours"
  53. , title => "error"
  54. , message => "errorMsg"
  55. , name => "city"
  56. , post_code => "postcode"
  57. , url => "url"
  58. );
  59. sub
  60. get_wday($)
  61. {
  62. my ($date) = @_;
  63. my @wday_txt = qw(So Mo Di Mi Do Fr Sa);
  64. my @th=localtime $date;
  65. return $wday_txt [$th[6]];
  66. }
  67. sub text
  68. {
  69. my ( $self, $text ) = @_;
  70. my $rName = $knownTags{$curTag};
  71. if (defined $rName)
  72. {
  73. if ($day == -2)
  74. {
  75. $fcReadings{$rName} = $text ;
  76. }
  77. elsif ( $day >= 0 )
  78. {
  79. #Umlaute entfernen
  80. if ($curTag eq "w_txt") {$text =~ s/ö/oe/; $text =~ s/ä/ae/; $text =~ s/ü/ue/; $text =~ s/ß/ss/;}
  81. $fcReadings{"fc".$day."_".$rName.$time} = $text ;
  82. # icon erzeugen
  83. # if ($curTag eq "w")
  84. # {
  85. # if ($time != "23")
  86. # {
  87. # $fcReadings{"fc".$day."_".$rName.$time} = "d_".$text."_L.png" ;
  88. # }
  89. # else
  90. # {
  91. # $fcReadings{"fc".$day."_".$rName.$time} = "n_".$text."_L.png" ;
  92. # }
  93. # }
  94. }
  95. }
  96. elsif ($curTag eq "d" && $time eq "")
  97. {
  98. $fcReadings{"fc".$day."_wday"} = get_wday $text ;
  99. }
  100. }
  101. sub start
  102. {
  103. my ( $self, $tagname, $attr, $attrseq, $origtext ) = @_;
  104. $curTag = $tagname;
  105. if ($tagname eq "forecast")
  106. {
  107. $day = -1;
  108. }
  109. elsif ( $tagname eq "date" && $day >= -1 )
  110. {
  111. $day++;
  112. $time = "";
  113. }
  114. elsif ($tagname eq "time")
  115. {
  116. $time = substr($attr->{value}, 0, 2);
  117. }
  118. }
  119. sub end
  120. {
  121. my ( $self, $tagname, $attr, $attrseq, $origtext ) = @_;
  122. $curTag = "";
  123. if ($tagname eq "time")
  124. {
  125. $time = "";
  126. }
  127. }
  128. #######################################################################
  129. package main;
  130. use strict;
  131. use warnings;
  132. use Blocking;
  133. my $missingModul;
  134. eval "use MIME::Base64;1" or $missingModul .= "MIME::Base64 ";
  135. eval "use Digest::MD5 'md5_hex';1" or $missingModul .= "Digest::MD5 ";
  136. eval "use LWP::UserAgent;1" or $missingModul .= "LWP::UserAgent ";
  137. eval "use HTTP::Request;1" or $missingModul .= "HTTP::Request ";
  138. eval "use HTML::Parser;1" or $missingModul .= "HTML::Parser ";
  139. my $MODUL = "OPENWEATHER";
  140. sub OPENWEATHER_Log($$$);
  141. sub OPENWEATHER_Start($);
  142. sub OPENWEATHER_Run($);
  143. sub OPENWEATHER_Done($);
  144. sub OPENWEATHER_UpdateAborted($);
  145. sub ##########################################
  146. OPENWEATHER_Log($$$)
  147. {
  148. my ( $hash, $loglevel, $text ) = @_;
  149. my $xline = ( caller(0) )[2];
  150. my $xsubroutine = ( caller(1) )[3];
  151. my $sub = ( split( ':', $xsubroutine ) )[2];
  152. $sub =~ s/OPENWEATHER_//;
  153. my $instName = ( ref($hash) eq "HASH" ) ? $hash->{NAME} : $hash;
  154. Log3 $hash, $loglevel, "$MODUL $instName: $sub.$xline " . $text;
  155. }
  156. sub ##########################################
  157. OPENWEATHER_Initialize($)
  158. {
  159. my ($hash) = @_;
  160. $hash->{DefFn} = "OPENWEATHER_Define";
  161. $hash->{UndefFn} = "OPENWEATHER_Undefine";
  162. $hash->{SetFn} = "OPENWEATHER_Set";
  163. $hash->{GetFn} = "OPENWEATHER_Get";
  164. $hash->{AttrFn} = "OPENWEATHER_Attr";
  165. $hash->{AttrList} = "disable:0,1 "
  166. ."INTERVAL "
  167. .$readingFnAttributes;
  168. } # end OPENWEATHER_Initialize
  169. sub ##########################################
  170. OPENWEATHER_Define($$)
  171. {
  172. my ($hash, $def) = @_;
  173. my @args = split("[ \t][ \t]*", $def);
  174. return "Error: Perl moduls ".$missingModul."are missing on this system"
  175. if $missingModul;
  176. return "Usage: define <name> OPENWEATHER <project> <cityCode> <apiKey> [language]" if(@args <5 || @args >6);
  177. my $name = $args[0];
  178. $hash->{NAME} = $name;
  179. $hash->{STATE} = "Initializing";
  180. $hash->{INTERVAL} = 3600;
  181. $hash->{PROJECT} = $args[2];
  182. $hash->{CITYCODE} = $args[3];
  183. $hash->{APIKEY} = $args[4];
  184. $hash->{LANGUAGE} = $args[5] if defined $args[5];
  185. $hash->{CREDIT} = "Powered by wetter.com";
  186. my $checkSum = md5_hex( $args[2] . $args[4] . $args[3] );
  187. my $URL = 'http://api.wetter.com/forecast/weather';
  188. $URL .= '/city/' . $args[3];
  189. $URL .= '/project/' . $args[2];
  190. $URL .= '/cs/' . $checkSum;
  191. $URL .= '/language/'. $args[5] if defined $args[5];
  192. $hash->{URL} = $URL;
  193. $hash->{fhem}{LOCAL} = 0;
  194. $hash->{fhem}{modulVersion} = '$Date: 2016-04-07 17:24:09 +0200 (Thu, 07 Apr 2016) $';
  195. RemoveInternalTimer($hash);
  196. # Get first data after 7 seconds
  197. InternalTimer(gettimeofday() + 7, "OPENWEATHER_Start", $hash, 0);
  198. return undef;
  199. } #end OPENWEATHER_Define
  200. sub ##########################################
  201. OPENWEATHER_Undefine($$)
  202. {
  203. my ($hash, $args) = @_;
  204. RemoveInternalTimer($hash);
  205. BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));
  206. return undef;
  207. } # end OPENWEATHER_Undefine
  208. sub ##########################################
  209. OPENWEATHER_Attr($@)
  210. {
  211. my ($cmd,$name,$aName,$aVal) = @_;
  212. # $cmd can be "del" or "set"
  213. # $name is device name
  214. # aName and aVal are Attribute name and value
  215. my $hash = $defs{$name};
  216. if ($cmd eq "set")
  217. {
  218. if ($aName eq "INTERVAL")
  219. {
  220. if ($aVal < 3600 && $aVal != 0)
  221. {
  222. OPENWEATHER_Log $name, 3, "Error: Minimum of attribute INTERVAL is 3600 or 0";
  223. return "Minimum of attribute INTERVAL is 3600 or 0";
  224. }
  225. else
  226. {
  227. # Internal Timer neu starten
  228. RemoveInternalTimer($hash);
  229. if ($aVal >0)
  230. {
  231. InternalTimer(gettimeofday()+7, "OPENWEATHER_Start", $hash, 0);
  232. }
  233. }
  234. }
  235. }
  236. elsif ($cmd eq "del")
  237. {
  238. if ($aName eq "INTERVAL")
  239. {
  240. # Internal Timer neu starten
  241. RemoveInternalTimer($hash);
  242. InternalTimer(gettimeofday()+1, "OPENWEATHER_Start", $hash, 0);
  243. }
  244. }
  245. return undef;
  246. } # OPENWEATHER_Attr ende
  247. sub ##########################################
  248. OPENWEATHER_Set($$@)
  249. {
  250. my ($hash, $name, $cmd, $val) = @_;
  251. my $resultStr = "";
  252. if(lc $cmd eq 'update')
  253. {
  254. $hash->{fhem}{LOCAL} = 1;
  255. OPENWEATHER_Start($hash);
  256. $hash->{fhem}{LOCAL} = 0;
  257. return undef;
  258. }
  259. my $list = "update:noArg";
  260. return "Unknown argument $cmd, choose one of $list";
  261. } # end OPENWEATHER_Set
  262. sub ##########################################
  263. OPENWEATHER_Get($@)
  264. {
  265. my ($hash, $name, $cmd) = @_;
  266. my $result;
  267. my $message;
  268. if (lc $cmd eq "apiresponse")
  269. {
  270. my $time = gettimeofday();
  271. $result = OPENWEATHER_Run $name;
  272. my @a = split /\|/, $result;
  273. if ($a[1]==0)
  274. {
  275. $message = $a[2];
  276. }
  277. else
  278. {
  279. $message = decode_base64($a[2]);
  280. }
  281. $time = gettimeofday() - $time;
  282. if ($time > AttrVal($name, "timeOut", 10)) {
  283. $message = sprintf( "Runtime: %.2f s (!!! Increase attribute 'timeOut' !!!)\n_________________\n\n", $time) . $message;
  284. } else {
  285. $message = sprintf( "Response of %s\nRuntime: %.2f s\n_________________\n\n %s", $hash->{URL}, $time, $message);
  286. }
  287. return $message;
  288. }
  289. my $list = "apiResponse:noArg";
  290. return "Unknown argument $cmd, choose one of $list";
  291. } # end OPENWEATHER_Get
  292. # Starts the data capturing and sets the new timer
  293. sub ##########################################
  294. OPENWEATHER_Start($)
  295. {
  296. my ($hash) = @_;
  297. my $name = $hash->{NAME};
  298. $hash->{INTERVAL} = AttrVal( $name, "INTERVAL", 3600 );
  299. readingsSingleUpdate($hash, "state", "disabled", 1) if AttrVal($name, "disable", 0 ) == 1;
  300. if( $hash->{fhem}{LOCAL} != 1 && $hash->{INTERVAL} > 0 )
  301. {
  302. RemoveInternalTimer($hash);
  303. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OPENWEATHER_Start", $hash, 1);
  304. return undef if AttrVal($name, "disable", 0 ) == 1;
  305. }
  306. my $timeOut = AttrVal($name, "timeOut", 10);
  307. $hash->{helper}{RUNNING_PID} = BlockingCall("OPENWEATHER_Run", $name,
  308. "OPENWEATHER_Done", $timeOut,
  309. "OPENWEATHER_UpdateAborted", $hash)
  310. unless(exists($hash->{helper}{RUNNING_PID}));
  311. }
  312. sub ##########################################
  313. OPENWEATHER_Run ($)
  314. {
  315. my ($name) = @_;
  316. my $returnStr;
  317. my $hash = $defs{$name};
  318. return $name."|0|Error: URL not created. Please re-define device."
  319. unless defined $hash->{URL};
  320. my $URL = $hash->{URL};
  321. OPENWEATHER_Log $hash, 5, "Start capturing data from $URL";
  322. my $err_log = "";
  323. my $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 10
  324. , agent => "Mozilla/5.0 (FHEM)" );
  325. my $request = HTTP::Request->new( GET => $URL );
  326. my $response = $agent->request($request);
  327. $err_log = "Error: Can't get $URL -- " . $response->status_line
  328. unless $response->is_success;
  329. if ( $err_log ne "" )
  330. {
  331. return "$name|0|" . $err_log;
  332. }
  333. OPENWEATHER_Log $hash, 5, length($response->content)." characters captured";
  334. my $message = encode_base64($response->content,"");
  335. return "$name|1|$message" ;
  336. } # end OPENWEATHER_Run
  337. sub ###########################
  338. OPENWEATHER_Done($)
  339. {
  340. my ($string) = @_;
  341. return unless defined $string;
  342. my ($name, $success, $result) = split("\\|", $string);
  343. my $hash = $defs{$name};
  344. delete($hash->{helper}{RUNNING_PID});
  345. readingsBeginUpdate($hash);
  346. if ( $success == 1 ) {
  347. my $message = decode_base64($result);
  348. OPENWEATHER_Log $hash, 5, "Start parsing of XML data.";
  349. my $parser = MyOPENWEATHERParser->new;
  350. %MyOPENWEATHERParser::fcReadings = ();
  351. $MyOPENWEATHERParser::day = -2;
  352. $MyOPENWEATHERParser::time = "";
  353. $parser->parse($message);
  354. OPENWEATHER_Log $hash, 4, "Captured values: " . keys (%MyOPENWEATHERParser::fcReadings);
  355. if (defined $MyOPENWEATHERParser::fcReadings{error} )
  356. {
  357. readingsBulkUpdate($hash, "lastConnection", $MyOPENWEATHERParser::fcReadings{error});
  358. OPENWEATHER_Log $hash, 1, $MyOPENWEATHERParser::fcReadings{error}." - ".$MyOPENWEATHERParser::fcReadings{errorMsg};
  359. }
  360. else
  361. {
  362. readingsBulkUpdate($hash, "lastConnection", keys (%MyOPENWEATHERParser::fcReadings) . " values captured");
  363. while (my ($rName, $rValue) = each(%MyOPENWEATHERParser::fcReadings) )
  364. {
  365. readingsBulkUpdate( $hash, $rName, $rValue );
  366. OPENWEATHER_Log $hash, 5, "reading:$rName value:$rValue";
  367. }
  368. my $state = "Tmin: ".$MyOPENWEATHERParser::fcReadings{fc0_tempMin};
  369. $state .= " Tmax: ".$MyOPENWEATHERParser::fcReadings{fc0_tempMax};
  370. readingsBulkUpdate ($hash, "state", $state);
  371. }
  372. }
  373. else {
  374. readingsBulkUpdate($hash, "lastConnection", $result);
  375. readingsBulkUpdate($hash, "state", "Error");
  376. OPENWEATHER_Log $hash, 1, $result;
  377. }
  378. readingsEndUpdate( $hash, 1 );
  379. } # end OPENWEATHER_Done
  380. sub ############################
  381. OPENWEATHER_UpdateAborted($)
  382. {
  383. my ($hash) = @_;
  384. delete($hash->{helper}{RUNNING_PID});
  385. OPENWEATHER_Log $hash, 1, "Timeout when connecting to wetter.com";
  386. readingsSingleUpdate($hash, "lastConnection", "Error: Timeout when connecting to wetter.com", 1);
  387. } # end OPENWEATHER_UpdateAborted
  388. ##### noch nicht fertig ###########
  389. sub #####################################
  390. OPENWEATHER_Html($@)
  391. {
  392. my %fhemicons = (
  393. 0 => "sunny.png", 1 => "partly_cloudy.png", 2 => "cloudy.png", 3 => "overcast.png"
  394. , 4 => "fog.png", 5 => "drizzle.png", 6 => "rain.png", 7 => "snow.png"
  395. , 8 => "shower.png", 9 => "thunderstorm.png", 10 => "partly_cloudy.png", 20 => "cloudy.png"
  396. , 30 => "overcast.png", 40 => "fog.png", 45 => "fog.png", 48 => "fog.png"
  397. , 49 => "fog.png", 50 => "drizzle.png", 51 => "drizzle.png", 53 => "drizzle.png"
  398. , 55 => "drizzle.png", 56 => "drizzle.png", 57 => "icy.png", 60 => "rain.png"
  399. , 61 => "rain.png", 63 => "rain.png", 65 => "heavyrain.png", 66 => "rain.png"
  400. , 67 => "icy.png", 68 => "sleet.png", 69 => "sleet.png", 70 => "snow.png"
  401. , 71 => "snow.png", 73 => "snow.png", 75 => "snow.png", 80 => "scatteredshowers.png"
  402. , 81 => "showers.png", 82 => "showers.png", 83 => "chance_of_sleet.png", 84 => "sleet.png"
  403. , 85 => "chance_of_snow.png", 86 => "sleet.png", 90 => "thunderstorm.png", 95 => "scatteredthunderstorm.png"
  404. , 96 => "thunderstorm.png", 999 => "na.png"
  405. );
  406. my ($d, $icons) = @_;
  407. $d = "<none>" if(!$d);
  408. return "$d is not a OPENWEATHER instance<br>"
  409. if(!$defs{$d} || $defs{$d}{TYPE} ne "OPENWEATHER");
  410. my $uselocal= 0; #AttrVal($d,"localicons",0);
  411. my $isday;
  412. if ( exists &isday)
  413. {
  414. $isday = isday();
  415. }
  416. else
  417. {
  418. $isday = 1; #($hour>6 && $hour<19);
  419. }
  420. my $ret = "<table>";
  421. $ret .= sprintf '<tr><td colspan=2><b>Vorhersage %s</b></td></tr>', ReadingsVal($d, "city", "");
  422. for(my $i=0; $i<=2; $i++)
  423. {
  424. $ret .= sprintf('<tr><td valign=top><b>%s</b></td><td>%s<br>min. %s &deg;C max. %s &deg;C<br>Nieders.risiko: %s %%<br>Wind: %s km/h aus %s</td></tr>',
  425. $i==0 ? "heute" : ReadingsVal($d, "fc".$i."_wday", "")
  426. , ReadingsVal($d, "fc".$i."_weather", "")
  427. , ReadingsVal($d, "fc".$i."_tempMin", ""), ReadingsVal($d, "fc".$i."_tempMax", "")
  428. , ReadingsVal($d, "fc".$i."_chOfRain", "")
  429. , ReadingsVal($d, "fc".$i."_wind", ""), ReadingsVal($d, "fc".$i."_windDirTxt", "")
  430. );
  431. }
  432. $ret .= sprintf ('<tr><td colspan=2>powered by <a href="http://www.wetter.com/%s">wetter.com</a></td></tr>', ReadingsVal($d, "url", "") );
  433. $ret .= "</table>";
  434. return $ret;
  435. }
  436. #####################################
  437. 1;
  438. =pod
  439. =begin html
  440. <a name="OPENWEATHER"></a>
  441. <h3>OPENWEATHER</h3>
  442. <div>
  443. <ul>
  444. The module extracts weather data via the <a href="http://www.wetter.com/apps_und_mehr/website/api/dokumentation">openweather API</a> of <a href="http://www.wetter.com">www.wetter.com</a>.
  445. <br>
  446. It requires a registration on this website to obtain the necessary parameters.
  447. <br>
  448. It uses the perl moduls HTTP::Request, LWP::UserAgent, HTML::Parse and Digest::MD5.
  449. <br/><br/>
  450. <a name="OPENWEATHERdefine"></a>
  451. <b>Define</b>
  452. <ul>
  453. <br>
  454. <code>define &lt;name&gt; OPENWEATHER &lt;project&gt; &lt;cityCode&gt; &lt;apiKey&gt; [language]</code>
  455. <br>
  456. Example:
  457. <br>
  458. <code>define wetter OPENWEATHER projectx DE0001020 3c551bc20819c19ee88d</code>
  459. <br/><br/>
  460. To obtain the below parameter you have to create a new project on <a href="http://www.wetter.com/apps_und_mehr/website/api/projekte/">www.wetter.com</a>.
  461. <br/><br/>
  462. <li><code>&lt;project&gt;</code>
  463. <br>
  464. Name of the 'openweather' project (create with a user account on wetter.com).
  465. </li><br>
  466. <li><code>&lt;cityCode&gt;</code>
  467. <br>
  468. Code of the location for which the forecast is requested.
  469. The code is part of the URL of the weather forecast page. For example <i>DE0009042</i> in:
  470. <br>
  471. <i>http://www.wetter.com/wetter_aktuell/aktuelles_wetter/deutschland/rostock/<u>DE0009042</u>.html</i>
  472. </li><br>
  473. <li><code>&lt;apiKey&gt;</code>
  474. <br>
  475. Secret key that is provided when the user creates a 'openweather' project on wetter.com.
  476. </li><br>
  477. <li><code>[language]</code>
  478. <br>
  479. Optional. Default language of weather description is German. Change with <i>en</i> to English or <i>es</i> to Spanish.
  480. </li><br>
  481. The function <code>OPENWEATHER_Html</code> creates a HTML code for a vertically arranged weather forecast.
  482. <br>
  483. Example:
  484. <br>
  485. <code>define MyForecast weblink htmlCode { OPENWEATHER_Html("MyWeather") }</code>
  486. <br/><br/>
  487. </ul>
  488. <a name="OPENWEATHERset"></a>
  489. <b>Set</b>
  490. <ul>
  491. <br>
  492. <li><code>set &lt;name&gt; update</code>
  493. <br>
  494. The weather data are immediately polled from the website.
  495. </li><br>
  496. </ul>
  497. <a name="OPENWEATHERget"></a>
  498. <b>Get</b>
  499. <ul>
  500. <br>
  501. <li><code>get &lt;name&gt; apiResponse</code>
  502. <br>
  503. Shows the response of the web site.
  504. </li><br>
  505. </ul>
  506. <a name="OPENWEATHERattr"></a>
  507. <b>Attributes</b>
  508. <ul>
  509. <br>
  510. <li><code>disable &lt;0 | 1&gt;</code>
  511. <br>
  512. Automatic update is stopped if set to 1.
  513. </li><br>
  514. <li><code>INTERVAL &lt;seconds&gt;</code>
  515. <br>
  516. Polling interval for weather data in seconds (default and smallest value is 3600 = 1 hour). 0 will stop automatic updates.
  517. </li><br>
  518. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  519. </ul>
  520. <br>
  521. <a name="OPENWEATHERreading"></a>
  522. <b>Forecast readings</b>
  523. <ul>
  524. Note! The forecast values (in brackets) have first to be selected on the project setup page on wetter.com.
  525. <br/>&nbsp;<br/>
  526. <li><b>fc</b><i>0|1|2</i><b>_...</b> - forecast values for <i>today|tommorrow|in 2 days</i></li>
  527. <li><b>fc</b><i>0</i><b>_...<i>06|11|17|23</i></b> - forecast values for <i>today</i> at <i>06|11|17|23</i> o'clock</li>
  528. <li><b>fc</b><i>1</i><b>_temp</b><i>Min|Max</i> - <i>minimal|maximal</i> temperature for <i>tommorrow</i> in &deg;C (tn,tx)</li>
  529. <li><b>fc</b><i>0</i><b>_temp</b><i>Min06</i> - <i>minimal</i> temperatur <i>today</i> at <i>06:00</i> o'clock in &deg;C</li>
  530. <li><b>fc</b><i>0</i><b>_chOfRain</b> - chance of rain <i>today</i> in % (pc)</li>
  531. <li><b>fc</b><i>0</i><b>_valHours</b><i>06</i> - validity period in hours of the forecast values starting at <i>06:00</i> o'clock (p)</li>
  532. <li><b>fc</b><i>0</i><b>_weather</b> - weather situation <i>today</i> in German (w_txt)</li>
  533. <li><b>fc</b><i>0</i><b>_weatherCode</b> - code of weather situation <i>today</i> (w)</li>
  534. <li><b>fc</b><i>0</i><b>_wday</b> - German abbreviation of week day of <i>today</i> (d)</li>
  535. <li><b>fc</b><i>0</i><b>_wind</b> - wind speed <i>today</i> in km/h (ws)</li>
  536. <li><b>fc</b><i>0</i><b>_windDir</b> - wind direction <i>today</i> in &deg; (degree) (wd)</li>
  537. <li><b>fc</b><i>0</i><b>_windDirTxt</b> - wind direction <i>today</i> in text form (wd_txt</li>
  538. <li>etc.</li>
  539. </ul>
  540. <br>
  541. </ul>
  542. </div>
  543. =end html
  544. =begin html_DE
  545. <a name="OPENWEATHER"></a>
  546. <h3>OPENWEATHER</h3>
  547. <div>
  548. <ul>
  549. <a name="OPENWEATHERdefine"></a>
  550. Das Modul extrahiert Wetterdaten &uuml;ber die <a href="http://www.wetter.com/apps_und_mehr/website/api/dokumentation">"openweather"-Schnittstelle (API)</a> von <a href="http://www.wetter.com">www.wetter.com</a>.
  551. <br/>
  552. Zuvor ist eine Registrierung auf der Webseite notwendig.
  553. <br/>
  554. Das Modul nutzt die Perlmodule HTTP::Request, LWP::UserAgent, HTML::Parse und Digest::MD5.
  555. <br>
  556. F&uuml;r detailierte Anleitungen bitte die <a href="http://www.fhemwiki.de/wiki/OPENWEATHER"><b>FHEM-Wiki</b></a> konsultieren und erg&auml;nzen.
  557. <br/><br/>
  558. <b>Define</b>
  559. <ul>
  560. <br>
  561. <code>define &lt;name&gt; OPENWEATHER &lt;Projekt&gt; &lt;Ortscode&gt; &lt;apiSchl&uuml;ssel&gt; [Sprache]</code>
  562. <br>
  563. Beispiel:
  564. <br>
  565. <code>define wetter OPENWEATHER projectx DE0001020 3c551bc20819c19ee88d</code>
  566. <br/><br/>
  567. Um die unteren Parameter zu erhalten, ist die Registrierung eines neuen Projektes auf <a href="http://www.wetter.com/apps_und_mehr/website/api/projekte/">www.wetter.com</a> notwendig.
  568. <br/><br/>
  569. <li><code>&lt;Projekt&gt;</code>
  570. <br>
  571. Name des benutzerspezifischen 'openweather'-Projektes (erzeugt &uuml;ber ein Konto auf wetter.com).
  572. </li><br>
  573. <li><code>&lt;Ortscode&gt;</code>
  574. <br>
  575. Code des Ortes, f&uuml;r den die Wettervorhersage ben&ouml;tigt wird. Er kann direkt aus der Adresszeile der jeweiligen Vorhersageseite genommen werden. Zum Beispiel <i>DE0009042</i> aus:
  576. <br>
  577. <i>http://www.wetter.com/wetter_aktuell/aktuelles_wetter/deutschland/rostock/<u>DE0009042</u>.html</i>
  578. </li><br>
  579. <li><code>&lt;apiSchl&uuml;ssel&gt;</code>
  580. <br>
  581. Geheimer Schl&uuml;ssel, den man erh&auml;lt, nachdem man ein neues 'Openweather'-Projekt auf der Website registriert hat.
  582. </li><br>
  583. <li><code>[Sprache]</code>
  584. <br>
  585. Optional. Standardsprache f&uuml;r die Wettersituation ist Deutsch. Mit <i>en</i> kann man zu Englisch und mit <i>es</i> zu Spanisch wechseln.
  586. </li><br>
  587. &Uuml;ber die Funktion <code>OPENWEATHER_Html</code> wird ein HTML-Code f&uuml;r ein vertikal arrangierte Wettervorhersage erzeugt.
  588. <br>
  589. Beispiel:
  590. <br>
  591. <code>define MyForecast weblink htmlCode { OPENWEATHER_Html("MyWeather") }</code>
  592. <br/><br/>
  593. </ul>
  594. <a name="OPENWEATHERset"></a>
  595. <b>Set</b>
  596. <ul>
  597. <br>
  598. <li><code>set &lt;name&gt; update</code>
  599. <br>
  600. Startet sofort ein neues Auslesen der Wetterdaten.
  601. </li><br>
  602. </ul>
  603. <a name="OPENWEATHERget"></a>
  604. <b>Get</b>
  605. <ul>
  606. <br>
  607. <li><code>get &lt;name&gt; apiResponse</code>
  608. <br>
  609. Zeigt die R&uuml;ckgabewerte der Website an.
  610. </li><br>
  611. </ul>
  612. <a name="OPENWEATHERattr"></a>
  613. <b>Attribute</b>
  614. <ul>
  615. <br>
  616. <li><code>disable &lt;0 | 1&gt;</code>
  617. <br>
  618. Automatische Aktuallisierung ist angehalten, wenn der Wert auf 1 gesetzt wird.
  619. </li><br>
  620. <li><code>INTERVAL &lt;Abfrageinterval&gt;</code>
  621. <br>
  622. Abfrageinterval in Sekunden (Standard und kleinster Wert ist 3600 = 1 Stunde). 0 stoppt die automatische Aktualisierung
  623. </li><br>
  624. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  625. </ul>
  626. <br/>
  627. <a name="OPENWEATHERreading"></a>
  628. <b>Vorhersagewerte</b>
  629. <ul>
  630. Wichtig! Die Vorhersagewerte (in Klammern) m&uuml;ssen zuerst in den Vorhersageeinstellungen des Projektes auf wetter.com ausgew&auml;hlt werden.
  631. <br/>&nbsp;<br/>
  632. <li><b>fc</b><i>0|1|2</i><b>_...</b> - Vorhersagewerte f&uuml;r <i>heute|morgen|&uuml;bermorgen</i></li>
  633. <li><b>fc</b><i>0</i><b>_...<i>06|11|17|23</i></b> - Vorhersagewerte f&uuml;r <i>heute</i> um <i>06|11|17|23</i> Uhr</li>
  634. <li><b>fc</b><i>0</i><b>_chOfRain</b> - <i>heutige</i> Niederschlagswahrscheinlichkeit in % (pc)</li>
  635. <li><b>fc</b><i>0</i><b>_temp</b><i>Min|Max</i> - <i>Mindest|Maximal</i>temperatur <i>heute</i> in &deg;C (tn, tx)</li>
  636. <li><b>fc</b><i>0</i><b>_temp</b><i>Min06</i> - <i>Mindest</i>temperatur <i>heute</i> um <i>06:00</i> Uhr in &deg;C</li>
  637. <li><b>fc</b><i>0</i><b>_valHours</b><i>06</i> - G&uuml;ltigkeitszeitraum der Prognose von <i>heute</i> ab <i>6:00 Uhr</i> in Stunden (p)</li>
  638. <li><b>fc</b><i>0</i><b>_weather</b> - Wetterzustand <i>heute</i> (w_txt)</li>
  639. <li><b>fc</b><i>0</i><b>_weatherCode</b> - Code des Wetterzustand <i>heute</i> (w)</li>
  640. <li><b>fc</b><i>0</i><b>_wday</b> - Abk&uuml;rzung des Wochentags von <i>heute</i> (d)</li>
  641. <li><b>fc</b><i>0</i><b>_wind</b> - Windgeschwindigkeit <i>heute</i> in km/h (ws)</li>
  642. <li><b>fc</b><i>0</i><b>_windDir</b> - Windrichtung <i>heute</i> in &deg; (Grad) (wd)</li>
  643. <li><b>fc</b><i>0</i><b>_windDirTxt</b> - Windrichtung <i>heute</i> in Textform (wd_txt)</li>
  644. <li>etc.</li>
  645. </ul>
  646. <br/>
  647. </ul>
  648. </div>
  649. =end html_DE
  650. =cut