22_HOMEMODE: v1.4.2 - add attr HomeAutoPresenceSuppressMode, add placeholder %DESCRIPTION%, minor fixes and improvements

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@15908 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
deespe 2018-01-16 21:40:30 +00:00
parent 06af540ed9
commit 9b7ad372b6

View File

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