95_VIEW.pm 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. ################################################################################
  2. # 95 VIEW
  3. # Feedback: http://groups.google.com/group/fhem-users
  4. # Define Custom View
  5. # Stand: 04.2011
  6. # Version: 1.0
  7. ################################################################
  8. #
  9. # Copyright notice
  10. #
  11. # (c) 2011 Copyright: Axel Rieger (fhem bei anax punkt info)
  12. # All rights reserved
  13. #
  14. # This script free software; you can redistribute it and/or modify
  15. # it under the terms of the GNU General Public License as published by
  16. # the Free Software Foundation; either version 2 of the License, or
  17. # (at your option) any later version.
  18. #
  19. # The GNU General Public License can be found at
  20. # http://www.gnu.org/copyleft/gpl.html.
  21. # A copy is found in the textfile GPL.txt and important notices to the license
  22. # from the author is found in LICENSE.txt distributed with these scripts.
  23. #
  24. # This script is distributed in the hope that it will be useful,
  25. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. # GNU General Public License for more details.
  28. #
  29. ################################################################################
  30. # Usage
  31. # define <NAME> VIEW
  32. # attr <NAME> ViewRegExType -> Chose Device-Type (Perl-RegExp)
  33. # attr <NAME> ViewRegExName -> Chose Device-Name (Perl-RegExp)
  34. # attr <NAME> ViewRegExReading -> Chose Readings (Perl-RegExp)
  35. # attr <Name> ViewRegExReadingStringCompare -> Chose ReadingValue (Perl-RegEx)
  36. #
  37. # Examples:
  38. # Show all Device with Type FHT
  39. # attr MyFHT ViewRegExType FHT
  40. # attr MyFHT ViewRegExName * or NotSet
  41. # attr MyFHT ViewRegExReading * or NotSet
  42. # attr MyFHT ViewRegExReadingStringCompare * or Notset
  43. #
  44. # Show all Warnings of ALL Devices without "none"-Values
  45. # attr MyFHT ViewRegExType * or NotSet
  46. # attr MyFHT ViewRegExName * or NotSet
  47. # attr MyFHT ViewRegExReading warnings
  48. # attr MyFHT ViewRegExReadingStringCompare [^none]
  49. ################################################################################
  50. package main;
  51. use strict;
  52. use warnings;
  53. use Data::Dumper;
  54. use vars qw(%data);
  55. #-------------------------------------------------------------------------------
  56. sub VIEW_Initialize($)
  57. {
  58. my ($hash) = @_;
  59. $hash->{DefFn} = "VIEW_Define";
  60. $hash->{AttrList} = "ViewRegExType ViewRegExName ViewRegExReading ViewRegExReadingStringCompare loglevel:0,5";
  61. # CGI
  62. my $name = "MyVIEWS";
  63. my $fhem_url = "/" . $name ;
  64. $data{FWEXT}{$fhem_url}{FUNC} = "VIEW_CGI";
  65. $data{FWEXT}{$fhem_url}{LINK} = $name;
  66. $data{FWEXT}{$fhem_url}{NAME} = $name;
  67. # Global-Config for CSS
  68. # $attr{global}{VIEW_CSS} = "";
  69. $modules{_internal_}{AttrList} .= " VIEW_CSS";
  70. return undef;
  71. }
  72. #-------------------------------------------------------------------------------
  73. sub VIEW_Define(){
  74. my ($hash, $def) = @_;
  75. $hash->{STATE} = $hash->{NAME};
  76. return undef;
  77. }
  78. #-------------------------------------------------------------------------------
  79. sub VIEW_CGI(){
  80. my ($htmlarg) = @_;
  81. # Remove trailing slash
  82. $htmlarg =~ s/^\///;
  83. # Log 0,"VIEW: htmlarg: " . $htmlarg ."\n";
  84. # URL: http(s)://[FHEM:xxxx]/fhem/MyVIEWS/<View-Name>
  85. my @params = split(/\//,$htmlarg);
  86. my $ret_html;
  87. if(int(@params) > 2) {
  88. $ret_html = "ERROR: Wrong URL \n";
  89. return ("text/plain; charset=ISO-8859-1", $ret_html);
  90. }
  91. my $view = $params[1];
  92. if($htmlarg ne "MyVIEWS"){
  93. if(!defined($defs{$view})){
  94. $ret_html = "ERROR: View $view not definde \n";
  95. return ("text/plain; charset=ISO-8859-1", $ret_html);
  96. }
  97. }
  98. $ret_html = "<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01\/\/EN\" \"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\">\n";
  99. $ret_html .= "<html>\n";
  100. $ret_html .= "<head>\n";
  101. # Select CSS-Style-Sheet
  102. my $css = $attr{global}{VIEW_CSS};
  103. if($css eq ""){$ret_html .= "<link href=\"$FW_ME/style.css\" rel=\"stylesheet\"/>\n";}
  104. else {$ret_html .= "<link href=\"$FW_ME/$css\" rel=\"stylesheet\"/>\n";}
  105. $ret_html .= "<title>FHEM VIEWS<\/title>\n";
  106. $ret_html .= "<\/head>\n";
  107. $ret_html .= "<body>\n";
  108. # DIV HDR
  109. $ret_html .= &VIEW_CGI_TOP($view);
  110. # DIV LEFT
  111. $ret_html .= &VIEW_CGI_LEFT();
  112. # DIV RIGHT
  113. if($view) {
  114. $ret_html .= &VIEW_CGI_RIGHT($view);
  115. }
  116. else{
  117. $ret_html .= "<div id=\"content\">\n";
  118. $ret_html .= "</div>\n";
  119. }
  120. # HTML
  121. $ret_html .= "</body>\n";
  122. $ret_html .= "</html>\n";
  123. return ("text/html; charset=ISO-8859-1", $ret_html);
  124. }
  125. #-------------------------------------------------------------------------------
  126. sub VIEW_CGI_TOP($) {
  127. my $v = shift(@_);
  128. # rh = return-Html
  129. my $rh;
  130. $rh = "<div id=\"hdr\">\n";
  131. $rh .= "<form method=\"get\" action=\"" . $FW_ME . "\">\n";
  132. $rh .= "<table WIDTH=\"100%\">\n";
  133. $rh .= "<tr>";
  134. if($v) {
  135. $rh .= "<td><a href=\"" . $FW_ME . "\">FHEM:</a>$v</td>";
  136. }
  137. else {
  138. $rh .= "<td><a href=\"" . $FW_ME . "\">FHEM:</a></td>";
  139. }
  140. $rh .= "<td><input type=\"text\" name=\"cmd\" size=\"30\"/></td>";
  141. $rh .= "</tr>\n";
  142. $rh .= "</table>\n";
  143. $rh .= "</form>\n";
  144. $rh .= "<br>\n";
  145. $rh .= "</div>\n";
  146. return $rh;
  147. }
  148. #-------------------------------------------------------------------------------
  149. sub VIEW_CGI_LEFT(){
  150. # rh = return-Html
  151. my $rh;
  152. $rh = "<div id=\"logo\"><img src=\"" . $FW_ME . "/fhem.png\"></div>";
  153. $rh .= "<div id=\"menu\">\n";
  154. # Print VIEWS
  155. $rh .= "<table class=\"room\">\n";
  156. foreach my $d (sort keys %defs) {
  157. next if ($defs{$d}{TYPE} ne "VIEW");
  158. $rh .= "<tr><td>";
  159. $rh .= "<a href=\"" . $FW_ME . "/MyVIEWS/$d\">$d</a></h3>";
  160. $rh .= "</td></tr>\n";
  161. }
  162. $rh .= "</table><br>\n";
  163. $rh .= "</div>\n";
  164. return $rh;
  165. }
  166. #-------------------------------------------------------------------------------
  167. sub VIEW_CGI_RIGHT(){
  168. my ($v) = @_;
  169. # rh = return-Html
  170. my $rh;
  171. # Filters ViewRegExType ViewRegExName ViewRegExReading
  172. my $f_type = ".*";
  173. if(defined($attr{$v}{ViewRegExType})) {
  174. $f_type = $attr{$v}{ViewRegExType};
  175. }
  176. my $f_name = ".*";
  177. if(defined($attr{$v}{ViewRegExName})){
  178. $f_name = $attr{$v}{ViewRegExName};
  179. }
  180. my $f_reading = ".*";
  181. if(defined($attr{$v}{ViewRegExReading})) {
  182. $f_reading = $attr{$v}{ViewRegExReading};
  183. }
  184. my $f_reading_val = ".*";
  185. if(defined($attr{$v}{ViewRegExReadingStringCompare})) {
  186. $f_reading_val = $attr{$v}{ViewRegExReadingStringCompare};
  187. }
  188. my $row = 1;
  189. $rh = "<div id=\"content\">\n";
  190. $rh .= "<hr>\n";
  191. $rh .= "[RegEx] Type: \"$f_type\" Name: \"$f_name\" Reading: \"$f_reading\" Value:\"$f_reading_val\"\n";
  192. $rh .= "<hr>\n";
  193. my ($d,$r,$tr_class);
  194. my $th = undef;
  195. # Get Devices and Readings
  196. foreach $d (sort keys %defs){
  197. if($defs{$d}{TYPE} =~ m/$f_type/ && $d =~ m/$f_name/){
  198. # Log 0,"VIEW-RIGHT: Device-Match $d";
  199. # Weblink
  200. my $web_rt;
  201. if($defs{$d}{TYPE} eq "weblink" && $f_reading eq ".*" && $f_reading_val eq ".*") {
  202. $rh .= "<table class=\"block\">\n";
  203. $rh .="<tr><td>WEBLINK: $d</td></tr>\n";
  204. # $rh .= FW_showWeblink($d, $defs{$d}{LINK}, $defs{$d}{WLTYPE});
  205. $rh .= VIEW_showWeblink($d, $defs{$d}{LINK}, $defs{$d}{WLTYPE});
  206. # Log 0,"VIEW-RIGHT: FW_showWeblink \n $web_rt\n";
  207. # FW_showWeblink($d, $defs{$d}{LINK}, $defs{$d}{WLTYPE});
  208. # Log 0,"VIEW-RIGHT: Render-Weblink $d";
  209. $rh .= "</table>\n";
  210. }
  211. else {
  212. foreach $r (sort keys %{$defs{$d}{READINGS}}) {
  213. if($r =~ m/$f_reading/) {
  214. # ViewRegExReadingStringCompare
  215. if($defs{$d}{READINGS}{$r}{VAL} =~ m/$f_reading_val/){
  216. $tr_class = $row?"odd":"even";
  217. if(!$th) {
  218. $rh .= "<br>\n";
  219. $rh .= "<table class=\"block\" id=\"" . $defs{$d}{TYPE} . "\" >\n";
  220. $rh .= "<tr class=\"" . $tr_class . "\">";
  221. $rh .= "<td align=\"left\"><a href=\"$FW_ME?detail=$d\">$d</a></td>";
  222. if(defined($attr{$d}{comment})) {
  223. $rh .= "<td>" . $attr{$d}{comment} . "</td>";
  224. }
  225. else {
  226. $rh .= "<td>" . $defs{$d}{TYPE} . "</td>";
  227. }
  228. $rh .= "<td>" . $defs{$d}{STATE} . "</td>";
  229. $rh .= "</tr>\n";
  230. $th = 1;
  231. $row = ($row+1)%2;
  232. $tr_class = $row?"odd":"even";
  233. }
  234. $rh .= "<tr class=\"" . $tr_class . "\">";
  235. $rh .= "<td>$r</td>";
  236. $rh .= "<td>" . $defs{$d}{READINGS}{$r}{VAL} . "</td>";
  237. $rh .= "<td>" . $defs{$d}{READINGS}{$r}{TIME} . "</td>";
  238. $rh .= "</tr>\n";
  239. $row = ($row+1)%2;
  240. # ViewRegExReadingStringCompare
  241. }
  242. }
  243. }
  244. $rh .= "</table>\n";
  245. }
  246. }
  247. $th = undef;
  248. }
  249. $rh .= "</div>\n";
  250. return $rh;
  251. }
  252. #-------------------------------------------------------------------------------
  253. sub VIEW_showWeblink($$$)
  254. {
  255. # Customized Function from 01_FHEMWEB.pm
  256. my $FW_plotmode = "gnuplot-scroll";
  257. my $FW_plotsize = "800,225";
  258. my ($d, $v, $t) = @_;
  259. my $rh;
  260. if($t eq "link") {
  261. $rh .= "<td><a href=\"$v\">$d</a></td>\n"; # no pH, want to open extra browser
  262. }
  263. elsif($t eq "image") {
  264. $rh .= "<td><img src=\"$v\"><br>";
  265. $rh .= "<a href=\"$FW_ME?detail=$d\">$d</a>";
  266. $rh .= "</td>\n";
  267. }
  268. elsif($t eq "fileplot") {
  269. my @va = split(":", $v, 3);
  270. if(@va != 3 || !$defs{$va[0]} || !$defs{$va[0]}{currentlogfile}) {
  271. $rh .= "<td>Broken definition: $v</td>\n";
  272. }
  273. else {
  274. if($va[2] eq "CURRENT") {
  275. $defs{$va[0]}{currentlogfile} =~ m,([^/]*)$,;
  276. $va[2] = $1;
  277. }
  278. $rh .= "<table><tr><td>";
  279. my $wl = "&amp;pos=";
  280. my $arg="$FW_ME?cmd=showlog $d $va[0] $va[1] $va[2]$wl";
  281. if(AttrVal($d,"plotmode",$FW_plotmode) eq "SVG") {
  282. my ($w, $h) = split(",", AttrVal($d,"plotsize",$FW_plotsize));
  283. $rh .= "<embed src=\"$arg\" type=\"image/svg+xml\"" .
  284. "width=\"$w\" height=\"$h\" name=\"$d\"/>\n";
  285. }
  286. else {
  287. $rh .= "<img src=\"$arg\"/>";
  288. }
  289. $rh .= "</td>\n";
  290. $rh .= "<td><a href=\"$FW_ME?detail=$d\">$d</a></td>\n";
  291. $rh .= "</tr></table>";
  292. }
  293. }
  294. }
  295. #-------------------------------------------------------------------------------
  296. 1;