From 32736358735fe662fefa3c130ac1eaea41267f31 Mon Sep 17 00:00:00 2001 From: ulimaass Date: Sun, 29 Nov 2015 09:51:06 +0000 Subject: [PATCH] FLOORPLAN: fix log-entries, 3rd round git-svn-id: https://svn.fhem.de/fhem/trunk@10042 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/95_FLOORPLAN.pm | 750 +++++++++++++++++++------------------- 1 file changed, 375 insertions(+), 375 deletions(-) diff --git a/fhem/FHEM/95_FLOORPLAN.pm b/fhem/FHEM/95_FLOORPLAN.pm index c4a3dbf05..987cfab77 100644 --- a/fhem/FHEM/95_FLOORPLAN.pm +++ b/fhem/FHEM/95_FLOORPLAN.pm @@ -137,7 +137,7 @@ sub FP_pOfill($@); # print line filled up with hash-signs # $ret_html; # from FHEMWEB: Returned data (html) my $FP_name; # current floorplan-name my $FP_arrange; # arrange-mode -my $FP_arrange_selected; # device selected to be arranged +my $FP_arrange_selected; # device selected to be arranged my $FP_arrange_default; # device selected in previous round my %FP_webArgs = (); # sections of analyzed URL my $FP_fwdetail; # set when floorplan is called from fhemweb-detailscreen @@ -148,11 +148,11 @@ my $FP_viewport; # Define width for touchpad device # $FW_longpoll; # from FHEMWEB: longpoll # $FW_wname; # from FHEMWEB: name of web-instance # %FW_pos=(); # from FHEMWEB: scroll position -# $FW_subdir # from FHEMWEB: path of floorplan-subdir - enables reusability of FHEMWEB-routines for sub-URLS like floorplan +# $FW_subdir # from FHEMWEB: path of floorplan-subdir - enables reusability of FHEMWEB-routines for sub-URLS like floorplan # $FW_cname # from FHEMWEB: Current connection name -my $FW_encoding="UTF-8"; # like in FHEMWEB: encoding hardcoded +my $FW_encoding="UTF-8"; # like in FHEMWEB: encoding hardcoded my $FW_plotmode=""; # like in FHEMWEB: SVG -my $FW_plotsize; # like in FHEMWEB: like in fhemweb dependent on regular/smallscreen/touchpad +my $FW_plotsize; # like in FHEMWEB: like in fhemweb dependent on regular/smallscreen/touchpad my %FW_zoom; # copied from FHEMWEB - using local version to avoid global variable my @FW_zoom; # copied from FHEMWEB - using local version to avoid global variable my @styles = ("0 (Icon only)","1 (Name+Icon)","2 (Name+Icon+Commands)","3 (Device-Reading)","4 (S300TH-specific)","5 (Icon+Commands)", @@ -198,7 +198,7 @@ FP_define(){ $hash->{STATE} = 'Defined'; my $name = $hash->{NAME}; if (AttrVal("global","userattr","") !~ m/fp_$name/) { - addToAttrList("fp_$name"); # create userattr fp_ if it doesn't exist yet + addToAttrList("fp_$name"); # create userattr fp_ if it doesn't exist yet Log3 $name, 3, "Floorplan - added global userattr fp_$name"; } return undef; @@ -248,15 +248,15 @@ FP_copy_rename_delete($$$) { Log3 $old, 3, "Floorplan - added global userattr $anew"; } foreach my $d (sort keys %defs) { - next if (!$attr{$d}{"$aold"} && !$attr{$d}{"$anew"}); - if ($cmd =~ m/(copy|rename)/) { + next if (!$attr{$d}{"$aold"} && !$attr{$d}{"$anew"}); + if ($cmd =~ m/(copy|rename)/) { AnalyzeCommand(undef, "attr $d $anew ".AttrVal($d,$aold,""),AttrVal($FW_wname,"allowedCommands",undef)); - Log3 $new, 3, "Floorplan - added attr $d $anew ".AttrVal($d,$anew,""); - } - if ($cmd =~ m/(rename|delete)/) { - Log3 $old, 3, "Floorplan - deleted attr $d $aold ".AttrVal($d,$aold,""); - AnalyzeCommand(undef, "deleteattr $d $aold",AttrVal($FW_wname,"allowedCommands",undef)); - } + Log3 $new, 3, "Floorplan - added attr $d $anew ".AttrVal($d,$anew,""); + } + if ($cmd =~ m/(rename|delete)/) { + Log3 $old, 3, "Floorplan - deleted attr $d $aold ".AttrVal($d,$aold,""); + AnalyzeCommand(undef, "deleteattr $d $aold",AttrVal($FW_wname,"allowedCommands",undef)); + } } if ($cmd =~ m/(rename|delete)/) { my $ua = $attr{global}{userattr}; @@ -307,29 +307,29 @@ FP_CGI(){ my @htmlpart = split("\\?", $params[1]) if ($params[1]); # split URL by ? -> htmlpart[0] = FP_name, htmlpart[1] = commandstring if (!$htmlpart[1] && $htmlpart[0] && $htmlpart[0] !~ "\\?") { # in case of 'post' URL does not contain ? $htmlpart[0] =~ /([a-z0-9.:_]+)&(.*)/i; - $htmlpart[1] = $2 if ($2); - $htmlpart[1] =~ s/\\+/&/g if ($htmlpart[1]); - $htmlpart[0] = $1 if ($1); + $htmlpart[1] = $2 if ($2); + $htmlpart[1] =~ s/\\+/&/g if ($htmlpart[1]); + $htmlpart[0] = $1 if ($1); } $FP_name = $htmlpart[0] if (!$FP_name); ### set global parameters, check floorplan-name - if ($FP_name) { # floorplan-name is part of URL - if(!defined($defs{$FP_name}) && $FP_name ne "floorplanstartpage"){ - $FW_RET = "ERROR: Floorplan $FP_name not defined \n"; # check for typo in URL + if ($FP_name) { # floorplan-name is part of URL + if(!defined($defs{$FP_name}) && $FP_name ne "floorplanstartpage"){ + $FW_RET = "ERROR: Floorplan $FP_name not defined \n"; # check for typo in URL return ("text/plain; charset=$FW_encoding", $FW_RET); - } + } $FP_arrange = AttrVal($FP_name, "fp_arrange", 0); # set arrange mode $FP_viewport = AttrVal($FP_name, "fp_viewport", "width=768") if ($FP_name); # viewport definition $FW_subdir = "/floorplan/$FP_name"; - } else { # no floorplan-name in URL.... - $FP_arrange_default = undef; - $FP_arrange_selected = undef; - my $dev = undef; - my $tmpname = undef; - my $cnt = 0; - foreach my $fp (keys %defs) { - next if ($defs{$fp}{TYPE} ne "FLOORPLAN"); - if (AttrVal($fp, "fp_default", undef)) { # use floorplan with attr fp_default + } else { # no floorplan-name in URL.... + $FP_arrange_default = undef; + $FP_arrange_selected = undef; + my $dev = undef; + my $tmpname = undef; + my $cnt = 0; + foreach my $fp (keys %defs) { + next if ($defs{$fp}{TYPE} ne "FLOORPLAN"); + if (AttrVal($fp, "fp_default", undef)) { # use floorplan with attr fp_default $FP_name = $fp; last; } else { @@ -355,7 +355,7 @@ FP_CGI(){ if( !$htmlpart[0] || (AttrVal($FW_wname, "redirectCmds", 1) && $me && $commands && !$FP_ret)) { if($FP_name) { $tgt = "/floorplan/$FP_name" - } else { + } else { $FW_RET = 'ERROR: floorplan-name could not be derived from URL, fp_default or single floorplanname.'; return ("text/plain; charset=$FW_encoding", $FW_RET); } @@ -368,7 +368,7 @@ FP_CGI(){ "Content-Length: 0\r\n", "Location: $tgt\r\n", "\r\n"; - return; + return; } ### output html-pages if($FP_name eq "floorplanstartpage") { @@ -398,7 +398,7 @@ FP_digestCgi($) { foreach my $pv (split("&", $arg)) { # per each URL-section devided by & next if($pv eq ""); # happens when post forgot to set FW_ME $pv =~ s/\+/ /g; - $pv =~ s/%([\dA-F][\dA-F])/chr(hex($1))/ige; + $pv =~ s/%([\dA-F][\dA-F])/chr(hex($1))/ige; my ($p,$v) = split("=",$pv, 2); # $p = parameter, $v = value $v =~ s/[\r]\n/\\\n/g if($v && $p && $p ne "data"); # Multiline: escape the NL for fhem $FP_webArgs{$p} = $v; @@ -410,13 +410,13 @@ FP_digestCgi($) { if($p =~ m/^dev\.(.*)$/) { $dev{$1} = $v; } if($p =~ m/^arg\.(.*)$/) { $arg{$1} = $v; } if($p =~ m/^val\.(.*)$/) { $val{$1} = $v; } - if($p =~ m/^deva\.(.*)$/) { $deva{$1} = $v; $FP_arrange_selected = undef; } + if($p =~ m/^deva\.(.*)$/) { $deva{$1} = $v; $FP_arrange_selected = undef; } if($p =~ m/^attr\.(.*)$/) { $attr{$1} = $v; } if($p =~ m/^top\.(.*)$/) { $top{$1} = $v; } if($p =~ m/^left\.(.*)$/) { $left{$1} = $v; } if($p =~ m/^style\.(.*)$/) { $style{$1} = int(substr($v,0,2)); } if($p =~ m/^text\.(.*)$/) { $text{$1} = $v; } - if($p eq "pos") { %FW_pos = split(/[=;]/, $v); } + if($p eq "pos") { %FW_pos = split(/[=;]/, $v); } } my $dele = ($cmd =~ m/^deleteattr/); $cmd.=" $dev{$c}" if(defined($dev{$c})); # FHT device @@ -522,21 +522,21 @@ FP_showStart() { FW_pO "
"; FW_pO "
"; FW_pO ""; - FW_pO ""; #input-field + FW_pO ""; #input-field FW_pO "
"; FW_pO "
"; # no floorplans defined? -> show message my $count=0; foreach my $f (sort keys %defs) { - next if ($defs{$f}{TYPE} ne "FLOORPLAN"); - $count++; + next if ($defs{$f}{TYPE} ne "FLOORPLAN"); + $count++; } if ($count == 0) { FW_pO '
'; - FW_pO "



No floorplans have been defined yet. For definition, enter
"; - FW_pO "
    define <name> FLOORPLAN
"; - FW_pO "Also check the commandref
"; - FW_pO "
"; + FW_pO "



No floorplans have been defined yet. For definition, enter
"; + FW_pO "
    define <name> FLOORPLAN
"; + FW_pO "Also check the commandref
"; + FW_pO ""; } FW_pO ""; } @@ -563,69 +563,69 @@ FP_show(){ if (AttrVal("$FP_name", "commandfield", undef)) { FW_pO "
\n"; FW_pO "
"; - FW_pO " \n"; #fhem-commandfield + FW_pO " \n"; #fhem-commandfield FW_pO "
"; FW_pO "
\n"; } ## let's go foreach my $d (sort keys %defs) { # loop all devices - my $type = $defs{$d}{TYPE}; - my $attr = AttrVal("$d","fp_$FP_name", undef); - next if(!$attr || $type eq "weblink"); # skip if device-attribute not set for current floorplan-name - - my ($top, $left, $style, $text, $text2) = split(/,/ , $attr); - # $top = position in px, top - # $left = position in px, left - # $style = style (0=icon only, 1=name+icon, 2=name+icon+commands, 3=device-Reading + name from $text2, 4=S300TH, 5=icon+commands, 6 device-Reading+timestamp, 7 command only, 8 icon+commands popup) - # $text = alternativeCaption - # $text2 = special for style3+6: $text = ReadingID, $text2=alternativeCaption - $top = 0 if (!$top); - $left = 0 if (!$left); - $style = 0 if (!$style); + my $type = $defs{$d}{TYPE}; + my $attr = AttrVal("$d","fp_$FP_name", undef); + next if(!$attr || $type eq "weblink"); # skip if device-attribute not set for current floorplan-name + my ($top, $left, $style, $text, $text2) = split(/,/ , $attr); + # $top = position in px, top + # $left = position in px, left + # $style = style (0=icon only, 1=name+icon, 2=name+icon+commands, 3=device-Reading + name from $text2, 4=S300TH, 5=icon+commands, 6 device-Reading+timestamp, 7 command only, 8 icon+commands popup) + # $text = alternativeCaption + # $text2 = special for style3+6: $text = ReadingID, $text2=alternativeCaption + $top = 0 if (!$top); + $left = 0 if (!$left); + $style = 0 if (!$style); # start device-specific table - my $t2 = $text2 ? $text2 : " "; + my $t1 = $text2 ? $text2 : " "; + my $t2 = $text ? $text : InternalVal($d,'NAME',' '); # wrapper-div needed for floorplan_drag.js and for positioning - FW_pO "\n
"; - FW_pO "
"; - FW_pO " "; # Main table per device - my ($allSets, $cmdlist, $txt) = FW_devState($d, ''); + FW_pO "\n
"; + FW_pO ""; + FW_pO "
"; # Main table per device + my ($allSets, $cmdlist, $txt) = FW_devState($d, ''); $allSets = FW_widgetOverride($d, $allSets); - $txt = ReadingsVal($d, $text, "Undefined Reading $d-$text") if ($style == 3 || $style == 6); # Style3+6 = DeviceReading given in $text - my $cols = ($cmdlist ? (split(":", $cmdlist)) : 0); # Need command-count for colspan of devicename+state - + $txt = ReadingsVal($d, $text, "Undefined Reading $d-$text") if ($style == 3 || $style == 6); # Style3+6 = DeviceReading given in $text + my $cols = ($cmdlist ? (split(":", $cmdlist)) : 0); # Need command-count for colspan of devicename+state + ######################## # Device-name per device - if ($style gt 0 && $style ne 5 && $style ne 7) { - FW_pO " "; # For css: class=devicename, id=-devicename - my $devName = ""; - if ($style == 3 || $style == 6) { - $devName = $text2 ? $text2 : ""; # Style 3 = Reading - use last part of comma-separated description - } else { - $devName = ($text ? $text : AttrVal($d, "alias", $d)); - } - if ($style == 4 && $txt =~ /T: ([\-0-9\.]+)[ ]+H: ([\-0-9\.]+).*/) { # S300TH-specific - $txt = "".$1."°C
".$2."%"; - } - FW_pO "
"; - } + if ($style gt 0 && $style ne 5 && $style ne 7) { + FW_pO " "; # For css: class=devicename, id=-devicename + my $devName = ""; + if ($style == 3 || $style == 6) { + $devName = $text2 ? $text2 : ""; # Style 3 = Reading - use last part of comma-separated description + } else { + $devName = ($text ? $text : AttrVal($d, "alias", $d)); + } + if ($style == 4 && $txt =~ /T: ([\-0-9\.]+)[ ]+H: ([\-0-9\.]+).*/) { # S300TH-specific + $txt = "".$1."°C
".$2."%"; + } + FW_pO "
"; + } ######################## # Device-state per device if ($style != 7) { - if ($style == 3 || $style == 6) { - FW_pO ""; # For css: class=devicereading, id=- - } else { + if ($style == 3 || $style == 6) { + FW_pO ""; # For css: class=devicereading, id=- + } else { FW_pO ""; # For css: class=devicestate, id= - } + } $txt =~ s/measured-temp: ([\.\d]*) \(Celsius\)/$1/; # format FHT-temperature - ### use device-specific icons according to userattr fp_image or fp_.image - my $fp_image = AttrVal("$d", "fp_image", undef); # floorplan-independent icon + ### use device-specific icons according to userattr fp_image or fp_.image + my $fp_image = AttrVal("$d", "fp_image", undef); # floorplan-independent icon my $fp_fpimage = AttrVal("$d","fp_$FP_name".".image", undef); # floorplan-dependent icon if ($fp_image) { my $state = ReadingsVal($d, "state", undef); - $fp_image =~ s/\{state\}/$state/; # replace {state} by actual device-status + $fp_image =~ s/\{state\}/$state/; # replace {state} by actual device-status $txt =~ s/\
$txt
"; # reading - } elsif ($style == 4) { - FW_pO "
"; - } - if ($style == 6) { # add ReadingsTimeStamp for style 6 - $txt=""; - FW_pO ""; # For css: class=devicetimestamp, id=-devicetimestamp - $txt = ReadingsTimestamp($d, $text, "Undefined Reading $d-$text"); # Style3+6 = DeviceReading given in $text - FW_pO ""; - } + FW_pO ""; + } + if ($style == 6) { # add ReadingsTimeStamp for style 6 + $txt=""; + FW_pO ""; # For css: class=devicetimestamp, id=-devicetimestamp + $txt = ReadingsTimestamp($d, $text, "Undefined Reading $d-$text"); # Style3+6 = DeviceReading given in $text + FW_pO ""; + } ######################## - # Commands per device + # Commands per device if($cmdlist && ( $style == 2 || $style == 5 || $style == 7 || $style == 8) ) { - my @a = split("[: ]", AttrVal($d, "cmdIcon", "")); #new + my @a = split("[: ]", AttrVal($d, "cmdIcon", "")); #new Log 1, "ERROR: bad cmdIcon definition for $d" if(@a % 2); #new my %cmdIcon = @a; #new my $firstIdx = 0; - FW_pO " "; + FW_pO " "; my $oldMe = $FW_ME; - my $h = ""; + my $h = ""; foreach my $cmd (split(":", $cmdlist)) { # Special handling (slider, dropdown, timepicker, ...) my $htmlTxt; @@ -672,12 +672,12 @@ FP_show(){ my $values = $1; $FW_ME = "$FW_ME/floorplan/$FP_name"; foreach my $fn (sort keys %{$data{webCmdFn}}) { - my $FW_room = ''; ##needed to be able to reuse code from FHEMWEB + my $FW_room = ''; ##needed to be able to reuse code from FHEMWEB no strict "refs"; - if ($data{webCmdFn}{$fn}) { + if ($data{webCmdFn}{$fn}) { $htmlTxt = &{$data{webCmdFn}{$fn}}($FW_ME, $d, $FW_room, $cmd, $values); - } + } $FW_ME = $oldMe if (defined($htmlTxt)); use strict "refs"; last if(defined($htmlTxt)); @@ -691,16 +691,16 @@ FP_show(){ $h .= "

$cmd

"; } } else { - if ($htmlTxt ne '') { - $htmlTxt =~ s/>desired-temp/>/; #for FHT - $htmlTxt =~ s/>desiredTemperature/>/; #for MAX! - FW_pO $htmlTxt; - } else { - my $nCmd = $cmdIcon{$cmd} ? + if (defined($htmlTxt)) { + $htmlTxt =~ s/>desired-temp/>/; #for FHT + $htmlTxt =~ s/>desiredTemperature/>/; #for MAX! + FW_pO $htmlTxt; + } else { + my $nCmd = $cmdIcon{$cmd} ? FW_makeImage($cmdIcon{$cmd},$cmd,"webCmd") : $cmd; - FW_pH "cmd.$d=set $d $cmd", $nCmd, 1, "col3"; - } - # END # Special handling (slider, dropdown, timepicker, ...) + FW_pH "cmd.$d=set $d $cmd", $nCmd, 1, "col3"; + } + # END # Special handling (slider, dropdown, timepicker, ...) } } $FW_ME = $oldMe; @@ -709,46 +709,46 @@ FP_show(){ if( $txt =~ m/]*)>]*>(.*)<\/a>/ ) { $txt = ""; } else { - FW_pO ""; - + FW_pO ""; + } elsif($type eq "FileLog") { # $row = FW_dumpFileLog($d, 1, $row); } - FW_pO "
"; - FW_pO "$devName" ; - FW_pO "
"; + FW_pO "$devName" ; + FW_pO "
$txt"; # state style4 - } elsif ($cmdlist && $style == 8) { - # first collect the popup data + if ($style == 3 || $style == 6) { + FW_pO "
$txt
"; # reading + } elsif ($style == 4) { + FW_pO "
$txt"; # state style4 + } elsif ($cmdlist && $style == 8) { + # first collect the popup data } else { - FW_pO "$txt"; # state - } - FW_pO "
$txt
"; - FW_pO "
$txt"; # state + } + FW_pO "
$txt
"; + FW_pO "
$txt
"; # reading + FW_pO "
$txt
"; # reading } - FW_pO "
$txt
"; # reading + FW_pO "
$txt
"; # reading } - FW_pO "
"; - FW_pO "
\n"; - } #end loop all decives + FW_pO ""; + FW_pO "\n"; + } #end loop all decives - ######################## - # Finally the weblinks - my $buttons = 1; - my @list = (keys %defs); + ######################## + # Finally the weblinks + my $buttons = 1; + my @list = (keys %defs); - foreach my $d (sort @list) { - my $attr = AttrVal("$d","fp_$FP_name", undef); - next if(IsIgnored($d) || !$attr); - my $type = $defs{$d}{TYPE}; - next if(!$type); + foreach my $d (sort @list) { + my $attr = AttrVal("$d","fp_$FP_name", undef); + next if(IsIgnored($d) || !$attr); + my $type = $defs{$d}{TYPE}; + next if(!$type); next if($type ne "weblink"); - # set position per weblink - my ($top, $left, $style, $text, $text2) = split(/,/ , AttrVal("$d", "fp_$FP_name", undef)); - $text = "" if (!$text); - $text2 = "" if (!$text2); - $left = 0 if (!$left); - $style = 0 if (!$style); - FW_pO "\n"; - } - FW_pO ""; - FW_pO "\n"; + # set position per weblink + my ($top, $left, $style, $text, $text2) = split(/,/ , AttrVal("$d", "fp_$FP_name", undef)); + $text = "" if (!$text); + $text2 = "" if (!$text2); + $left = 0 if (!$left); + $style = 0 if (!$style); + FW_pO "\n"; + } + FW_pO ""; + FW_pO "\n"; } @@ -758,24 +758,24 @@ FP_show(){ sub FP_menu() { return if ($FP_name && AttrVal($FP_name, "fp_noMenu", 0)); # fp_noMenu suppresses menu - FW_pO "
"; + FW_pO "
"; # List FPs - FW_pO ""; - FW_pO ""; - FW_pH "$FW_ME", "fhem", 1; - FW_pO ""; - foreach my $f (sort keys %defs) { - next if (!$defs{$f}{TYPE} || $defs{$f}{TYPE} ne "FLOORPLAN"); - FW_pO ""; + FW_pO "
"; + FW_pO ""; + FW_pH "$FW_ME", "fhem", 1; + FW_pO ""; + foreach my $f (sort keys %defs) { + next if (!$defs{$f}{TYPE} || $defs{$f}{TYPE} ne "FLOORPLAN"); + FW_pO ""; my $icoName = "ico$f"; map { my ($n,$v) = split(":",$_); $icoName=$v if($f =~ m/$n/); } split(" ", AttrVal($FP_name, "fp_roomIcons", "")); my $icon = FW_iconName($icoName) ? FW_makeImage($icoName,$icoName,"icon")." " : ""; FW_pH "$FW_ME/floorplan/$f", "$icon$f", 1; - FW_pO ""; - } - FW_pO "

"; - FW_pO "
\n"; + FW_pO ""; + } + FW_pO "
"; + FW_pO "
\n"; } @@ -784,78 +784,78 @@ FP_menu() { # Arrange-menu sub FP_menuArrange() { - my %desc=(); - ## collect data - $FP_arrange_default = "" if (!$FP_arrange_default); - my @fpl; # devices assigned to floorplan - my @nfpl; # devices not assigned to floorplan - foreach my $d (sort keys %defs) { # loop all devices - my $type = $defs{$d}{TYPE}; - $type = '?' if (!$type); - # exclude these types from list of available devices - next if ($type =~ m/^(WEB|CUL$|FHEM2FHEM|FHEMWEB|FileLog|PachLog|PID|SUNRISE.*|FLOORPLAN|holiday|Global|notify|autocreate)/ ); - my $disp = $d; - $disp .= ' (' . AttrVal($d,"room","Unsorted").") $type"; - my $alias = AttrVal($d, "alias", undef); - $disp .= ' (' . $alias . ')' if ($alias); - $desc{$d} = $disp; - if (AttrVal("$d","fp_$FP_name", undef)) { - push(@fpl, $disp); # all devices on floorplan - } else { - push(@nfpl, $disp); # all devices not on floorplan - } - } - my $d = $FP_arrange_selected; - my $attrd = AttrVal($d, "fp_$FP_name", undef) if ($d); - if ( $FP_arrange_selected && !$attrd) { # arrange-selected, but device is not part of fp now chosen -> reset arrange-selected - $FP_arrange_selected = undef; - } - FW_pO "
"; + my %desc=(); + ## collect data + $FP_arrange_default = "" if (!$FP_arrange_default); + my @fpl; # devices assigned to floorplan + my @nfpl; # devices not assigned to floorplan + foreach my $d (sort keys %defs) { # loop all devices + my $type = $defs{$d}{TYPE}; + $type = '?' if (!$type); + # exclude these types from list of available devices + next if ($type =~ m/^(WEB|CUL$|FHEM2FHEM|FHEMWEB|FileLog|PachLog|PID|SUNRISE.*|FLOORPLAN|holiday|Global|notify|autocreate)/ ); + my $disp = $d; + $disp .= ' (' . AttrVal($d,"room","Unsorted").") $type"; + my $alias = AttrVal($d, "alias", undef); + $disp .= ' (' . $alias . ')' if ($alias); + $desc{$d} = $disp; + if (AttrVal("$d","fp_$FP_name", undef)) { + push(@fpl, $disp); # all devices on floorplan + } else { + push(@nfpl, $disp); # all devices not on floorplan + } + } + my $d = $FP_arrange_selected; + my $attrd = AttrVal($d, "fp_$FP_name", undef) if ($d); + if ( $FP_arrange_selected && !$attrd) { # arrange-selected, but device is not part of fp now chosen -> reset arrange-selected + $FP_arrange_selected = undef; + } + FW_pO "
"; - # add device to floorplan - if (!defined($FP_arrange_selected)) { - FW_pO "
"; #form1 - FW_pO "
\n" . - ($FP_fwdetail?FP_input("detl.$FP_fwdetail", $FP_fwdetail, "hidden") . "\n" :"") . - FW_select("","add.dev", \@nfpl, "", "menu-add") . - FW_submit("ccc.one", "add"); - FW_pO "
\n"; #form1 - } + # add device to floorplan + if (!defined($FP_arrange_selected)) { + FW_pO "
"; #form1 + FW_pO "
\n" . + ($FP_fwdetail?FP_input("detl.$FP_fwdetail", $FP_fwdetail, "hidden") . "\n" :"") . + FW_select("","add.dev", \@nfpl, "", "menu-add") . + FW_submit("ccc.one", "add"); + FW_pO "
\n"; #form1 + } - # select device to be arranged - if (!defined($FP_arrange_selected)) { - my $dv = $FP_arrange_default; - $dv = $desc{$dv} if ($dv); - FW_pO "
"; #form2 - FW_pO "
\n" . - ($FP_fwdetail?FP_input("detl.$FP_fwdetail", $FP_fwdetail, "hidden") . "\n" :"") . - FW_select("","arr.dev", \@fpl, $dv, "menu-select") . - FW_submit("ccc.one", "select"); - FW_pO "
"; #form2 - } + # select device to be arranged + if (!defined($FP_arrange_selected)) { + my $dv = $FP_arrange_default; + $dv = $desc{$dv} if ($dv); + FW_pO "
"; #form2 + FW_pO "
\n" . + ($FP_fwdetail?FP_input("detl.$FP_fwdetail", $FP_fwdetail, "hidden") . "\n" :"") . + FW_select("","arr.dev", \@fpl, $dv, "menu-select") . + FW_submit("ccc.one", "select"); + FW_pO "
"; #form2 + } - # fields for top,left,style,text - if ($attrd) { - ### build the form - my $disp = $FP_arrange eq "detail" ? $desc{$d} : $d; - FW_pO "
"; #form3 - my ($top, $left, $style, $text, $text2) = split(",", $attrd); - $text .= ','.$text2 if ($text2); # re-append Description after reading-ID for style3 - $style = $styles[$style]; - FW_pO "
\n" . - ($FP_fwdetail?FP_input("detl.$FP_fwdetail", $FP_fwdetail, "hidden") . "\n" :"") . - FP_input("deva.$d", $d, "hidden") . "\n" . - FP_input("dscr.$d", $disp, "text", "Selected device", 45, "", "disabled") . "\n
\n" . - FP_input("attr.$d", "fp_$FP_name", "hidden") . "\n" . - FP_input("top.$d", $top ? $top : 10, "text", "Top", 4, 4, 'onkeydown="increment(event, this)" class="'.$d.'" id="fp_ar_input_top"') . "\n" . - FP_input("left.$d", $left ? $left : 10, "text", "Left", 4, 4, 'onkeydown="increment(event, this)" class="'.$d.'" id="fp_ar_input_left"' ) . "\n" . - FW_select("","style.$d", \@styles, $style ? $style : 0, "menu-arrange") . "\n" . - FP_input("text.$d", $text ? $text : "", "text", "Description", 15) . "\n" . - FW_submit("cmd.$d", "attr") . "\n" . - FW_submit("cmd.$d", "deleteattr"); - FW_pO "
"; # form3 - } - FW_pO "
"; + # fields for top,left,style,text + if ($attrd) { + ### build the form + my $disp = $FP_arrange eq "detail" ? $desc{$d} : $d; + FW_pO "
"; #form3 + my ($top, $left, $style, $text, $text2) = split(",", $attrd); + $text .= ','.$text2 if ($text2); # re-append Description after reading-ID for style3 + $style = $styles[$style]; + FW_pO "
\n" . + ($FP_fwdetail?FP_input("detl.$FP_fwdetail", $FP_fwdetail, "hidden") . "\n" :"") . + FP_input("deva.$d", $d, "hidden") . "\n" . + FP_input("dscr.$d", $disp, "text", "Selected device", 45, "", "disabled") . "\n
\n" . + FP_input("attr.$d", "fp_$FP_name", "hidden") . "\n" . + FP_input("top.$d", $top ? $top : 10, "text", "Top", 4, 4, 'onkeydown="increment(event, this)" class="'.$d.'" id="fp_ar_input_top"') . "\n" . + FP_input("left.$d", $left ? $left : 10, "text", "Left", 4, 4, 'onkeydown="increment(event, this)" class="'.$d.'" id="fp_ar_input_left"' ) . "\n" . + FW_select("","style.$d", \@styles, $style ? $style : 0, "menu-arrange") . "\n" . + FP_input("text.$d", $text ? $text : "", "text", "Description", 15) . "\n" . + FW_submit("cmd.$d", "attr") . "\n" . + FW_submit("cmd.$d", "deleteattr"); + FW_pO "
"; # form3 + } + FW_pO "
"; } @@ -865,12 +865,12 @@ FP_menuArrange() { sub FP_input(@) { - my ($n, $v, $type, $title, $size, $maxlength, $addition) = @_; - $title = $title ? " title=\"$title\"" : ""; - $size = $size ? " size=\"$size\"" : ""; - $maxlength = $maxlength ? " maxlength=\"$maxlength\"" : ""; - $addition = "" if (!defined($addition)); - return "\n"; + my ($n, $v, $type, $title, $size, $maxlength, $addition) = @_; + $title = $title ? " title=\"$title\"" : ""; + $size = $size ? " size=\"$size\"" : ""; + $maxlength = $maxlength ? " maxlength=\"$maxlength\"" : ""; + $addition = "" if (!defined($addition)); + return "\n"; } @@ -897,10 +897,10 @@ FP_detailFn($$$$) { FW_pO 'DeviceXYStyleText'; foreach my $fpd (sort keys %defs) { my $val = AttrVal($fpd,"fp_$d",undef); - next if (!$val); + next if (!$val); my ($x,$y,$style,$txt,$txt2) = split(",",$val); - $txt = "" if (!$txt); - $txt2 = "" if (!$txt2); + $txt = "" if (!$txt); + $txt2 = "" if (!$txt2); $row++; my $ret = '$x"; $ret .= "
$y
"; $ret .= "
"; - $ret .= $styles[$style] if (defined($style)&& defined($styles[$style])); - $ret .= "
"; + $ret .= $styles[$style] if (defined($style)&& defined($styles[$style])); + $ret .= ""; $ret .= "
$txt".($txt2?",$txt2":"")."
"; $ret .= ""; FW_pO $ret; @@ -945,7 +945,7 @@ FP_getConfig($) { ## attributes of floorplan-device foreach my $a (sort keys %{$attr{$dev}}) { my $val = AttrVal($dev,$a,undef); - next if (!$val); + next if (!$val); $html .= "attr $dev $a $val\n"; } $html .= "\n\n"; @@ -953,7 +953,7 @@ FP_getConfig($) { ## attributes of assigned devices foreach my $d (sort keys %defs) { my $val = AttrVal($d,"fp_$dev",undef); - next if (!$val); + next if (!$val); $html .= "attr $d fp_$dev $val\n"; } $html .= "\n\n".FP_pOfill(80, "End of config for FLOORPLAN $dev"); @@ -1007,9 +1007,9 @@ FP_pOfill($@) { Example:
    - define Groundfloor FLOORPLAN
    - fp_Groundfloor.png -

    + define Groundfloor FLOORPLAN
    + fp_Groundfloor.png +

@@ -1026,7 +1026,7 @@ FP_pOfill($@) {
    get <name> config
    - Displays the configuration of the floorplan with all attributes. Can be used in an include-file. + Displays the configuration of the floorplan with all attributes. Can be used in an include-file.

@@ -1035,114 +1035,114 @@ FP_pOfill($@) {
  • userattr fp_<name> <top>,<left>[,<style>[,<description>]]

    A userattr fp_<name> will be created automatically if it does not exist yet.
    -
      +
      • top = screen-position, pixels from top of screen
      • left = screen-position, pixels from left of screen
      • style = -
          -
        • 0 icon/state only
        • -
        • 1 devicename and icon/state
        • -
        • 2 devicename, icon/state and commands
        • -
        • 3 device-reading and optional description
        • -
        • 4 S300TH-specific, displays temperature above humidity
        • -
        • 5 icon/state and commands
        • -
        • 6 device-reading, reading-timestamp and optional description
        • +
            +
          • 0 icon/state only
          • +
          • 1 devicename and icon/state
          • +
          • 2 devicename, icon/state and commands
          • +
          • 3 device-reading and optional description
          • +
          • 4 S300TH-specific, displays temperature above humidity
          • +
          • 5 icon/state and commands
          • +
          • 6 device-reading, reading-timestamp and optional description
          • 7 commands only
          • 8 commands popup
          - +
        • description will be displayed instead of the original devicename

      • Examples:
          - - - - - -
          attr lamp1 fp_Groundfloor 100,100#display lamp1 with icon only at screenposition 100,100
          attr lamp2 fp_Groundfloor 100,140,1,Art-Deco#display lamp2 with description 'Art-Deco-Light' at 100,140
          attr lamp2 fp_FirstFloor 130,100,1#display the same device at different positions on other floorplans
          attr myFHT fp_Groundfloor 300,20,10,Temperature#display given Text + FHT-temperature
          -
        - Hint: no blanks between parameters

        + + + + + +
        attr lamp1 fp_Groundfloor 100,100#display lamp1 with icon only at screenposition 100,100
        attr lamp2 fp_Groundfloor 100,140,1,Art-Deco#display lamp2 with description 'Art-Deco-Light' at 100,140
        attr lamp2 fp_FirstFloor 130,100,1#display the same device at different positions on other floorplans
        attr myFHT fp_Groundfloor 300,20,10,Temperature#display given Text + FHT-temperature
        +
      + Hint: no blanks between parameters

    • fp_arrange
      - Activates the "arrange mode" which shows an additional menu on the screen to choose style and description.
      - When the arrange-mode is activated, devices can be placed freely on the screen by drag&drop. - allowing to place devices easily on the screen.
      - Example: -
        + Activates the "arrange mode" which shows an additional menu on the screen to choose style and description.
        + When the arrange-mode is activated, devices can be placed freely on the screen by drag&drop. + allowing to place devices easily on the screen.
        + Example: +
          attr Groundfloor fp_arrange 1
          - attr Groundfloor fp_arrange WEB #activates arrange mode for frontend-device WEB only

          + attr Groundfloor fp_arrange WEB #activates arrange mode for frontend-device WEB only

      • stylesheet
        - Explicitely sets your personal stylesheet for the floorplan. This overrides the standard stylesheet. - The standard stylesheet for floorplans is floorplanstyle.css. If the stylesheetPrefix is set for the corresponding FHEMWEB instance, this same - stylesheetPrefix is also prepended to the stylesheet for floorplans.
        - All stylesheets must be stored in the stylesheet subfolder of the fhem filesystem hierarchy. Store your personal - stylesheet along with floorplanstyle.css in the same folder.
        - Example: -
          + Explicitely sets your personal stylesheet for the floorplan. This overrides the standard stylesheet. + The standard stylesheet for floorplans is floorplanstyle.css. If the stylesheetPrefix is set for the corresponding FHEMWEB instance, this same + stylesheetPrefix is also prepended to the stylesheet for floorplans.
          + All stylesheets must be stored in the stylesheet subfolder of the fhem filesystem hierarchy. Store your personal + stylesheet along with floorplanstyle.css in the same folder.
          + Example: +
            attr Groundfloor stylesheet myfloorplanstyle.css

          -
        • fp_default
          - The floorplan startscreen is skipped if this attribute is assigned to one of the floorplans in your installation. -
        • +
        • fp_default
          + The floorplan startscreen is skipped if this attribute is assigned to one of the floorplans in your installation. +
        • Example: -
            +
              attr Groundfloor fp_default 1

            -
          • fp_noMenu
            - Suppresses the menu which usually shows the links to all your floorplans. -
          • +
          • fp_noMenu
            + Suppresses the menu which usually shows the links to all your floorplans. +
          • Example: -
              +
                attr Groundfloor fp_noMenu 1

            • commandfield
              - Adds a fhem-commandfield to the floorplan screen. -
            • + Adds a fhem-commandfield to the floorplan screen. + Example: -
                +
                  attr Groundfloor commandfield 1

                - +
              • fp_backgroundimg
                - Allows to choose a background-picture independent of the floorplan-name. -
              • + Allows to choose a background-picture independent of the floorplan-name. + Example: -
                  +
                    attr Groundfloor fp_backgroundimg foobar.png

                  - +
                • fp_viewport
                  - Allows usage of a user-defined viewport-value for touchpad.
                  - Default-viewport-value is "width=768". + Allows usage of a user-defined viewport-value for touchpad.
                  + Default-viewport-value is "width=768".
                • - - + +
                • fp_roomIcons
                  Space separated list of floorplan:icon pairs, to assign icons to the floorplan-menu, just like the functionality for rooms in FHEMWEB. Example:
                  attr Grundriss fp_roomIcons Grundriss:control_building_empty Media:audio_eq
                • - +
                • Inherited from FHEMWEB
                  - The following attributes are inherited from the underlying FHEMWEB instance:
                  + The following attributes are inherited from the underlying FHEMWEB instance:

                • @@ -1177,9 +1177,9 @@ FP_pOfill($@) { Beispiel:
                    - define Grundriss FLOORPLAN
                    - fp_Grundriss.png -

                    + define Grundriss FLOORPLAN
                    + fp_Grundriss.png +

                @@ -1196,7 +1196,7 @@ FP_pOfill($@) {
                  get <name> config
                  - Zeigt die Konfiguration des FLOORPLAN incl. allen Attributen an. Kann fuer ein include-file verwendet werden.
                  + Zeigt die Konfiguration des FLOORPLAN incl. allen Attributen an. Kann fuer ein include-file verwendet werden.

                @@ -1205,116 +1205,116 @@ FP_pOfill($@) {
                • userattr fp_<name> <top>,<left>[,<style>[,<description>]]

                  A userattr fp_<name> wird automatisch angelegt, sofern es noch nicht existiert.
                  -
                    +
                    • top = Bildschirmposition, pixel vom oberen Bildschirmrand
                    • left = Bildschirmposition, pixel vom linken Bildschirmrand
                    • style = -
                        -
                      • 0 nur icon/Status
                      • -
                      • 1 Gerätename und icon/Status
                      • -
                      • 2 Gerätename, icon/Status und Kommandos
                      • -
                      • 3 Geräte-reading und optionale Beschreibung
                      • -
                      • 4 S300TH-spezifisch, zeigt Temperatur und Luftfeuchtigkeit an
                      • -
                      • 5 icon/Status und Kommandos (ohne Gerätename)
                      • -
                      • 6 Geräte-reading, Zeitstempel und optionale Beschreibung
                      • +
                          +
                        • 0 nur icon/Status
                        • +
                        • 1 Gerätename und icon/Status
                        • +
                        • 2 Gerätename, icon/Status und Kommandos
                        • +
                        • 3 Geräte-reading und optionale Beschreibung
                        • +
                        • 4 S300TH-spezifisch, zeigt Temperatur und Luftfeuchtigkeit an
                        • +
                        • 5 icon/Status und Kommandos (ohne Gerätename)
                        • +
                        • 6 Geräte-reading, Zeitstempel und optionale Beschreibung
                        • 7 nur Kommandos
                        • 8 popup für kommandos
                        • -
                        - +
                      +
                    • Eine ggf. angegebene Bschreibung wird anstelle des original-Gerätenamens angezeigt.

                    Beispiele:
                      - - - - - -
                      attr lamp1 fp_Erdgeschoss 100,100#display lamp1 with icon only at screenposition 100,100
                      attr lamp2 fp_Erdgeschoss 100,140,1,Art-Deco#display lamp2 with description 'Art-Deco-Light' at 100,140
                      attr lamp2 fp_ErsteEtage 130,100,1#display the same device at different positions on other floorplans
                      attr myFHT fp_Erdgeschoss 300,20,10,Temperature#display given Text + FHT-temperature
                      -
                    - Hinweis: Die Parameter müssen ohne Leerstellen aneinandergereiht werden.

                    + + + + + +
                    attr lamp1 fp_Erdgeschoss 100,100#display lamp1 with icon only at screenposition 100,100
                    attr lamp2 fp_Erdgeschoss 100,140,1,Art-Deco#display lamp2 with description 'Art-Deco-Light' at 100,140
                    attr lamp2 fp_ErsteEtage 130,100,1#display the same device at different positions on other floorplans
                    attr myFHT fp_Erdgeschoss 300,20,10,Temperature#display given Text + FHT-temperature
                    +
                  + Hinweis: Die Parameter müssen ohne Leerstellen aneinandergereiht werden.

                • fp_arrange
                  - Aktiviert den "arrange-Modus" der ein zusätzliches Menü anzeigt, - mit dem Geräte auf dem Bildschirm angeordnet werden können. Bei aktiviertem arrange-mode können alle devices per drag&drop platziert werden.
                  - Beispiel: -
                    + Aktiviert den "arrange-Modus" der ein zusätzliches Menü anzeigt, + mit dem Geräte auf dem Bildschirm angeordnet werden können. Bei aktiviertem arrange-mode können alle devices per drag&drop platziert werden.
                    + Beispiel: +
                      attr Erdgeschoss fp_arrange 1
                      - attr Erdgeschoss fp_arrange WEB #Aktiviert den arrange-Modus nur für die Webinstanz WEB

                      + attr Erdgeschoss fp_arrange WEB #Aktiviert den arrange-Modus nur für die Webinstanz WEB

                  • stylesheet
                    - Ermöglicht die Verwendung eines eigenen css-stylesheet für Ihren floorplan. Dieses Attribut hat Vorrang vor dem Standard-stylesheet. - Das Standard-stylesheet für floorplans ist floorplanstyle.css. Falls stylesheetPrefix in der korrespondierenden FHEMWEB-Instanz gesetzt ist, wird dieser - stylesheetPrefix auch dem stylesheet für floorplans vorangestellt (prepend).
                    - Alle stylesheets werden im stylesheet-Ordner des fhem-Dateisystems abgelegt. Legen Sie dort - Ihr eigenes stylesheet neben floorplanstyle.css in demselben Ordner ab.
                    - Beispiel: -
                      + Ermöglicht die Verwendung eines eigenen css-stylesheet für Ihren floorplan. Dieses Attribut hat Vorrang vor dem Standard-stylesheet. + Das Standard-stylesheet für floorplans ist floorplanstyle.css. Falls stylesheetPrefix in der korrespondierenden FHEMWEB-Instanz gesetzt ist, wird dieser + stylesheetPrefix auch dem stylesheet für floorplans vorangestellt (prepend).
                      + Alle stylesheets werden im stylesheet-Ordner des fhem-Dateisystems abgelegt. Legen Sie dort + Ihr eigenes stylesheet neben floorplanstyle.css in demselben Ordner ab.
                      + Beispiel: +
                        attr Erdgeschoss stylesheet myfloorplanstyle.css

                      -
                    • fp_default
                      - Der floorplan-Startbildschirm wird übersprungen wenn dieses Attribut einem der von Ihnen definierten floorplans zugeordnet ist. -
                    • +
                    • fp_default
                      + Der floorplan-Startbildschirm wird übersprungen wenn dieses Attribut einem der von Ihnen definierten floorplans zugeordnet ist. +
                    • Beispiel: -
                        +
                          attr Erdgeschoss fp_default 1

                        -
                      • fp_noMenu
                        - Blendet das floorplans-Menü aus, das normalerweise am linken Bildschirmrand angezeigt wird. -
                      • +
                      • fp_noMenu
                        + Blendet das floorplans-Menü aus, das normalerweise am linken Bildschirmrand angezeigt wird. +
                      • Beispiel: -
                          +
                            attr Erdgeschoss fp_noMenu 1

                        • commandfield
                          - Fügt Ihrem floorplan ein fhem-Kommandofeld hinzu. -
                        • + Fügt Ihrem floorplan ein fhem-Kommandofeld hinzu. + Beispiel: -
                            +
                              attr Erdgeschoss commandfield 1

                            - +
                          • fp_backgroundimg
                            - Gestattet die Bennung eine Hintergundbilds unabhängig vom floorplan-Namen.
                            + Gestattet die Bennung eine Hintergundbilds unabhängig vom floorplan-Namen.
                            Hinweis: Das Attribut kann mittels notify geändert werden, um z.B. unterschiedliche Hintergundbidlder am Tag oder in der Nacht anzuzeigen.
                            Beispiel: -
                              +
                                attr Erdgeschoss fp_backgroundimg foobar.png

                              - - + +
                            • fp_viewport
                              - Gestattet die Verwendung eines abweichenden viewport-Wertes für die touchpad-Ausgabe.
                              - Die Default-viewport-Angbe ist "width=768". -
                            • - - + Gestattet die Verwendung eines abweichenden viewport-Wertes für die touchpad-Ausgabe.
                              + Die Default-viewport-Angbe ist "width=768". + + +
                            • fp_roomIcons
                              Mit Leerstellen getrennte Liste von floorplan:icon -Paaren, um einem Eintrag des floorplan-Menues icons zuzuordnen, genau wie - die entsprechende Funktionalitaet in FHEMWEB. Beispiel:
                              + die entsprechende Funktionalitaet in FHEMWEB. Beispiel:
                              attr Grundriss fp_roomIcons Grundriss:control_building_empty Media:audio_eq
                            • - +
                            • Vererbt von FHEMWEB
                              - Die folgenden Attribute werden von der zugrundliegenden FHEMWEB-Instanz vererbt:
                              + Die folgenden Attribute werden von der zugrundliegenden FHEMWEB-Instanz vererbt: