diff --git a/FHEM/00_HMLAN.pm b/FHEM/00_HMLAN.pm index 8eed54c31..bfec31202 100755 --- a/FHEM/00_HMLAN.pm +++ b/FHEM/00_HMLAN.pm @@ -7,14 +7,25 @@ use strict; use warnings; use Time::HiRes qw(gettimeofday time); -sub HMLAN_Parse($$); -sub HMLAN_Read($); -sub HMLAN_Write($$$); +sub HMLAN_Initialize($); +sub HMLAN_Define($$); +sub HMLAN_Undef($$); +sub HMLAN_RemoveHMPair($); +sub HMLAN_Attr(@); +sub HMLAN_Set($@); sub HMLAN_ReadAnswer($$$); +sub HMLAN_Write($$$); +sub HMLAN_Read($); sub HMLAN_uptime($@); -sub HMLAN_secSince2000(); - +sub HMLAN_Parse($$); +sub HMLAN_Ready($); sub HMLAN_SimpleWrite(@); +sub HMLAN_DoInit($); +sub HMLAN_KeepAlive($); +sub HMLAN_secSince2000(); +sub HMLAN_relOvrLd($); +sub HMLAN_relOvrLd($); +sub HMLAN_condUpdate($$); my $debug = 1; # set 1 for better log readability my %sets = ( "hmPairForSec" => "HomeMatic" diff --git a/FHEM/01_FHEMWEB.pm b/FHEM/01_FHEMWEB.pm index bd0679062..e9dc46fcd 100755 --- a/FHEM/01_FHEMWEB.pm +++ b/FHEM/01_FHEMWEB.pm @@ -709,19 +709,25 @@ FW_makeTable($$$@) } else { $val = FW_htmlEscape($val); # if possible provide link to reference - if ($defs{$val}){ - FW_pH "detail=$val", $val,1; + if ($n eq "room"){ + my @tmp; + push @tmp,FW_pH("room=$_" , $_ ,0,"",1,1)foreach(split(",",$val)); + FW_pO "
" + .join(",",@tmp) + ."
"; } - elsif ($n eq "room"){ - FW_pO "
"; - FW_pH "room=$_", $_ foreach(split(",",$val)); - FW_pO "
"; - } - elsif ($n =~ m/^fp_(.*)/ && $defs{$1}){ + elsif ($n =~ m/^fp_(.*)/ && $defs{$1}){#special for Floorplan FW_pH "detail=$1", $val,1; } else{ - FW_pO "
$val
"; + my @tmp; + foreach(split(",",$val)){ + if ($defs{$_}){ push @tmp, FW_pH( "detail=$_", $_ ,0,"",1,1);} + else{ push @tmp, $_;} + } + FW_pO "
" + .join(",",@tmp) + ."
"; } } } @@ -808,7 +814,6 @@ FW_doDetail($) FW_makeSelect($d, "attr", $attrList,"attr"); FW_makeTable("Attributes", $d, $attr{$d}, "deleteattr"); - ## dependent objects my @dob; # dependent objects - triggered by current device foreach my $dn (sort keys %defs) { @@ -1992,23 +1997,23 @@ FW_pO(@) sub FW_pH(@) { - my ($link, $txt, $td, $class, $doRet) = @_; - my $ret = ""; + my ($link, $txt, $td, $class, $doRet,$nonl) = @_; + my $ret; - $ret .= "" if($td); $link = ($link =~ m,^/,) ? $link : "$FW_ME$FW_subdir?$link"; - $class = "" if(!defined($class)); - $class = " class=\"$class\"" if($class); - + #actually 'div' should be removed if no class is defined + # as I can't check all code for consistancy I add nonl instead + $class = ($class)?" class=\"$class\"":""; + $txt = "$txt" if (!$nonl); + # Using onclick, as href starts safari in a webapp. # Known issue: the pointer won't change if($FW_ss || $FW_tp) { - $ret .= "$txt"; - + $ret = "$txt"; } else { - $ret .= "$txt"; + $ret = "$txt"; } - $ret .= "" if($td); + $ret = "$ret" if($td); return $ret if($doRet); FW_pO $ret; } diff --git a/FHEM/10_CUL_HM.pm b/FHEM/10_CUL_HM.pm index ece0cd2e7..acaf0d9bf 100755 --- a/FHEM/10_CUL_HM.pm +++ b/FHEM/10_CUL_HM.pm @@ -36,41 +36,83 @@ my $K_actDetID =HMConfig::HMConfig_getHash("K_actDetID"); ############################################################ sub CUL_HM_Initialize($); +sub CUL_HM_reqStatus($); +sub CUL_HM_autoReadConfig($); +sub CUL_HM_updateConfig($); sub CUL_HM_Define($$); sub CUL_HM_Undef($$); +sub CUL_HM_Rename($$$); +sub CUL_HM_Attr(@); sub CUL_HM_Parse($$); +sub CUL_HM_parseCommon(@); +sub CUL_HM_queueAutoRead($); sub CUL_HM_Get($@); -sub CUL_HM_fltCvT($); sub CUL_HM_Set($@); +sub CUL_HM_valvePosUpdt(@); sub CUL_HM_infoUpdtDevData($$$); +sub CUL_HM_infoUpdtChanData(@); sub CUL_HM_Pair(@); sub CUL_HM_getConfig($$$$$); sub CUL_HM_SndCmd($$); sub CUL_HM_responseSetup($$); sub CUL_HM_eventP($$); +sub CUL_HM_protState($$); sub CUL_HM_respPendRm($); sub CUL_HM_respPendTout($); +sub CUL_HM_respPendToutProlong($); sub CUL_HM_PushCmdStack($$); sub CUL_HM_ProcessCmdStack($); +sub CUL_HM_pushConfig($$$$$$$$); sub CUL_HM_Resend($); +sub CUL_HM_ID2PeerList ($$$); +sub CUL_HM_peerChId($$$); +sub CUL_HM_peerChName($$$); +sub CUL_HM_getMId($); +sub CUL_HM_getRxType($); +sub CUL_HM_getFlag($); +sub CUL_HM_getAssChnIds($); sub CUL_HM_Id($); +sub CUL_HM_IOid($); +sub CUL_HM_hash2Id($); +sub CUL_HM_hash2Name($); sub CUL_HM_name2Hash($); sub CUL_HM_name2Id(@); sub CUL_HM_id2Name($); +sub CUL_HM_id2Hash($); sub CUL_HM_getDeviceHash($); +sub CUL_HM_getDeviceName($); sub CUL_HM_DumpProtocol($$@); -sub CUL_HM_parseCommon(@); +sub CUL_HM_getRegFromStore($$$$@); +sub CUL_HM_updtRegDisp($$$); sub CUL_HM_encodeTime8($); sub CUL_HM_decodeTime8($); sub CUL_HM_encodeTime16($); sub CUL_HM_convTemp($); -sub CUL_HM_updtRegDisp($$$); sub CUL_HM_decodeTime16($); -sub CUL_HM_pushConfig($$$$$$$$); -sub CUL_HM_maticFn($$$$$); sub CUL_HM_secSince2000(); +sub CUL_HM_getChnLvl($); +sub CUL_HM_initRegHash(); +sub CUL_HM_fltCvT($); +sub CUL_HM_CvTflt($); +sub CUL_HM_4DisText($); +sub CUL_HM_TCtempReadings($); +sub CUL_HM_repReadings($); +sub CUL_HM_dimLog($); +sub CUL_HM_ActGetCreateHash(); +sub CUL_HM_time2sec($); +sub CUL_HM_ActAdd($$); +sub CUL_HM_ActDel($); +sub CUL_HM_ActCheck(); +sub CUL_HM_UpdtReadBulk(@); +sub CUL_HM_UpdtReadSingle(@); +sub CUL_HM_setAttrIfCh($$$$); sub CUL_HM_noDup(@); #return list with no duplicates sub CUL_HM_noDupInString($);#return string with no duplicates, comma separated +sub CUL_HM_storeRssi(@); +sub CUL_HM_stateUpdat($); +sub CUL_HM_qStateUpdatIfEnab($@); +sub CUL_HM_getAttrInt($$); +sub CUL_HM_putHash($); # ----------------modul globals----------------------- my $respRemoved; # used to control trigger of stack processing @@ -1875,12 +1917,17 @@ sub CUL_HM_Set($@) { foreach my $var (keys %{$hash}){ delete ($hash->{$var}) if ($var =~ m/^prot/); delete ($hash->{EVENTS}); - delete ($hash->{helper}{rssi}); } CUL_HM_protState($hash,"Info_Cleared"); } + elsif($sect eq "rssi"){ + delete $defs{$name}{helper}{rssi}; + foreach my $var (keys %{$hash}){ + delete ($hash->{$var}) if ($var =~ m/^rssi_/); + } + } else{ - return "unknown section. User readings or msgEvents"; + return "unknown section. User readings, msgEvents or rssi"; } $state = ""; } @@ -2833,7 +2880,8 @@ sub CUL_HM_responseSetup($$) {#store all we need to handle the response } } sub CUL_HM_eventP($$) {#handle protocol events - #todo: add severity, counter, history and acknowledge + # Current Events are Rcv,NACK,IOerr,Resend,ResendFail,Snd + # additional variables are protCmdDel,protCmdPend,protState,protLastRcv my ($hash, $evntType) = @_; my $nAttr = $hash; if ($evntType eq "Rcv"){ @@ -2870,7 +2918,7 @@ sub CUL_HM_protState($$){ Log GetLogLevel($name,6),"CUL_HM $name protEvent:$state". ($hash->{cmdStack}?" pending:".scalar @{$hash->{cmdStack}}:""); - DoTrigger($name, undef) if ($state eq "CMDs_done"); + DoTrigger($name, undef) if ($state =~ m/^CMDs_done/); } sub CUL_HM_respPendRm($) {#del response related entries in messageing entity my ($hash) = @_; @@ -3755,8 +3803,9 @@ sub CUL_HM_ActCheck() {# perform supervision $state = "switchedOff"; } else{ - $actHash->{helper}{$devId}{recent} = $devHash->{"protLastRcv"} #update recent - if ($devHash->{"protLastRcv"}); + $actHash->{helper}{$devId}{recent} = ($devHash->{"protLastRcv"})?#update recent + $devHash->{"protLastRcv"} + :0; my $tLast = $actHash->{helper}{$devId}{recent}; my @t = localtime($tod - $tSec); #time since when a trigger is expected my $tSince = sprintf("%04d-%02d-%02d %02d:%02d:%02d", @@ -4033,6 +4082,7 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
  • getConfig
    @@ -4879,7 +4929,7 @@ sub CUL_HM_putHash($) {# provide data for HMinfo [normal|added|addedStrong] #HM-CC-SCD
    SDteam [add|remove]_$dname
    battery [low|ok]
    - smoke_detect on from $src
    + smoke_detect [none|<src>]
    test:from $src
  • threeStateSensor
    diff --git a/FHEM/98_HMinfo.pm b/FHEM/98_HMinfo.pm index d22768627..5c14069e7 100644 --- a/FHEM/98_HMinfo.pm +++ b/FHEM/98_HMinfo.pm @@ -5,8 +5,17 @@ use strict; use warnings; use POSIX; -sub CommandXmlList($$); -sub XmlEscape($); +sub HMinfo_Initialize($$); +sub HMinfo_Define($$); +sub HMinfo_getParam(@); +sub HMinfo_regCheck(@); +sub HMinfo_peerCheck(@); +sub HMinfo_peerCheck(@); +sub HMinfo_getEntities(@); +sub HMinfo_SetFn($$); +sub HMinfo_SetFnDly($); +sub HMinfo_post($); + use Blocking; sub HMinfo_Initialize($$) {#################################################### @@ -14,13 +23,33 @@ sub HMinfo_Initialize($$) {#################################################### $hash->{DefFn} = "HMinfo_Define"; $hash->{SetFn} = "HMinfo_SetFn"; + $hash->{AttrList} = "loglevel:0,1,2,3,4,5,6 ". + "sumStatus sumERROR ". + $readingFnAttributes; + } sub HMinfo_Define($$){######################################################### my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); my $name = $hash->{NAME}; $hash->{Version} = "01"; - $attr{$name}{webCmd} = "protoEvents:rssi:peerXref:configCheck:models"; + $attr{$name}{webCmd} = "update:protoEvents:rssi:peerXref:configCheck:models"; + $attr{$name}{sumStatus} = "battery" + .",sabotageError" + .",powerError" + .",motor"; + $attr{$name}{sumERROR} = "battery:ok" + .",sabotageError:off" + .",powerError:ok" + .",overload:off" + .",overheat:off" + .",reduced:off" + .",motorError:no" + .",error:none" + .",uncertain:yes" + .",smoke_detect:none" + .",cover:closed" + ; return; } sub HMinfo_getParam(@) { ###################################################### @@ -174,19 +203,17 @@ sub HMinfo_SetFn($$) {######################################################### } if ($cmd eq "?" ) {##actionImmediate: clear parameter-------------- - return "autoReadReg clear configCheck param peerCheck peerXref protoEvents models regCheck register rssi saveConfig"; + return "autoReadReg clear configCheck param peerCheck peerXref protoEvents models regCheck register rssi saveConfig update"; } elsif($cmd eq "clear" ) {##actionImmediate: clear parameter-------------- my ($type) = @a; $opt .= "d" if ($type ne "Readings");# readings apply to all, others device only my @entities; + return "unknown parameter - use Protocol,readings or rssi" if ($type !~ m/^(Protocol|readings|rssi)$/); + $type = "msgEvents" if ($type eq "Protocol");# translate parameter foreach my $dName (HMinfo_getEntities($opt."v",$filter)){ push @entities,$dName; - if ($type eq "Rssi"){ - delete $defs{$dName}{helper}{rssi}; - next; - } - CUL_HM_Set($defs{$dName},$dName,"clear",(($type eq "Protocol")?"msgEvents":"readings")); + CUL_HM_Set($defs{$dName},$dName,"clear",$type); } return $cmd.$type." done:" ."\n cleared" ."\n ".(join "\n ",sort @entities) ; @@ -371,6 +398,9 @@ sub HMinfo_SetFn($$) {######################################################### ) .join"\n ",grep(/$filter/,sort @model); } + elsif($cmd eq "update") {##update hm counts ----------------------------- + return HMinfo_status($hash); + } elsif($cmd eq "help") { $ret = " Unknown argument $cmd, choose one of " ."\n ---checks---" @@ -381,8 +411,9 @@ sub HMinfo_SetFn($$) {######################################################### ."\n saveConfig [] # stores peers and register with saveConfig" ."\n autoReadReg [] # trigger update readings if attr autoReadReg is set" ."\n ---infos---" + ."\n update # update HMindfo counts" ."\n register [] # devicefilter parse devicename. Partial strings supported" - ."\n peerXref [] peer cross-reference" + ."\n peerXref [] # peer cross-reference" ."\n models [] # list of models incl native parameter" ."\n protoEvents [] # protocol status - names can be filtered" ."\n param [] [] [] ... # displays params for all entities as table" @@ -422,18 +453,6 @@ sub HMinfo_SetFn($$) {######################################################### my $chCnt = ($hash->{helper}{childCnt}+1)%1000; my $childName = "child_".$chCnt; - -# my $blkH = BlockingCall("HMinfo_SetFnDly", -# join( ",",($childName,$name,$cmd,$opt,$optEmpty,$filter,@a)), -# "HMinfo_post", -# 10); -# $hash->{helper}{child}{$childName} = " started:".gettimeofday(); -# $hash->{helper}{childCnt} = $chCnt; -# my $chPid = $blkH->{pid}; -# Log 1,"General parent started $childName PID:$chPid ".$hash->{helper}{child}{$childName}; -# return "unblock started $childName PID:$chPid ".$hash->{helper}{child}{$childName}; - - return HMinfo_SetFnDly(join(",",($childName,$name,$cmd,$opt,$optEmpty,$filter,@a))); } return $ret; @@ -472,6 +491,109 @@ sub HMinfo_post($) {########################################################### Log 1,"General deleted $childName now++++++++++++++"; return "finished"; } +sub HMinfo_status($){########################################################## + # - count defined HM entities, selected readings, errors on filtered readings + # - display Assigned IO devices + # - show ActionDetector status + # - prot events if error + my $hash = shift; + my $name = $hash->{NAME}; + my @IDs = keys%{$modules{CUL_HM}{defptr}}; + my ($nbrE,$nbrD,$nbrC,$nbrV) = (scalar(@IDs),0,0,0);# count entities + my @crit = split ",",$attr{$name}{sumStatus};#prepare event + my %sum; + my @erro = split ",",$attr{$name}{sumERROR}; + my %errFlt; + my %err; + my @errNames; + my @IOdev; + my %prot = (NACK =>0,IOerr =>0,ResendFail =>0,CmdDel =>0,CmdPend =>0); + my @protNames; + my @Anames; + foreach (@erro){ #prepare reading filter for error counts + my ($p,@a) = split ":",$_; + $errFlt{$p}{x}=1; # at least one reading + $errFlt{$p}{$_}=1 foreach (@a); + } + foreach my $id (@IDs){#search for Parameter + my $ehash = $modules{CUL_HM}{defptr}{$id}; + my $eName = $ehash->{NAME}; + $nbrC++ if ($ehash->{helper}{role}{chn}); + $nbrV++ if ($ehash->{helper}{role}{vrt}); + foreach my $read (@crit){ + if ($ehash->{READINGS}{$read}){ + my $val = $ehash->{READINGS}{$read}{VAL}; + $sum{$read}{$val} =0 if (!$sum{$read}{$val}); + $sum{$read}{$val}++; + } + } + foreach my $read (keys %errFlt){ + if ($ehash->{READINGS}{$read}){ + my $val = $ehash->{READINGS}{$read}{VAL}; + next if (grep (/$val/,(keys%{$errFlt{$read}})));# filter non-Error + $err{$read}{$val} =0 if (!$err{$read}{$val}); + $err{$read}{$val}++; + push @errNames,$eName; + } + } + if ($ehash->{helper}{role}{dev}){#restrict to devices + $nbrD++; + push @IOdev,$ehash->{IODev}{NAME} if($ehash->{IODev}); + push @Anames,$eName if ($attr{$eName}{actStatus} && $attr{$eName}{actStatus} ne "alive"); + foreach (keys%prot){ + if ($ehash->{"prot".$_}){ + $prot{$_}++; + push @protNames,$eName; + } + } + } + } + + foreach my $v(keys%{$hash}){# remove old readings + delete $hash->{$v} if($v =~ m/^(ERR_|sum_)/); + } + foreach my $read(@crit){ + next if (!defined $sum{$read} ); + $hash->{"sum_".$read} = ""; + $hash->{"sum_".$read} .= "$_:$sum{$read}{$_};"foreach(keys %{$sum{$read}}); + } + foreach my $read(keys %errFlt){ + next if (!defined $err{$read} ); + $hash->{"ERR_".$read} = ""; + $hash->{"ERR_".$read} .= "$_:$err{$read}{$_};"foreach(keys %{$err{$read}}); + } + delete $hash->{ERR_names}; + $hash->{ERR_names} = join",",@errNames if(@errNames); + + $hash->{sumDefined} = "entities:$nbrE device:$nbrD channel:$nbrC virtual:$nbrV"; + # ------- what about IO devices??? ------ + $hash->{actTotal} = $modules{CUL_HM}{defptr}{"000000"}{STATE};# display actionDetector + delete $hash->{ERRactNames}if(!@Anames); + $hash->{ERRactNames} = join",",@Anames; + + # ------- what about IO devices??? ------ + my %tmp; + $tmp{$_}=0 for @IOdev; + delete $tmp{""}; #remove empties if present + + @IOdev = sort keys %tmp; + foreach (@IOdev){ + $_ .= ":".$defs{$_}{READINGS}{cond}{VAL} if($defs{$_}{READINGS}{cond}); + } + $hash->{HM_IOdevices}= join",",@IOdev; + # ------- what about protocol events ------ + # Current Events are Rcv,NACK,IOerr,Resend,ResendFail,Snd + # additional variables are protCmdDel,protCmdPend,protState,protLastRcv + my @tp; + foreach (keys(%prot)){ push @tp,"$_:$prot{$_}" if ($prot{$_})}; + delete $hash->{ERR__protocol}; + delete $hash->{ERR__protoNames}; + $hash->{ERR__protocol} = join",",@tp if(@tp); + $hash->{ERR__protoNames} = join",",@protNames if(@protNames); + + return; +} + 1; =pod =begin html @@ -481,7 +603,24 @@ sub HMinfo_post($) {###########################################################
      HMinfo is a module that shall support in getting an overview of - eQ-3 HomeMatic devices as defines in CUL_HM. + eQ-3 HomeMatic devices as defines in CUL_HM.

      + Status information and counter
      + hminfo tries to give an overview on the CUL_HM installed base including current conditions. + Readings and counter will not be updates automatically due to performance issues.
      + Command update must be used to refresh the values. +
        + set hm update
        +
      + Webview of HMinfo will provide details, mainly based counter drivern, on how + many CUL_HM entities experience certain conditions. Areas provided are +
    • Action Detector status
    • +
    • CUL_HM related IO devices with their condition
    • +
    • Device protocol events which are related to communication errors
    • +
    • count of certain readings (e.g. batterie) with their condition - attribut controlled
    • +
    • count of error condition in readings (e.g. overheat, motorError) - attribut controlled
    • + +
      + It also allows some HM wide commands such as store all collected register settings.

      @@ -489,7 +628,7 @@ sub HMinfo_post($) {########################################################### If applicable and evident execution is restricted to related entities. This means that rssi is executed only on devices, never channels since they never have support rssi values.

      - Filter + Filter
        can be applied as following:

        set <name> <cmd> <filter> [<param>]
        whereby filter has two segments, typefilter and name filter
        @@ -515,56 +654,60 @@ sub HMinfo_post($) {########################################################### set hm param -dcv expert # get attribut expert for all channels,devices or virtuals
    -
    - - Define +
    + Define
      define <name> HMinfo
      Just one entity needs to be defines, no parameter are necessary.

    - - Set + + Set
      even though the commands are more a get funktion they are implemented as set to allow simple web interface usage
        -
      • models
        +
      • update
        + updates HM status counter. +
      • +
      • models
        list all HM models that are supported in FHEM
      • -
      • param <name> <name>...
        +
      • param [filter] <name> <name>...
        returns a table parameter values (attribute, readings,...) for all entities as a table
      • -
      • regCheck
        - performs a consistancy check on register readings for completeness +
      • peerXref [filter]
        + provides a cross-reference on peerings, a kind of who-with-who summary over HM
      • -
      • peerCheck
        +
      • register [filter]
        + provides a tableview of register of an entity +
      • + +
      • configCheck [filter]
        + performs a consistancy check of HM settings. It includes regCheck and peerCheck +
      • +
      • peerCheck [filter]
        performs a consistancy check on peers. If a peer is set in one channel this funktion will search wether the peer also exist on the opposit side.
      • -
      • configCheck
        - performs a consistancy check of HM settings. It includes regCheck and peerCheck +
      • regCheck [filter]
        + performs a consistancy check on register readings for completeness
      • -
      • peerXref
        - provides a cross-reference on peerings, a kind of who-with-who summary over HM + +
      • autoReadReg [filter]
        + schedules a read of the configuration for the CUL_HM devices with attribut autoReadReg set to 1 or higher.
      • -
      • saveConfig
        +
      • clear [Protocol|Readings|Rssi] [filter]
        + executes a set clear ... on all HM entities
        +
      • Protocol relates to set clear msgEvents
      • +
      • Readings relates to set clear readings
      • +
      • Rssi clears all rssi counters
      • + +
      • saveConfig [filter]
        performs a save for all HM register setting and peers. See CUL_HM saveConfig.
      • -
      • clearProtocol
        - executes a set clear msgEvents on all HM devices -
      • -
      • clearReadings
        - executes a set clear readings on all HM devices -
      • -
      • clearRssi
        - executes a set clear rssi on all HM devices -
      • -
      • autoReadReg
        - stimulates a read of the configuration for the CUL_HM devices with attribut autoReadReg set to 1 or higher. -

    @@ -574,9 +717,39 @@ sub HMinfo_post($) {###########################################################
      N/A


    - - Attributes -
      N/A
    + Attributes +
      +
    • sumStatus
      + List of readings that shall be screend and counted based on current presence. + I.e. counter is the number of entities with this reading and the same value. + Readings to be searched are separated by comma.
      + Example:
      + + attr hm sumStatus battery,sabotageError
      +
      + will cause a reading like
      + sum_batterie ok:5 low:3
      + sum_sabotageError on:1
      +
      + Note: counter with '0' value will not be reported. HMinfo will find all present values autonomously
      + Setting is meant to give user a fast overview of parameter that are expected to be system critical
      +
    • +
    • sumERROR + Similar to sumStatus but with a focus on error conditions in the system. + Here user can add readingvalues that are not displayed. I.e. the value is the + good-condition that will not be counted.
      + This way user must not know all error values but it is sufficient to supress known non-ciritical ones. + Example:
      + + attr hm sumERROR battery:ok,sabotageError:off,overheat:off,Activity:alive:unknown
      +
      + will cause a reading like
      + ERR_batterie low:3
      + ERR_sabotageError on:1
      + ERR_overheat on:3
      + ERR_Activity dead:5
      +
    • +
    =end html =cut