######################################################################################## # # 95_Dashboard.pm # ######################################################################################## # Released : 20.12.2013 @svenson08 # Version : # 1.00: Released to testers # 1.02: Don't show link on Groups with WebLinks. Hide GroupToogle Button (new Attribut dashboard_showtooglebuttons). # Set the Columnheight (new Attribur dashboard_colheight). # 1.03: Dashboard Entry over the Room-List, set the Room "Dashboard" to hiddenroom. Build weblink independently. # Dashboard Row on Top and Bottom (no separately columns). Detail Button # to jump into define Detailview. Don't show link on Groups with SVG and readingsGroup. # 1.04: Sort the Groupentrys (@gemx). Hide Room Dashboard. # 1.05: Fix dashboard_row center # 1.10: Released Version 1.10. Rename Module from 95_FWViews to 95_Dashboard. Rename view_* Attributes to # dashboard_*. Rename fhemweb_FWViews.js to dashboard.js. Cleanup CSS. Reduce single png-Images to one File only. # Fix duplicated run of JS Script. Dashboard STAT show "Missing File" Information if installation is wrong. # 1.11: use jquery.min and jquery-ui.min. add dashboard_debug attribute. Check dashboard_sorting value plausibility. # Change default Values. First Release to FHEM SVN. # 1.12: Add Germyn command_ref Text. Add Default Values to command_ref (@cotecmania). Fix identification of an existing # Dashboard-Weblink (Message *_weblink already defined, delete it first on rereadcfg). Remove white space from # both ends of a group in dashboard_groups. Fix dashboard_sorting check. Wrong added hiddenroom to FHEMWEB # Browsersession fixed. Buttonbar can now placed on top or bottom of the Dashboard (@cotecmania). # Dashboard is always edited out the Room Dashboard (@justme1968) # Fix Dashboard Entry over the Room-List after 01_FHEMWEB.pm changes # 2.00: First Changes vor Dashboard Tabs. Change while saving positioning. Alterd max/min Group positioning. # Many changes in Dasboard.js. Replaced the attributes dashboard_groups, dashboard_colheight and dashboard_sorting # Many new Attributes vor Tabs, Dashboard sizing. Set of mimimal attributes (helpful for beginners). # Provisionally the columns widths are dependent on the total width of the Dashboard. # 2.01: attibute dashboard_colwidth replace with dashboard_rowcentercolwidth. rowcentercolwidth can now be defined per # column. Delete Groups Attribut with Value 1. Dashboard can hide FHEMWEB Roomliste and Header => Fullscreenmode # 2.02: Tabs can set on top, bottom or hidden. Fix "variable $tabgroups masks earlier" Errorlog. # 2.03: dashboard_showfullsize only in DashboardRoom. Tabs can show Icons (new Attributes). Fix showhelper Bug on lock/unlock. # The error that after a trigger action the curren tab is changed to the "old" activetab tab has been fixed. dashboard_activetab # is stored after tab change # 2.04: change view of readingroups. Attribute dashboard_groups removed. New Attribute dashboard_webfrontendfilter to define # separate Dashboards per FHEMWEB Instance. # 2.05: bugfix, changes in dashboard.js, groups can show Icons (group:icon@color,group:icon@color ...). "Back"-Button in Fullsize-Mode. # Dashboard near top in Fullsize-Mode. dashboard_activetab store the active Tab, not the last active tab. # 2.06: Attribute dashboard_colheight removed. Change Groupcontent sorting in compliance by alias and sortby. # Custom CSS over new Attribute dashboard_customcss. Fix Bug that affect new groups. # 2.07: Fix GroupWidget-Error with readingGroups in hiddenroom # 2.08: Fix dashboard_webfrontendfilter Error-Message. Internal changes. Attribute dashboard_colwidth and dashboard_sorting removed. # 2.09: dashboard_showfullsize not applied in room "all" resp. "Everything". First small implementation over Dashboard_DetailFN. # # Known Bugs/Todos: # BUG: Nicht alle Inhalte aller Tabs laden, bei Plots dauert die bedienung des Dashboards zu lange. -> elemente hidden? # BUG: Variabler abstand wird nicht gesichert # BUG: dashboard_webfrontendfilter doesn't Work Antwort #469 # BUG: Überlappen Gruppen andere? # # Log 1, "[DASHBOARD simple debug] '".$g."' "; ######################################################################################## # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ######################################################################################## # Helpfull Links: # http://jquery.10927.n7.nabble.com/saving-portlet-state-td125831.html # http://jsfiddle.net/w7ZvQ/ # http://jsfiddle.net/adamboduch/e6zdX/1/ # http://www.innovativephp.com/jquery-resizable-practical-examples-and-demos/ # http://jsfiddle.net/raulfernandez/mAuxn/ # http://jsfiddle.net/zeTP8/ package main; use strict; use warnings; use vars qw($FW_dir); # base directory for web server use vars qw($FW_icondir); # icon base directory use vars qw($FW_room); # currently selected room use vars qw(%defs); # FHEM device/button definitions use vars qw($FW_wname); # Web instance use vars qw(%FW_hiddenroom);# hash of hidden rooms, used by weblink use vars qw(%FW_types); # device types use vars qw($FW_ss); # is smallscreen, needed by 97_GROUP/95_VIEW # --------------------------- Global Variable ----------------------------------------------- my %group; my $fwjquery = "jquery.min.js"; my $fwjqueryui = "jquery-ui.min.js"; my $dashboardname = "Dashboard"; # Link Text my $dashboardhiddenroom = "DashboardRoom"; # Hiddenroom my $dashboardversion = "2.09"; # ------------------------------------------------------------------------------------------- ############################################################################################# sub Dashboard_Initialize ($) { my ($hash) = @_; $hash->{DefFn} = "Dashboard_define"; $hash->{UndefFn} = "Dashboard_undef"; $hash->{FW_detailFn} = "Dashboard_DetailFN"; $hash->{AttrFn} = "Dashboard_attr"; $hash->{AttrList} = "disable:0,1 ". "dashboard_colcount:1,2,3,4,5 ". "dashboard_debug:0,1 ". "dashboard_lockstate:unlock,lock ". "dashboard_rowtopheight ". "dashboard_rowbottomheight ". "dashboard_row:top,center,bottom,top-center,center-bottom,top-center-bottom ". "dashboard_showhelper:0,1 ". "dashboard_showtooglebuttons:0,1 ". #new attribute vers. 2.00 "dashboard_tabcount:1,2,3,4,5,6,7 ". "dashboard_activetab:1,2,3,4,5,6,7 ". "dashboard_tab1name ". "dashboard_tab2name ". "dashboard_tab3name ". "dashboard_tab4name ". "dashboard_tab5name ". "dashboard_tab1groups ". "dashboard_tab2groups ". "dashboard_tab3groups ". "dashboard_tab4groups ". "dashboard_tab5groups ". "dashboard_tab1sorting ". "dashboard_tab2sorting ". "dashboard_tab3sorting ". "dashboard_tab4sorting ". "dashboard_tab5sorting ". "dashboard_width ". "dashboard_rowcenterheight ". #new attribute vers. 2.01 "dashboard_rowcentercolwidth ". "dashboard_showfullsize:0,1 ". #new attribute vers. 2.02 "dashboard_showtabs:tabs-and-buttonbar-at-the-top,tabs-at-the-top-buttonbar-hidden,tabs-and-buttonbar-on-the-bottom,tabs-on-the-bottom-buttonbar-hidden,tabs-and-buttonbar-hidden ". #new attribute vers. 2.03 "dashboard_tab1icon ". "dashboard_tab2icon ". "dashboard_tab3icon ". "dashboard_tab4icon ". "dashboard_tab5icon ". #new attribute vers. 2.04 "dashboard_webfrontendfilter ". #new attribute vers. 2.06 "dashboard_customcss ". "dashboard_tab6name ". "dashboard_tab7name ". "dashboard_tab6groups ". "dashboard_tab7groups ". "dashboard_tab6sorting ". "dashboard_tab7sorting ". "dashboard_tab6icon ". "dashboard_tab7icon ". $readingFnAttributes; $data{FWEXT}{jquery}{SCRIPT} = "/pgm2/".$fwjquery if (!$data{FWEXT}{jquery}{SCRIPT}); $data{FWEXT}{jqueryui}{SCRIPT} = "/pgm2/".$fwjqueryui if (!$data{FWEXT}{jqueryui}{SCRIPT}); $data{FWEXT}{z_dashboard}{SCRIPT} = "/pgm2/dashboard.js" if (!$data{FWEXT}{z_dashboard}); $data{FWEXT}{Dashboardx}{LINK} = "?room=".$dashboardhiddenroom; $data{FWEXT}{Dashboardx}{NAME} = $dashboardname; return undef; } sub Dashboard_DetailFN() { my ($name, $d, $room, $pageHash) = @_; my $hash = $defs{$name}; my $ret = ""; $ret .= "\n"; $ret .= "\n"; $ret .= "
\n"; $ret .= "
\n"; $ret .= " \n"; $ret .= " \n"; $ret .= "
\n"; $ret .= "
\n"; $ret .= "
\n"; return $ret; } ############################################################################################# ############################################################################################# sub DashboardAsHtml($) { my ($d) = @_; my $ret = ""; my $showbuttonbar = "hidden"; my $debugfield = "hidden"; my $h = $defs{$d}; my $name = $defs{$d}{NAME}; my $id = $defs{$d}{NR}; ######################### Read Dashboard Attributes and set Default-Values #################################### my $disable = AttrVal($defs{$d}{NAME}, "disable", 0); my $colcount = AttrVal($defs{$d}{NAME}, "dashboard_colcount", 1); my $colwidth = AttrVal($defs{$d}{NAME}, "dashboard_rowcentercolwidth", 100); my $colheight = AttrVal($defs{$d}{NAME}, "dashboard_rowcenterheight", 400); my $rowtopheight = AttrVal($defs{$d}{NAME}, "dashboard_rowtopheight", 250); my $rowbottomheight = AttrVal($defs{$d}{NAME}, "dashboard_rowbottomheight", 250); my $showhelper = AttrVal($defs{$d}{NAME}, "dashboard_showhelper", 1); my $showtabs = AttrVal($defs{$d}{NAME}, "dashboard_showtabs", "tabs-and-buttonbar-at-the-top"); my $showtooglebuttons = AttrVal($defs{$d}{NAME}, "dashboard_showtooglebuttons", 1); my $showfullsize = AttrVal($defs{$d}{NAME}, "dashboard_showfullsize", 0); my $webfrontendfilter = AttrVal($defs{$d}{NAME}, "dashboard_webfrontendfilter", "*"); my $customcss = AttrVal($defs{$d}{NAME}, "dashboard_customcss", "none"); my $row = AttrVal($defs{$d}{NAME}, "dashboard_row", "center"); my $debug = AttrVal($defs{$d}{NAME}, "dashboard_debug", "0"); my $lockstate = AttrVal($defs{$d}{NAME}, "dashboard_lockstate", "unlock"); my $activetab = AttrVal($defs{$d}{NAME}, "dashboard_activetab", 1); my $tabcount = AttrVal($defs{$d}{NAME}, "dashboard_tabcount", 1); my $dbwidth = AttrVal($defs{$d}{NAME}, "dashboard_width", "100%"); my @tabnames = (AttrVal($defs{$d}{NAME}, "dashboard_tab1name", "Dashboard-Tab 1"), AttrVal($defs{$d}{NAME}, "dashboard_tab2name", "Dashboard-Tab 2"), AttrVal($defs{$d}{NAME}, "dashboard_tab3name", "Dashboard-Tab 3"), AttrVal($defs{$d}{NAME}, "dashboard_tab4name", "Dashboard-Tab 4"), AttrVal($defs{$d}{NAME}, "dashboard_tab5name", "Dashboard-Tab 5"), AttrVal($defs{$d}{NAME}, "dashboard_tab6name", "Dashboard-Tab 6"), AttrVal($defs{$d}{NAME}, "dashboard_tab7name", "Dashboard-Tab 7")); my @tabgroups = (AttrVal($defs{$d}{NAME}, "dashboard_tab1groups", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab2groups", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab3groups", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab4groups", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab5groups", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab6groups", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab7groups", "")); my @tabsortings = (AttrVal($defs{$d}{NAME}, "dashboard_tab1sorting", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab2sorting", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab3sorting", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab4sorting", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab5sorting", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab6sorting", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab7sorting", "")); my @tabicons = (AttrVal($defs{$d}{NAME}, "dashboard_tab1icon", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab2icon", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab3icon", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab4icon", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab5icon", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab6icon", ""), AttrVal($defs{$d}{NAME}, "dashboard_tab7icon", "")); ############################################################################################# if ($disable == 1) { $defs{$d}{STATE} = "disabled"; return $ret; } unless (@tabgroups) { $defs{$d}{STATE} = "No Groups set"; return $ret; } ############# Filter Dashboard display depending on $FW_wname ################################### if ($webfrontendfilter ne "*") { my $filterhit = 0; my @webfilter = split(",", $webfrontendfilter); for (my $i=0;$i<@webfilter;$i++){ if (trim($FW_wname) eq trim($webfilter[$i]) ) { $filterhit = 1; } } if ($filterhit == 0) { # $ret .= "No Dashboard configured for ".$FW_wname."
"; # $ret .= "Set Attribute dashboard_webfrontendfilter, see Details"; return $ret; } } ################################################################################## if ($debug == 1) { $debugfield = "edit" }; if ($showtabs eq "tabs-and-buttonbar-at-the-top") { $showbuttonbar = "top"; } if ($showtabs eq "tabs-and-buttonbar-on-the-bottom") { $showbuttonbar = "bottom"; } if ($showbuttonbar eq "hidden") { $lockstate = "lock" }; if ($activetab > $tabcount) { $activetab = $tabcount; } $colwidth =~ tr/,/:/; if (not ($colheight =~ /^\d+$/)) { $colheight = 400 }; if (not ($rowtopheight =~ /^\d+$/)) { $rowtopheight = 50 }; if (not ($rowbottomheight =~ /^\d+$/)) { $rowbottomheight = 50 }; #------------------- Check dashboard_sorting on false content ------------------------------------ for (my $i=0;$i<@tabsortings;$i++){ if (($tabsortings[$i-1] !~ /[0-9]/ || $tabsortings[$i-1] !~ /:/ || $tabsortings[$i-1] !~ /,/ ) && ($tabsortings[$i-1] ne "," && $tabsortings[$i-1] ne "")){ Log3 $d, 3, "[".$name." V".$dashboardversion."] Value of attribut dashboard_tab".$i."sorting is wrong. Saved sorting can not be set. Fix Value or delete the Attribute. [".$tabsortings[$i-1]."]"; } else { Log3 $d, 5, "[".$name." V".$dashboardversion."] Sorting OK or Empty: dashboard_tab".$i."sorting "; } } #------------------------------------------------------------------------------------------------- $ret .= "\n"; $ret .= "\n"; $ret .= "\n"; $ret .= "
\n"; $ret .= "\n"; $ret .= "\n"; $ret .= "
\n"; ########################### Dashboard Tab-Liste ############################################## my $tabshow = "hidden"; my $tabicon = ""; if ($showtabs eq "tabs-and-buttonbar-at-the-top" || $showtabs eq "tabs-at-the-top-buttonbar-hidden") { $tabshow = "top";} if ($showtabs eq "tabs-and-buttonbar-on-the-bottom" || $showtabs eq "tabs-on-the-bottom-buttonbar-hidden") { $tabshow = "bottom";} $ret .= "
    \n"; if ($showtabs ne "tabs-at-the-top-buttonbar-hidden" && $showtabs ne "tabs-on-the-bottom-buttonbar-hidden" && $showtabs ne "tabs-and-buttonbar-hidden") { $ret .= BuildButtonBar($d,$showtabs,$showfullsize); } for (my $i=0;$i<$tabcount;$i++){ $tabicon = ""; if ($tabicons[$i] ne "") { $tabicon = FW_makeImage($tabicons[$i],$tabicons[$i],"dashboard_tabicon") . " "; } $ret .= "
  • ".$tabicon."".trim($tabnames[$i])."
  • "; } $ret .= "
\n"; ############################################################################################## for (my $t=0;$t<$tabcount;$t++){ my @tabgroup = split(",", $tabgroups[$t]); #Set temp. position for groups without an stored position for (my $i=0;$i<@tabgroup;$i++){ my @stabgroup = split(":", trim($tabgroup[$i])); if (index($tabsortings[$t],trim($stabgroup[0])) < 0) { $tabsortings[$t] = $tabsortings[$t]."t".$t."c".GetMaxColumnId($row,$colcount).",".trim($stabgroup[0]).",true,0,0:"; } } %group = BuildGroupList($tabgroups[$t]); $ret .= "
\n"; $ret .= "
    \n"; $ret .= " \n"; ##################### Top Row (only one Column) ############################################# if ($row eq "top-center-bottom" || $row eq "top-center" || $row eq "top"){ $ret .= BuildDashboardTopRow($t,$id,$tabgroups[$t],$tabsortings[$t]); } ##################### Center Row (max. 5 Column) ############################################ if ($row eq "top-center-bottom" || $row eq "top-center" || $row eq "center-bottom" || $row eq "center"){ $ret .= BuildDashboardCenterRow($t,$id,$tabgroups[$t],$tabsortings[$t],$colcount);} ############################# Bottom Row (only one Column) ############################################ if ($row eq "top-center-bottom" || $row eq "center-bottom" || $row eq "bottom"){ $ret .= BuildDashboardBottomRow($t,$id,$tabgroups[$t],$tabsortings[$t]); } ############################################################################################# $ret .= "
    \n"; $ret .= "
\n"; $ret .= "
\n"; } $ret .= "
\n"; return $ret; } sub BuildDashboardTopRow($$$$){ my ($t,$id, $dbgroups, $dbsorting) = @_; my $ret; $ret .= "\n"; $ret .= "
\n"; $ret .= "
\n"; $ret .= BuildGroupWidgets($t,"100",$id,$dbgroups,$dbsorting); $ret .= "
\n"; $ret .= "
\n"; $ret .= "\n"; return $ret; } sub BuildDashboardCenterRow($$$$$){ my ($t,$id, $dbgroups, $dbsorting, $colcount) = @_; my $ret; $ret .= "\n"; $ret .= "
\n"; for (my $i=0;$i<$colcount;$i++){ $ret .= "
\n"; $ret .= BuildGroupWidgets($t,$i,$id,$dbgroups,$dbsorting); $ret .= "
\n"; } $ret .= "
\n"; $ret .= "\n"; return $ret; } sub BuildDashboardBottomRow($$$$){ my ($t,$id, $dbgroups, $dbsorting) = @_; my $ret; $ret .= "\n"; $ret .= "
\n"; $ret .= "
\n"; $ret .= BuildGroupWidgets($t,"200",$id,$dbgroups,$dbsorting); $ret .= "
\n"; $ret .= "
\n"; $ret .= "\n"; return $ret; } sub BuildButtonBar($$$){ my ($d,$pos,$fullsize) = @_; my $ret = ""; my $cssclass = "hidden"; if ($pos eq "tabs-and-buttonbar-at-the-top") { $cssclass = "top"; } if ($pos eq "tabs-and-buttonbar-on-the-bottom") { $cssclass = "bottom"; } if ($fullsize eq "1" && $pos ne "hidden" ) { $ret .= "
\n"; $ret .= "
\n"; $ret .= "
\n"; } if ($pos ne "hidden") { $ret .= "
\n"; $ret .= "
Set
\n"; $ret .= " \n"; $ret .= " \n"; $ret .= "
\n"; } return $ret; } sub BuildGroupWidgets($$$$$) { my ($tab,$column,$id,$dbgroups, $dbsorting) = @_; my $ret = ""; my $counter = 0; my @storedsorting = split(":", $dbsorting); my @dbgroup = split(",", $dbgroups); my $widgetheader = ""; foreach my $singlesorting (@storedsorting) { my @groupdata = split(",", $singlesorting); if (scalar(@groupdata) > 1) { if (index($dbsorting, "t".$tab."c".$column.",".$groupdata[1]) >= 0 && index($dbgroups, $groupdata[1]) >= 0 && $groupdata[1] ne "" ) { #group is set to tab $widgetheader = $groupdata[1]; foreach my $strdbgroup (@dbgroup) { my @groupicon = split(":", trim($strdbgroup)); if ($groupicon[0] eq $groupdata[1]) { if ($#groupicon > 0) { $widgetheader = FW_makeImage($groupicon[1],$groupicon[1],"dashboard_tabicon") . " ".$groupdata[1]; } } } $ret .= "
\n"; $ret .= "
\n"; $ret .= "
".$widgetheader."
\n"; $ret .= "
\n"; $ret .= BuildGroup($groupdata[1]); $ret .= "
\n"; $ret .= "
\n"; $ret .= "
\n"; $counter++; } } } return $ret; } sub BuildGroupList($) { my @dashboardgroups = split(",", $_[0]); #array for all groups to build an widget my %group = (); my $test; foreach my $d (sort keys %defs) { foreach my $grp (split(",", AttrVal($d, "group", ""))) { $grp = trim($grp); foreach my $g (@dashboardgroups){ my ($gtitle, $iconName) = split(":", trim($g)); $group{$grp}{$d} = 1 if($gtitle eq $grp); } } } return %group; } sub BuildGroup($) { my ($currentgroup) = @_; my $ret = ""; my $row = 1; my %extPage = (); my $rf = ($FW_room ? "&room=$FW_room" : ""); # stay in the room foreach my $g (keys %group) { next if ($g ne $currentgroup); $ret .= ""; #foreach my $d (sort keys %{$group{$g}}) { foreach my $d (sort { lc(AttrVal($a,"sortby",AttrVal($a,"alias",$a))) cmp lc(AttrVal($b,"sortby",AttrVal($b,"alias",$b))) } keys %{$group{$g}}) { $ret .= sprintf("", ($row&1)?"odd":"even"); my $type = $defs{$d}{TYPE}; my $devName = AttrVal($d, "alias", $d); my $icon = AttrVal($d, "icon", ""); $icon = FW_makeImage($icon,$icon,"icon dashboard_groupicon") . " " if($icon); #if($FW_hiddenroom{detail}) { # $ret .= ""; #} #else { if ($type ne "weblink" && $type ne "SVG" && $type ne "readingsGroup") { # Don't show Link by weblink, svg and readingsGroup $ret .= FW_pH "detail=$d", "$icon$devName", 1, "col1", 1; } #} $row++; my ($allSets, $cmdlist, $txt) = FW_devState($d, $rf, \%extPage); ################ Edit Result for readingroup etc. ##################### my @txtarray = split(">", $txt); if ($type eq "readingsGroup" && $txtarray[0] eq " -1) {$storeinfo = 0; } if ($storeinfo == 3) { $txtreturn .= $txtarray[$i].">"; } if ($storeinfo == 2 && index($txtarray[$i]," -1 ) { $storeinfo = $storeinfo+1;} if ($storeinfo == 1 && index($txtarray[$i]," -1 ) { $linkreturn = $txtarray[$i].">"; } if (index($txtarray[$i]," -1) {$storeinfo = $storeinfo+1; } } $ret .= ""; } else { $ret .= ""; } ########################################################### ###### Commands, slider, dropdown if(!$FW_ss && $cmdlist) { foreach my $cmd (split(":", $cmdlist)) { my $htmlTxt; my @c = split(' ', $cmd); if($allSets && $allSets =~ m/$c[0]:([^ ]*)/) { my $values = $1; foreach my $fn (sort keys %{$data{webCmdFn}}) { no strict "refs"; $htmlTxt = &{$data{webCmdFn}{$fn}}($FW_wname, $d, $FW_room, $cmd, $values); use strict "refs"; last if(defined($htmlTxt)); } } if($htmlTxt) { $ret .= $htmlTxt; } else { $ret .= FW_pH "cmd.$d=set $d $cmd$rf", $cmd, 1, "col3", 1; } } } $ret .= ""; } $ret .= "
$icon$devName
$txtreturn$txt
"; } if ($ret eq "") { $ret .= ""; $ret .= ""; $ret .= ""; $ret .= ""; $ret .= "
Unknown Group: $currentgroup
Check if the group attribute is really set
Check if the groupname is correct written
"; } return $ret; } sub GetMaxColumnId($$) { my ($row, $colcount) = @_; my $maxcolid = "0"; if (index($row,"bottom") > 0) { $maxcolid = "200"; } elsif (index($row,"center") > 0) { $maxcolid = $colcount-1; } elsif (index($row,"top") > 0) { $maxcolid = "100"; } return $maxcolid; } sub CheckInstallation($) { my ($hash) = @_; unless (-e $FW_dir."/pgm2/".$fwjquery) { Log3 $hash, 3, "[".$hash->{NAME}. " V".$dashboardversion."] Missing File ".$FW_dir."/pgm2/".$fwjquery; $hash->{STATE} = 'Missing File, see LogFile for Details'; } unless (-e $FW_dir."/pgm2/".$fwjqueryui) { Log3 $hash, 3, "[".$hash->{NAME}. " V".$dashboardversion."] Missing File ".$FW_dir."/pgm2/".$fwjqueryui; $hash->{STATE} = 'Missing File, see LogFile for Details'; } unless (-e $FW_dir."/pgm2/dashboard.js") { Log3 $hash, 3, "[".$hash->{NAME}. " V".$dashboardversion."] Missing File ".$FW_dir."/pgm2/dashboard.js"; $hash->{STATE} = 'Missing File, see LogFile for Details'; } unless (-e $FW_icondir."/default/dashboardicons.png") { Log3 $hash, 3, "[".$hash->{NAME}. " V".$dashboardversion."] Missing File ".$FW_icondir."/default/dashboardicons.png"; $hash->{STATE} = 'Missing File, see LogFile for Details'; } } sub CheckDashboardEntry($) { my ($hash) = @_; my $now = time(); my $timeToExec = $now + 5; RemoveInternalTimer($hash); InternalTimer ($timeToExec, 'CreateDashboardEntry', $hash, 0); InternalTimer ($timeToExec, 'CheckDashboardAttributUssage', $hash, 0); } sub CheckDashboardAttributUssage($) { # replaces old disused attributes and their values | set minimal attributes my ($hash) = @_; my $d = $hash->{NAME}; my $detailnote = ""; # --------- Set minimal Attributes in the hope to make it easier for beginners -------------------- my $tabcount = AttrVal($defs{$d}{NAME}, "dashboard_tabcount", "0"); if ($tabcount eq "0") { FW_fC("attr ".$d." dashboard_tabcount 1"); } my $tab1groups = AttrVal($defs{$d}{NAME}, "dashboard_tab1groups", ""); if ($tab1groups eq "") { FW_fC("attr ".$d." dashboard_tab1groups Set Your Groups - See Attribute dashboard_tab1groups-"); } # ------------------------------------------------------------------------------------------------- # ---------------- Delete empty Groups entries ---------------------------------------------------------- my $tabgroups = AttrVal($defs{$d}{NAME}, "dashboard_tab1groups", "999"); if ($tabgroups eq "1" ) { FW_fC("deleteattr ".$d." dashboard_tab1groups"); } $tabgroups = AttrVal($defs{$d}{NAME}, "dashboard_tab2groups", "999"); if ($tabgroups eq "1" ) { FW_fC("deleteattr ".$d." dashboard_tab2groups"); } $tabgroups = AttrVal($defs{$d}{NAME}, "dashboard_tab3groups", "999"); if ($tabgroups eq "1" ) { FW_fC("deleteattr ".$d." dashboard_tab3groups"); } $tabgroups = AttrVal($defs{$d}{NAME}, "dashboard_tab4groups", "999"); if ($tabgroups eq "1" ) { FW_fC("deleteattr ".$d." dashboard_tab4groups"); } $tabgroups = AttrVal($defs{$d}{NAME}, "dashboard_tab5groups", "999"); if ($tabgroups eq "1" ) { FW_fC("deleteattr ".$d." dashboard_tab5groups"); } # ------------------------------------------------------------------------------------------------- } sub CreateDashboardEntry($) { my ($hash) = @_; my $h = $hash->{NAME}; if (!defined $defs{$h."_weblink"}) { FW_fC("define ".$h."_weblink weblink htmlCode {DashboardAsHtml(\"".$h."\")}"); Log3 $hash, 3, "[".$hash->{NAME}. " V".$dashboardversion."]"." Weblink dosen't exists. Created weblink ".$h."_weblink. Don't forget to save config."; } FW_fC("attr ".$h."_weblink room ".$dashboardhiddenroom); foreach my $dn (sort keys %defs) { if ($defs{$dn}{TYPE} eq "FHEMWEB" && $defs{$dn}{NAME} !~ /FHEMWEB:/) { my $hr = AttrVal($defs{$dn}{NAME}, "hiddenroom", ""); #---------- Delete older Hiddenroom for Dashboard due changes in 01_FHEMWEB.pm (01.2014) --------- if (index($hr,$dashboardname) != -1 && index($hr,$dashboardhiddenroom) == -1) { $hr =~ s/$dashboardname/$dashboardhiddenroom/g; FW_fC("attr ".$defs{$dn}{NAME}." hiddenroom ".$hr); Log3 $hash, 3, "[".$hash->{NAME}. " V".$dashboardversion."]"." Corrected hiddenroom '".$dashboardname."' -> '".$dashboardhiddenroom."' in ".$defs{$dn}{NAME}.". Don't forget to save config."; } #------------------------------------------------------------------------------------------------- if (index($hr,$dashboardhiddenroom) == -1){ if ($hr eq "") {FW_fC("attr ".$defs{$dn}{NAME}." hiddenroom ".$dashboardhiddenroom);} else {FW_fC("attr ".$defs{$dn}{NAME}." hiddenroom ".$hr.",".$dashboardhiddenroom);} Log3 $hash, 3, "[".$hash->{NAME}. " V".$dashboardversion."]"." Added hiddenroom '".$dashboardhiddenroom."' to ".$defs{$dn}{NAME}.". Don't forget to save config."; } } } } sub Dashboard_define ($$) { my ($hash, $def) = @_; my $name = $hash->{NAME}; $hash->{STATE} = 'Initialized'; CheckInstallation($hash); CheckDashboardEntry($hash); return; } sub Dashboard_undef ($$) { my ($hash,$arg) = @_; RemoveInternalTimer($hash); return undef; } sub Dashboard_detailFn() { my ($name, $d, $room, $pageHash) = @_; my $hash = $defs{$name}; return; } sub Dashboard_attr($$$) { my ($cmd, $name, $attrName, $attrVal) = @_; return; } 1; =pod =begin html

Dashboard

=end html =begin html_DE

Dashboard

=end html_DE =cut