diff --git a/FHEM/22_HOMEMODE.pm b/FHEM/22_HOMEMODE.pm index 0e956b646..87d1d8f57 100644 --- a/FHEM/22_HOMEMODE.pm +++ b/FHEM/22_HOMEMODE.pm @@ -16,7 +16,7 @@ use Time::HiRes qw(gettimeofday); use HttpUtils; use vars qw{%attr %defs %modules $FW_CSRF}; -my $HOMEMODE_version = "1.4.1"; +my $HOMEMODE_version = "1.4.2"; my $HOMEMODE_Daytimes = "05:00|morning 10:00|day 14:00|afternoon 18:00|evening 23:00|night"; my $HOMEMODE_Seasons = "03.01|spring 06.01|summer 09.01|autumn 12.01|winter"; my $HOMEMODE_UserModes = "gotosleep,awoken,asleep"; @@ -171,6 +171,7 @@ sub HOMEMODE_Notify($$) } CommandAttr(undef,"$dev room ".AttrVal($name,"HomeAtTmpRoom","")) if ($dev =~ /^atTmp_.*_$name$/ && HOMEMODE_ID($dev,"at") && AttrVal($name,"HomeAtTmpRoom","")); + last; } } elsif (grep /^REREADCFG|MODIFIED\s$name$/,@{$events}) @@ -260,6 +261,7 @@ sub HOMEMODE_Notify($$) { next unless ($evt =~ /^($read):\s(.*)$/); HOMEMODE_PowerEnergy($hash,$devname,$1,(split " ",$2)[0]); + last; } } elsif ($hash->{SENSORSSMOKE} && grep(/^$devname$/,split /,/,$hash->{SENSORSSMOKE})) @@ -269,6 +271,7 @@ sub HOMEMODE_Notify($$) { next unless ($evt =~ /^$read:\s(.*)$/); HOMEMODE_Smoke($hash,$devname,$1); + last; } } else @@ -292,6 +295,7 @@ sub HOMEMODE_Notify($$) { next unless ($evt =~ /^$read:\s(.*)$/); HOMEMODE_Luminance($hash,$devname,(split " ",$1)[0]); + last; } } } @@ -330,6 +334,7 @@ sub HOMEMODE_Notify($$) my $val = (split " ",$1)[0]; readingsSingleUpdate($hash,"humidity",$val,1); HOMEMODE_ReadingTrend($hash,"humidity",$val); + last; } } if (AttrVal($name,"HomeSensorWindspeed",undef) && $devname eq (split /:/,AttrVal($name,"HomeSensorWindspeed",""))[0]) @@ -343,6 +348,7 @@ sub HOMEMODE_Notify($$) my $val = (split " ",$1)[0]; readingsSingleUpdate($hash,"wind",$val,1); HOMEMODE_ReadingTrend($hash,"wind",$val); + last; } } } @@ -357,6 +363,7 @@ sub HOMEMODE_Notify($$) my $val = (split " ",$1)[0]; readingsSingleUpdate($hash,"pressure",$val,1); HOMEMODE_ReadingTrend($hash,"pressure",$val); + last; } } } @@ -368,21 +375,24 @@ sub HOMEMODE_Notify($$) { my $regex = lc($_); $regex =~ s/^(rr_|rg_)//; - next if (lc($devname) !~ /$regex/); + next unless (lc($devname) =~ /$regex/); $resident = $_; $residentregex = $regex; + last; } return if (!$resident); $hash->{helper}{lar} = $resident; + my $residentstate = ReadingsVal($resident,"state",""); + my $suppressstate = "[gn]one|absent"; if (ReadingsVal($devname,"presence","") !~ /^maybe/) { my @presentdevicespresent; foreach my $device (devspec2array("TYPE=$prestype:FILTER=presence=^(maybe.)?(absent|present|appeared|disappeared)")) { - next if (lc($device) !~ /$residentregex/); + next unless (lc($device) =~ /$residentregex/); push @presentdevicespresent,$device if (ReadingsVal($device,"presence","") =~ /^(present|appeared|maybe.absent)$/); } - if (grep /^.*:\s(present|appeared)$/,@{$events}) + if (grep /^presence:\s(present|appeared)$/,@{$events}) { readingsBeginUpdate($hash); readingsBulkUpdate($hash,"lastActivityByPresenceDevice",$devname); @@ -392,12 +402,12 @@ sub HOMEMODE_Notify($$) push @commands,AttrVal($name,"HomeCMDpresence-present-$resident-device","") if (AttrVal($name,"HomeCMDpresence-present-$resident-device",undef)); push @commands,AttrVal($name,"HomeCMDpresence-present-$resident-$devname","") if (AttrVal($name,"HomeCMDpresence-present-$resident-$devname",undef)); if (@presentdevicespresent >= AttrNum($name,"HomePresenceDevicePresentCount-$resident",1) - && ReadingsVal($resident,"state","") =~ /^(absent|[gn]one)$/) + && $residentstate =~ /^($suppressstate)$/) { CommandSet(undef,"$resident:FILTER=state!=home state home"); } } - elsif (grep /^.*:\s(absent|disappeared)$/,@{$events}) + elsif (grep /^presence:\s(absent|disappeared)$/,@{$events}) { readingsBeginUpdate($hash); readingsBulkUpdate($hash,"lastActivityByPresenceDevice",$devname); @@ -409,8 +419,9 @@ sub HOMEMODE_Notify($$) my $devcount = 1; $devcount = @{$hash->{helper}{presdevs}{$resident}} if ($hash->{helper}{presdevs}{$resident}); my $presdevsabsent = $devcount - scalar @presentdevicespresent; + $suppressstate .= "|".AttrVal($name,"HomeAutoPresenceSuppressState","") if (AttrVal($name,"HomeAutoPresenceSuppressState","")); if ($presdevsabsent >= AttrNum($name,"HomePresenceDeviceAbsentCount-$resident",1) - && ReadingsVal($resident,"state","absent") !~ /^(absent|gone|none)$/) + && $residentstate !~ /^($suppressstate)$/) { CommandSet(undef,"$resident:FILTER=state!=absent state absent"); } @@ -443,6 +454,7 @@ sub HOMEMODE_Notify($$) } @low = @lown; } + last; } readingsBeginUpdate($hash); if (@low) @@ -536,7 +548,7 @@ sub HOMEMODE_updateInternals($;$$) my @residentspresdevs; foreach my $p (@presdevs) { - next if (lc($p) !~ /$short/); + next unless (lc($p) =~ /$short/); push @residentspresdevs,$p; push @allMonitoredDevices,$p if (!grep /^$p$/,@allMonitoredDevices); } @@ -1171,6 +1183,7 @@ sub HOMEMODE_RESIDENTS($;$) next unless ($_ =~ /^state:.(.*)$/ && grep /^$1$/,split /,/,$HOMEMODE_UserModesAll); $mode = $1; Log3 $name,5,"$name: HOMEMODE_RESIDENTS mode: $mode"; + last; } } if ($mode && $devtype eq "RESIDENTS") @@ -1271,6 +1284,7 @@ sub HOMEMODE_Attributes($) push @attribs,"HomeAutoAwoken"; push @attribs,"HomeAutoDaytime:0,1"; push @attribs,"HomeAutoPresence:1,0"; + push @attribs,"HomeAutoPresenceSuppressState"; push @attribs,"HomeCMDalarmSmoke:textField-long"; push @attribs,"HomeCMDalarmSmoke-on:textField-long"; push @attribs,"HomeCMDalarmSmoke-off:textField-long"; @@ -1471,7 +1485,7 @@ sub HOMEMODE_userattr($) foreach my $resident (split /,/,$hash->{RESIDENTS}) { my $devtype = HOMEMODE_ID($resident,"ROOMMATE|GUEST") ? $defs{$resident}->{TYPE} : ""; - next if (!$devtype); + next unless ($devtype); if ($adv) { my $states = "absent"; @@ -1639,6 +1653,13 @@ sub HOMEMODE_Attr(@) return $err if ($err); } } + elsif ($attr_name =~ /^HomeAutoPresenceSuppressState$/ && $init_done) + { + $trans = $HOMEMODE_de? + "Ungültiger Wert $attr_value für Attribut $attr_name. Es wird wenigstens ein Wert oder maximal 3 Pipe separierte Werte benötigt! z.B. asleep|gotosleep": + "Invalid value $attr_value for attribute $attr_name. You have to provide at least one value or max 3 values pipe separated, e.g. asleep|gotosleep"; + return $trans if ($attr_value !~ /^(asleep|gotosleep|awoken)(\|(asleep|gotosleep|awoken)){0,2}$/); + } elsif ($attr_name =~ /^HomeEvents(Holiday|Calendar)Devices$/ && $init_done) { my @wd; @@ -1677,7 +1698,7 @@ sub HOMEMODE_Attr(@) elsif ($attr_name =~ /^(HomeSensorsContactValues|HomeSensorsMotionValues|HomeSensorsSmokeValue)$/) { $trans = $HOMEMODE_de? - "Ungültiger Wert $attr_value für Attribut $attr_name. Es wird wenigstens ein Wert oder mehrere Pipe separierte Readings benötigt! z.B. open|tilted|on": + "Ungültiger Wert $attr_value für Attribut $attr_name. Es wird wenigstens ein Wert oder mehrere Pipe separierte Werte benötigt! z.B. open|tilted|on": "Invalid value $attr_value for attribute $attr_name. You have to provide at least one value or more values pipe separated, e.g. open|tilted|on"; return $trans if ($attr_value !~ /^[\w\-\+\*\.\(\)]+(\|[\w\-\+\*\.\(\)]+){0,}$/i); } @@ -2278,7 +2299,7 @@ sub HOMEMODE_serializeCMD($@) my @newcmd; foreach (split /\n+/,$cmd) { - next if ($_ =~ /^\s*(#|$)/); + next unless ($_ !~ /^\s*(#|$)/); $_ =~ s/\s{2,}/ /g; push @newcmd,$_; } @@ -2624,10 +2645,10 @@ sub HOMEMODE_Luminance($;$$) my @sensorsa; foreach (@sensors) { - next if (HOMEMODE_IsDisabled($hash,$_)); + next unless (!HOMEMODE_IsDisabled($hash,$_)); push @sensorsa,$_; my $val = ReadingsNum($_,$read,0); - next if ($val < 0); + next unless ($val > 0); $lum += $val if (!$dev || $dev ne $_); } my $lumval = defined $lum ? int ($lum / scalar @sensorsa) : undef; @@ -3047,11 +3068,16 @@ sub HOMEMODE_EventCommands($$$$) { $event =~ s/[\s ]//g; my $summary; - foreach (Calendar_GetEvents($defs{$cal},time(),undef,undef)) + my $description = ""; + my $t = time(); + foreach (Calendar_GetEvents($defs{$cal},$t,undef,undef)) { - next if ($_->{uid} ne $event); + next unless ($_->{uid} eq $event); $summary = $_->{summary}; + $description = $_->{description}; + last; } + next unless $summary; $summary =~ s/[,;]//g; Log3 $name,5,"Calendar_GetEvents event: $summary"; my $sum = $summary; @@ -3084,11 +3110,13 @@ sub HOMEMODE_EventCommands($$$$) { $_ =~ s/%EVENT%/$summary/gm; $_ =~ s/%PREVEVENT%/none/gm; + $_ =~ s/%DESCRIPTION%/$description/gm; } elsif ($read eq "end") { $_ =~ s/%EVENT%/none/gm; $_ =~ s/%PREVEVENT%/$summary/gm; + $_ =~ s/%DESCRIPTION%/$description/gm; } } } @@ -3116,6 +3144,7 @@ sub HOMEMODE_UWZCommands($$) next unless (grep /^WarnCount:\s[0-9]$/,$evt); $count = $evt; $count =~ s/^WarnCount:\s//; + last; } if (defined $count) { @@ -3162,7 +3191,7 @@ sub HOMEMODE_PowerEnergy($;$$$) { foreach (split /,/,$hash->{SENSORSENERGY}) { - next if ($_ eq $trigger); + next unless ($_ ne $trigger); my $v = ReadingsNum($_,$read,0); $val += $v if ($v && $v > 0); } @@ -3325,7 +3354,7 @@ sub HOMEMODE_CalendarEvents($$) my (undef,@holidayfile) = FileRead($fname); foreach (@holidayfile) { - next if ($_ =~ /^\s*(#|$)/); + next unless ($_ !~ /^\s*(#|$)/); my @parts = split; my $part = $parts[0] =~ /^(1|2)$/ ? 2 : $parts[0] == 3 ? 4 : $parts[0] == 4 ? 3 : 5; for (my $p = 0; $p < $part; $p++) @@ -3338,7 +3367,8 @@ sub HOMEMODE_CalendarEvents($$) } else { - foreach (Calendar_GetEvents($defs{$cal},time(),undef,undef)) + my $t = time(); + foreach (Calendar_GetEvents($defs{$cal},$t,undef,undef)) { my $evt = $_->{summary}; Log3 $name,5,"Calendar_GetEvents event: $evt"; @@ -3730,6 +3760,13 @@ sub HOMEMODE_Details($$$) values 0 or 1, value 0 disables auto presence
default: 0 +
  • + HomeAutoPresenceSuppressState
    + suppress mode(s) for HomeAutoPresence (p.e. gotosleep|asleep)
    + if set this/these mode(s) of a resident will not affect the residents to change to absent by its presence device
    + p.e. for misteriously disappearing presence devices in the middle of the night
    + default: +
  • HomeCMDalarmSmoke
    cmds to execute on any smoke alarm state @@ -5145,13 +5182,17 @@ sub HOMEMODE_Details($$$) %CALENDAR%
    name of the calendar
  • +
  • + %DESCRIPTION%
    + description of current event of the calendar (not applicable for holiday devices) +
  • %EVENT%
    - current event of the calendar + summary of current event of the calendar
  • %PREVEVENT%
    - previous event of the calendar + summary of previous event of the calendar
  • These placeholders can only be used within HomeCMDdeviceDisable and HomeCMDdeviceEnable attributes