98_FHTCONF.pm 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. ################################################################################
  2. # 98_FHTCONF.pm
  3. #
  4. # Version: 1.5
  5. # Stand: 09/2010
  6. # Autor: Axel Rieger
  7. # a[PUNKT]r[BEI]oo2p[PUNKT]net
  8. #
  9. # Configure multiple FHT´s
  10. # Usage: define <NAME> FHTCONF
  11. # FHTConf-Name: FHTC01
  12. # Assign FHTROOM...All FHT´s in this Room will be configured
  13. # FHEM: define FHTC01 FHTCONF
  14. # FHEM: attr FHTC01 FHTRoom R01
  15. # Assign FHT-Device to FHTRoom
  16. # FHEM: attr <FHT-Name> room R01
  17. # Get a list of FHT-Devices in FHTRoom:
  18. # FHEM: set FHTC01 A0_FHT_DEVICES
  19. #
  20. # Update:
  21. # 09/2010 Added PRIV-CGI OverView
  22. #
  23. ################################################################################
  24. package main;
  25. use strict;
  26. use warnings;
  27. use Data::Dumper;
  28. use vars qw(%data);
  29. use vars qw(%cmds);
  30. use vars qw(%attr);
  31. # FHEM Command to Update FHTs
  32. sub Commandfhtconf($);
  33. ################################################################################
  34. sub FHTCONF_Initialize($)
  35. {
  36. my ($hash) = @_;
  37. $hash->{SetFn} = "FHTCONF_Set";
  38. $hash->{DefFn} = "FHTCONF_Define";
  39. $hash->{AttrList} = "loglevel:0,5 disable:0,1 FHTRoom";
  40. # FHEM Command to Update FHTs
  41. $cmds{fhtconf}{Fn} = "Commandfhtconf";
  42. $cmds{fhtconf}{Hlp} = "FHTCONF[HELP]: fhtconf <FHTCONF-NAME>";
  43. # FHTCONF CGI
  44. my $name = "FHTCONF";
  45. my $fhem_url = "/" . $name ;
  46. $data{FWEXT}{$fhem_url}{FUNC} = "FHTCONF_CGI";
  47. $data{FWEXT}{$fhem_url}{LINK} = $name;
  48. $data{FWEXT}{$fhem_url}{NAME} = $name;
  49. Log 0, "FHEM-MODUL[98_FHTCONF.pm] LOADED";
  50. }
  51. ################################################################################
  52. sub FHTCONF_Define($)
  53. {
  54. my ($hash, @a) = @_;
  55. return "Wrong syntax: use define <name> fht_conf" if(int(@a) !=1 );
  56. # Default Room
  57. my $room = "GRP.FHTCONF";
  58. my $name = $hash->{NAME};
  59. #Room
  60. $attr{$name}{room} = $room;
  61. # State
  62. $hash->{STATE} = "Created " . TimeNow();
  63. return undef;
  64. }
  65. ################################################################################
  66. sub FHTCONF_Set($)
  67. {
  68. my ($hash, @a) = @_;
  69. # 4 Argumente
  70. # 1. Device Selbst als HASH
  71. # $a[0] => Device Name als String
  72. # $a[1] => Reading
  73. # $a[2] => Value for READING
  74. my $fields;
  75. $fields = join(" ",sort keys %{$hash->{READINGS}});
  76. $fields = "A1_mode A2_day_temp A2_night_temp ";
  77. $fields .= "A2_windowopen_temp A2_lowtemp_offset ";
  78. $fields .= "B0_MONTAG B1_DIENSTAG B2_MITTWOCH B3_DONNERSTAG B4_FREITAG B5_SAMSTAG B6_SONNTAG ";
  79. return "Unknown argument $a[1], choose one of ". $fields if($a[1] eq "?");
  80. my ($name,$room);
  81. $name = $hash->{NAME};
  82. # LogLevel
  83. my $ll = 0;
  84. if(defined($attr{$name}{loglevel})) {$ll = $attr{$name}{loglevel};}
  85. # INIT READINGS
  86. if(!defined($defs{$name}{READINGS}{Z0_INIT})) {
  87. &FHTCONF_init_READINGS($name);
  88. }
  89. # A0_FHT_DEVICES => List of FHT-Devices in Room <FHTRoom>
  90. if($a[1] eq "A0_FHT_DEVICES") {
  91. if(defined($attr{$name}{FHTRoom})){
  92. $room = $attr{$name}{FHTRoom};
  93. my $fht_devices = GetDevType_Room($room);
  94. Log 0, "FHTCONF[SET] => FHT_DEVICES Room:$room -> " . $fht_devices;
  95. $a[2] = $fht_devices;
  96. }
  97. else {return "FHTCONF[ERROR] no FHTRoom defined";}
  98. }
  99. # A1_mode FHT Modes ----------------------------------------------------------
  100. if($a[1] eq "A1_mode") {
  101. Log 0, "FHT_CONF|SET|MODE-Values: auto,manual,holiday,holiday_short";
  102. my $mode_value_ok = undef;
  103. my @mode_values = ("auto","manual","holiday","holiday_short");
  104. foreach my $value(@mode_values) {
  105. if($a[2] =~ /$value/){
  106. $mode_value_ok = 1;
  107. }
  108. }
  109. if(!$mode_value_ok) {return "FHTCONF[ERROR] MODE $a[2]: choose on of auto,manual,holiday,holiday_short";}
  110. }
  111. # FHT-Temperatures => NUR Ziffern und EIN Punkt [0-9.] -----------------------
  112. if($a[1] =~ /^A2/) {
  113. if($a[2] =~ /[^0-9.]/) {
  114. return "FHTCONF|$a[2]|ERROR|wrong format: 00.00";
  115. }
  116. if($a[1] ne "A2_lowtemp_offset" && $a[2] < 5.5) {$a[2] = 5.5};
  117. Log 0, "FHTCONF[SET] => Temperatures => $a[1] = $a[2]";
  118. }
  119. # B* FHT-Times
  120. if($a[1] =~ /^B/) {
  121. # Time Values
  122. # Sort-Array @b = sort(@b)
  123. # Values = 12:00;13:00 => mindestens 2 maximal 4; kein Wert über 24
  124. my @times = split(/\|/,$a[2]);
  125. Log 0, "FHT_TIMES[INFO] times = " . @times;
  126. if (@times ne 2 && @times ne 4) {
  127. return "FHT_TIMES[ERROR] Wrong Argument count";}
  128. foreach my $time (@times) {
  129. if (not ($time =~ /([01][0-9]:[0-4])|[0-5][0-9]/) ) {
  130. return "FHT_TIMES[ERROR] $time => 00:00";}
  131. }
  132. # Allwas 4 Values 24:00|24:00|24:00|24:00
  133. if(@times == 2) {push(@times,"24:00");}
  134. if(@times == 3) {push(@times,"24:00");}
  135. # Sort
  136. @times = sort(@times);
  137. $a[2] = join("|", @times);
  138. }
  139. # Set READINGs
  140. $hash->{READINGS}{$a[1]}{TIME} = TimeNow();
  141. $hash->{READINGS}{$a[1]}{VAL} = $a[2];
  142. return undef;
  143. }
  144. ################################################################################
  145. sub Commandfhtconf($)
  146. {
  147. my ($cl, $dn) = @_;
  148. # $dn = FHTCONF Device-Name
  149. # Device exists
  150. if(!defined($defs{$dn})){
  151. Log 0, "FHTCONF CMD Device $dn not found";
  152. return undef;
  153. }
  154. # Type FHTCONF
  155. if($defs{$dn}{TYPE} ne "FHTCONF") {
  156. Log 0, "FHTCONF CMD $dn wrong Device-Type";
  157. return undef;
  158. }
  159. # Device disabled
  160. if(defined($attr{$dn}{disable})) {
  161. Log 0, "FHTCONF CMD $dn disabled";
  162. $defs{$dn}{STATE} = "[DISBALED] ". TimeNow();
  163. return undef;
  164. }
  165. #LogLevel
  166. my $ll = 0;
  167. if(defined($attr{$dn}{'loglevel'})) {
  168. $ll = $attr{$dn}{'loglevel'};
  169. }
  170. Log $ll, "FHTCONF-CMD: $dn";
  171. # FHT_Devices
  172. my ($room,$device_list_reading);
  173. if(defined($attr{$dn}{FHTRoom})){
  174. $room = $attr{$dn}{FHTRoom};
  175. $device_list_reading = GetDevType_Room($room);
  176. # GetDevType_ROOM[ERROR]: No Room"
  177. if($device_list_reading =~ m/\[ERROR\]/) {
  178. $defs{$dn}{STATE} = "[ERROR] ". TimeNow();
  179. Log $ll ,"FHTCONF-CMD[ERROR] $dn: $device_list_reading";
  180. return undef;
  181. }
  182. $defs{$dn}{READINGS}{A0_FHT_DEVICES}{VAL} = $device_list_reading;
  183. $defs{$dn}{READINGS}{A0_FHT_DEVICES}{TIME} = TimeNow();
  184. }
  185. else {
  186. Log 0,"FHTCONF[ERROR] no FHTRoom defined";
  187. $defs{$dn}{STATE} = "[ERROR] No FHTRoom defined ". TimeNow();
  188. return undef;
  189. }
  190. #-----------------------------------------------------------------------------
  191. # Building FHEM-Commands to send
  192. # fhem "set <DAVEICE-NAME> params
  193. my (%params);
  194. $params{"mode"} = $defs{$dn}{READINGS}{A1_mode}{VAL};
  195. $params{"day-temp"} = $defs{$dn}{READINGS}{A2_day_temp}{VAL};
  196. $params{"night-temp"} = $defs{$dn}{READINGS}{A2_night_temp}{VAL};
  197. $params{"windowopen-temp"} = $defs{$dn}{READINGS}{A2_windowopen_temp}{VAL};
  198. $params{"lowtemp-offset"} = $defs{$dn}{READINGS}{A2_lowtemp_offset}{VAL};
  199. # Times ----------------------------------------------------------------------
  200. # Mapping ersten drei Buchstaben Wochentag => from1 to1 bzw. from2 to2
  201. my ($reading,@times,$j,$index);
  202. my %weekdays = (
  203. B0_MONTAG => ["mon-from1", "mon-to1", "mon-from2","mon-to2"],
  204. B1_DIENSTAG=> ["tue-from1", "tue-to1", "tue-from2","tue-to2"],
  205. B2_MITTWOCH => ["wed-from1", "wed-to1", "wed-from2","wed-to2"],
  206. B3_DONNERSTAG => ["thu-from1", "thu-to1", "thu-from2","thu-to2"],
  207. B4_FREITAG => ["fri-from1", "fri-to1", "fri-from2","fri-to2"],
  208. B5_SAMSTAG => ["sat-from1", "sat-to1", "sat-from2","sat-to2"],
  209. B6_SONNTAG => ["sun-from1", "sun-to1", "sun-from2","sun-to2"],
  210. );
  211. foreach $reading (sort keys %{$defs{$dn}{READINGS}}) {
  212. next if($reading !~ /^B/);
  213. @times = split(/\|/,$defs{$dn}{READINGS}{$reading}{VAL});
  214. for ($j=0; $j < @times; $j++) {
  215. $index = $weekdays{$reading}[$j];
  216. $params{$index} = $times[$j];
  217. }
  218. }
  219. # FHT-Devices ----------------------------------------------------------------
  220. my (@fht_devices,$fht);
  221. Log $ll ,"FHTCONF $dn update FHT-DEVICES: $device_list_reading";
  222. @fht_devices = split(/\|/,$device_list_reading);
  223. my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time());
  224. $month = $month + 1;
  225. $year = $year + 1900;
  226. my ($p,$old,$new,$at_time,$at_name,$tsecs);
  227. # SendList
  228. my $fhemcmd = "";
  229. foreach $fht (@fht_devices){
  230. foreach $p (sort keys %params){
  231. # Send only Changes
  232. $old = $defs{$fht}{READINGS}{$p}{VAL};
  233. $new = $params{$p};
  234. Log $ll, "FHTCONF-CMD-OLD: $fht -> $p -> OLD:$old NEW:$new";
  235. if($old ne $new){
  236. # Commands to Send
  237. $fhemcmd .= " $p $new";
  238. }
  239. }
  240. # Send Out
  241. if($fhemcmd ne "") {
  242. my $cmd = "set $fht" . $fhemcmd;
  243. Log $ll, "FHTCONF-CMD-SEND: $fhemcmd";
  244. fhem $cmd;
  245. #Reset
  246. $fhemcmd = "";
  247. $cmd = "";
  248. }
  249. else {
  250. Log 0, "FHTCONF-CMD-SEND: $fht No Changes";}
  251. # Report 1&2
  252. fhem "set $fht report1 255 report2 255";
  253. # FHT Time&Date
  254. fhem "set $fht hour $hour minute $min year $year month $month day $mday";
  255. }
  256. # Set STATE
  257. $defs{$dn}{STATE} = "LastUpdate ". TimeNow();
  258. return undef;
  259. }
  260. ################################################################################
  261. sub GetDevType_Room($){
  262. # Get All Dives By Type from Room
  263. # Params: GetDevType_Room <ROOM>
  264. # GetDevType_Room
  265. # Return: List of Devices seperated by | <PIPE>
  266. my ($room) = @_;
  267. my $type = "FHT";
  268. if(!defined($room)) {return "GetDevType_ROOM[ERROR]: No Room";}
  269. if(!defined($type)) {return "GetDevType_ROOM[ERROR]: No Type";}
  270. my (@devices);
  271. foreach my $d (sort keys %attr) {
  272. if($defs{$d}{TYPE} eq $type && $attr{$d}{room} =~ /$room/ ) {
  273. push(@devices,$d);
  274. }
  275. }
  276. return join("|",@devices);
  277. }
  278. ################################################################################
  279. sub FHTCONF_init_READINGS($) {
  280. my ($name) = @_;
  281. Log 0,"FHTCONF:$name ------INIT--------------";
  282. # Set DEFAULT Values
  283. # FHT's
  284. $defs{$name}{READINGS}{A0_FHT_DEVICES}{TIME} = TimeNow();
  285. $defs{$name}{READINGS}{A0_FHT_DEVICES}{VAL} = "";
  286. #Mode
  287. # Values auto, manual, holiday or holiday_short
  288. $defs{$name}{READINGS}{A1_mode}{TIME} = TimeNow();
  289. $defs{$name}{READINGS}{A1_mode}{VAL} = "auto";
  290. # Temperaturen...defualt 5.5 = disable
  291. $defs{$name}{READINGS}{A2_day_temp}{TIME} = TimeNow();
  292. $defs{$name}{READINGS}{A2_day_temp}{VAL} = "5.5";
  293. $defs{$name}{READINGS}{A2_night_temp}{TIME} = TimeNow();
  294. $defs{$name}{READINGS}{A2_night_temp}{VAL} = "5.5";
  295. $defs{$name}{READINGS}{A2_windowopen_temp}{TIME} = TimeNow();
  296. $defs{$name}{READINGS}{A2_windowopen_temp}{VAL} = "5.5";
  297. # LowTemp-Offest
  298. $defs{$name}{READINGS}{A2_lowtemp_offset}{TIME} = TimeNow();
  299. $defs{$name}{READINGS}{A2_lowtemp_offset}{VAL} = "2.0";
  300. # Montag = Monday
  301. $defs{$name}{READINGS}{B0_MONTAG}{TIME} = TimeNow();
  302. $defs{$name}{READINGS}{B0_MONTAG}{VAL} = "24:00|24:00|24:00|24:00";
  303. # Dienstag = Tuesday
  304. $defs{$name}{READINGS}{B1_DIENSTAG}{TIME} = TimeNow();
  305. $defs{$name}{READINGS}{B1_DIENSTAG}{VAL} = "24:00|24:00|24:00|24:00";
  306. # Mittwoch = Wednesday
  307. $defs{$name}{READINGS}{B2_MITTWOCH}{TIME} = TimeNow();
  308. $defs{$name}{READINGS}{B2_MITTWOCH}{VAL} = "24:00|24:00|24:00|24:00";
  309. # Donnerstag = Thursday
  310. $defs{$name}{READINGS}{B3_DONNERSTAG}{TIME} = TimeNow();
  311. $defs{$name}{READINGS}{B3_DONNERSTAG}{VAL} = "24:00|24:00|24:00|24:00";
  312. # Freitag = Friday
  313. $defs{$name}{READINGS}{B4_FREITAG}{TIME} = TimeNow();
  314. $defs{$name}{READINGS}{B4_FREITAG}{VAL} = "24:00|24:00|24:00|24:00";
  315. # Samstag = Saturday
  316. $defs{$name}{READINGS}{B5_SAMSTAG}{TIME} = TimeNow();
  317. $defs{$name}{READINGS}{B5_SAMSTAG}{VAL} = "24:00|24:00|24:00|24:00";
  318. # Sonntag = Sunday
  319. $defs{$name}{READINGS}{B6_SONNTAG}{TIME} = TimeNow();
  320. $defs{$name}{READINGS}{B6_SONNTAG}{VAL} = "24:00|24:00|24:00|24:00";
  321. # INIT done
  322. $defs{$name}{READINGS}{Z0_INIT}{VAL} = 1;
  323. $defs{$name}{READINGS}{Z0_INIT}{TIME} = TimeNow();
  324. return undef;
  325. }
  326. ################################################################################
  327. # FHTCONF CGI
  328. ################################################################################
  329. sub FHTCONF_CGI() {
  330. my ($htmlarg) = @_;
  331. # htmlarg = /GROUPS/<CAT-NAME>
  332. my $Cat = FHTCONF_CGI_DISPTACH_URL($htmlarg);
  333. if(!defined($Cat)){$Cat = ""};
  334. my ($ret_html);
  335. $ret_html = "<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01\/\/EN\" \"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\">\n";
  336. $ret_html .= "<html>\n";
  337. $ret_html .= "<head>\n";
  338. $ret_html .= &FHTCONF_CGI_CSS();
  339. $ret_html .= "<title>FHEM GROUPS<\/title>\n";
  340. $ret_html .= "<link href=\"$__ME/style.css\" rel=\"stylesheet\"/>\n";
  341. $ret_html .= "<\/head>\n";
  342. $ret_html .= "<body>\n";
  343. # DIV HDR
  344. $ret_html .= &FHTCONF_CGI_TOP($Cat);
  345. # DIV LEFT
  346. $ret_html .= &FHTCONF_CGI_LEFT($Cat);
  347. # DIV RIGHT
  348. if($Cat ne "") {
  349. $ret_html .= &FHTCONF_CGI_RIGHT($Cat);
  350. }
  351. # HTML
  352. $ret_html .= "</body>\n";
  353. $ret_html .= "</html>\n";
  354. return ("text/html; charset=ISO-8859-1", $ret_html);
  355. }
  356. #-------------------------------------------------------------------------------
  357. sub FHTCONF_CGI_DISPTACH_URL($){
  358. my ($htmlarg) = @_;
  359. my @params = split(/\//,$htmlarg);
  360. my $CAT = undef;
  361. if($params[2]) {
  362. $CAT = $params[2];
  363. # Log 0,"GRP URL-DISP-CAT: " . $CAT;
  364. }
  365. return $CAT;
  366. }
  367. #-------------------------------------------------------------------------------
  368. sub FHTCONF_CGI_CSS() {
  369. my $css;
  370. $css = "<style type=\"text/css\"><!--\n";
  371. $css .= "\#left {float: left; width: 15%; height:100%;}\n";
  372. $css .= "table.GROUP { border:thin solid; background: #E0E0E0; text-align:left;}\n";
  373. $css .= "table.GROUP tr.odd { background: #F0F0F0;}\n";
  374. $css .= "table.GROUP td {nowrap;}";
  375. $css .= "\/\/--><\/style>";
  376. # TEST
  377. #$css = "<link href=\"$__ME/group.css\" rel=\"stylesheet\"/>\n";
  378. return $css;
  379. }
  380. #-------------------------------------------------------------------------------
  381. sub FHTCONF_CGI_TOP($) {
  382. my $CAT = shift(@_);
  383. # rh = return-Html
  384. my $rh;
  385. $rh = "<div id=\"hdr\">\n";
  386. $rh .= "<form method=\"get\" action=\"" . $__ME . "\">\n";
  387. $rh .= "<table WIDTH=\"100%\">\n";
  388. $rh .= "<tr>";
  389. $rh .= "<td><a href=\"" . $__ME . "\">FHEM:</a>$CAT</td>";
  390. $rh .= "<td><input type=\"text\" name=\"cmd\" size=\"30\"/></td>";
  391. $rh .= "</tr>\n";
  392. $rh .= "</table>\n";
  393. $rh .= "</form>\n";
  394. $rh .= "<br>\n";
  395. $rh .= "</div>\n";
  396. return $rh;
  397. }
  398. #-------------------------------------------------------------------------------
  399. sub FHTCONF_CGI_LEFT(){
  400. # rh = return-Html
  401. my $rh;
  402. $rh = "<div id=\"logo\"><img src=\"" . $__ME . "/fhem.png\"></div>";
  403. $rh .= "<div id=\"menu\">\n";
  404. # Print FHTCONF-Devices
  405. $rh .= "<table class=\"room\">\n";
  406. foreach my $d (sort keys %defs) {
  407. next if($defs{$d}{TYPE} ne "FHTCONF");
  408. $rh .= "<tr><td>";
  409. $rh .= "<a href=\"" . $__ME . "/FHTCONF/$d\">$d</a></h3>";
  410. $rh .= "</td></tr>\n";
  411. }
  412. $rh .= "</table>\n";
  413. $rh .= "</div>\n";
  414. return $rh;
  415. }
  416. #-------------------------------------------------------------------------------
  417. sub FHTCONF_CGI_RIGHT(){
  418. my ($CAT) = @_;
  419. my ($rh,$fhtroom,$fht,@fhts,@ft,@fp,$fht_list);
  420. $fhtroom = $attr{$CAT}{FHTRoom};
  421. $fht_list = GetDevType_Room($fhtroom);
  422. $rh = "<div id=\"content\">\n";
  423. if($CAT eq "") {$CAT = "***";}
  424. # $rh .="CAT: " . $CAT . " FHTROOM:" . $fhtroom . "<br>\n";
  425. # $rh .= "FHT-Devices: " . $fht_list . "<br>\n";
  426. $rh .= "<table>\n";
  427. # Tabelle
  428. # Zeile - Row Namen FHTCONFDevice FHT-Devices
  429. $fp[0] .= "<th></th>";
  430. $fp[1] .= "<td></td>";
  431. $fp[2] .= "<td>IODEV</td>";
  432. $fp[3] .= "<td>Warnings</td>";
  433. $fp[4] .= "<td></td>";
  434. $fp[5] .= "<td>Mode</td>";
  435. $fp[6] .= "<td>Day-Temp</td>";
  436. $fp[7] .= "<td>LowTemp-OffSet</td>";
  437. $fp[8] .= "<td>Night-Temp</td>";
  438. $fp[9] .= "<td>WindowOpen-Temp</td>";
  439. $fp[10] .= "<td></td>";
  440. $fp[11] .= "<td>Montag</td>";
  441. $fp[12] .= "<td>Dienstag</td>";
  442. $fp[13] .= "<td>Mittwoch</td>";
  443. $fp[14] .= "<td>Donnerstag</td>";
  444. $fp[15] .= "<td>Freitag</td>";
  445. $fp[16] .= "<td>Samstag</td>";
  446. $fp[17] .= "<td>Sonntag</td>";
  447. $fp[18] .= "<td></td>";
  448. #Values FHTCONF-Device
  449. $fp[0] .= "<th><a href=\"$__ME?detail=$CAT\">$CAT</a></th>";
  450. # $fp[0] .= "<th>" . $CAT . "</th>";
  451. $fp[1] .= "<td></td>";
  452. $fp[2] .= "<td></td>";
  453. $fp[3] .= "<td></td>";
  454. $fp[4] .= "<td></td>";
  455. $fp[5] .= "<td>" . $defs{$CAT}{READINGS}{A1_mode}{VAL} . "</td>";
  456. $fp[6] .= "<td>" . $defs{$CAT}{READINGS}{A2_day_temp}{VAL} . "</td>";
  457. $fp[7] .= "<td>" . $defs{$CAT}{READINGS}{A2_lowtemp_offset}{VAL} . "</td>";
  458. $fp[8] .= "<td>" . $defs{$CAT}{READINGS}{A2_night_temp}{VAL} . "</td>";
  459. $fp[9] .= "<td>" . $defs{$CAT}{READINGS}{A2_windowopen_temp}{VAL} . "</td>";
  460. $fp[10] .= "<td></td>";
  461. $fp[11] .= "<td>" . $defs{$CAT}{READINGS}{B0_MONTAG}{VAL} . "</td>";
  462. $fp[12] .= "<td>" . $defs{$CAT}{READINGS}{B1_DIENSTAG}{VAL} . "</td>";
  463. $fp[13] .= "<td>" . $defs{$CAT}{READINGS}{B2_MITTWOCH}{VAL} . "</td>";
  464. $fp[14] .= "<td>" . $defs{$CAT}{READINGS}{B3_DONNERSTAG}{VAL} . "</td>";
  465. $fp[15] .= "<td>" . $defs{$CAT}{READINGS}{B4_FREITAG}{VAL} . "</td>";
  466. $fp[16] .= "<td>" . $defs{$CAT}{READINGS}{B5_SAMSTAG}{VAL} . "</td>";
  467. $fp[17] .= "<td>" . $defs{$CAT}{READINGS}{B6_SONNTAG}{VAL} . "</td>";
  468. $fp[18] .= "<td></td>";
  469. # FHT Devices
  470. @fhts = split(/\|/,$fht_list);
  471. foreach $fht (@fhts){
  472. $fp[0] .= "<th><a href=\"$__ME?detail=$fht\">$fht</a></th>";
  473. # $fp[0] .= "<th>" . $fht . "</td>";
  474. $fp[1] .= "<td></td>";
  475. $fp[2] .= "<td>" . $attr{$fht}{IODev} . "</td>";
  476. $fp[3] .= "<td>" . $defs{$fht}{READINGS}{warnings}{VAL} . "</td>";
  477. $fp[4] .= "<td></td>";
  478. $fp[5] .= "<td>" . $defs{$fht}{READINGS}{mode}{VAL} . "</td>";
  479. $fp[6] .= "<td>" . $defs{$fht}{READINGS}{'day-temp'}{VAL} . "</td>";
  480. $fp[7] .= "<td>" . $defs{$fht}{READINGS}{'lowtemp-offset'}{VAL} . "</td>";
  481. $fp[8] .= "<td>" . $defs{$fht}{READINGS}{'night-temp'}{VAL} . "</td>";
  482. $fp[9] .= "<td>" . $defs{$fht}{READINGS}{'windowopen-temp'}{VAL} . "</td>";
  483. $fp[10] .= "<td></td>";
  484. $fp[11] .= "<td>" . $defs{$fht}{READINGS}{'mon-from1'}{VAL} . "|" . $defs{$fht}{READINGS}{'mon-to1'}{VAL} . "|";
  485. $fp[11] .= $defs{$fht}{READINGS}{'mon-from2'}{VAL} . "|" . $defs{$fht}{READINGS}{'mon-to2'}{VAL} . "</td>";
  486. $fp[12] .= "<td>" . $defs{$fht}{READINGS}{'tue-from1'}{VAL} . "|" . $defs{$fht}{READINGS}{'tue-to1'}{VAL} . "|";
  487. $fp[12] .= $defs{$fht}{READINGS}{'tue-from2'}{VAL} . "|" . $defs{$fht}{READINGS}{'tue-to2'}{VAL} . "</td>";
  488. $fp[13] .= "<td>" . $defs{$fht}{READINGS}{'wed-from1'}{VAL} . "|" . $defs{$fht}{READINGS}{'wed-to1'}{VAL} . "|";
  489. $fp[13] .= $defs{$fht}{READINGS}{'wed-from2'}{VAL} . "|" . $defs{$fht}{READINGS}{'wed-to2'}{VAL} . "</td>";
  490. $fp[14] .= "<td>" . $defs{$fht}{READINGS}{'thu-from1'}{VAL} . "|" . $defs{$fht}{READINGS}{'thu-to1'}{VAL} . "|";
  491. $fp[14] .= $defs{$fht}{READINGS}{'thu-from2'}{VAL} . "|" . $defs{$fht}{READINGS}{'thu-to2'}{VAL} . "</td>";
  492. $fp[15] .= "<td>" . $defs{$fht}{READINGS}{'fri-from1'}{VAL} . "|" . $defs{$fht}{READINGS}{'fri-to1'}{VAL} . "|";
  493. $fp[15] .= $defs{$fht}{READINGS}{'fri-from2'}{VAL} . "|" . $defs{$fht}{READINGS}{'fri-to2'}{VAL} . "</td>";
  494. $fp[16] .= "<td>" . $defs{$fht}{READINGS}{'sat-from1'}{VAL} . "|" . $defs{$fht}{READINGS}{'sat-to1'}{VAL} . "|";
  495. $fp[16] .= $defs{$fht}{READINGS}{'sat-from2'}{VAL} . "|" . $defs{$fht}{READINGS}{'sat-to2'}{VAL} . "</td>";
  496. $fp[17] .= "<td>" . $defs{$fht}{READINGS}{'sun-from1'}{VAL} . "|" . $defs{$fht}{READINGS}{'sun-to1'}{VAL} . "|";
  497. $fp[17] .= $defs{$fht}{READINGS}{'sun-from2'}{VAL} . "|" . $defs{$fht}{READINGS}{'sun-to2'}{VAL} . "</td>";
  498. $fp[18] .= "<td>" . $attr{$fht}{comment} . "</td>";
  499. }
  500. foreach (@fp) {
  501. $rh .= "<tr ALIGN=LEFT>" . $_ . "</tr>\n";
  502. }
  503. $rh .= "</table>\n";
  504. $rh .= "</div>\n";
  505. return $rh;
  506. }
  507. ################################################################################
  508. 1;