2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-20 01:06:04 +00:00

98_monitoring: PBP code restructured (Part I)

git-svn-id: https://svn.fhem.de/fhem/trunk@25912 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2022-04-02 08:15:10 +00:00
parent 6033f5aca3
commit 7304b0aa24
2 changed files with 251 additions and 262 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # 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. # Do not insert empty lines here, update check depends on it.
- change: 98_monitoring: PBP code restructured (part I)
- feature: 31_LightScene: support for configDB (by Beta-User) - feature: 31_LightScene: support for configDB (by Beta-User)
- bugfix: 72_FB_CALLMONITOR: create reading "internal_connection" also - bugfix: 72_FB_CALLMONITOR: create reading "internal_connection" also
for unknown connection type values for unknown connection type values

View File

@ -5,7 +5,7 @@
# #
# 98_monitoring.pm # 98_monitoring.pm
# #
# Copyright by igami # Originally initiated by igami
# #
# This file is part of FHEM. # This file is part of FHEM.
# #
@ -26,25 +26,9 @@ package main;
use strict; use strict;
use warnings; use warnings;
# forward declarations ########################################################
sub monitoring_Initialize($);
sub monitoring_Define($$);
sub monitoring_Undefine($$);
sub monitoring_Set($@);
sub monitoring_Get($@);
sub archetype_Attr(@);
sub monitoring_Notify($$);
sub monitoring_modify($);
sub monitoring_RemoveInternalTimer($);
sub monitoring_return($$);
sub monitoring_setActive($);
sub monitoring_setInactive($);
# initialize ################################################################## # initialize ##################################################################
sub monitoring_Initialize($) { sub monitoring_Initialize {
my ($hash) = @_; my $hash = shift // return;
my $TYPE = "monitoring"; my $TYPE = "monitoring";
$hash->{DefFn} = $TYPE."_Define"; $hash->{DefFn} = $TYPE."_Define";
@ -75,24 +59,26 @@ sub monitoring_Initialize($) {
"whitelist:textField-long ". "whitelist:textField-long ".
$readingFnAttributes $readingFnAttributes
; ;
return;
} }
# regular Fn ################################################################## # regular Fn ##################################################################
sub monitoring_Define($$) { sub monitoring_Define {
my ($hash, $def) = @_; my $hash = shift // return;
my ($SELF, $TYPE, @re) = split(/[\s]+/, $def, 5); my $def = shift // return;
my ($SELF, $TYPE, @re) = split m{\s+}xms, $def, 5;
return("Usage: define <name> $TYPE <add-event> [<remove-event>]") return("Usage: define <name> $TYPE <add-event> [<remove-event>]")
if(int(@re) < 1 || int(@re) > 2); if( !@re || @re > 2);
monitoring_NOTIFYDEV($hash); monitoring_NOTIFYDEV($hash) if !$init_done;
monitoring_setActive($hash) if($init_done); monitoring_setActive($hash) if $init_done;
return; return;
} }
sub monitoring_Undefine($$) { sub monitoring_Undefine {
my ($hash, $arg) = @_; my $hash = shift // return;
monitoring_setInactive($hash); monitoring_setInactive($hash);
monitoring_RemoveInternalTimer($hash); monitoring_RemoveInternalTimer($hash);
@ -100,64 +86,63 @@ sub monitoring_Undefine($$) {
return; return;
} }
sub monitoring_Set($@) { sub monitoring_Set {
my ($hash, @a) = @_; my ($hash, @arr) = @_;
my $TYPE = $hash->{TYPE}; my $TYPE = $hash->{TYPE};
return("\"set $TYPE\" needs at least one argument") if(@a < 2); return '"set <monitoring>" needs at least one argument' if @arr < 2;
my $SELF = shift @a; my $SELF = shift @arr;
my $argument = shift @a; my $argument = shift @arr;
my $value = join(" ", @a) if (@a); my $value = @arr ? join ' ', @arr : '';
my %monitoring_sets = ( my %monitoring_sets = (
"active" => "active:noArg", active => 'active:noArg',
"clear" => "clear:all,error,warning", clear => 'clear:all,error,warning',
"errorAdd" => "errorAdd:textField", errorAdd => 'errorAdd:textField',
"errorRemove" => "errorRemove:". errorRemove => 'errorRemove:'.
join(",", ReadingsVal($SELF, "error", "")), join q{,}, ReadingsVal($SELF, 'error', ''),
"inactive" => "inactive:noArg", inactive => 'inactive:noArg',
"warningAdd" => "warningAdd:textField", warningAdd => 'warningAdd:textField',
"warningRemove" => "warningRemove:". warningRemove => 'warningRemove:'.
join(",", ReadingsVal($SELF, "warning", "")) join q{,}, ReadingsVal($SELF, 'warning', '')
); );
return( return "Unknown argument $argument, choose one of ".
"Unknown argument $argument, choose one of ". join " ", sort values %monitoring_sets
join(" ", sort(values %monitoring_sets)) if !exists $monitoring_sets{$argument};
) unless(exists($monitoring_sets{$argument}));
if($argument eq "active"){ if ( $argument eq 'active' ) {
monitoring_setActive($hash); return monitoring_setActive($hash);
} }
elsif($argument eq "inactive"){ if ( $argument eq 'inactive' ) {
monitoring_setInactive($hash); monitoring_setInactive($hash);
readingsSingleUpdate($hash, "state", $argument, 0); readingsSingleUpdate($hash, 'state', $argument, 0);
Log3($SELF, 3, "$SELF ($TYPE) set $SELF inactive"); Log3($SELF, 3, "$SELF ($TYPE) set $SELF inactive");
monitoring_RemoveInternalTimer($hash); return monitoring_RemoveInternalTimer($hash);
} }
elsif($argument eq "clear"){ if ( $argument eq 'clear' ) {
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
if($value =~ m/^(warning|all)$/){ if ( $value =~ m{\A(warning|all)\z}xms ) {
readingsBulkUpdate($hash, "warning", "", 0); readingsBulkUpdate($hash, 'warning', '', 0);
readingsBulkUpdate($hash, "warningCount", 0, 0); readingsBulkUpdate($hash, 'warningCount', 0, 0);
foreach my $r (keys %{$hash->{READINGS}}){ for my $r (keys %{$hash->{READINGS}}){
if($r =~ m/(warning)Add_(.+)/){ if($r =~ m{(warning)Add_(.+)}xms){
RemoveInternalTimer("$SELF|$1|add|$2"); RemoveInternalTimer("$SELF|$1|add|$2");
delete $hash->{READINGS}{$r}; delete $hash->{READINGS}{$r};
} }
} }
} }
if($value =~ m/^(error|all)$/){ if ( $value =~ m{\A(error|all)\z}xms ) {
readingsBulkUpdate($hash, "error", "", 0); readingsBulkUpdate($hash, 'error', '', 0);
readingsBulkUpdate($hash, "errorCount", 0, 0); readingsBulkUpdate($hash, 'errorCount', 0, 0);
foreach my $r (keys %{$hash->{READINGS}}){ for my $r ( keys %{$hash->{READINGS}} ) {
if($r =~ m/(error)Add_(.+)/){ if ( $r =~ m{(error)Add_(.+)}xms ) {
RemoveInternalTimer("$SELF|$1|add|$2"); RemoveInternalTimer("$SELF|$1|add|$2");
delete $hash->{READINGS}{$r}; delete $hash->{READINGS}{$r};
@ -165,109 +150,103 @@ sub monitoring_Set($@) {
} }
} }
readingsBulkUpdate($hash, "state", "$argument $value", 0) readingsBulkUpdate($hash, 'state', "$argument $value", 0)
unless(IsDisabled($SELF)); if !IsDisabled($SELF);
readingsEndUpdate($hash, 0); readingsEndUpdate($hash, 0);
Log3($SELF, 2, "$TYPE ($SELF) set $SELF $argument $value"); Log3($SELF, 2, "$TYPE ($SELF) set $SELF $argument $value");
} }
elsif($argument =~ /^(error|warning)(Add|Remove)$/){ elsif($argument =~ m{\A(error|warning)(Add|Remove)\z}xms){
monitoring_modify("$SELF|$1|".lc($2)."|$value"); monitoring_modify("$SELF|$1|".lc($2)."|$value");
} }
return; return;
} }
sub monitoring_Get($@) { sub monitoring_Get {
my ($hash, @a) = @_; my ($hash, @arr) = @_;
my $TYPE = $hash->{TYPE}; my $TYPE = $hash->{TYPE};
my $SELF = shift @a; my $SELF = shift @arr;
return if(IsDisabled($SELF)); return if IsDisabled($SELF);
return("\"get $TYPE\" needs at least one argument") if(@a < 1); return("\"get $TYPE\" needs at least one argument") if !@arr;
my $argument = shift @a; my $argument = shift @arr;
my $value = join(" ", @a) if (@a); my $value = @arr ? join ' ', @arr : '';
my $default = AttrVal($SELF, "getDefault", "all"); my $default = AttrVal($SELF, 'getDefault', 'all');
my %monitoring_gets = ( my %monitoring_gets = (
"all" => "all:noArg", all => 'all:noArg',
"default" => "default:noArg", default => 'default:noArg',
"error" => "error:noArg", error => 'error:noArg',
"warning" => "warning:noArg" warning => 'warning:noArg'
); );
my @ret; my @ret;
return( return
"Unknown argument $argument, choose one of ". "Unknown argument $argument, choose one of ".
join(" ", sort(values %monitoring_gets)) join ' ', sort values %monitoring_gets if !exists $monitoring_gets{$argument};
) unless(exists($monitoring_gets{$argument}));
if($argument eq "all" || ($argument eq "default" && $default eq "all")){ if ( $argument eq 'all' || $argument eq 'default' && $default eq 'all' ) {
push(@ret, monitoring_return($hash, "error")); push @ret, monitoring_return($hash, 'error');
push(@ret, monitoring_return($hash, "warning")); push @ret, monitoring_return($hash, 'warning');
} }
elsif($argument eq "default"){ elsif ( $argument eq 'default' ) {
push(@ret, monitoring_return($hash, $default)); push @ret, monitoring_return($hash, $default);
} }
elsif($argument eq "error"){ elsif($argument eq 'error' || $argument eq 'warning') {
push(@ret, monitoring_return($hash, "error")); push @ret, monitoring_return($hash, $argument);
}
elsif($argument eq "warning"){
push(@ret, monitoring_return($hash, "warning"));
} }
return(join("\n\n", @ret)."\n") if(@ret); return join("\n\n", @ret)."\n" if @ret;
return; return;
} }
sub monitoring_Attr(@) { sub monitoring_Attr {
my ($cmd, $SELF, $attribute, $value) = @_; my ($cmd, $SELF, $attribute, $value) = @_;
my ($hash) = $defs{$SELF}; my $hash = $defs{$SELF} // return;
if($attribute =~ "blacklist" && $value){ if($attribute =~ "blacklist" && $value){
my @blacklist; my @blacklist;
push(@blacklist, devspec2array($_)) foreach (split(/[\s]+/, $value)); push @blacklist, devspec2array($_) for (split m{[\s]+}x, $value);
my %blacklist = map{$_, 1} @blacklist; my %blacklist = map{ $_ => 1 } @blacklist;
foreach my $name (sort(keys %blacklist)){ for my $name (sort keys %blacklist){
monitoring_modify("$SELF|warning|remove|$name"); monitoring_modify("$SELF|warning|remove|$name");
monitoring_modify("$SELF|error|remove|$name"); monitoring_modify("$SELF|error|remove|$name");
} }
} }
elsif($attribute eq "whitelist"){ elsif($attribute eq 'whitelist'){
monitoring_NOTIFYDEV($hash); monitoring_NOTIFYDEV($hash);
if($value){ return if !$value;
my @whitelist; my @whitelist;
push(@whitelist, devspec2array($_)) foreach (split(/[\s]+/, $value)); push @whitelist, devspec2array($_) for (split m{[\s]+}x, $value);
foreach my $list ("warning", "error"){ for my $list ( qw(warning error) ){
foreach my $name (split(",", ReadingsVal($SELF, $list, ""))){ for my $name ( split m{,}x, ReadingsVal($SELF, $list, '') ) {
monitoring_modify("$SELF|$list|remove|$name") monitoring_modify("$SELF|$list|remove|$name")
unless(grep(/$name/, @whitelist)); if !grep {m/$name/} @whitelist;
}
} }
} }
} }
elsif($attribute eq "disable"){ elsif($attribute eq 'disable'){
if($cmd eq "set" and $value == 1){ if($cmd eq 'set' and $value == 1){
monitoring_setActive($hash); return monitoring_setActive($hash);
}
else{
monitoring_setInactive($hash);
readingsSingleUpdate($hash, "state", "disabled", 0);
Log3($SELF, 3, "$hash->{TYPE} ($SELF) attr $SELF disabled");
} }
monitoring_setInactive($hash);
readingsSingleUpdate($hash, 'state', 'disabled', 0);
Log3($SELF, 3, "$hash->{TYPE} ($SELF) attr $SELF disabled");
} }
return; return;
} }
sub monitoring_Notify($$) { sub monitoring_Notify {
my ($hash, $dev_hash) = @_; my $hash = shift // return;
my $dev_hash = shift // return;
my $SELF = $hash->{NAME}; my $SELF = $hash->{NAME};
my $name = $dev_hash->{NAME}; my $name = $dev_hash->{NAME};
my $TYPE = $hash->{TYPE}; my $TYPE = $hash->{TYPE};
@ -279,66 +258,71 @@ sub monitoring_Notify($$) {
$SELF eq $name # do not process own events $SELF eq $name # do not process own events
); );
my $events = deviceEvents($dev_hash, AttrVal($SELF, "addStateEvent", 0)); my $events = deviceEvents($dev_hash, AttrVal($SELF, 'addStateEvent', 0));
return unless($events); return if !$events;
if($name eq "global" && "INITIALIZED" =~ m/\Q@{$events}\E/){ if($name eq 'global' && 'INITIALIZED|REREADCFG' =~ m/\Q@{$events}\E/){
monitoring_setActive($hash); monitoring_setActive($hash);
return; return;
} }
my ($addRegex, $removeRegex) = split(/[\s]+/, InternalVal($SELF, "DEF", "")); my ($addRegex, $removeRegex) = split m{[\s]+}x, InternalVal($SELF, 'DEF', '');
=pod this seems to be useless?
return unless( return unless(
$addRegex =~ m/^$name:/ || $addRegex =~ m/^$name:/ ||
$removeRegex && $removeRegex =~ m/^$name:/ || $removeRegex && $removeRegex =~ m/^$name:/ ||
$events $events
); );
=cut
my @blacklist; my @blacklist;
push(@blacklist, devspec2array($_)) push @blacklist, devspec2array($_)
foreach (split(/[\s]+/, AttrVal($SELF, "blacklist", ""))); for (split m{[\s]+}x, AttrVal($SELF, 'blacklist', ''));
return if(@blacklist && grep(/$name/, @blacklist)); return if @blacklist && grep {/$name/} @blacklist;
my @whitelist; my @whitelist;
push(@whitelist, devspec2array($_)) push @whitelist, devspec2array($_)
foreach (split(/[\s]+/, AttrVal($SELF, "whitelist", ""))); for (split m{[\s]+}x, AttrVal($SELF, 'whitelist', ''));
return if(@whitelist && !(grep(/$name/, @whitelist))); return if @whitelist && !grep {/$name/} @whitelist;
foreach my $event (@{$events}){ for my $event (@{$events}){
next unless($event); next if !$event;
my $addMatch = "$name:$event" =~ m/^$addRegex$/; my $addMatch = "$name:$event" =~ m{\A$addRegex\z}xms;
my $removeMatch = $removeRegex ? "$name:$event" =~ m/^$removeRegex$/ : 0; my $removeMatch = $removeRegex ? "$name:$event" =~ m{\A$removeRegex\z}xms : 0;
#Log3($hash, 3, "monitoring_notify called with add $addMatch and remove $removeMatch");
next unless(defined($event) && ($addMatch || $removeMatch)); #next unless(defined($event) && ($addMatch || $removeMatch));
next if !$addMatch && !$removeMatch;
#Log3($hash, 3, "monitoring_notify unless 1 replacement passed w. $addMatch and remove $removeMatch");
Log3($SELF, 4 , "$TYPE ($SELF) triggered by \"$name $event\""); Log3($SELF, 4 , "$TYPE ($SELF) triggered by \"$name $event\"");
foreach my $list ("error", "warning"){ for my $list ( qw (error warning) ){
my $listFuncAdd = AttrVal($SELF, $list."FuncAdd", "preset"); my $listFuncAdd = AttrVal($SELF, $list.'FuncAdd', 'preset');
my $listFuncRemove = AttrVal($SELF, $list."FuncRemove", "preset"); my $listFuncRemove = AttrVal($SELF, $list.'FuncRemove', 'preset');
my $listWait = eval(AttrVal($SELF, $list."Wait", 0)); my $listWait = eval(AttrVal($SELF, $list.'Wait', 0));
$listWait = 0 unless(looks_like_number($listWait)); $listWait = 0 if !looks_like_number($listWait);
if($listFuncAdd eq "preset" && $listFuncRemove eq "preset"){ if ( $listFuncAdd eq 'preset' && $listFuncRemove eq 'preset' ) {
Log3( Log3(
$SELF, 5, "$TYPE ($SELF) ". $SELF, 5, "$TYPE ($SELF) ".
$list."FuncAdd and $list"."FuncRemove are preset" $list."FuncAdd and $list"."FuncRemove are preset"
); );
if(!$removeRegex){ if ( !$removeRegex ) {
if($listWait == 0){ if ( $listWait == 0 ) {
Log3( Log3(
$SELF, 2, "$TYPE ($SELF) ". $SELF, 2, "$TYPE ($SELF) ".
"set \"$list"."Wait\" while \"$list". "set \"$list"."Wait\" while \"$list".
"FuncAdd\" and \"$list"."FuncRemove\" are same" "FuncAdd\" and \"$list"."FuncRemove\" are same"
) if($list eq "error"); ) if $list eq 'error';
next; next;
} }
@ -351,32 +335,33 @@ sub monitoring_Notify($$) {
next; next;
} }
else{ else{
next unless($list eq "error" || AttrVal($SELF, "errorWait", undef)); #next unless($list eq 'error' || AttrVal($SELF, 'errorWait', undef));
next if $list ne 'error' && !AttrVal($SELF, 'errorWait', undef);
Log3( Log3(
$SELF, 5, "$TYPE ($SELF) ". $SELF, 5, "$TYPE ($SELF) ".
"addRegex ($addRegex) and removeRegex ($removeRegex) are defined" "addRegex ($addRegex) and removeRegex ($removeRegex) are defined"
); );
monitoring_modify("$SELF|$list|remove|$name") if($removeMatch); monitoring_modify("$SELF|$list|remove|$name") if $removeMatch;
monitoring_modify("$SELF|$list|add|$name|$listWait") if($addMatch); monitoring_modify("$SELF|$list|add|$name|$listWait") if $addMatch;
next; next;
} }
} }
$listFuncAdd = 1 if($listFuncAdd eq "preset" && $addMatch); $listFuncAdd = 1 if $listFuncAdd eq 'preset' && $addMatch;
if(!$removeRegex){ if(!$removeRegex){
Log3($SELF, 5, "$TYPE ($SELF) only addRegex is defined"); Log3($SELF, 5, "$TYPE ($SELF) only addRegex is defined");
if($listFuncRemove eq "preset"){ if ( $listFuncRemove eq 'preset' ) {
if($listWait == 0){ if ( $listWait == 0 ) {
Log3( Log3(
$SELF, 2, "$TYPE ($SELF) ". $SELF, 2, "$TYPE ($SELF) ".
"set \"$list"."Wait\" while \"$list". "set \"$list"."Wait\" while \"$list".
"FuncAdd\" and \"$list"."FuncRemove\" are same" "FuncAdd\" and \"$list"."FuncRemove\" are same"
) if($list eq "error"); ) if $list eq 'error';
next; next;
} }
@ -390,17 +375,17 @@ sub monitoring_Notify($$) {
"addRegex ($addRegex) and removeRegex ($removeRegex) are defined" "addRegex ($addRegex) and removeRegex ($removeRegex) are defined"
); );
$listFuncRemove = 1 if($listFuncRemove eq "preset" && $removeMatch); $listFuncRemove = 1 if $listFuncRemove eq 'preset' && $removeMatch;
} }
$listFuncAdd = eval($listFuncAdd) if($listFuncAdd =~ /^\{.*\}$/s); $listFuncAdd = eval($listFuncAdd) if $listFuncAdd =~ /^\{.*\}$/s;
$listFuncRemove = eval($listFuncRemove) $listFuncRemove = eval($listFuncRemove)
if($listFuncRemove =~ /^\{.*\}$/s); if($listFuncRemove =~ /^\{.*\}$/s);
monitoring_modify("$SELF|$list|remove|$name") monitoring_modify("$SELF|$list|remove|$name")
if($listFuncRemove && $listFuncRemove eq "1"); if $listFuncRemove && $listFuncRemove eq '1';
monitoring_modify("$SELF|$list|add|$name|$listWait") monitoring_modify("$SELF|$list|add|$name|$listWait")
if($listFuncAdd && $listFuncAdd eq "1"); if $listFuncAdd && $listFuncAdd eq '1';
next; next;
} }
@ -410,17 +395,17 @@ sub monitoring_Notify($$) {
} }
# module Fn ################################################################### # module Fn ###################################################################
sub monitoring_modify($) { sub monitoring_modify {
my ($SELF, $list, $operation, $value, $wait) = split("\\|", shift); my ($SELF, $list, $operation, $value, $wait) = split m{[|]}x, shift;
my ($hash) = $defs{$SELF}; my $hash = $defs{$SELF} // return;
return unless(defined($hash)); return if IsDisabled($SELF);
return if(IsDisabled($SELF));
my $at = eval($wait + gettimeofday()) if($wait && $wait ne "quiet"); my $at;
$at = eval($wait + gettimeofday()) if $wait && $wait ne 'quiet';
my $TYPE = $hash->{TYPE}; my $TYPE = $hash->{TYPE};
my (@change, %readings); my (@change, %readings);
%readings = map{$_, 1} split(",", ReadingsVal($SELF, $list, "")); %readings = map{ $_ => 1 } split m{,}xms, ReadingsVal($SELF, $list, '');
my $arg = "$SELF|$list|$operation|$value"; my $arg = "$SELF|$list|$operation|$value";
my $reading = $list."Add_".$value; my $reading = $list."Add_".$value;
@ -433,108 +418,111 @@ sub monitoring_modify($) {
"\n at: ".($at ? FmtDateTime($at) : "now") "\n at: ".($at ? FmtDateTime($at) : "now")
); );
if($operation eq "add"){ if ( $operation eq 'add' ) {
return if( return if
$readings{$value} || $readings{$value} ||
ReadingsVal($SELF, "error", "") =~ m/(?:^|,)$value(?:,|$)/ ReadingsVal($SELF, 'error', '') =~ m/(?:^|,)$value(?:,|$)/
); ;
if($at){ if ( $at ){
return if($hash->{READINGS}{$reading}); return if $hash->{READINGS}{$reading};
readingsSingleUpdate($hash, $reading, FmtDateTime($at), 0); readingsSingleUpdate($hash, $reading, FmtDateTime($at), 0);
InternalTimer($at, "monitoring_modify", $arg); InternalTimer($at, 'monitoring_modify', $arg);
return; return;
} }
else{ monitoring_modify("$SELF|warning|remove|$value|quiet")
monitoring_modify("$SELF|warning|remove|$value|quiet") if $list eq 'error';
if($list eq "error");
$readings{$value} = 1; $readings{$value} = 1;
delete $hash->{READINGS}{$reading}; delete $hash->{READINGS}{$reading};
}
} }
elsif($operation eq "remove"){ elsif ( $operation eq 'remove' ) {
push(@change, 1) if(delete $readings{$value}); push(@change, 1) if delete $readings{$value};
delete $hash->{READINGS}{"$reading"}; delete $hash->{READINGS}{$reading};
} }
RemoveInternalTimer("$SELF|$list|add|$value"); RemoveInternalTimer("$SELF|$list|add|$value");
return unless(@change || $operation eq "add"); #return unless(@change || $operation eq 'add');
return if !@change && $operation ne 'add';
my $allCount = my $allCount =
int(keys %readings) + int(keys %readings) +
ReadingsNum($SELF, ($list eq "warning" ? "error" : "warning")."Count", 0) ReadingsNum($SELF, ($list eq 'warning' ? 'error' : 'warning').'Count', 0)
; ;
if ($operation eq "add") { if ($operation eq 'add') {
my $name = $value; my $name = $value;
my $listFuncAdded = AttrVal($SELF, $list."FuncAdded", ""); my $listFuncAdded = AttrVal($SELF, $list.'FuncAdded', '');
$listFuncAdded = $listFuncAdded =~ /^\{.*\}$/s ? eval($listFuncAdded) : fhem($listFuncAdded); $listFuncAdded = $listFuncAdded =~ /^\{.*\}$/s ? eval($listFuncAdded) : fhem($listFuncAdded);
} }
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "state", "$list $operation: $value"); readingsBulkUpdate($hash, 'state', "$list $operation: $value");
readingsBulkUpdate($hash, $list, join(",", sort(keys %readings))); readingsBulkUpdate($hash, $list, join ",", sort keys %readings);
readingsBulkUpdate($hash, $list."Count", int(keys %readings)); readingsBulkUpdate($hash, $list.'Count', int(keys %readings));
readingsBulkUpdate($hash, "allCount", $allCount) readingsBulkUpdate($hash, 'allCount', $allCount)
unless($wait &&$wait eq "quiet"); if !$wait || $wait ne 'quiet';
readingsEndUpdate($hash, 1); readingsEndUpdate($hash, 1);
return; return;
} }
sub monitoring_NOTIFYDEV($) { sub monitoring_NOTIFYDEV {
my ($hash) = @_; my $hash = shift // return;
my $SELF = $hash->{NAME}; my $SELF = $hash->{NAME} // return;
my $NOTIFYDEV = my $NOTIFYDEV = $init_done ? AttrVal($SELF, 'whitelist', undef) : 'global'; #|| join(",", (InternalVal($SELF, "DEF", undef) =~ m/(?:^|\s)([^:\s]+):/g))
AttrVal($SELF, "whitelist", undef) ||
join(",", (InternalVal($SELF, "DEF", undef) =~ m/(?:^|\s)([^:\s]+):/g))
;
$NOTIFYDEV =~ s/\s/,/g;
notifyRegexpChanged($hash, $NOTIFYDEV); if ($NOTIFYDEV) {
$NOTIFYDEV =~ s{[\s]+}{,}gx;
return notifyRegexpChanged($hash, "$NOTIFYDEV,global");
}
$NOTIFYDEV = join q{|}, split m{[\s]+}x, InternalVal($SELF, 'DEF', undef);
return notifyRegexpChanged($hash, "$NOTIFYDEV|global");
} }
sub monitoring_RemoveInternalTimer($) { sub monitoring_RemoveInternalTimer {
my ($hash) = @_; my $hash = shift // return;
my $SELF = $hash->{NAME}; my $SELF = $hash->{NAME} // return;
foreach my $reading (sort(keys %{$hash->{READINGS}})){ for my $reading (sort keys %{$hash->{READINGS}}){
RemoveInternalTimer("$SELF|$1|add|$2") RemoveInternalTimer("$SELF|$1|add|$2")
if($reading =~ m/(error|warning)Add_(.+)/); if $reading =~ m{(error|warning)Add_(.+)}xms;
} }
return; return;
} }
sub monitoring_return($$) { sub monitoring_return {
my ($hash, $list) = @_; my $hash = shift // return;
my $SELF = $hash->{NAME}; my $list = shift // return;
my @errors = split(",", ReadingsVal($SELF, "error", ""));
my @warnings = split(",", ReadingsVal($SELF, "warning", ""));
my $value = ReadingsVal($SELF, $list, undef);
my $ret = AttrVal($SELF, $list."Return", undef);
$ret = '"$list: $value"' if(!$ret && $value);
return unless($ret); my $SELF = $hash->{NAME} // return;
my @errors = split m{,}xms, ReadingsVal($SELF, 'error', '');
my @warnings = split m{,}xms, ReadingsVal($SELF, 'warning', '');
my $value = ReadingsVal($SELF, $list, undef);
my $ret = AttrVal($SELF, $list.'Return', undef);
$ret = '"$list: $value"' if !$ret && $value;
return if !$ret;
return eval($ret); return eval($ret);
} }
sub monitoring_setActive($) { sub monitoring_setActive {
my ($hash) = @_; my $hash = shift // return;
my $SELF = $hash->{NAME}; my $SELF = $hash->{NAME} // return;
my $TYPE = $hash->{TYPE}; my $TYPE = $hash->{TYPE};
readingsSingleUpdate($hash, "state", "active", 0); monitoring_NOTIFYDEV($hash);
readingsSingleUpdate($hash, 'state', 'active', 0);
Log3($SELF, 3, "$TYPE ($SELF) set $SELF active"); Log3($SELF, 3, "$TYPE ($SELF) set $SELF active");
foreach my $reading (reverse sort(keys %{$hash->{READINGS}})){ for my $reading (reverse sort keys %{$hash->{READINGS}}){
if($reading =~ m/(error|warning)Add_(.+)/){ if ( $reading =~ m{(error|warning)Add_(.+)}xms ) {
my $wait = time_str2num(ReadingsVal($SELF, $reading, "")); my $wait = time_str2num(ReadingsVal($SELF, $reading, ''));
next unless(looks_like_number($wait)); next if !looks_like_number($wait);
$wait -= gettimeofday(); $wait -= gettimeofday();
@ -549,17 +537,18 @@ sub monitoring_setActive($) {
} }
} }
AnalyzeCommandChain(undef, AttrVal($SELF, "setActiveFunc", "preset")); AnalyzeCommandChain(undef, AttrVal($SELF, 'setActiveFunc', 'preset'));
return; return;
} }
sub monitoring_setInactive($) { sub monitoring_setInactive {
my ($hash) = @_; my $hash = shift // return;
my $SELF = $hash->{NAME}; my $SELF = $hash->{NAME} // return;
my $TYPE = $hash->{TYPE}; my $TYPE = $hash->{TYPE};
AnalyzeCommandChain(undef, AttrVal($SELF, "setInactiveFunc", "preset")); notifyRegexpChanged($hash,'',1);
AnalyzeCommandChain(undef, AttrVal($SELF, 'setInactiveFunc', 'preset'));
return; return;
} }
@ -742,7 +731,7 @@ __END__
</a> </a>
</li> </li>
<a id="monitoring-attr-blacklist"></a><li> <a id="monitoring-attr-blacklist"></a><li>
<code>blacklist</code><br> <code>blacklist &lt;devspec list&gt;</code><br>
Space-separated list of devspecs which will be ignored.<br> Space-separated list of devspecs which will be ignored.<br>
If the attribute is set all devices which are specified by the devspecs If the attribute is set all devices which are specified by the devspecs
are removed from both lists. are removed from both lists.
@ -879,7 +868,7 @@ __END__
Like errorReturn, just for the warning list. Like errorReturn, just for the warning list.
</li> </li>
<a id="monitoring-attr-whitelist"></a><li> <a id="monitoring-attr-whitelist"></a><li>
<code>whitelist {&lt;devspec list&gt;}</code><br> <code>whitelist &lt;devspec list&gt;</code><br>
Space-separated list of devspecs which are allowed.<br> Space-separated list of devspecs which are allowed.<br>
If the attribute is set all devices which are not specified by the If the attribute is set all devices which are not specified by the
devspecs are removed from both lists. devspecs are removed from both lists.
@ -906,15 +895,15 @@ __END__
</b> </b>
<br> <br>
<pre>defmod Fenster_monitoring monitoring .*:(open|tilted) .*:closed <pre>defmod Fenster_monitoring monitoring .*:(open|tilted) .*:closed
attr Fenster_monitoring errorReturn {return unless(@errors);;\ attr Fenster_monitoring errorReturn {return if !@errors;;\
$_ = AttrVal($_, "alias", $_) foreach(@errors);;\ $_ = AttrVal($_, 'alias', $_) for @errors;;\
return("Das Fenster \"$errors[0]\" ist schon l&auml;nger ge&ouml;ffnet.") if(int(@errors) == 1);;\ return("Das Fenster \"$errors[0]\" ist schon l&auml;nger ge&ouml;ffnet.") if(int(@errors) == 1);;\
@errors = sort {lc($a) cmp lc($b)} @errors;;\ @errors = sort {lc($a) cmp lc($b)} @errors;;\
return(join("\n - ", "Die folgenden ".@errors." Fenster sind schon l&auml;nger ge&ouml;ffnet:", @errors))\ return(join("\n - ", "Die folgenden ".@errors." Fenster sind schon l&auml;nger ge&ouml;ffnet:", @errors))\
} }
attr Fenster_monitoring errorWait {AttrVal($name, "winOpenTimer", 60*10)} attr Fenster_monitoring errorWait {AttrVal($name, "winOpenTimer", 60*10)}
attr Fenster_monitoring warningReturn {return unless(@warnings);;\ attr Fenster_monitoring warningReturn {return if !@warnings;;\
$_ = AttrVal($_, "alias", $_) foreach(@warnings);;\ $_ = AttrVal($_, 'alias', $_) for @warnings;;\
return("Das Fenster \"$warnings[0]\" ist seit kurzem ge&ouml;ffnet.") if(int(@warnings) == 1);;\ return("Das Fenster \"$warnings[0]\" ist seit kurzem ge&ouml;ffnet.") if(int(@warnings) == 1);;\
@warnings = sort {lc($a) cmp lc($b)} @warnings;;\ @warnings = sort {lc($a) cmp lc($b)} @warnings;;\
return(join("\n - ", "Die folgenden ".@warnings." Fenster sind seit kurzem ge&ouml;ffnet:", @warnings))\ return(join("\n - ", "Die folgenden ".@warnings." Fenster sind seit kurzem ge&ouml;ffnet:", @warnings))\
@ -931,15 +920,15 @@ attr Fenster_monitoring warningReturn {return unless(@warnings);;\
<li> <li>
<b>Battery monitoring</b><br> <b>Battery monitoring</b><br>
<pre>defmod Batterie_monitoring monitoring .*:battery:.low .*:battery:.ok <pre>defmod Batterie_monitoring monitoring .*:battery:.low .*:battery:.ok
attr Batterie_monitoring errorReturn {return unless(@errors);;\ attr Batterie_monitoring errorReturn {return if !@errors;;\
$_ = AttrVal($_, "alias", $_) foreach(@errors);;\ $_ = AttrVal($_, 'alias', $_) for @errors;;\
return("Bei dem Ger&auml;t \"$errors[0]\" muss die Batterie gewechselt werden.") if(int(@errors) == 1);;\ return("Bei dem Ger&auml;t \"$errors[0]\" muss die Batterie gewechselt werden.") if(int(@errors) == 1);;\
@errors = sort {lc($a) cmp lc($b)} @errors;;\ @errors = sort {lc($a) cmp lc($b)} @errors;;\
return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten muss die Batterie gewechselt werden:", @errors))\ return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten muss die Batterie gewechselt werden:", @errors))\
} }
attr Batterie_monitoring errorWait 60*60*24*14 attr Batterie_monitoring errorWait 60*60*24*14
attr Batterie_monitoring warningReturn {return unless(@warnings);;\ attr Batterie_monitoring warningReturn {return if !@warnings;;\
$_ = AttrVal($_, "alias", $_) foreach(@warnings);;\ $_ = AttrVal($_, 'alias', $_) for @warnings;;\
return("Bei dem Ger&auml;t \"$warnings[0]\" muss die Batterie demn&auml;chst gewechselt werden.") if(int(@warnings) == 1);;\ return("Bei dem Ger&auml;t \"$warnings[0]\" muss die Batterie demn&auml;chst gewechselt werden.") if(int(@warnings) == 1);;\
@warnings = sort {lc($a) cmp lc($b)} @warnings;;\ @warnings = sort {lc($a) cmp lc($b)} @warnings;;\
return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten muss die Batterie demn&auml;chst gewechselt werden:", @warnings))\ return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten muss die Batterie demn&auml;chst gewechselt werden:", @warnings))\
@ -955,15 +944,15 @@ attr Batterie_monitoring warningReturn {return unless(@warnings);;\
<li> <li>
<b>Activity Monitor</b><br> <b>Activity Monitor</b><br>
<pre>defmod Activity_monitoring monitoring .*:.* <pre>defmod Activity_monitoring monitoring .*:.*
attr Activity_monitoring errorReturn {return unless(@errors);;\ attr Activity_monitoring errorReturn {return if !@errors;;\
$_ = AttrVal($_, "alias", $_) foreach(@errors);;\ $_ = AttrVal($_, 'alias', $_) for @errors;;\
return("Das Ger&auml;t \"$errors[0]\" hat sich seit mehr als 24 Stunden nicht mehr gemeldet.") if(int(@errors) == 1);;\ return("Das Ger&auml;t \"$errors[0]\" hat sich seit mehr als 24 Stunden nicht mehr gemeldet.") if(int(@errors) == 1);;\
@errors = sort {lc($a) cmp lc($b)} @errors;;\ @errors = sort {lc($a) cmp lc($b)} @errors;;\
return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten haben sich seit mehr als 24 Stunden nicht mehr gemeldet:", @errors))\ return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten haben sich seit mehr als 24 Stunden nicht mehr gemeldet:", @errors))\
} }
attr Activity_monitoring errorWait 60*60*24 attr Activity_monitoring errorWait 60*60*24
attr Activity_monitoring warningReturn {return unless(@warnings);;\ attr Activity_monitoring warningReturn {return if !@warnings;;\
$_ = AttrVal($_, "alias", $_) foreach(@warnings);;\ $_ = AttrVal($_, 'alias', $_) for @warnings;;\
return("Das Ger&auml;t \"$warnings[0]\" hat sich seit mehr als 12 Stunden nicht mehr gemeldet.") if(int(@warnings) == 1);;\ return("Das Ger&auml;t \"$warnings[0]\" hat sich seit mehr als 12 Stunden nicht mehr gemeldet.") if(int(@warnings) == 1);;\
@warnings = sort {lc($a) cmp lc($b)} @warnings;;\ @warnings = sort {lc($a) cmp lc($b)} @warnings;;\
return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten haben sich seit mehr als 12 Stunden nicht mehr gemeldet:", @warnings))\ return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten haben sich seit mehr als 12 Stunden nicht mehr gemeldet:", @warnings))\
@ -982,11 +971,11 @@ attr Activity_monitoring warningWait 60*60*12</pre>
<b>Regular maintenance (for example changing the table water filter)</b> <b>Regular maintenance (for example changing the table water filter)</b>
<br> <br>
<pre>defmod Wasserfilter_monitoring monitoring Wasserfilter_DashButton:.*:.short <pre>defmod Wasserfilter_monitoring monitoring Wasserfilter_DashButton:.*:.short
attr Wasserfilter_monitoring errorReturn {return unless(@errors);;\ attr Wasserfilter_monitoring errorReturn {return if !@errors;;\
return "Der Wasserfilter muss gewechselt werden.";;\ return "Der Wasserfilter muss gewechselt werden.";;\
} }
attr Wasserfilter_monitoring errorWait 60*60*24*30 attr Wasserfilter_monitoring errorWait 60*60*24*30
attr Wasserfilter_monitoring warningReturn {return unless(@warnings);;\ attr Wasserfilter_monitoring warningReturn {return if !@warnings;;\
return "Der Wasserfilter muss demn&auml;chst gewechselt werden.";;\ return "Der Wasserfilter muss demn&auml;chst gewechselt werden.";;\
} }
attr Wasserfilter_monitoring warningWait 60*60*24*25</pre> attr Wasserfilter_monitoring warningWait 60*60*24*25</pre>
@ -1015,7 +1004,7 @@ attr putzen_monitoring errorFuncAdd {$event =~ m/^(.+):/;;\
$name = $1;;\ $name = $1;;\
return 1;;\ return 1;;\
} }
attr putzen_monitoring errorReturn {return unless(@errors);;\ attr putzen_monitoring errorReturn {return if !@errors;;\
return("Der Raum \"$errors[0]\" muss wieder geputzt werden.") if(int(@errors) == 1);;\ return("Der Raum \"$errors[0]\" muss wieder geputzt werden.") if(int(@errors) == 1);;\
return(join("\n - ", "Die folgenden Räume müssen wieder geputzt werden:", @errors))\ return(join("\n - ", "Die folgenden Räume müssen wieder geputzt werden:", @errors))\
} }
@ -1043,7 +1032,7 @@ attr BeamerFilter_monitoring errorFuncAdd {return 1\
);;\ );;\
return;;\ return;;\
} }
attr BeamerFilter_monitoring errorFuncRemove {return unless($removeMatch);;\ attr BeamerFilter_monitoring errorFuncRemove {return if !$removeMatch;;\
$name = "Beamer_HourCounter";;\ $name = "Beamer_HourCounter";;\
fhem(\ fhem(\
"setreading $name pulseTimeService "\ "setreading $name pulseTimeService "\
@ -1052,7 +1041,7 @@ attr BeamerFilter_monitoring errorFuncRemove {return unless($removeMatch);;\
return 1;;\ return 1;;\
} }
attr BeamerFilter_monitoring errorInterval 60*60*200 attr BeamerFilter_monitoring errorInterval 60*60*200
attr BeamerFilter_monitoring errorReturn {return unless(@errors);;\ attr BeamerFilter_monitoring errorReturn {return if !@errors;;\
return "Der Filter vom Beamer muss gereinigt werden.";;\ return "Der Filter vom Beamer muss gereinigt werden.";;\
} }
attr BeamerFilter_monitoring warningFuncAdd {return} attr BeamerFilter_monitoring warningFuncAdd {return}
@ -1247,10 +1236,10 @@ attr BeamerFilter_monitoring warningFuncRemove {return}</pre>
</a> </a>
</li> </li>
<a id="monitoring-attr-blacklist"></a><li> <a id="monitoring-attr-blacklist"></a><li>
<code>blacklist</code><br> <code>blacklist &lt;devspec list&gt;</code><br>
Durch Leerzeichen getrennte Liste von devspecs die ignoriert werden.<br> Durch Leerzeichen getrennte Liste von devspecs, die ignoriert werden.<br>
Wenn das Attribut gesetzt wird werden alle Geräte die durch die Wenn das Attribut gesetzt wird, werden alle Geräte von beiden Listen gelöscht,
devspecs definiert sind von beiden Listen gelöscht. die durch die devspecs definiert sind .
</li> </li>
<a id="monitoring-attr-disable"></a><li> <a id="monitoring-attr-disable"></a><li>
<code>disable (1|0)</code><br> <code>disable (1|0)</code><br>
@ -1387,11 +1376,10 @@ attr BeamerFilter_monitoring warningFuncRemove {return}</pre>
Wie errorReturn, nur f&uuml;r die warning-Liste. Wie errorReturn, nur f&uuml;r die warning-Liste.
</li> </li>
<a id="monitoring-attr-whitelist"></a><li> <a id="monitoring-attr-whitelist"></a><li>
<code>whitelist {&lt;perl code&gt;}</code><br> <code>whitelist &lt;devspec list&gt;</code><br>
Durch Leerzeichen getrennte Liste von devspecs die erlaubt sind Durch Leerzeichen getrennte Liste von devspecs die erlaubt sind.<br>
werden.<br> Wenn das Attribut gesetzt wird, werden alle Geräte von beiden Listen
Wenn das Attribut gesetzt wird werden alle Geräte die nicht durch die gelöscht, die nicht durch die devspecs definiert sind .
devspecs definiert sind von beiden Listen gelöscht.
</li> </li>
<li> <li>
<a href="#readingFnAttributes"> <a href="#readingFnAttributes">
@ -1418,15 +1406,15 @@ attr BeamerFilter_monitoring warningFuncRemove {return}</pre>
</b> </b>
<br> <br>
<pre>defmod Fenster_monitoring monitoring .*:(open|tilted) .*:closed <pre>defmod Fenster_monitoring monitoring .*:(open|tilted) .*:closed
attr Fenster_monitoring errorReturn {return unless(@errors);;\ attr Fenster_monitoring errorReturn {return if !@errors;;\
$_ = AttrVal($_, "alias", $_) foreach(@errors);;\ $_ = AttrVal($_, 'alias', $_) for @errors;;\
return("Das Fenster \"$errors[0]\" ist schon l&auml;nger ge&ouml;ffnet.") if(int(@errors) == 1);;\ return("Das Fenster \"$errors[0]\" ist schon l&auml;nger ge&ouml;ffnet.") if(int(@errors) == 1);;\
@errors = sort {lc($a) cmp lc($b)} @errors;;\ @errors = sort {lc($a) cmp lc($b)} @errors;;\
return(join("\n - ", "Die folgenden ".@errors." Fenster sind schon l&auml;nger ge&ouml;ffnet:", @errors))\ return(join("\n - ", "Die folgenden ".@errors." Fenster sind schon l&auml;nger ge&ouml;ffnet:", @errors))\
} }
attr Fenster_monitoring errorWait {AttrVal($name, "winOpenTimer", 60*10)} attr Fenster_monitoring errorWait {AttrVal($name, 'winOpenTimer', 60*10)}
attr Fenster_monitoring warningReturn {return unless(@warnings);;\ attr Fenster_monitoring warningReturn {return if !@warnings;;\
$_ = AttrVal($_, "alias", $_) foreach(@warnings);;\ $_ = AttrVal($_, 'alias', $_) for @warnings;;\
return("Das Fenster \"$warnings[0]\" ist seit kurzem ge&ouml;ffnet.") if(int(@warnings) == 1);;\ return("Das Fenster \"$warnings[0]\" ist seit kurzem ge&ouml;ffnet.") if(int(@warnings) == 1);;\
@warnings = sort {lc($a) cmp lc($b)} @warnings;;\ @warnings = sort {lc($a) cmp lc($b)} @warnings;;\
return(join("\n - ", "Die folgenden ".@warnings." Fenster sind seit kurzem ge&ouml;ffnet:", @warnings))\ return(join("\n - ", "Die folgenden ".@warnings." Fenster sind seit kurzem ge&ouml;ffnet:", @warnings))\
@ -1445,16 +1433,16 @@ attr Fenster_monitoring warningReturn {return unless(@warnings);;\
<li> <li>
<b>Batterie&uuml;berwachung</b><br> <b>Batterie&uuml;berwachung</b><br>
<pre>defmod Batterie_monitoring monitoring .*:battery:.low .*:battery:.ok <pre>defmod Batterie_monitoring monitoring .*:battery:.low .*:battery:.ok
attr Batterie_monitoring errorReturn {return unless(@errors);;\ attr Batterie_monitoring errorReturn {return if !@errors;;\
$_ = AttrVal($_, "alias", $_) foreach(@errors);;\ $_ = AttrVal($_, 'alias', $_) for @errors;;\
return("Bei dem Ger&auml;t \"$errors[0]\" muss die Batterie gewechselt werden.") if(int(@errors) == 1);;\ return("Bei dem Ger&auml;t \"$errors[0]\" muss die Batterie gewechselt werden.") if(int(@errors) == 1);;\
@errors = sort {lc($a) cmp lc($b)} @errors;;\ @errors = sort {lc($a) cmp lc($b)} @errors;;\
return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten muss die Batterie gewechselt werden:", @errors))\ return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten muss die Batterie gewechselt werden:", @errors))\
} }
attr Batterie_monitoring errorWait 60*60*24*14 attr Batterie_monitoring errorWait 60*60*24*14
attr Batterie_monitoring warningReturn {return unless(@warnings);;\ attr Batterie_monitoring warningReturn {return if !@warnings;;\
$_ = AttrVal($_, "alias", $_) foreach(@warnings);;\ $_ = AttrVal($_, 'alias', $_) for @warnings;;\
return("Bei dem Ger&auml;t \"$warnings[0]\" muss die Batterie demn&auml;chst gewechselt werden.") if(int(@warnings) == 1);;\ return("Bei dem Ger&auml;t \"$warnings[0]\" muss die Batterie demn&auml;chst gewechselt werden.") if int @warnings == 1;;\
@warnings = sort {lc($a) cmp lc($b)} @warnings;;\ @warnings = sort {lc($a) cmp lc($b)} @warnings;;\
return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten muss die Batterie demn&auml;chst gewechselt werden:", @warnings))\ return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten muss die Batterie demn&auml;chst gewechselt werden:", @warnings))\
}</pre> }</pre>
@ -1471,15 +1459,15 @@ attr Batterie_monitoring warningReturn {return unless(@warnings);;\
<li> <li>
<b>Activity Monitor</b><br> <b>Activity Monitor</b><br>
<pre>defmod Activity_monitoring monitoring .*:.* <pre>defmod Activity_monitoring monitoring .*:.*
attr Activity_monitoring errorReturn {return unless(@errors);;\ attr Activity_monitoring errorReturn {return if !@errors;;\
$_ = AttrVal($_, "alias", $_) foreach(@errors);;\ $_ = AttrVal($_, 'alias', $_) for @errors;;\
return("Das Ger&auml;t \"$errors[0]\" hat sich seit mehr als 24 Stunden nicht mehr gemeldet.") if(int(@errors) == 1);;\ return("Das Ger&auml;t \"$errors[0]\" hat sich seit mehr als 24 Stunden nicht mehr gemeldet.") if(int(@errors) == 1);;\
@errors = sort {lc($a) cmp lc($b)} @errors;;\ @errors = sort {lc($a) cmp lc($b)} @errors;;\
return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten haben sich seit mehr als 24 Stunden nicht mehr gemeldet:", @errors))\ return(join("\n - ", "Die folgenden ".@errors." Ger&auml;ten haben sich seit mehr als 24 Stunden nicht mehr gemeldet:", @errors))\
} }
attr Activity_monitoring errorWait 60*60*24 attr Activity_monitoring errorWait 60*60*24
attr Activity_monitoring warningReturn {return unless(@warnings);;\ attr Activity_monitoring warningReturn {return if !@warnings;;\
$_ = AttrVal($_, "alias", $_) foreach(@warnings);;\ $_ = AttrVal($_, 'alias', $_) for @warnings;;\
return("Das Ger&auml;t \"$warnings[0]\" hat sich seit mehr als 12 Stunden nicht mehr gemeldet.") if(int(@warnings) == 1);;\ return("Das Ger&auml;t \"$warnings[0]\" hat sich seit mehr als 12 Stunden nicht mehr gemeldet.") if(int(@warnings) == 1);;\
@warnings = sort {lc($a) cmp lc($b)} @warnings;;\ @warnings = sort {lc($a) cmp lc($b)} @warnings;;\
return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten haben sich seit mehr als 12 Stunden nicht mehr gemeldet:", @warnings))\ return(join("\n - ", "Die folgenden ".@warnings." Ger&auml;ten haben sich seit mehr als 12 Stunden nicht mehr gemeldet:", @warnings))\
@ -1501,11 +1489,11 @@ attr Activity_monitoring warningWait 60*60*12</pre>
</b> </b>
<br> <br>
<pre>defmod Wasserfilter_monitoring monitoring Wasserfilter_DashButton:.*:.short <pre>defmod Wasserfilter_monitoring monitoring Wasserfilter_DashButton:.*:.short
attr Wasserfilter_monitoring errorReturn {return unless(@errors);;\ attr Wasserfilter_monitoring errorReturn {return if !@errors;;\
return "Der Wasserfilter muss gewechselt werden.";;\ return "Der Wasserfilter muss gewechselt werden.";;\
} }
attr Wasserfilter_monitoring errorWait 60*60*24*30 attr Wasserfilter_monitoring errorWait 60*60*24*30
attr Wasserfilter_monitoring warningReturn {return unless(@warnings);;\ attr Wasserfilter_monitoring warningReturn {return if !@warnings;;\
return "Der Wasserfilter muss demn&auml;chst gewechselt werden.";;\ return "Der Wasserfilter muss demn&auml;chst gewechselt werden.";;\
} }
attr Wasserfilter_monitoring warningWait 60*60*24*25</pre> attr Wasserfilter_monitoring warningWait 60*60*24*25</pre>
@ -1537,7 +1525,7 @@ attr putzen_monitoring errorFuncAdd {$event =~ m/^(.+):/;;\
$name = $1;;\ $name = $1;;\
return 1;;\ return 1;;\
} }
attr putzen_monitoring errorReturn {return unless(@errors);;\ attr putzen_monitoring errorReturn {return if !@errors;;\
return("Der Raum \"$errors[0]\" muss wieder geputzt werden.") if(int(@errors) == 1);;\ return("Der Raum \"$errors[0]\" muss wieder geputzt werden.") if(int(@errors) == 1);;\
return(join("\n - ", "Die folgenden Räume müssen wieder geputzt werden:", @errors))\ return(join("\n - ", "Die folgenden Räume müssen wieder geputzt werden:", @errors))\
} }
@ -1566,7 +1554,7 @@ attr BeamerFilter_monitoring errorFuncAdd {return 1\
);;\ );;\
return;;\ return;;\
} }
attr BeamerFilter_monitoring errorFuncRemove {return unless($removeMatch);;\ attr BeamerFilter_monitoring errorFuncRemove {return if !$removeMatch;;\
$name = "Beamer_HourCounter";;\ $name = "Beamer_HourCounter";;\
fhem(\ fhem(\
"setreading $name pulseTimeService "\ "setreading $name pulseTimeService "\
@ -1575,7 +1563,7 @@ attr BeamerFilter_monitoring errorFuncRemove {return unless($removeMatch);;\
return 1;;\ return 1;;\
} }
attr BeamerFilter_monitoring errorInterval 60*60*200 attr BeamerFilter_monitoring errorInterval 60*60*200
attr BeamerFilter_monitoring errorReturn {return unless(@errors);;\ attr BeamerFilter_monitoring errorReturn {return if !@errors;;\
return "Der Filter vom Beamer muss gereinigt werden.";;\ return "Der Filter vom Beamer muss gereinigt werden.";;\
} }
attr BeamerFilter_monitoring warningFuncAdd {return} attr BeamerFilter_monitoring warningFuncAdd {return}