diff --git a/fhem/CHANGED b/fhem/CHANGED index 0a504af2a..2dea2a686 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,9 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 95_Dashboard: added new attribute dashboard_tabXdevices which + supports devspec definitions for shown dashboard groups. + Storage of current opened tab and restore when opening dashboard. + Fixed some CSS issues (text alignment, colors ...) - change: SYSMON: warning (userdefined readings), reading for perl version - feature: 38_CO20.pm: added advanced features, retries and timeout (by Markus M.) - feature: 32_yowsup.pm: added support for groups diff --git a/fhem/FHEM/95_Dashboard.pm b/fhem/FHEM/95_Dashboard.pm index cf81458de..fa2913b73 100644 --- a/fhem/FHEM/95_Dashboard.pm +++ b/fhem/FHEM/95_Dashboard.pm @@ -60,6 +60,7 @@ # Optimized icon loading. # Optimized fullscreen view. # Minor improvements in javascript and css. +# 3.10: added attribute dashboard_tabXdevices, which can contain devspec definitions and thus allow to also shown not grouped devices # # Known Bugs/Todos: # BUG: Nicht alle Inhalte aller Tabs laden, bei Plots dauert die bedienung des Dashboards zu lange. -> elemente hidden? -> widgets aus js über XHR nachladen und dann anzeigen (jquery xml nachladen...) @@ -115,9 +116,7 @@ my %group; my $dashboard_groupListfhem; my $fwjquery = "jquery.min.js"; my $fwjqueryui = "jquery-ui.min.js"; -my $dashboardversion = "3.00"; -my @fhemweb_instances = (); - +my $dashboardversion = "3.10"; ############################################################################################# sub Dashboard_Initialize ($) { @@ -132,11 +131,9 @@ sub Dashboard_Initialize ($) { $hash->{AttrList} = "disable:0,1 ". "dashboard_colcount:1,2,3,4,5 ". "dashboard_debug:0,1 ". - "dashboard_lockstate:dont-use-this-attribut ". #obolet since 04.2014 "dashboard_rowtopheight ". "dashboard_rowbottomheight ". "dashboard_row:top,center,bottom,top-center,center-bottom,top-center-bottom ". - "dashboard_showhelper:dont-use-this-attribut ". #obolet since 04.2014 "dashboard_showtogglebuttons:0,1 ". #new attribute vers. 2.00 "dashboard_activetab:1,2,3,4,5,6,7 ". @@ -146,15 +143,16 @@ sub Dashboard_Initialize ($) { "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 ". "dashboard_showtabs:tabs-and-buttonbar-at-the-top,tabs-and-buttonbar-on-the-bottom,tabs-and-buttonbar-hidden ". - #new attribute vers. 2.03 #new attribute vers. 2.06 "dashboard_customcss " . + #new attribute vers. 3.00 "dashboard_flexible " . #tab-specific attributes "dashboard_tab1name " . "dashboard_tab1groups " . + #new attribute vers. 3.10 + "dashboard_tab1devices " . "dashboard_tab1sorting " . "dashboard_tab1icon " . "dashboard_tab1colcount " . @@ -163,6 +161,8 @@ sub Dashboard_Initialize ($) { # dynamic attributes "dashboard_tab[0-9]+name " . "dashboard_tab[0-9]+groups " . + #new attribute vers. 3.10 + "dashboard_tab[0-9]+devices " . "dashboard_tab[0-9]+sorting " . "dashboard_tab[0-9]+icon " . "dashboard_tab[0-9]+colcount " . @@ -239,7 +239,7 @@ sub Dashboard_Get($@) { my @iconFolders = split(":", AttrVal($FW_wname, "iconPath", "$FW_sp:default:fhemSVG:openautomation")); my $iconDirs = ""; foreach my $idir (@iconFolders) {$iconDirs .= "$attr{global}{modpath}/www/images/".$idir.",";} - $res .= " \"icondirs\": \"$iconDirs\", \"dashboard_tabcount\": " . GetTabCount($hash, 0); + $res .= " \"icondirs\": \"$iconDirs\", \"dashboard_tabcount\": " . GetTabCount($hash, 0). ", \"dashboard_activetab\": " . GetActiveTab($hash->{NAME}); $res .= ($i != $x) ? ",\n" : "\n"; foreach my $attr (sort keys %$attrdata) { @@ -248,7 +248,10 @@ sub Dashboard_Get($@) { if (@splitattr == 2) { $res .= " \"".Dashboard_Escape($attr)."\": \"".$splitattr[0]."\",\n"; $res .= " \"".Dashboard_Escape($attr)."color\": \"".$splitattr[1]."\""; - } else { $res .= " \"".Dashboard_Escape($attr)."\": \"".$attrdata->{$attr}."\"";} + } elsif ($attr ne "dashboard_activetab") { $res .= " \"".Dashboard_Escape($attr)."\": \"".$attrdata->{$attr}."\"";} + else { + next; + } $res .= ($i != $x) ? ",\n" : "\n"; } $res .= " }\n"; @@ -258,15 +261,15 @@ sub Dashboard_Get($@) { } elsif ($arg eq "groupWidget") { #### Comming Soon ###### # For dynamic load of GroupWidgets from JavaScript - my $dbgroup = ""; + #my $dbgroup = ""; #for (my $p=2;$p<@a;$p++){$dbgroup .= @a[$p]." ";} #For Groupnames with Space - for (my $p=2;$p<@a;$p++){$dbgroup .= $a[$p]." ";} #For Groupnames with Space + #for (my $p=2;$p<@a;$p++){$dbgroup .= $a[$p]." ";} #For Groupnames with Space - $dashboard_groupListfhem = Dashboard_GetGroupList; - %group = BuildGroupList($dashboard_groupListfhem); - $res .= BuildGroupWidgets(1,1,1212,trim($dbgroup),"t1c1,".trim($dbgroup).",true,0,0:"); - return $res; -#For dynamic loading of tabs + #$dashboard_groupListfhem = Dashboard_GetGroupList; + #%group = BuildGroupList($dashboard_groupListfhem); + #$res .= BuildGroupWidgets(1,1,1212,trim($dbgroup),"t1c1,".trim($dbgroup).",true,0,0:"); + #return $res; + #For dynamic loading of tabs } elsif ($arg eq "tab" && $arg2 =~ /^\d+$/) { return BuildDashboardTab($arg2, $hash->{NAME}); } elsif ($arg eq "icon") { @@ -277,7 +280,7 @@ sub Dashboard_Get($@) { return FW_iconPath($icon); } else { - return "Unknown argument $arg choose one of config:noArg groupWidget"; + return "Unknown argument $arg choose one of config:noArg groupWidget tab icon"; } } @@ -293,7 +296,6 @@ sub Dashboard_define ($$) { RemoveInternalTimer($hash); InternalTimer ($now + 5, 'CheckDashboardAttributUssage', $hash, 0); - my $dashboard_groupListfhem = Dashboard_GetGroupList; my $url = '/dashboard/' . $name; @@ -320,8 +322,15 @@ sub Dashboard_attr($$$) { my ($cmd, $name, $attrName, $attrVal) = @_; # add dynamic attributes - if ($cmd eq "set" && $attrName =~ m/dashboard_tab([1-9][0-9]*)groups/) { + if ( + $cmd eq "set" && + ( + $attrName =~ m/dashboard_tab([1-9][0-9]*)groups/ + || $attrName =~ m/dashboard_tab([1-9][0-9]*)devices/ + ) + ) { addToDevAttrList($name, "dashboard_tab" . ($1 + 1) . "name"); + addToDevAttrList($name, "dashboard_tab" . ($1 + 1) . "devices"); addToDevAttrList($name, "dashboard_tab" . ($1 + 1) . "groups"); addToDevAttrList($name, "dashboard_tab" . ($1 + 1) . "sorting"); addToDevAttrList($name, "dashboard_tab" . ($1 + 1) . "icon"); @@ -358,7 +367,7 @@ sub Dashboard_CGI($) FW_pO $ret; - return 1; + return 0; } sub DashboardAsHtml($) @@ -399,7 +408,7 @@ sub Dashboard_SummaryFN($$$$) my $row = AttrVal($defs{$d}{NAME}, "dashboard_row", "center"); my $debug = AttrVal($defs{$d}{NAME}, "dashboard_debug", "0"); - my $activetab = AttrVal($defs{$d}{NAME}, "dashboard_activetab", 1); + my $activetab = GetActiveTab($d); my $tabcount = GetTabCount($defs{$d}, 1); my $dbwidth = AttrVal($defs{$d}{NAME}, "dashboard_width", "100%"); my @tabnames = (); @@ -407,7 +416,7 @@ sub Dashboard_SummaryFN($$$$) if ($showfullsize) { if ($FW_RET =~ m/
]*class="([^"]+)"[^>]*>/) { - $FW_RET =~ s/style="$1"/style="$1 dashboard_fullsize"/; + $FW_RET =~ s/class="$1"/class="$1 dashboard_fullsize"/; } else { $FW_RET =~ s/\n"; @@ -519,90 +527,89 @@ sub BuildDashboardTab($$) my $id = $defs{$d}{NR}; my $colcount = AttrVal($defs{$d}{NAME}, 'dashboard_tab' . ($t + 1) . 'colcount', AttrVal($defs{$d}{NAME}, "dashboard_colcount", 1)); my $colwidths = AttrVal($defs{$d}{NAME}, 'dashboard_tab' . ($t + 1) . 'rowcentercolwidth', AttrVal($defs{$d}{NAME}, "dashboard_rowcentercolwidth", 100)); - my $backgroundimage = AttrVal($defs{$d}{NAME}, 'dashboard_tab' . ($t + 1) . 'backgroundimage', ""); $colwidths =~ tr/,/:/; + my $backgroundimage = AttrVal($defs{$d}{NAME}, 'dashboard_tab' . ($t + 1) . 'backgroundimage', ""); my $row = AttrVal($defs{$d}{NAME}, "dashboard_row", "center"); my $tabcount = GetTabCount($defs{$d}, 1); - my @tabgroups = (); - my @tabsortings = (); + my $tabgroups = AttrVal($defs{$d}{NAME}, "dashboard_tab" . ($t + 1) . "groups", ""); + my $tabsortings = AttrVal($defs{$d}{NAME}, "dashboard_tab" . ($t + 1) . "sorting", ""); + my $tabdevicegroups = AttrVal($defs{$d}{NAME}, "dashboard_tab" . ($t + 1) . "devices", ""); - for (my $i = 0; $i < $tabcount; $i++) { - $tabgroups[$i] = AttrVal($defs{$d}{NAME}, "dashboard_tab" . ($i + 1) . "groups", ""); - $tabsortings[$i] = AttrVal($defs{$d}{NAME}, "dashboard_tab" . ($i + 1) . "sorting", ""); - } - - unless (@tabgroups) { - readingsSingleUpdate( $defs{$d}, "state", "No Groups set", 0 ); + unless ($tabgroups || $tabdevicegroups) { + readingsSingleUpdate( $defs{$d}, "state", "No Groups or devices set", 0 ); return ""; } - my $groups = Dashboard_GetGroupList(); + my @temptabdevicegroup = split(' ', $tabdevicegroups); + my @tabdevicegroups = (); + + # make sure device groups without a group name are splitted into + # separate groups for every device they are containing + for my $devicegroup (@temptabdevicegroup) { + my @groupparts = split(':', $devicegroup); + + if (@groupparts == 1) { + my @devices = map { $_ . ':' . $_ } devspec2array($groupparts[0]); + push(@tabdevicegroups, @devices); + } + else { + push(@tabdevicegroups, $devicegroup); + } + } + + my $groups = Dashboard_GetGroupList(); $groups =~ s/#/ /g; - my @groups = split(',', $groups); - - my @temptabgroup = split(",", $tabgroups[$t]); #Set temp. position for groups without an stored position - my @tabgroup = (); - my @index = (); - + my @groups = split(',', $groups); + my @temptabgroup = split(",", $tabgroups); + + # resolve group names from regular expressions for (my $i=0;$i<@temptabgroup;$i++) { my @stabgroup = split(":", trim($temptabgroup[$i])); - @index = grep { $groups[$_] eq $stabgroup[0] } (0 .. @groups-1); + my @index = grep { $groups[$_] eq $stabgroup[0] } (0 .. @groups-1); + + if (@index == 0) { + my $matchGroup = '^' . $stabgroup[0] . '$'; + @index = grep { $groups[$_] =~ m/$matchGroup/ } (0 .. @groups-1); + } if (@index > 0) { for (my $j=0; $j<@index;$j++) { my $groupname = @groups[$index[$j]]; + $groupname .= ':' . 'group=' . $groupname; if (@stabgroup > 1) { $groupname .= ':' . $stabgroup[1]; } - push(@tabgroup,$groupname); + push(@tabdevicegroups,$groupname); } } - else { - my $matchGroup = '^' . $stabgroup[0] . '$'; - @index = grep { $groups[$_] =~ m/$matchGroup/ } (0 .. @groups-1); - - if (@index > 0) { - for (my $j=0; $j<@index;$j++) { - my $groupname = @groups[$index[$j]]; - if (@stabgroup > 1) { - $groupname .= ':' . $stabgroup[1]; - } - push(@tabgroup,$groupname); - } - } - } - } - + $tabgroups = join('§§§', @tabdevicegroups); - $tabgroups[$t] = join(',', @tabgroup); - - for (my $i=0;$i<@tabgroup;$i++) { - my @stabgroup = split(":", trim($tabgroup[$i])); + # add sortings for groups not already having a defined sorting + for (my $i=0;$i<@tabdevicegroups;$i++) { + my @stabgroup = split(":", trim($tabdevicegroups[$i])); my $matchGroup = "," . quotemeta(trim($stabgroup[0])) . ","; - if ($tabsortings[$t] !~ m/$matchGroup/) { - $tabsortings[$t] = $tabsortings[$t]."t".$t."c".GetMaxColumnId($row,$colcount).",".trim($stabgroup[0]).",true,0,0:"; + if ($tabsortings !~ m/$matchGroup/) { + $tabsortings = $tabsortings."t".$t."c".GetMaxColumnId($row,$colcount).",".trim($stabgroup[0]).",true,0,0:"; } - } + } - %group = BuildGroupList($tabgroups[$t]); - - my $ret = "