From 2bbf7fce4e100befc3fc0cb752041490db3a762c Mon Sep 17 00:00:00 2001 From: DeeSPe Date: Wed, 7 Dec 2022 21:19:57 +0000 Subject: [PATCH] 22_HOMEMODE: v1.5.6 - change from double quotes to single quotes where possible, substitute problematic characters for regex matching with dashes within cal events, add more logging for PRESENCE devices, add attributes HomeCMDtwilight-sr_naut and HomeCMDtwilight-ss_naut, fix unassigned variable, fix humidity reading from sensor gets overwritten by weather device, remove helper for external humidity sensor git-svn-id: https://svn.fhem.de/fhem/trunk@26813 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/22_HOMEMODE.pm | 2920 +++++++++++++++++++------------------- 1 file changed, 1463 insertions(+), 1457 deletions(-) diff --git a/fhem/FHEM/22_HOMEMODE.pm b/fhem/FHEM/22_HOMEMODE.pm index 6d9defb6d..53c9c7d8d 100644 --- a/fhem/FHEM/22_HOMEMODE.pm +++ b/fhem/FHEM/22_HOMEMODE.pm @@ -16,99 +16,99 @@ use Time::HiRes qw(gettimeofday); use HttpUtils; use vars qw{%attr %defs %modules $FW_CSRF}; -my $HOMEMODE_version = "1.5.5"; -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"; -my $HOMEMODE_UserModesAll = "$HOMEMODE_UserModes,home,absent,gone"; -my $HOMEMODE_AlarmModes = "disarm,confirm,armhome,armnight,armaway"; -my $HOMEMODE_Locations = "arrival,home,bed,underway,wayhome"; +my $HOMEMODE_version = '1.5.6'; +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'; +my $HOMEMODE_UserModesAll = $HOMEMODE_UserModes.',home,absent,gone'; +my $HOMEMODE_AlarmModes = 'disarm,confirm,armhome,armnight,armaway'; +my $HOMEMODE_Locations = 'arrival,home,bed,underway,wayhome'; my $HOMEMODE_de; sub HOMEMODE_Initialize($) { my ($hash) = @_; - $hash->{AttrFn} = "HOMEMODE_Attr"; - $hash->{DefFn} = "HOMEMODE_Define"; - $hash->{NotifyFn} = "HOMEMODE_Notify"; - $hash->{GetFn} = "HOMEMODE_Get"; - $hash->{SetFn} = "HOMEMODE_Set"; - $hash->{UndefFn} = "HOMEMODE_Undef"; - $hash->{FW_detailFn} = "HOMEMODE_Details"; - $hash->{AttrList} = HOMEMODE_Attributes($hash)." $readingFnAttributes"; - $hash->{NotifyOrderPrefix} = "51-"; + $hash->{AttrFn} = 'HOMEMODE_Attr'; + $hash->{DefFn} = 'HOMEMODE_Define'; + $hash->{NotifyFn} = 'HOMEMODE_Notify'; + $hash->{GetFn} = 'HOMEMODE_Get'; + $hash->{SetFn} = 'HOMEMODE_Set'; + $hash->{UndefFn} = 'HOMEMODE_Undef'; + $hash->{FW_detailFn} = 'HOMEMODE_Details'; + $hash->{AttrList} = HOMEMODE_Attributes($hash).' '.$readingFnAttributes; + $hash->{NotifyOrderPrefix} = '51-'; $hash->{FW_deviceOverview} = 1; $hash->{FW_addDetailToSummary} = 1; - $hash->{AttrRenameMap} = { "HomeYahooWeatherDevice" => "HomeWeatherDevice" }; + $hash->{AttrRenameMap} = { 'HomeYahooWeatherDevice' => 'HomeWeatherDevice' }; } sub HOMEMODE_Define($$) { my ($hash,$def) = @_; - my @args = split " ",$def; + my @args = split ' ',$def; my ($name,$type,$resdev) = @args; - $HOMEMODE_de = AttrVal("global","language","EN") eq "DE" || AttrVal($name,"HomeLanguage","EN" eq "DE") ? 1 : 0; + $HOMEMODE_de = AttrVal('global','language','EN') eq 'DE' || AttrVal($name,'HomeLanguage','EN' eq 'DE') ? 1 : 0; my $trans; if (@args < 2 || @args > 3) { $trans = $HOMEMODE_de? - "Benutzung: define HOMEMODE [RESIDENTS-MASTER-GERAET]": - "Usage: define HOMEMODE [RESIDENTS-MASTER-DEVICE]"; + 'Benutzung: define HOMEMODE [RESIDENTS-MASTER-GERAET]': + 'Usage: define HOMEMODE [RESIDENTS-MASTER-DEVICE]'; return $trans; } RemoveInternalTimer($hash); if (!$resdev) { my @resdevs; - for (devspec2array("TYPE=RESIDENTS")) + for (devspec2array('TYPE=RESIDENTS')) { push @resdevs,$_; } if (@resdevs == 1) { $trans = $HOMEMODE_de? - "$resdevs[0] existiert nicht": - "$resdevs[0] doesn't exists"; + $resdevs[0].' existiert nicht': + $resdevs[0].' doesn´t exists'; return $trans if (!HOMEMODE_ID($resdevs[0])); $hash->{DEF} = $resdevs[0]; } elsif (@resdevs > 1) { $trans = $HOMEMODE_de? - "Es gibt zu viele RESIDENTS Geräte! Bitte das Master RESIDENTS Gerät angeben! Verfügbare RESIDENTS Geräte:": - "Found too many available RESIDENTS devives! Please specify the RESIDENTS master device! Available RESIDENTS devices:"; - return "$trans ".join(",",@resdevs); + 'Es gibt zu viele RESIDENTS Geräte! Bitte das Master RESIDENTS Gerät angeben! Verfügbare RESIDENTS Geräte:': + 'Found too many available RESIDENTS devives! Please specify the RESIDENTS master device! Available RESIDENTS devices:'; + return "$trans ".join(',',@resdevs); } else { $trans = $HOMEMODE_de? - "Kein RESIDENTS Gerät gefunden! Bitte erst ein RESIDENTS Gerät anlegen und ein paar ROOMMATE/GUEST/PET und ihre korrespondierenden PRESENCE Geräte hinzufügen um Spaß mit diesem Modul zu haben!": - "No RESIDENTS device found! Please define a RESIDENTS device first and add some ROOMMATE/GUEST/PET and their PRESENCE device(s) to have fun with this module!"; + 'Kein RESIDENTS Gerät gefunden! Bitte erst ein RESIDENTS Gerät anlegen und ein paar ROOMMATE/GUEST/PET und ihre korrespondierenden PRESENCE Geräte hinzufügen um Spaß mit diesem Modul zu haben!': + 'No RESIDENTS device found! Please define a RESIDENTS device first and add some ROOMMATE/GUEST/PET and their PRESENCE device(s) to have fun with this module!'; return $trans; } } - $hash->{NOTIFYDEV} = "global"; + $hash->{NOTIFYDEV} = 'global'; if ($init_done && !defined $hash->{OLDDEF}) { - $attr{$name}{devStateIcon} = "absent:user_away:dnd+on\n". - "gone:user_ext_away:dnd+on\n". - "dnd:audio_volume_mute:dnd+off\n". - "gotosleep:scene_sleeping:dnd+on\n". - "asleep:scene_sleeping_alternat:dnd+on\n". - "awoken:weather_sunrise:dnd+on\n". - "home:status_available:dnd+on\n". - "morning:weather_sunrise:dnd+on\n". - "day:weather_sun:dnd+on\n". - "afternoon:weather_summer:dnd+on\n". - "evening:weather_sunset:dnd+on\n". - "night:weather_moon_phases_2:dnd+on"; - $attr{$name}{icon} = "floor"; - $attr{$name}{room} = "HOMEMODE"; - $attr{$name}{webCmd} = "modeAlarm"; + $attr{$name}{devStateIcon} = 'absent:user_away:dnd+on\n'. + 'gone:user_ext_away:dnd+on\n'. + 'dnd:audio_volume_mute:dnd+off\n'. + 'gotosleep:scene_sleeping:dnd+on\n'. + 'asleep:scene_sleeping_alternat:dnd+on\n'. + 'awoken:weather_sunrise:dnd+on\n'. + 'home:status_available:dnd+on\n'. + 'morning:weather_sunrise:dnd+on\n'. + 'day:weather_sun:dnd+on\n'. + 'afternoon:weather_summer:dnd+on\n'. + 'evening:weather_sunset:dnd+on\n'. + 'night:weather_moon_phases_2:dnd+on'; + $attr{$name}{icon} = 'floor'; + $attr{$name}{room} = 'HOMEMODE'; + $attr{$name}{webCmd} = 'modeAlarm'; readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"dnd","off") if (!defined ReadingsVal($name,"dnd",undef)); - readingsBulkUpdate($hash,"anyoneElseAtHome","off") if (!defined ReadingsVal($name,"anyoneElseAtHome",undef)); - readingsBulkUpdate($hash,"panic","off") if (!defined ReadingsVal($name,"panic",undef)); + readingsBulkUpdate($hash,'dnd','off') if (!defined ReadingsVal($name,'dnd',undef)); + readingsBulkUpdate($hash,'anyoneElseAtHome','off') if (!defined ReadingsVal($name,'anyoneElseAtHome',undef)); + readingsBulkUpdate($hash,'panic','off') if (!defined ReadingsVal($name,'panic',undef)); readingsEndUpdate($hash,0); HOMEMODE_updateInternals($hash,1); } @@ -120,10 +120,10 @@ sub HOMEMODE_Undef($$) my ($hash,$arg) = @_; RemoveInternalTimer($hash); my $name = $hash->{NAME}; - if (devspec2array("TYPE=HOMEMODE") == 1) + if (devspec2array('TYPE=HOMEMODE') == 1) { - HOMEMODE_cleanUserattr($hash,AttrVal($name,"HomeSensorsContact","")) if (AttrVal($name,"HomeSensorsContact",undef)); - HOMEMODE_cleanUserattr($hash,AttrVal($name,"HomeSensorsMotion","")) if (AttrVal($name,"HomeSensorsMotion",undef)); + HOMEMODE_cleanUserattr($hash,AttrVal($name,'HomeSensorsContact','')) if (AttrVal($name,'HomeSensorsContact',undef)); + HOMEMODE_cleanUserattr($hash,AttrVal($name,'HomeSensorsMotion','')) if (AttrVal($name,'HomeSensorsMotion',undef)); } return; } @@ -137,26 +137,26 @@ sub HOMEMODE_Notify($$) my $devtype = $dev->{TYPE}; my $events = deviceEvents($dev,1); return if (!$events); - Log3 $name,5,"$name: Events from monitored device $devname: ". join " --- ",@{$events}; - my $prestype = AttrVal($name,"HomePresenceDeviceType","PRESENCE"); + Log3 $name,5,"$name: Events from monitored device $devname: ". join ' --- ',@{$events}; + my $prestype = AttrVal($name,'HomePresenceDeviceType','PRESENCE'); my @commands; - if ($devname eq "global") + if ($devname eq 'global') { if (grep /^INITIALIZED$/,@{$events}) { HOMEMODE_updateInternals($hash); - push @commands,AttrVal($name,"HomeCMDfhemINITIALIZED","") - if (AttrVal($name,"HomeCMDfhemINITIALIZED","")); + push @commands,AttrVal($name,'HomeCMDfhemINITIALIZED','') + if (AttrVal($name,'HomeCMDfhemINITIALIZED','')); } elsif (grep /^SAVE$/,@{$events}) { - push @commands,AttrVal($name,"HomeCMDfhemSAVE","") - if (AttrVal($name,"HomeCMDfhemSAVE","")); + push @commands,AttrVal($name,'HomeCMDfhemSAVE','') + if (AttrVal($name,'HomeCMDfhemSAVE','')); } elsif (grep /^UPDATE$/,@{$events}) { - push @commands,AttrVal($name,"HomeCMDfhemUPDATE","") - if (AttrVal($name,"HomeCMDfhemUPDATE","")); + push @commands,AttrVal($name,'HomeCMDfhemUPDATE','') + if (AttrVal($name,'HomeCMDfhemUPDATE','')); } elsif (grep /^DEFINED/,@{$events}) { @@ -164,14 +164,14 @@ sub HOMEMODE_Notify($$) { next unless ($_ =~ /^DEFINED\s(.+)$/); my $dev = $1; - my $cmd = AttrVal($name,"HomeCMDfhemDEFINED",""); + my $cmd = AttrVal($name,'HomeCMDfhemDEFINED',''); if ($cmd) { $cmd =~ s/%DEFINED%/$dev/gm; push @commands,$cmd; } - CommandAttr(undef,"$dev room ".AttrVal($name,"HomeAtTmpRoom","")) - if ($dev =~ /^atTmp_.+_$name$/ && HOMEMODE_ID($dev,"at") && AttrVal($name,"HomeAtTmpRoom","")); + CommandAttr(undef,"$dev room ".AttrVal($name,'HomeAtTmpRoom','')) + if ($dev =~ /^atTmp_.+_$name$/ && HOMEMODE_ID($dev,'at') && AttrVal($name,'HomeAtTmpRoom','')); last; } } @@ -186,33 +186,33 @@ sub HOMEMODE_Notify($$) { HOMEMODE_RESIDENTS($hash,$devname); } - elsif (AttrVal($name,"HomeWeatherDevice",undef) && $devname eq AttrVal($name,"HomeWeatherDevice","")) + elsif (AttrVal($name,'HomeWeatherDevice',undef) && $devname eq AttrVal($name,'HomeWeatherDevice','')) { HOMEMODE_Weather($hash,$devname); } - elsif (AttrVal($name,"HomeTwilightDevice",undef) && $devname eq AttrVal($name,"HomeTwilightDevice","")) + elsif (AttrVal($name,'HomeTwilightDevice',undef) && $devname eq AttrVal($name,'HomeTwilightDevice','')) { HOMEMODE_Twilight($hash,$devname); } - elsif ((AttrVal($name,"HomeEventsHolidayDevices",undef) - && grep(/^$devname$/,devspec2array(AttrVal($name,"HomeEventsHolidayDevices","")))) + elsif ((AttrVal($name,'HomeEventsHolidayDevices',undef) + && grep(/^$devname$/,devspec2array(AttrVal($name,'HomeEventsHolidayDevices','')))) || - (AttrVal($name,"HomeEventsCalendarDevices",undef) - && grep(/^$devname$/,devspec2array(AttrVal($name,"HomeEventsCalendarDevices",""))))) + (AttrVal($name,'HomeEventsCalendarDevices',undef) + && grep(/^$devname$/,devspec2array(AttrVal($name,'HomeEventsCalendarDevices',''))))) { for my $evt (@{$events}) { - next unless ((HOMEMODE_ID($devname,"Calendar") && $evt =~ /^(start|end):\s(.+)$/) || (HOMEMODE_ID($devname,"holiday") && $evt =~ /^(state):\s(.+)$/)); + next unless ((HOMEMODE_ID($devname,'Calendar') && $evt =~ /^(start|end):\s(.+)$/) || (HOMEMODE_ID($devname,'holiday') && $evt =~ /^(state):\s(.+)$/)); HOMEMODE_EventCommands($hash,$devname,$1,$2); } } - elsif (AttrVal($name,"HomeUWZ",undef) && $devname eq AttrVal($name,"HomeUWZ","") && grep /^WarnCount:\s/,@{$events}) + elsif (AttrVal($name,'HomeUWZ',undef) && $devname eq AttrVal($name,'HomeUWZ','') && grep /^WarnCount:\s/,@{$events}) { HOMEMODE_UWZCommands($hash,$events); } - elsif (AttrVal($name,"HomeTriggerPanic","") && $devname eq (split /:/,AttrVal($name,"HomeTriggerPanic",""))[0]) + elsif (AttrVal($name,'HomeTriggerPanic','') && $devname eq (split /:/,AttrVal($name,'HomeTriggerPanic',''))[0]) { - my ($d,$r,$on,$off) = split /:/,AttrVal($name,"HomeTriggerPanic",""); + my ($d,$r,$on,$off) = split /:/,AttrVal($name,'HomeTriggerPanic',''); if ($devname eq $d) { if (grep /^$r:\s$on$/,@{$events}) @@ -223,7 +223,7 @@ sub HOMEMODE_Notify($$) } else { - if (ReadingsVal($name,"panic","off") eq "off") + if (ReadingsVal($name,'panic','off') eq 'off') { CommandSet(undef,"$name:FILTER=panic=off panic on"); } @@ -239,9 +239,9 @@ sub HOMEMODE_Notify($$) } } } - elsif (AttrVal($name,"HomeTriggerAnyoneElseAtHome","") && $devname eq (split /:/,AttrVal($name,"HomeTriggerAnyoneElseAtHome",""))[0]) + elsif (AttrVal($name,'HomeTriggerAnyoneElseAtHome','') && $devname eq (split /:/,AttrVal($name,'HomeTriggerAnyoneElseAtHome',''))[0]) { - my ($d,$r,$on,$off) = split /:/,AttrVal($name,"HomeTriggerAnyoneElseAtHome",""); + my ($d,$r,$on,$off) = split /:/,AttrVal($name,'HomeTriggerAnyoneElseAtHome',''); if ($devname eq $d) { if (grep /^$r:\s$on$/,@{$events}) @@ -256,18 +256,18 @@ sub HOMEMODE_Notify($$) } elsif ($hash->{SENSORSENERGY} && grep(/^$devname$/,split /,/,$hash->{SENSORSENERGY})) { - my $read = AttrVal($name,"HomeSensorsPowerEnergyReadings","power energy"); + my $read = AttrVal($name,'HomeSensorsPowerEnergyReadings','power energy'); $read =~ s/ /\|/g; for my $evt (@{$events}) { 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})) { - my $read = AttrVal($name,"HomeSensorsSmokeReading","state"); + my $read = AttrVal($name,'HomeSensorsSmokeReading','state'); for my $evt (@{$events}) { next unless ($evt =~ /^$read:\s(.+)$/); @@ -279,96 +279,91 @@ sub HOMEMODE_Notify($$) { if ($hash->{SENSORSCONTACT} && grep(/^$devname$/,split /,/,$hash->{SENSORSCONTACT})) { - my ($oread,$tread) = split " ",AttrVal($devname,"HomeReadings",AttrVal($name,"HomeSensorsContactReadings","state sabotageError")); + my ($oread,$tread) = split ' ',AttrVal($devname,'HomeReadings',AttrVal($name,'HomeSensorsContactReadings','state sabotageError')); HOMEMODE_TriggerState($hash,undef,undef,$devname) if (grep /^($oread|$tread):\s.+$/,@{$events}); } if ($hash->{SENSORSMOTION} && grep(/^$devname$/,split /,/,$hash->{SENSORSMOTION})) { - my ($oread,$tread) = split " ",AttrVal($devname,"HomeReadings",AttrVal($name,"HomeSensorsMotionReadings","state sabotageError")); + my ($oread,$tread) = split ' ',AttrVal($devname,'HomeReadings',AttrVal($name,'HomeSensorsMotionReadings','state sabotageError')); HOMEMODE_TriggerState($hash,undef,undef,$devname) if (grep /^($oread|$tread):\s.+$/,@{$events}); } if ($hash->{SENSORSLUMINANCE} && grep(/^$devname$/,split /,/,$hash->{SENSORSLUMINANCE})) { - my $read = AttrVal($name,"HomeSensorsLuminanceReading","luminance"); + my $read = AttrVal($name,'HomeSensorsLuminanceReading','luminance'); if (grep /^$read:\s.+$/,@{$events}) { for my $evt (@{$events}) { next unless ($evt =~ /^$read:\s(.+)$/); - HOMEMODE_Luminance($hash,$devname,(split " ",$1)[0]); + HOMEMODE_Luminance($hash,$devname,(split ' ',$1)[0]); last; } } } - if (AttrVal($name,"HomeSensorTemperatureOutside",undef) && $devname eq AttrVal($name,"HomeSensorTemperatureOutside","") && grep /^(temperature|humidity):\s/,@{$events}) + if (AttrVal($name,'HomeSensorTemperatureOutside',undef) && $devname eq AttrVal($name,'HomeSensorTemperatureOutside','') && grep /^(temperature|humidity):\s/,@{$events}) { my $temp; my $humi; for my $evt (@{$events}) { next unless ($evt =~ /^(humidity|temperature):\s(.+)$/); - $temp = (split " ",$2)[0] if ($1 eq "temperature"); - $humi = (split " ",$2)[0] if ($1 eq "humidity"); + $temp = (split ' ',$2)[0] if ($1 eq 'temperature'); + $humi = (split ' ',$2)[0] if ($1 eq 'humidity'); } - readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"temperature",$temp); - if (defined $humi && !AttrVal($name,"HomeSensorHumidityOutside",undef)) + if (defined $temp) { - readingsBulkUpdate($hash,"humidity",$humi); - $hash->{helper}{externalHumidity} = 1; + readingsSingleUpdate($hash,'temperature',$temp,1); + HOMEMODE_ReadingTrend($hash,'temperature',$temp); + HOMEMODE_Icewarning($hash); } - elsif (!AttrVal($name,"HomeSensorHumidityOutside",undef)) + if (defined $humi && !AttrVal($name,'HomeSensorHumidityOutside',undef)) { - delete $hash->{helper}{externalHumidity}; + readingsSingleUpdate($hash,'humidity',$humi,1); + HOMEMODE_ReadingTrend($hash,'humidity',$humi); } - readingsEndUpdate($hash,1); - HOMEMODE_ReadingTrend($hash,"humidity",$humi) if (defined $humi); - HOMEMODE_ReadingTrend($hash,"temperature",$temp); - HOMEMODE_Icewarning($hash); } - if (AttrVal($name,"HomeSensorHumidityOutside",undef) && $devname eq AttrVal($name,"HomeSensorHumidityOutside","") && grep /^humidity:\s/,@{$events}) + if (AttrVal($name,'HomeSensorHumidityOutside',undef) && $devname eq AttrVal($name,'HomeSensorHumidityOutside','') && grep /^humidity:\s/,@{$events}) { - $hash->{helper}{externalHumidity} = 1; for my $evt (@{$events}) { next unless ($evt =~ /^humidity:\s(.+)$/); - my $val = (split " ",$1)[0]; - readingsSingleUpdate($hash,"humidity",$val,1); - HOMEMODE_ReadingTrend($hash,"humidity",$val); + 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]) + if (AttrVal($name,'HomeSensorWindspeed',undef) && $devname eq (split /:/,AttrVal($name,'HomeSensorWindspeed',''))[0]) { - my $read = (split /:/,AttrVal($name,"HomeSensorWindspeed",""))[1]; + my $read = (split /:/,AttrVal($name,'HomeSensorWindspeed',''))[1]; if (grep /^$read:\s(.+)$/,@{$events}) { for my $evt (@{$events}) { next unless ($evt =~ /^$read:\s(.+)$/); - my $val = (split " ",$1)[0]; - readingsSingleUpdate($hash,"wind",$val,1); - HOMEMODE_ReadingTrend($hash,"wind",$val); + my $val = (split ' ',$1)[0]; + readingsSingleUpdate($hash,'wind',$val,1); + HOMEMODE_ReadingTrend($hash,'wind',$val); last; } } } - if (AttrVal($name,"HomeSensorAirpressure",undef) && $devname eq (split /:/,AttrVal($name,"HomeSensorAirpressure",""))[0]) + if (AttrVal($name,'HomeSensorAirpressure',undef) && $devname eq (split /:/,AttrVal($name,'HomeSensorAirpressure',''))[0]) { - my $read = (split /:/,AttrVal($name,"HomeSensorAirpressure",""))[1]; + my $read = (split /:/,AttrVal($name,'HomeSensorAirpressure',''))[1]; if (grep /^$read:\s(.+)$/,@{$events}) { for my $evt (@{$events}) { next unless ($evt =~ /^$read:\s(.+)$/); - my $val = (split " ",$1)[0]; - readingsSingleUpdate($hash,"pressure",$val,1); - HOMEMODE_ReadingTrend($hash,"pressure",$val); + my $val = (split ' ',$1)[0]; + readingsSingleUpdate($hash,'pressure',$val,1); + HOMEMODE_ReadingTrend($hash,'pressure',$val); last; } } } - if (AttrNum($name,"HomeAutoPresence",0) && $devtype =~ /^($prestype)$/ && grep(/^presence:\s(absent|present|appeared|disappeared)$/,@{$events})) + if (AttrNum($name,'HomeAutoPresence',0) && $devtype =~ /^($prestype)$/ && grep(/^presence:\s(absent|present|appeared|disappeared)$/,@{$events})) { my $resident; my $residentregex; @@ -383,47 +378,54 @@ sub HOMEMODE_Notify($$) } return if (!$resident); $hash->{helper}{lar} = $resident; - my $residentstate = ReadingsVal($resident,"state",""); - my $suppressstate = "[gn]one|absent"; - if (ReadingsVal($devname,"presence","") !~ /^maybe/) + my $residentstate = ReadingsVal($resident,'state',''); + my $suppressstate = '[gn]one|absent'; + if (ReadingsVal($devname,'presence','') !~ /^maybe/) { my @presentdevicespresent; for my $device (devspec2array("TYPE=$prestype:FILTER=presence=^(maybe.)?(absent|present|appeared|disappeared)")) { 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)$/); } + my $presdevspresent = scalar @presentdevicespresent; + Log3 $name,5,"$name: var presdevspresent=$presdevspresent"; if (grep /^presence:\s(present|appeared)$/,@{$events}) { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"lastActivityByPresenceDevice",$devname); - readingsBulkUpdate($hash,"lastPresentByPresenceDevice",$devname); + readingsBulkUpdate($hash,'lastActivityByPresenceDevice',$devname); + readingsBulkUpdate($hash,'lastPresentByPresenceDevice',$devname); readingsEndUpdate($hash,1); - push @commands,AttrVal($name,"HomeCMDpresence-present-device","") if (AttrVal($name,"HomeCMDpresence-present-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)); - if (@presentdevicespresent >= AttrNum($name,"HomePresenceDevicePresentCount-$resident",1) + push @commands,AttrVal($name,'HomeCMDpresence-present-device','') if (AttrVal($name,'HomeCMDpresence-present-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)); + Log3 $name,5,"$name: attr HomePresenceDevicePresentCount-$resident=".AttrVal($name,"HomePresenceDevicePresentCount-$resident",'unset'); + if ($presdevspresent >= AttrNum($name,"HomePresenceDevicePresentCount-$resident",1) && $residentstate =~ /^($suppressstate)$/) { + Log3 $name,5,"$name: set $resident:FILTER=state!=home state home"; CommandSet(undef,"$resident:FILTER=state!=home state home"); } } elsif (grep /^presence:\s(absent|disappeared)$/,@{$events}) { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"lastActivityByPresenceDevice",$devname); - readingsBulkUpdate($hash,"lastAbsentByPresenceDevice",$devname); + readingsBulkUpdate($hash,'lastActivityByPresenceDevice',$devname); + readingsBulkUpdate($hash,'lastAbsentByPresenceDevice',$devname); readingsEndUpdate($hash,1); - push @commands,AttrVal($name,"HomeCMDpresence-absent-device","") if (AttrVal($name,"HomeCMDpresence-absent-device",undef)); - push @commands,AttrVal($name,"HomeCMDpresence-absent-$resident-device","") if (AttrVal($name,"HomeCMDpresence-absent-$resident-device",undef)); - push @commands,AttrVal($name,"HomeCMDpresence-absent-$resident-$devname","") if (AttrVal($name,"HomeCMDpresence-absent-$resident-$devname",undef)); + push @commands,AttrVal($name,'HomeCMDpresence-absent-device','') if (AttrVal($name,'HomeCMDpresence-absent-device',undef)); + push @commands,AttrVal($name,"HomeCMDpresence-absent-$resident-device",'') if (AttrVal($name,"HomeCMDpresence-absent-$resident-device",undef)); + push @commands,AttrVal($name,"HomeCMDpresence-absent-$resident-$devname",'') if (AttrVal($name,"HomeCMDpresence-absent-$resident-$devname",undef)); 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","")); + $devcount = scalar @{$hash->{helper}{presdevs}{$resident}} if ($hash->{helper}{presdevs}{$resident}); + my $presdevsabsent = $devcount - $presdevspresent; + Log3 $name,5,"$name: var presdevsabsent=$presdevsabsent"; + $suppressstate .= '|'.AttrVal($name,'HomeAutoPresenceSuppressState','') if (AttrVal($name,'HomeAutoPresenceSuppressState','')); + Log3 $name,5,"$name: attr HomePresenceDeviceAbsentCount-$resident=".AttrVal($name,"HomePresenceDeviceAbsentCount-$resident",'unset'); if ($presdevsabsent >= AttrNum($name,"HomePresenceDeviceAbsentCount-$resident",1) && $residentstate !~ /^($suppressstate)$/) { + Log3 $name,5,"$name: set $resident:FILTER=state!=absent state absent"; CommandSet(undef,"$resident:FILTER=state!=absent state absent"); } } @@ -432,17 +434,17 @@ sub HOMEMODE_Notify($$) } if ($hash->{SENSORSBATTERY} && grep(/^$devname$/,split /,/,$hash->{SENSORSBATTERY})) { - my $read = AttrVal($name,"HomeSensorsBatteryReading","battery"); + my $read = AttrVal($name,'HomeSensorsBatteryReading','battery'); if (grep /^$read:\s(.+)$/,@{$events}) { - my @lowOld = split /,/,ReadingsVal($name,"batteryLow",""); + my @lowOld = split /,/,ReadingsVal($name,'batteryLow',''); my @low; @low = @lowOld if (@lowOld); for my $evt (@{$events}) { next unless ($evt =~ /^$read:\s(.+)$/); my $val = $1; - if (($val =~ /^(\d{1,3})(%|\s%)?$/ && $1 <= AttrNum($name,"HomeSensorsBatteryLowPercentage",50)) || $val =~ /^(nok|low)$/) + if (($val =~ /^(\d{1,3})(%|\s%)?$/ && $1 <= AttrNum($name,'HomeSensorsBatteryLowPercentage',50)) || $val =~ /^(nok|low)$/) { push @low,$devname if (!grep /^$devname$/,@low); } @@ -460,27 +462,27 @@ sub HOMEMODE_Notify($$) readingsBeginUpdate($hash); if (@low) { - readingsBulkUpdateIfChanged($hash,"batteryLow",join(",",@low)); - readingsBulkUpdateIfChanged($hash,"batteryLow_ct",scalar @low); - readingsBulkUpdateIfChanged($hash,"batteryLow_hr",HOMEMODE_makeHR($hash,1,@low)); - readingsBulkUpdateIfChanged($hash,"lastBatteryLow",$devname) if (grep(/^$devname$/,@low) && !grep(/^$devname$/,@lowOld)); + readingsBulkUpdateIfChanged($hash,'batteryLow',join(',',@low)); + readingsBulkUpdateIfChanged($hash,'batteryLow_ct',scalar @low); + readingsBulkUpdateIfChanged($hash,'batteryLow_hr',HOMEMODE_makeHR($hash,1,@low)); + readingsBulkUpdateIfChanged($hash,'lastBatteryLow',$devname) if (grep(/^$devname$/,@low) && !grep(/^$devname$/,@lowOld)); } else { - readingsBulkUpdateIfChanged($hash,"batteryLow",""); - readingsBulkUpdateIfChanged($hash,"batteryLow_ct",scalar @low); - readingsBulkUpdateIfChanged($hash,"batteryLow_hr",""); + readingsBulkUpdateIfChanged($hash,'batteryLow',''); + readingsBulkUpdateIfChanged($hash,'batteryLow_ct',scalar @low); + readingsBulkUpdateIfChanged($hash,'batteryLow_hr',''); } - readingsBulkUpdateIfChanged($hash,"lastBatteryNormal",$devname) if (!grep(/^$devname$/,@low) && grep(/^$devname$/,@lowOld)); + readingsBulkUpdateIfChanged($hash,'lastBatteryNormal',$devname) if (!grep(/^$devname$/,@low) && grep(/^$devname$/,@lowOld)); readingsEndUpdate($hash,1); - push @commands,AttrVal($name,"HomeCMDbattery","") if (AttrVal($name,"HomeCMDbattery",undef) && (grep(/^$devname$/,@low) || grep(/^$devname$/,@lowOld))); - push @commands,AttrVal($name,"HomeCMDbatteryLow","") if (AttrVal($name,"HomeCMDbatteryLow",undef) && grep(/^$devname$/,@low) && !grep(/^$devname$/,@lowOld)); - push @commands,AttrVal($name,"HomeCMDbatteryNormal","") if (AttrVal($name,"HomeCMDbatteryNormal",undef) && !grep(/^$devname$/,@low) && grep(/^$devname$/,@lowOld)); + push @commands,AttrVal($name,'HomeCMDbattery','') if (AttrVal($name,'HomeCMDbattery',undef) && (grep(/^$devname$/,@low) || grep(/^$devname$/,@lowOld))); + push @commands,AttrVal($name,'HomeCMDbatteryLow','') if (AttrVal($name,'HomeCMDbatteryLow',undef) && grep(/^$devname$/,@low) && !grep(/^$devname$/,@lowOld)); + push @commands,AttrVal($name,'HomeCMDbatteryNormal','') if (AttrVal($name,'HomeCMDbatteryNormal',undef) && !grep(/^$devname$/,@low) && grep(/^$devname$/,@lowOld)); } } } HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); - HOMEMODE_GetUpdate($hash) if (!$hash->{".TRIGGERTIME_NEXT"} || $hash->{".TRIGGERTIME_NEXT"} + 1 < gettimeofday()); + HOMEMODE_GetUpdate($hash) if (!$hash->{'.TRIGGERTIME_NEXT'} || $hash->{'.TRIGGERTIME_NEXT'} + 1 < gettimeofday()); return; } @@ -495,14 +497,14 @@ sub HOMEMODE_updateInternals($;$$) $trans = $HOMEMODE_de? "$resdev ist nicht definiert!": "$resdev is not defined!"; - readingsSingleUpdate($hash,"state",$trans,0); + readingsSingleUpdate($hash,'state',$trans,0); } - elsif (!HOMEMODE_ID($resdev,"RESIDENTS")) + elsif (!HOMEMODE_ID($resdev,'RESIDENTS')) { $trans = $HOMEMODE_de? "$resdev ist kein gültiges RESIDENTS Gerät!": "$resdev is not a valid RESIDENTS device!"; - readingsSingleUpdate($hash,"state",$trans,0); + readingsSingleUpdate($hash,'state',$trans,0); } else { @@ -527,18 +529,18 @@ sub HOMEMODE_updateInternals($;$$) "Keine verfügbaren ROOMMATE/GUEST/PET im RESIDENTS Gerät $resdev": "No available ROOMMATE/GUEST/PET in RESIDENTS device $resdev"; Log3 $name,2,$trans; - readingsSingleUpdate($hash,"HomeInfo",$trans,1); + readingsSingleUpdate($hash,'HomeInfo',$trans,1); return; } else { - $hash->{RESIDENTS} = join(",",sort @residents); + $hash->{RESIDENTS} = join(',',sort @residents); } my @allMonitoredDevices; - push @allMonitoredDevices,"global"; + push @allMonitoredDevices,'global'; push @allMonitoredDevices,$resdev; - my $autopresence = HOMEMODE_AttrCheck($hash,"HomeAutoPresence",0); - my $presencetype = HOMEMODE_AttrCheck($hash,"HomePresenceDeviceType","PRESENCE"); + my $autopresence = HOMEMODE_AttrCheck($hash,'HomeAutoPresence',0); + my $presencetype = HOMEMODE_AttrCheck($hash,'HomePresenceDeviceType','PRESENCE'); my @presdevs = devspec2array("TYPE=$presencetype:FILTER=presence=^(maybe.)?(absent|present|appeared|disappeared)"); my @residentsshort; my @logtexte; @@ -560,7 +562,7 @@ sub HOMEMODE_updateInternals($;$$) if (@residentspresdevs) { my $c = scalar @residentspresdevs; - my $devlist = join(",",@residentspresdevs); + my $devlist = join(',',@residentspresdevs); $trans = $HOMEMODE_de? "Gefunden wurden $c übereinstimmende(s) Anwesenheits Gerät(e) vom Devspec \"TYPE=$presencetype\" für Bewohner \"$resident\"! Übereinstimmende Geräte: \"$devlist\"": "Found $c matching presence devices of devspec \"TYPE=$presencetype\" for resident \"$resident\"! Matching devices: \"$devlist\""; @@ -580,15 +582,15 @@ sub HOMEMODE_updateInternals($;$$) if (@logtexte && $set) { $trans = $HOMEMODE_de? - "Falls ein oder mehr Anweseheits Geräte falsch zugeordnet wurden, so benenne diese bitte so um dass die Bewohner Namen (".join(",",@residentsshort).") nicht Bestandteil des Namen sind.\nNach dem Umbenennen führe einfach \"set $name updateInternalsForce\" aus um diese Überprüfung zu wiederholen.": - "If any recognized presence device is wrong, please rename this device so that it will NOT match the residents names (".join(",",@residentsshort).") somewhere in the device name.\nAfter renaming simply execute \"set $name updateInternalsForce\" to redo this check."; + 'Falls ein oder mehr Anweseheits Geräte falsch zugeordnet wurden, so benenne diese bitte so um dass die Bewohner Namen ('.join(',',@residentsshort).") nicht Bestandteil des Namen sind.\nNach dem Umbenennen führe einfach \"set $name updateInternalsForce\" aus um diese Überprüfung zu wiederholen.": + 'If any recognized presence device is wrong, please rename this device so that it will NOT match the residents names ('.join(',',@residentsshort).") somewhere in the device name.\nAfter renaming simply execute \"set $name updateInternalsForce\" to redo this check."; push @logtexte,"\n$trans"; - my $log = join("\n",@logtexte); + my $log = join('\n',@logtexte); Log3 $name,3,"$name: $log"; $log =~ s/\n/
/gm; - readingsSingleUpdate($hash,"HomeInfo","$log",1); + readingsSingleUpdate($hash,'HomeInfo',"$log",1); } - my $contacts = HOMEMODE_AttrCheck($hash,"HomeSensorsContact"); + my $contacts = HOMEMODE_AttrCheck($hash,'HomeSensorsContact'); if ($contacts) { my @sensors; @@ -597,7 +599,7 @@ sub HOMEMODE_updateInternals($;$$) push @sensors,$s; push @allMonitoredDevices,$s if (!grep /^$s$/,@allMonitoredDevices); } - my $list = join(",",sort @sensors); + my $list = join(',',sort @sensors); $hash->{SENSORSCONTACT} = $list; HOMEMODE_addSensorsuserattr($hash,$list,$oldContacts) if (($force && !$oldContacts) || ($oldContacts && $list ne $oldContacts)); } @@ -605,7 +607,7 @@ sub HOMEMODE_updateInternals($;$$) { HOMEMODE_cleanUserattr($hash,$oldContacts); } - my $motion = HOMEMODE_AttrCheck($hash,"HomeSensorsMotion"); + my $motion = HOMEMODE_AttrCheck($hash,'HomeSensorsMotion'); if ($motion) { my @sensors; @@ -614,7 +616,7 @@ sub HOMEMODE_updateInternals($;$$) push @sensors,$s; push @allMonitoredDevices,$s if (!grep /^$s$/,@allMonitoredDevices); } - my $list = join(",",sort @sensors); + my $list = join(',',sort @sensors); $hash->{SENSORSMOTION} = $list; HOMEMODE_addSensorsuserattr($hash,$list,$oldMotions) if (($force && !$oldMotions) || ($oldMotions && $list ne $oldMotions)); } @@ -622,45 +624,45 @@ sub HOMEMODE_updateInternals($;$$) { HOMEMODE_cleanUserattr($hash,$oldMotions); } - my $power = HOMEMODE_AttrCheck($hash,"HomeSensorsPowerEnergy"); + my $power = HOMEMODE_AttrCheck($hash,'HomeSensorsPowerEnergy'); if ($power) { my @sensors; - my ($p,$e) = split " ",AttrVal($name,"HomeSensorsPowerEnergyReadings","power energy"); + my ($p,$e) = split ' ',AttrVal($name,'HomeSensorsPowerEnergyReadings','power energy'); for my $s (devspec2array($power)) { next unless (HOMEMODE_ID($s,undef,$p) && HOMEMODE_ID($s,undef,$e)); push @sensors,$s; push @allMonitoredDevices,$s if (!grep /^$s$/,@allMonitoredDevices); } - $hash->{SENSORSENERGY} = join(",",sort @sensors) if (@sensors); + $hash->{SENSORSENERGY} = join(',',sort @sensors) if (@sensors); } - my $smoke = HOMEMODE_AttrCheck($hash,"HomeSensorsSmoke"); + my $smoke = HOMEMODE_AttrCheck($hash,'HomeSensorsSmoke'); if ($smoke) { my @sensors; - my $r = AttrVal($name,"HomeSensorsSmokeReading","state"); + my $r = AttrVal($name,'HomeSensorsSmokeReading','state'); for my $s (devspec2array($smoke)) { next unless (HOMEMODE_ID($s,undef,$r)); push @sensors,$s; push @allMonitoredDevices,$s if (!grep /^$s$/,@allMonitoredDevices); } - $hash->{SENSORSSMOKE} = join(",",sort @sensors) if (@sensors); + $hash->{SENSORSSMOKE} = join(',',sort @sensors) if (@sensors); } - my $battery = HOMEMODE_AttrCheck($hash,"HomeSensorsBattery"); + my $battery = HOMEMODE_AttrCheck($hash,'HomeSensorsBattery'); if ($battery) { my @sensors; for my $s (devspec2array($battery)) { - my $read = AttrVal($name,"HomeSensorsBatteryReading","battery"); + my $read = AttrVal($name,'HomeSensorsBatteryReading','battery'); my $val = ReadingsVal($s,$read,undef); next unless (defined $val && $val =~ /^(ok|low|nok|\d{1,3})(%|\s%)?$/); push @sensors,$s; push @allMonitoredDevices,$s if (!grep /^$s$/,@allMonitoredDevices); - $hash->{SENSORSBATTERY} = join(",",sort @sensors) if (@sensors); - if (!grep(/^$s$/,split(/,/,ReadingsVal($name,"batteryLow","")))) + $hash->{SENSORSBATTERY} = join(',',sort @sensors) if (@sensors); + if (!grep(/^$s$/,split(/,/,ReadingsVal($name,'batteryLow','')))) { CommandTrigger(undef,"$s $read: ok") if ($val =~ /^(low|nok)$/); CommandTrigger(undef,"$s $read: 100") if ($val =~ /^\d{1,3}$/); @@ -670,29 +672,29 @@ sub HOMEMODE_updateInternals($;$$) } } } - my $weather = HOMEMODE_AttrCheck($hash,"HomeWeatherDevice"); + my $weather = HOMEMODE_AttrCheck($hash,'HomeWeatherDevice'); push @allMonitoredDevices,$weather if ($weather && !grep /^$weather$/,@allMonitoredDevices); - my $twilight = HOMEMODE_AttrCheck($hash,"HomeTwilightDevice"); + my $twilight = HOMEMODE_AttrCheck($hash,'HomeTwilightDevice'); push @allMonitoredDevices,$twilight if ($twilight && !grep /^$twilight$/,@allMonitoredDevices); - my $temperature = HOMEMODE_AttrCheck($hash,"HomeSensorTemperatureOutside"); + my $temperature = HOMEMODE_AttrCheck($hash,'HomeSensorTemperatureOutside'); push @allMonitoredDevices,$temperature if ($temperature && !grep /^$temperature$/,@allMonitoredDevices); - my $humidity = HOMEMODE_AttrCheck($hash,"HomeSensorHumidityOutside"); + my $humidity = HOMEMODE_AttrCheck($hash,'HomeSensorHumidityOutside'); if ($humidity) { push @allMonitoredDevices,$humidity if (!grep /^$humidity$/,@allMonitoredDevices); } my @cals; CommandDeleteReading(undef,"$name event-.+"); - if (HOMEMODE_AttrCheck($hash,"HomeEventsHolidayDevices")) + if (HOMEMODE_AttrCheck($hash,'HomeEventsHolidayDevices')) { - for my $c (devspec2array(HOMEMODE_AttrCheck($hash,"HomeEventsHolidayDevices"))) + for my $c (devspec2array(HOMEMODE_AttrCheck($hash,'HomeEventsHolidayDevices'))) { push @cals,$c if (!grep /^$c$/,@cals); } } - if (HOMEMODE_AttrCheck($hash,"HomeEventsCalendarDevices")) + if (HOMEMODE_AttrCheck($hash,'HomeEventsCalendarDevices')) { - for my $c (devspec2array(HOMEMODE_AttrCheck($hash,"HomeEventsCalendarDevices"))) + for my $c (devspec2array(HOMEMODE_AttrCheck($hash,'HomeEventsCalendarDevices'))) { push @cals,$c if (!grep /^$c$/,@cals); } @@ -700,41 +702,41 @@ sub HOMEMODE_updateInternals($;$$) for my $c (@cals) { push @allMonitoredDevices,$c if (!grep /^$c$/,@allMonitoredDevices); - if (HOMEMODE_ID($c,"Calendar")) + if (HOMEMODE_ID($c,'Calendar')) { - HOMEMODE_EventCommands($hash,$c,"modeStarted",ReadingsVal($c,"modeStarted","none")); + HOMEMODE_EventCommands($hash,$c,'modeStarted',ReadingsVal($c,'modeStarted','none')); } else { - readingsSingleUpdate($hash,"event-$c",ReadingsVal($c,"state","none"),1); + readingsSingleUpdate($hash,"event-$c",ReadingsVal($c,'state','none'),1); } } - my $uwz = HOMEMODE_AttrCheck($hash,"HomeUWZ",""); + my $uwz = HOMEMODE_AttrCheck($hash,'HomeUWZ',''); push @allMonitoredDevices,$uwz if ($uwz && !grep /^$uwz$/,@allMonitoredDevices); - my $luminance = HOMEMODE_AttrCheck($hash,"HomeSensorsLuminance"); + my $luminance = HOMEMODE_AttrCheck($hash,'HomeSensorsLuminance'); if ($luminance) { - my $read = AttrVal($name,"HomeSensorsLuminanceReading","luminance"); + my $read = AttrVal($name,'HomeSensorsLuminanceReading','luminance'); my @sensors; for my $s (devspec2array($luminance)) { - next unless (HOMEMODE_ID($s,undef,AttrVal($name,"HomeSensorsLuminanceReading","luminance"))); + next unless (HOMEMODE_ID($s,undef,AttrVal($name,'HomeSensorsLuminanceReading','luminance'))); push @sensors,$s; push @allMonitoredDevices,$s if (!grep /^$s$/,@allMonitoredDevices); } - $hash->{SENSORSLUMINANCE} = join(",",sort @sensors) if (@sensors); + $hash->{SENSORSLUMINANCE} = join(',',sort @sensors) if (@sensors); } - my $pressure = (split /:/,HOMEMODE_AttrCheck($hash,"HomeSensorAirpressure"))[0]; + my $pressure = (split /:/,HOMEMODE_AttrCheck($hash,'HomeSensorAirpressure'))[0]; push @allMonitoredDevices,$pressure if ($pressure && !grep /^$pressure$/,@allMonitoredDevices); - my $wind = (split /:/,HOMEMODE_AttrCheck($hash,"HomeSensorWindspeed"))[0]; + my $wind = (split /:/,HOMEMODE_AttrCheck($hash,'HomeSensorWindspeed'))[0]; push @allMonitoredDevices,$wind if ($wind && !grep /^$wind$/,@allMonitoredDevices); - my $panic = (split /:/,HOMEMODE_AttrCheck($hash,"HomeTriggerPanic"))[0]; + my $panic = (split /:/,HOMEMODE_AttrCheck($hash,'HomeTriggerPanic'))[0]; push @allMonitoredDevices,$panic if ($panic && !grep /^$panic$/,@allMonitoredDevices); - my $aeah = (split /:/,HOMEMODE_AttrCheck($hash,"HomeTriggerAnyoneElseAtHome"))[0]; + my $aeah = (split /:/,HOMEMODE_AttrCheck($hash,'HomeTriggerAnyoneElseAtHome'))[0]; push @allMonitoredDevices,$aeah if ($aeah && !grep /^$aeah$/,@allMonitoredDevices); Log3 $name,5,"$name: new monitored device count: ".@allMonitoredDevices; @allMonitoredDevices = sort @allMonitoredDevices; - $hash->{NOTIFYDEV} = join(",",@allMonitoredDevices); + $hash->{NOTIFYDEV} = join(',',@allMonitoredDevices); HOMEMODE_GetUpdate($hash); return if (!@allMonitoredDevices); HOMEMODE_RESIDENTS($hash); @@ -754,16 +756,16 @@ sub HOMEMODE_GetUpdate(@) { my ($hash) = @_; my $name = $hash->{NAME}; - RemoveInternalTimer($hash,"HOMEMODE_GetUpdate"); + RemoveInternalTimer($hash,'HOMEMODE_GetUpdate'); return if (IsDisabled($name)); my $mode = HOMEMODE_DayTime($hash); HOMEMODE_SetDaytime($hash); HOMEMODE_SetSeason($hash); - CommandSet(undef,"$name:FILTER=mode!=$mode mode $mode") if (ReadingsVal($hash->{DEF},"state","") eq "home" && AttrNum($name,"HomeAutoDaytime",1)); - HOMEMODE_checkIP($hash) if ((AttrNum($name,"HomePublicIpCheckInterval",0) && !$hash->{".IP_TRIGGERTIME_NEXT"}) || (AttrNum($name,"HomePublicIpCheckInterval",0) && $hash->{".IP_TRIGGERTIME_NEXT"} && $hash->{".IP_TRIGGERTIME_NEXT"} < gettimeofday())); + CommandSet(undef,"$name:FILTER=mode!=$mode mode $mode") if (ReadingsVal($hash->{DEF},'state','') eq 'home' && AttrNum($name,'HomeAutoDaytime',1)); + HOMEMODE_checkIP($hash) if ((AttrNum($name,'HomePublicIpCheckInterval',0) && !$hash->{'.IP_TRIGGERTIME_NEXT'}) || (AttrNum($name,'HomePublicIpCheckInterval',0) && $hash->{'.IP_TRIGGERTIME_NEXT'} && $hash->{'.IP_TRIGGERTIME_NEXT'} < gettimeofday())); my $timer = gettimeofday() + 5; - $hash->{".TRIGGERTIME_NEXT"} = $timer; - InternalTimer($timer,"HOMEMODE_GetUpdate",$hash); + $hash->{'.TRIGGERTIME_NEXT'} = $timer; + InternalTimer($timer,'HOMEMODE_GetUpdate',$hash); return; } @@ -771,34 +773,34 @@ sub HOMEMODE_Get($@) { my ($hash,$name,@aa) = @_; my ($cmd,@args) = @aa; - return if (IsDisabled($name) && $cmd ne "?"); - my $params = "mode:noArg modeAlarm:noArg publicIP:noArg devicesDisabled:noArg"; - $params .= " contactsOpen:all,doorsinside,doorsoutside,doorsmain,outside,windows" if ($hash->{SENSORSCONTACT}); - $params .= " sensorsTampered:noArg" if ($hash->{SENSORSCONTACT} || $hash->{SENSORSMOTION}); - if (AttrVal($name,"HomeWeatherDevice",undef)) + return if (IsDisabled($name) && $cmd ne '?'); + my $params = 'mode:noArg modeAlarm:noArg publicIP:noArg devicesDisabled:noArg'; + $params .= ' contactsOpen:all,doorsinside,doorsoutside,doorsmain,outside,windows' if ($hash->{SENSORSCONTACT}); + $params .= ' sensorsTampered:noArg' if ($hash->{SENSORSCONTACT} || $hash->{SENSORSMOTION}); + if (AttrVal($name,'HomeWeatherDevice',undef)) { - if (AttrVal($name,"HomeTextWeatherLong",undef) || AttrVal($name,"HomeTextWeatherShort",undef)) + if (AttrVal($name,'HomeTextWeatherLong',undef) || AttrVal($name,'HomeTextWeatherShort',undef)) { - $params .= " weather:"; - $params .= "long" if (AttrVal($name,"HomeTextWeatherLong",undef)); - $params .= "," if (AttrVal($name,"HomeTextWeatherLong",undef) && AttrVal($name,"HomeTextWeatherShort",undef)); - $params .= "short" if (AttrVal($name,"HomeTextWeatherShort",undef)) + $params .= ' weather:'; + $params .= 'long' if (AttrVal($name,'HomeTextWeatherLong',undef)); + $params .= ',' if (AttrVal($name,'HomeTextWeatherLong',undef) && AttrVal($name,'HomeTextWeatherShort',undef)); + $params .= 'short' if (AttrVal($name,'HomeTextWeatherShort',undef)) } - $params .= " weatherForecast" if (AttrVal($name,"HomeTextWeatherLong",undef)); + $params .= ' weatherForecast' if (AttrVal($name,'HomeTextWeatherLong',undef)); } my $value = $args[0]; my $trans; - if ($cmd eq "devicesDisabled") + if ($cmd eq 'devicesDisabled') { - return join "\n",split /,/,ReadingsVal($name,"devicesDisabled",""); + return join '\n',split /,/,ReadingsVal($name,'devicesDisabled',''); } - elsif ($cmd eq "mode") + elsif ($cmd eq 'mode') { - return ReadingsVal($name,"mode","no mode available"); + return ReadingsVal($name,'mode','no mode available'); } - elsif ($cmd eq "modeAlarm") + elsif ($cmd eq 'modeAlarm') { - return ReadingsVal($name,"modeAlarm","no modeAlarm available"); + return ReadingsVal($name,'modeAlarm','no modeAlarm available'); } elsif ($cmd =~ /^contactsOpen$/) { @@ -816,16 +818,16 @@ sub HOMEMODE_Get($@) return $trans if ($value); HOMEMODE_TriggerState($hash,$cmd); } - elsif ($cmd eq "weather") + elsif ($cmd eq 'weather') { $trans = $HOMEMODE_de? "$cmd benötigt ein Argument, entweder long oder short!": "$cmd needs one argument of long or short!"; return $trans if (!$value || $value !~ /^(long|short)$/); - my $m = $value eq "short"?"Short":"Long"; - HOMEMODE_WeatherTXT($hash,AttrVal($name,"HomeTextWeather$m","")); + my $m = $value eq 'short'?'Short':'Long'; + HOMEMODE_WeatherTXT($hash,AttrVal($name,"HomeTextWeather$m",'')); } - elsif ($cmd eq "weatherForecast") + elsif ($cmd eq 'weatherForecast') { $trans = $HOMEMODE_de? "Der Wert für $cmd muss zwischen 1 und 10 sein. Falls der Wert weggelassen wird, so wird 2 (für morgen) benutzt.": @@ -833,7 +835,7 @@ sub HOMEMODE_Get($@) return $trans if ($value && $value !~ /^[1-9]0?$/ && ($value < 1 || $value > 10)); HOMEMODE_ForecastTXT($hash,$value); } - elsif ($cmd eq "publicIP") + elsif ($cmd eq 'publicIP') { return HOMEMODE_checkIP($hash); } @@ -847,20 +849,20 @@ sub HOMEMODE_Set($@) { my ($hash,$name,@aa) = @_; my ($cmd,@args) = @aa; - return if (IsDisabled($name) && $cmd ne "?"); - $HOMEMODE_de = AttrVal("global","language","EN") eq "DE" || AttrVal($name,"HomeLanguage","EN") eq "DE" ? 1 : 0; + return if (IsDisabled($name) && $cmd ne '?'); + $HOMEMODE_de = AttrVal('global','language','EN') eq 'DE' || AttrVal($name,'HomeLanguage','EN') eq 'DE' ? 1 : 0; my $trans = $HOMEMODE_de? "\"set $name\" benötigt mindestens ein und maximal drei Argumente": "\"set $name\" needs at least one argument and maximum three arguments"; return $trans if (@aa > 3); my $option = defined $args[0] ? $args[0] : undef; my $value = defined $args[1] ? $args[1] : undef; - my $mode = ReadingsVal($name,"mode",""); - my $amode = ReadingsVal($name,"modeAlarm",""); - my $plocation = ReadingsVal($name,"location",""); - my $presence = ReadingsVal($name,"presence",""); + my $mode = ReadingsVal($name,'mode',''); + my $amode = ReadingsVal($name,'modeAlarm',''); + my $plocation = ReadingsVal($name,'location',''); + my $presence = ReadingsVal($name,'presence',''); my @locations = split /,/,$HOMEMODE_Locations; - my $slocations = HOMEMODE_AttrCheck($hash,"HomeSpecialLocations"); + my $slocations = HOMEMODE_AttrCheck($hash,'HomeSpecialLocations'); if ($slocations) { for (split /,/,$slocations) @@ -869,7 +871,7 @@ sub HOMEMODE_Set($@) } } my @modeparams = split /,/,$HOMEMODE_UserModesAll; - my $smodes = HOMEMODE_AttrCheck($hash,"HomeSpecialModes"); + my $smodes = HOMEMODE_AttrCheck($hash,'HomeSpecialModes'); if ($smodes) { for (split /,/,$smodes) @@ -878,77 +880,77 @@ sub HOMEMODE_Set($@) } } my $para; - $para .= "mode:".join(",",sort @modeparams)." " if (!AttrNum($name,"HomeAutoDaytime",1)); - $para .= "anyoneElseAtHome:on,off"; - $para .= " deviceDisable:"; - $para .= $hash->{helper}{enabledDevices} ? $hash->{helper}{enabledDevices} : "noArg"; - $para .= " deviceEnable:"; - $para .= ReadingsVal($name,"devicesDisabled","") ? ReadingsVal($name,"devicesDisabled","") : "noArg"; - $para .= " dnd:on,off"; - $para .= " dnd-for-minutes"; - $para .= " modeAlarm:$HOMEMODE_AlarmModes"; - $para .= " modeAlarm-for-minutes"; - $para .= " panic:on,off"; - $para .= " location:".join(",", sort @locations); - $para .= " updateInternalsForce:noArg"; - $para .= " updateHomebridgeMapping:noArg"; - return "$cmd is not a valid command for $name, please choose one of $para" if (!$cmd || $cmd eq "?"); + $para .= 'mode:'.join(',',sort @modeparams).' ' if (!AttrNum($name,'HomeAutoDaytime',1)); + $para .= 'anyoneElseAtHome:on,off'; + $para .= ' deviceDisable:'; + $para .= $hash->{helper}{enabledDevices} ? $hash->{helper}{enabledDevices} : 'noArg'; + $para .= ' deviceEnable:'; + $para .= ReadingsVal($name,'devicesDisabled','') ? ReadingsVal($name,'devicesDisabled','') : 'noArg'; + $para .= ' dnd:on,off'; + $para .= ' dnd-for-minutes'; + $para .= ' modeAlarm:'.$HOMEMODE_AlarmModes; + $para .= ' modeAlarm-for-minutes'; + $para .= ' panic:on,off'; + $para .= ' location:'.join(',', sort @locations); + $para .= ' updateInternalsForce:noArg'; + $para .= ' updateHomebridgeMapping:noArg'; + return "$cmd is not a valid command for $name, please choose one of $para" if (!$cmd || $cmd eq '?'); my @commands; - if ($cmd eq "mode") + if ($cmd eq 'mode') { - my $namode = "disarm"; - my $present = "absent"; - my $location = "underway"; - $option = HOMEMODE_DayTime($hash) if ($option && $option eq "home" && AttrNum($name,"HomeAutoDaytime",1)); + my $namode = 'disarm'; + my $present = 'absent'; + my $location = 'underway'; + $option = HOMEMODE_DayTime($hash) if ($option && $option eq 'home' && AttrNum($name,'HomeAutoDaytime',1)); if ($option !~ /^absent|gone$/) { - push @commands,AttrVal($name,"HomeCMDpresence-present","") if (AttrVal($name,"HomeCMDpresence-present",undef) && $mode =~ /^(absent|gone)$/); - $present = "present"; - $location = grep(/^$plocation$/,split /,/,$slocations) ? $plocation : "home"; - if ($presence eq "absent") + push @commands,AttrVal($name,'HomeCMDpresence-present','') if (AttrVal($name,'HomeCMDpresence-present',undef) && $mode =~ /^(absent|gone)$/); + $present = 'present'; + $location = grep(/^$plocation$/,split /,/,$slocations) ? $plocation : 'home'; + if ($presence eq 'absent') { - if (AttrNum($name,"HomeAutoArrival",0)) + if (AttrNum($name,'HomeAutoArrival',0)) { - my $hour = HOMEMODE_hourMaker(AttrNum($name,"HomeAutoArrival",0)); - CommandDelete(undef,"atTmp_set_home_$name") if (HOMEMODE_ID("atTmp_set_home_$name","at")); + my $hour = HOMEMODE_hourMaker(AttrNum($name,'HomeAutoArrival',0)); + CommandDelete(undef,"atTmp_set_home_$name") if (HOMEMODE_ID("atTmp_set_home_$name",'at')); CommandDefine(undef,"atTmp_set_home_$name at +$hour set $name:FILTER=location=arrival location home"); - $location = "arrival"; + $location = 'arrival'; } } - if ($option eq "asleep") + if ($option eq 'asleep') { - $namode = "armnight"; - $location = "bed"; + $namode = 'armnight'; + $location = 'bed'; } } elsif ($option =~ /^absent|gone$/) { - push @commands,AttrVal($name,"HomeCMDpresence-absent","") if (AttrVal($name,"HomeCMDpresence-absent",undef) && $mode !~ /^(absent|gone)$/); - $namode = ReadingsVal($name,"anyoneElseAtHome","off") eq "off" ? "armaway" : "armhome"; - if (AttrNum($name,"HomeModeAbsentBelatedTime",0) && AttrVal($name,"HomeCMDmode-absent-belated",undef)) + push @commands,AttrVal($name,'HomeCMDpresence-absent','') if (AttrVal($name,'HomeCMDpresence-absent',undef) && $mode !~ /^(absent|gone)$/); + $namode = ReadingsVal($name,'anyoneElseAtHome','off') eq 'off' ? 'armaway' : 'armhome'; + if (AttrNum($name,'HomeModeAbsentBelatedTime',0) && AttrVal($name,'HomeCMDmode-absent-belated',undef)) { - my $hour = HOMEMODE_hourMaker(AttrNum($name,"HomeModeAbsentBelatedTime",0)); - CommandDelete(undef,"atTmp_absent_belated_$name") if (HOMEMODE_ID("atTmp_absent_belated_$name","at")); + my $hour = HOMEMODE_hourMaker(AttrNum($name,'HomeModeAbsentBelatedTime',0)); + CommandDelete(undef,"atTmp_absent_belated_$name") if (HOMEMODE_ID("atTmp_absent_belated_$name",'at')); CommandDefine(undef,"atTmp_absent_belated_$name at +$hour {HOMEMODE_execCMDs_belated(\"$name\",\"HomeCMDmode-absent-belated\",\"$option\")}"); } } HOMEMODE_ContactOpenCheckAfterModeChange($hash,$option,$mode) if ($hash->{SENSORSCONTACT} && $option && $mode ne $option); - push @commands,AttrVal($name,"HomeCMDmode","") if ($mode && AttrVal($name,"HomeCMDmode",undef)); - push @commands,AttrVal($name,"HomeCMDmode-$option","") if (AttrVal($name,"HomeCMDmode-$option",undef)); + push @commands,AttrVal($name,'HomeCMDmode','') if ($mode && AttrVal($name,'HomeCMDmode',undef)); + push @commands,AttrVal($name,'HomeCMDmode-'.makeReadingName($option),'') if (AttrVal($name,'HomeCMDmode-'.makeReadingName($option),undef)); readingsBeginUpdate($hash); readingsBulkUpdate($hash,$cmd,$option); - readingsBulkUpdate($hash,"prevMode",$mode); - readingsBulkUpdateIfChanged($hash,"presence",$present); - readingsBulkUpdate($hash,"state",$option); + readingsBulkUpdate($hash,'prevMode',$mode); + readingsBulkUpdateIfChanged($hash,'presence',$present); + readingsBulkUpdate($hash,'state',$option); readingsEndUpdate($hash,1); CommandSet(undef,"$name:FILTER=location!=$location location $location"); - if (AttrNum($name,"HomeAutoAlarmModes",1)) + if (AttrNum($name,'HomeAutoAlarmModes',1)) { - CommandDelete(undef,"atTmp_modeAlarm_delayed_arm_$name") if (HOMEMODE_ID("atTmp_modeAlarm_delayed_arm_$name","at")); + CommandDelete(undef,"atTmp_modeAlarm_delayed_arm_$name") if (HOMEMODE_ID("atTmp_modeAlarm_delayed_arm_$name",'at')); CommandSet(undef,"$name:FILTER=modeAlarm!=$namode modeAlarm $namode"); } } - elsif ($cmd eq "modeAlarm-for-minutes") + elsif ($cmd eq 'modeAlarm-for-minutes') { $trans = $HOMEMODE_de? "$cmd benötigt zwei Parameter: einen modeAlarm und die Minuten": @@ -956,11 +958,11 @@ sub HOMEMODE_Set($@) return $trans if (!$option || !$value); my $timer = "atTmp_alarmMode_for_timer_$name"; my $time = HOMEMODE_hourMaker($value); - CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,"at")); + CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,'at')); CommandDefine(undef,"$timer at +$time set $name:FILTER=modeAlarm!=$amode modeAlarm $amode"); CommandSet(undef,"$name:FILTER=modeAlarm!=$option modeAlarm $option"); } - elsif ($cmd eq "dnd-for-minutes") + elsif ($cmd eq 'dnd-for-minutes') { $trans = $HOMEMODE_de? "$cmd benötigt einen Paramter: Minuten": @@ -969,44 +971,44 @@ sub HOMEMODE_Set($@) $trans = $HOMEMODE_de? "$name darf nicht im dnd Modus sein um diesen Modus für bestimmte Minuten zu setzen! Bitte deaktiviere den dnd Modus zuerst!": "$name can't be in dnd mode to turn dnd on for minutes! Please disable dnd mode first!"; - return $trans if (ReadingsVal($name,"dnd","off") eq "on"); + return $trans if (ReadingsVal($name,'dnd','off') eq 'on'); my $timer = "atTmp_dnd_for_timer_$name"; my $time = HOMEMODE_hourMaker($option); - CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,"at")); + CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,'at')); CommandDefine(undef,"$timer at +$time set $name:FILTER=dnd!=off dnd off"); CommandSet(undef,"$name:FILTER=dnd!=on dnd on"); } - elsif ($cmd eq "dnd") + elsif ($cmd eq 'dnd') { - push @commands,AttrVal($name,"HomeCMDdnd","") if (AttrVal($name,"HomeCMDdnd",undef)); - push @commands,AttrVal($name,"HomeCMDdnd-$option","") if (AttrVal($name,"HomeCMDdnd-$option",undef)); + push @commands,AttrVal($name,'HomeCMDdnd','') if (AttrVal($name,'HomeCMDdnd',undef)); + push @commands,AttrVal($name,"HomeCMDdnd-$option",'') if (AttrVal($name,"HomeCMDdnd-$option",undef)); readingsBeginUpdate($hash); readingsBulkUpdate($hash,$cmd,$option); - readingsBulkUpdate($hash,"state","dnd") if ($option eq "on"); - readingsBulkUpdate($hash,"state",$mode) if ($option ne "on"); + readingsBulkUpdate($hash,'state','dnd') if ($option eq 'on'); + readingsBulkUpdate($hash,'state',$mode) if ($option ne 'on'); readingsEndUpdate($hash,1); } - elsif ($cmd eq "location") + elsif ($cmd eq 'location') { - push @commands,AttrVal($name,"HomeCMDlocation","") if (AttrVal($name,"HomeCMDlocation",undef)); - push @commands,AttrVal($name,"HomeCMDlocation-$option","") if (AttrVal($name,"HomeCMDlocation-$option",undef)); + push @commands,AttrVal($name,'HomeCMDlocation','') if (AttrVal($name,'HomeCMDlocation',undef)); + push @commands,AttrVal($name,'HomeCMDlocation-'.makeReadingName($option),'') if (AttrVal($name,'HomeCMDlocation-'.makeReadingName($option),undef)); readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"prevLocation",$plocation); + readingsBulkUpdate($hash,'prevLocation',$plocation); readingsBulkUpdate($hash,$cmd,$option); readingsEndUpdate($hash,1); } - elsif ($cmd eq "modeAlarm") + elsif ($cmd eq 'modeAlarm') { - CommandDelete(undef,"atTmp_modeAlarm_delayed_arm_$name") if (HOMEMODE_ID("atTmp_modeAlarm_delayed_arm_$name","at")); + CommandDelete(undef,"atTmp_modeAlarm_delayed_arm_$name") if (HOMEMODE_ID("atTmp_modeAlarm_delayed_arm_$name",'at')); my $delay; - if ($option =~ /^arm/ && AttrVal($name,"HomeModeAlarmArmDelay",0)) + if ($option =~ /^arm/ && AttrVal($name,'HomeModeAlarmArmDelay',0)) { - my @delays = split " ",AttrVal($name,"HomeModeAlarmArmDelay",0); + my @delays = split ' ',AttrVal($name,'HomeModeAlarmArmDelay',0); if (defined $delays[1]) { - $delay = $delays[0] if ($option eq "armaway"); - $delay = $delays[1] if ($option eq "armnight"); - $delay = $delays[2] if ($option eq "armhome"); + $delay = $delays[0] if ($option eq 'armaway'); + $delay = $delays[1] if ($option eq 'armnight'); + $delay = $delays[2] if ($option eq 'armhome'); } else { @@ -1015,7 +1017,7 @@ sub HOMEMODE_Set($@) } if ($delay) { - my $hours = HOMEMODE_hourMaker(sprintf("%.2f",$delay / 60)); + my $hours = HOMEMODE_hourMaker(sprintf('%.2f',$delay / 60)); CommandDefine(undef,"atTmp_modeAlarm_delayed_arm_$name at +$hours {HOMEMODE_set_modeAlarm(\"$name\",\"$option\",\"$amode\")}"); } else @@ -1023,42 +1025,42 @@ sub HOMEMODE_Set($@) HOMEMODE_set_modeAlarm($name,$option,$amode); } } - elsif ($cmd eq "anyoneElseAtHome") + elsif ($cmd eq 'anyoneElseAtHome') { $trans = $HOMEMODE_de? "Zulässige Werte für $cmd sind nur on oder off!": "Values for $cmd can only be on or off!"; return $trans if ($option !~ /^(on|off)$/); - push @commands,AttrVal($name,"HomeCMDanyoneElseAtHome","") if (AttrVal($name,"HomeCMDanyoneElseAtHome",undef)); - push @commands,AttrVal($name,"HomeCMDanyoneElseAtHome-$option","") if (AttrVal($name,"HomeCMDanyoneElseAtHome-$option",undef)); - if (AttrNum($name,"HomeAutoAlarmModes",1)) + push @commands,AttrVal($name,'HomeCMDanyoneElseAtHome','') if (AttrVal($name,'HomeCMDanyoneElseAtHome',undef)); + push @commands,AttrVal($name,"HomeCMDanyoneElseAtHome-$option",'') if (AttrVal($name,"HomeCMDanyoneElseAtHome-$option",undef)); + if (AttrNum($name,'HomeAutoAlarmModes',1)) { - CommandSet(undef,"$name:FILTER=modeAlarm=armaway modeAlarm armhome") if ($option eq "on"); - CommandSet(undef,"$name:FILTER=modeAlarm=armhome modeAlarm armaway") if ($option eq "off"); + CommandSet(undef,"$name:FILTER=modeAlarm=armaway modeAlarm armhome") if ($option eq 'on'); + CommandSet(undef,"$name:FILTER=modeAlarm=armhome modeAlarm armaway") if ($option eq 'off'); } - readingsSingleUpdate($hash,"anyoneElseAtHome",$option,1); + readingsSingleUpdate($hash,'anyoneElseAtHome',$option,1); } - elsif ($cmd eq "panic") + elsif ($cmd eq 'panic') { $trans = $HOMEMODE_de? "Zulässige Werte für $cmd sind nur on oder off!": "Values for $cmd can only be on or off!"; return $trans if ($option !~ /^(on|off)$/); - push @commands,AttrVal($name,"HomeCMDpanic","") if (AttrVal($name,"HomeCMDpanic",undef)); - push @commands,AttrVal($name,"HomeCMDpanic-$option","") if (AttrVal($name,"HomeCMDpanic-$option",undef)); - readingsSingleUpdate($hash,"panic",$option,1); + push @commands,AttrVal($name,'HomeCMDpanic','') if (AttrVal($name,'HomeCMDpanic',undef)); + push @commands,AttrVal($name,"HomeCMDpanic-$option",'') if (AttrVal($name,"HomeCMDpanic-$option",undef)); + readingsSingleUpdate($hash,'panic',$option,1); } elsif ($cmd =~ /^device(Dis|En)able$/) { HOMEMODE_ToggleDevice($hash,$option) - if (($1 eq "En" && grep /^$option$/,split /,/,ReadingsVal($name,"devicesDisabled","")) - || ($1 eq "Dis" && grep /^$option$/,split /,/,$hash->{helper}{enabledDevices})); + if (($1 eq 'En' && grep /^$option$/,split /,/,ReadingsVal($name,'devicesDisabled','')) + || ($1 eq 'Dis' && grep /^$option$/,split /,/,$hash->{helper}{enabledDevices})); } - elsif ($cmd eq "updateInternalsForce") + elsif ($cmd eq 'updateInternalsForce') { HOMEMODE_updateInternals($hash,1,1); } - elsif ($cmd eq "updateHomebridgeMapping") + elsif ($cmd eq 'updateHomebridgeMapping') { HOMEMODE_HomebridgeMapping($hash); } @@ -1070,23 +1072,23 @@ sub HOMEMODE_set_modeAlarm($$$) { my ($name,$option,$amode) = @_; my $hash = $defs{$name}; - my $resident = $hash->{helper}{lar} ? $hash->{helper}{lar} : ReadingsVal($name,"lastActivityByResident",""); + my $resident = $hash->{helper}{lar} ? $hash->{helper}{lar} : ReadingsVal($name,'lastActivityByResident',''); delete $hash->{helper}{lar} if ($hash->{helper}{lar}); my @commands; - push @commands,AttrVal($name,"HomeCMDmodeAlarm","") if (AttrVal($name,"HomeCMDmodeAlarm",undef)); - push @commands,AttrVal($name,"HomeCMDmodeAlarm-$option","") if (AttrVal($name,"HomeCMDmodeAlarm-$option",undef)); - if ($option eq "confirm") + push @commands,AttrVal($name,'HomeCMDmodeAlarm','') if (AttrVal($name,'HomeCMDmodeAlarm',undef)); + push @commands,AttrVal($name,"HomeCMDmodeAlarm-$option",'') if (AttrVal($name,"HomeCMDmodeAlarm-$option",undef)); + if ($option eq 'confirm') { CommandDefine(undef,"atTmp_modeAlarm_confirm_$name at +00:00:30 setreading $name:FILTER=alarmState=confirmed alarmState $amode"); - readingsSingleUpdate($hash,"alarmState",$option."ed",1); + readingsSingleUpdate($hash,'alarmState',$option.'ed',1); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands),$resident) if (@commands); } else { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"prevModeAlarm",$amode); - readingsBulkUpdate($hash,"modeAlarm",$option); - readingsBulkUpdateIfChanged($hash,"alarmState",$option); + readingsBulkUpdate($hash,'prevModeAlarm',$amode); + readingsBulkUpdate($hash,'modeAlarm',$option); + readingsBulkUpdateIfChanged($hash,'alarmState',$option); readingsEndUpdate($hash,1); HOMEMODE_TriggerState($hash) if ($hash->{SENSORSCONTACT} || $hash->{SENSORSMOTION}); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands),$resident) if (@commands); @@ -1096,10 +1098,10 @@ sub HOMEMODE_set_modeAlarm($$$) sub HOMEMODE_execCMDs_belated($$$) { my ($name,$attrib,$option) = @_; - return if (!AttrVal($name,$attrib,undef) || ReadingsVal($name,"mode","") ne $option); + return if (!AttrVal($name,$attrib,undef) || ReadingsVal($name,'mode','') ne $option); my $hash = $defs{$name}; my @commands; - push @commands,AttrVal($name,$attrib,""); + push @commands,AttrVal($name,$attrib,''); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); } @@ -1109,25 +1111,25 @@ sub HOMEMODE_alarmTriggered($@) my $name = $hash->{NAME}; my @commands; my $text = HOMEMODE_makeHR($hash,0,@triggers); - push @commands,AttrVal($name,"HomeCMDalarmTriggered","") if (AttrVal($name,"HomeCMDalarmTriggered",undef)); + push @commands,AttrVal($name,'HomeCMDalarmTriggered','') if (AttrVal($name,'HomeCMDalarmTriggered',undef)); readingsBeginUpdate($hash); - readingsBulkUpdateIfChanged($hash,"alarmTriggered_ct",scalar @triggers); + readingsBulkUpdateIfChanged($hash,'alarmTriggered_ct',scalar @triggers); if ($text) { - push @commands,AttrVal($name,"HomeCMDalarmTriggered-on","") if (AttrVal($name,"HomeCMDalarmTriggered-on",undef)); - readingsBulkUpdateIfChanged($hash,"alarmTriggered",join ",",@triggers); - readingsBulkUpdateIfChanged($hash,"alarmTriggered_hr",$text); - readingsBulkUpdateIfChanged($hash,"alarmState","alarm"); + push @commands,AttrVal($name,'HomeCMDalarmTriggered-on','') if (AttrVal($name,'HomeCMDalarmTriggered-on',undef)); + readingsBulkUpdateIfChanged($hash,'alarmTriggered',join ',',@triggers); + readingsBulkUpdateIfChanged($hash,'alarmTriggered_hr',$text); + readingsBulkUpdateIfChanged($hash,'alarmState','alarm'); } else { - push @commands,AttrVal($name,"HomeCMDalarmTriggered-off","") if (AttrVal($name,"HomeCMDalarmTriggered-off",undef) && ReadingsVal($name,"alarmTriggered","")); - readingsBulkUpdateIfChanged($hash,"alarmTriggered",""); - readingsBulkUpdateIfChanged($hash,"alarmTriggered_hr",""); - readingsBulkUpdateIfChanged($hash,"alarmState",ReadingsVal($name,"modeAlarm","disarm")); + push @commands,AttrVal($name,'HomeCMDalarmTriggered-off','') if (AttrVal($name,'HomeCMDalarmTriggered-off',undef) && ReadingsVal($name,'alarmTriggered','')); + readingsBulkUpdateIfChanged($hash,'alarmTriggered',''); + readingsBulkUpdateIfChanged($hash,'alarmTriggered_hr',''); + readingsBulkUpdateIfChanged($hash,'alarmState',ReadingsVal($name,'modeAlarm','disarm')); } readingsEndUpdate($hash,1); - HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands && ReadingsAge($name,"modeAlarm","") > 5); + HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands && ReadingsAge($name,'modeAlarm','') > 5); } sub HOMEMODE_makeHR($$@) @@ -1135,7 +1137,7 @@ sub HOMEMODE_makeHR($$@) my ($hash,$noart,@names) = @_; my $name = $hash->{NAME}; my @aliases; - my $and = (split /\|/,AttrVal($name,"HomeTextAndAreIs","and|are|is"))[0]; + my $and = (split /\|/,AttrVal($name,'HomeTextAndAreIs','and|are|is'))[0]; my $text; for (@names) { @@ -1152,12 +1154,12 @@ sub HOMEMODE_makeHR($$@) for (my $i = 1; $i < @aliases; $i++) { $text .= " $and " if ($i == @aliases - 1); - $text .= ", " if ($i < @aliases - 1); + $text .= ', ' if ($i < @aliases - 1); $text .= $aliases[$i]; } } } - $text = $text ? $text : ""; + $text = $text ? $text : ''; return $text; } @@ -1167,14 +1169,14 @@ sub HOMEMODE_alarmTampered($@) my $name = $hash->{NAME}; my @commands; my $text = HOMEMODE_makeHR($hash,0,@triggers); - push @commands,AttrVal($name,"HomeCMDalarmTampered","") if (AttrVal($name,"HomeCMDalarmTampered",undef)); + push @commands,AttrVal($name,'HomeCMDalarmTampered','') if (AttrVal($name,'HomeCMDalarmTampered',undef)); if ($text) { - push @commands,AttrVal($name,"HomeCMDalarmTampered-on","") if (AttrVal($name,"HomeCMDalarmTampered-on",undef)); + push @commands,AttrVal($name,'HomeCMDalarmTampered-on','') if (AttrVal($name,'HomeCMDalarmTampered-on',undef)); } else { - push @commands,AttrVal($name,"HomeCMDalarmTampered-off","") if (AttrVal($name,"HomeCMDalarmTampered-off",undef)); + push @commands,AttrVal($name,'HomeCMDalarmTampered-off','') if (AttrVal($name,'HomeCMDalarmTampered-off',undef)); } HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); } @@ -1187,10 +1189,10 @@ sub HOMEMODE_RESIDENTS($;$) my $events = deviceEvents($defs{$dev},1); my $devtype = $defs{$dev}->{TYPE}; Log3 $name,5,"$name: HOMEMODE_RESIDENTS dev: $dev type: $devtype"; - my $lad = ReadingsVal($name,"lastActivityByResident",""); + my $lad = ReadingsVal($name,'lastActivityByResident',''); my $mode; - my $ema = ReplaceEventMap($dev,"absent",1); - my $emp = ReplaceEventMap($dev,"present",1); + my $ema = ReplaceEventMap($dev,'absent',1); + my $emp = ReplaceEventMap($dev,'present',1); if (grep /^state:\s/,@{$events}) { for (@{$events}) @@ -1201,42 +1203,42 @@ sub HOMEMODE_RESIDENTS($;$) last; } } - if ($mode && $devtype eq "RESIDENTS") + if ($mode && $devtype eq 'RESIDENTS') { - readingsSingleUpdate($hash,"lastActivityByResident",ReadingsVal($dev,"lastActivityByDev",""),1); - $mode = $mode eq "home" && AttrNum($name,"HomeAutoDaytime",1) ? HOMEMODE_DayTime($hash) : $mode; + readingsSingleUpdate($hash,'lastActivityByResident',ReadingsVal($dev,'lastActivityByDev',''),1); + $mode = $mode eq 'home' && AttrNum($name,'HomeAutoDaytime',1) ? HOMEMODE_DayTime($hash) : $mode; CommandSet(undef,"$name:FILTER=mode!=$mode mode $mode"); } elsif ($devtype =~ /^ROOMMATE|GUEST|PET$/) { readingsBeginUpdate($hash); - readingsBulkUpdateIfChanged($hash,"lastActivityByResident",$dev); - readingsBulkUpdate($hash,"prevActivityByResident",$lad); + readingsBulkUpdateIfChanged($hash,'lastActivityByResident',$dev); + readingsBulkUpdate($hash,'prevActivityByResident',$lad); readingsEndUpdate($hash,1); my @commands; if (grep /^wayhome:\s1$/,@{$events}) { - CommandSet(undef,"$name:FILTER=location!=wayhome location wayhome") if (ReadingsVal($name,"state","") =~ /^absent|gone$/); + CommandSet(undef,"$name:FILTER=location!=wayhome location wayhome") if (ReadingsVal($name,'state','') =~ /^absent|gone$/); } elsif (grep /^wayhome:\s0$/,@{$events}) { my $rx = $hash->{RESIDENTS}; $rx =~ s/,/|/g; - CommandSet(undef,"$name:FILTER=location!=underway location underway") if (ReadingsVal($name,"state","") =~ /^absent|gone$/ && !devspec2array("$rx:FILTER=wayhome=1")); + CommandSet(undef,"$name:FILTER=location!=underway location underway") if (ReadingsVal($name,'state','') =~ /^absent|gone$/ && !devspec2array("$rx:FILTER=wayhome=1")); } if (grep /^presence:\s$ema$/,@{$events}) { Log3 $name,5,"$name: HOMEMODE_RESIDENTS dev: $dev - presence: $ema"; - readingsSingleUpdate($hash,"lastAbsentByResident",$dev,1); - push @commands,AttrVal($name,"HomeCMDpresence-absent-resident","") if (AttrVal($name,"HomeCMDpresence-absent-resident",undef)); - push @commands,AttrVal($name,"HomeCMDpresence-absent-$dev","") if (AttrVal($name,"HomeCMDpresence-absent-$dev",undef)); + readingsSingleUpdate($hash,'lastAbsentByResident',$dev,1); + push @commands,AttrVal($name,'HomeCMDpresence-absent-resident','') if (AttrVal($name,'HomeCMDpresence-absent-resident',undef)); + push @commands,AttrVal($name,"HomeCMDpresence-absent-$dev",'') if (AttrVal($name,"HomeCMDpresence-absent-$dev",undef)); } elsif (grep /^presence:\s$emp$/,@{$events}) { Log3 $name,5,"$name: HOMEMODE_RESIDENTS dev: $dev - presence: $emp"; - readingsSingleUpdate($hash,"lastPresentByResident",$dev,1); - push @commands,AttrVal($name,"HomeCMDpresence-present-resident","") if (AttrVal($name,"HomeCMDpresence-present-resident",undef)); - push @commands,AttrVal($name,"HomeCMDpresence-present-$dev","") if (AttrVal($name,"HomeCMDpresence-present-$dev",undef)); + readingsSingleUpdate($hash,'lastPresentByResident',$dev,1); + push @commands,AttrVal($name,'HomeCMDpresence-present-resident','') if (AttrVal($name,'HomeCMDpresence-present-resident',undef)); + push @commands,AttrVal($name,"HomeCMDpresence-present-$dev",'') if (AttrVal($name,"HomeCMDpresence-present-$dev",undef)); } if (grep /^location:\s/,@{$events}) { @@ -1250,57 +1252,57 @@ sub HOMEMODE_RESIDENTS($;$) if ($loc) { Log3 $name,5,"$name: HOMEMODE_RESIDENTS dev: $dev - location: $loc"; - readingsSingleUpdate($hash,"lastLocationByResident","$dev - $loc",1); - push @commands,AttrVal($name,"HomeCMDlocation-resident","") if (AttrVal($name,"HomeCMDlocation-resident",undef)); - push @commands,AttrVal($name,"HomeCMDlocation-$loc-resident","") if (AttrVal($name,"HomeCMDlocation-$loc-resident",undef)); - push @commands,AttrVal($name,"HomeCMDlocation-$loc-$dev","") if (AttrVal($name,"HomeCMDlocation-$loc-$dev",undef)); + readingsSingleUpdate($hash,'lastLocationByResident',"$dev - $loc",1); + push @commands,AttrVal($name,'HomeCMDlocation-resident','') if (AttrVal($name,'HomeCMDlocation-resident',undef)); + push @commands,AttrVal($name,'HomeCMDlocation-'.makeReadingName($loc).'-resident','') if (AttrVal($name,'HomeCMDlocation-'.makeReadingName($loc).'-resident',undef)); + push @commands,AttrVal($name,'HomeCMDlocation-'.makeReadingName($loc).'-'.$dev,'') if (AttrVal($name,'HomeCMDlocation-'.makeReadingName($loc).'-'.$dev,undef)); } } if ($mode) { - my $ls = ReadingsVal($dev,"lastState",""); - if ($mode =~ /^(home|awoken)$/ && AttrNum($name,"HomeAutoAwoken",0)) + my $ls = ReadingsVal($dev,'lastState',''); + if ($mode =~ /^(home|awoken)$/ && AttrNum($name,'HomeAutoAwoken',0)) { - if ($mode eq "home" && $ls eq "asleep") + if ($mode eq 'home' && $ls eq 'asleep') { AnalyzeCommandChain(undef,"sleep 0.1; set $dev:FILTER=state!=awoken state awoken"); return; } - elsif ($mode eq "awoken") + elsif ($mode eq 'awoken') { - my $hours = HOMEMODE_hourMaker(AttrNum($name,"HomeAutoAwoken",0)); - CommandDelete(undef,"atTmp_awoken_".$dev."_$name") if (HOMEMODE_ID("atTmp_awoken_".$dev."_$name","at")); - CommandDefine(undef,"atTmp_awoken_".$dev."_$name at +$hours set $dev:FILTER=state=awoken state home"); + my $hours = HOMEMODE_hourMaker(AttrNum($name,'HomeAutoAwoken',0)); + CommandDelete(undef,'atTmp_awoken_'.$dev."_$name") if (HOMEMODE_ID('atTmp_awoken_'.$dev."_$name",'at')); + CommandDefine(undef,'atTmp_awoken_'.$dev."_$name at +$hours set $dev:FILTER=state=awoken state home"); } } - if ($mode eq "home" && $ls =~ /^absent|[gn]one$/ && AttrNum($name,"HomeAutoArrival",0)) + if ($mode eq 'home' && $ls =~ /^absent|[gn]one$/ && AttrNum($name,'HomeAutoArrival',0)) { - my $hours = HOMEMODE_hourMaker(AttrNum($name,"HomeAutoArrival",0)); + my $hours = HOMEMODE_hourMaker(AttrNum($name,'HomeAutoArrival',0)); AnalyzeCommandChain(undef,"sleep 0.1; set $dev:FILTER=location!=arrival location arrival"); - CommandDelete(undef,"atTmp_location_home_".$dev."_$name") if (HOMEMODE_ID("atTmp_location_home_".$dev."_$name","at")); - CommandDefine(undef,"atTmp_location_home_".$dev."_$name at +$hours set $dev:FILTER=location=arrival location home"); + CommandDelete(undef,'atTmp_location_home_'.$dev."_$name") if (HOMEMODE_ID('atTmp_location_home_'.$dev."_$name",'at')); + CommandDefine(undef,'atTmp_location_home_'.$dev."_$name at +$hours set $dev:FILTER=location=arrival location home"); } - elsif ($mode eq "gotosleep" && AttrNum($name,"HomeAutoAsleep",0)) + elsif ($mode eq 'gotosleep' && AttrNum($name,'HomeAutoAsleep',0)) { - my $hours = HOMEMODE_hourMaker(AttrNum($name,"HomeAutoAsleep",0)); - CommandDelete(undef,"atTmp_asleep_".$dev."_$name") if (HOMEMODE_ID("atTmp_asleep_".$dev."_$name","at")); - CommandDefine(undef,"atTmp_asleep_".$dev."_$name at +$hours set $dev:FILTER=state=gotosleep state asleep"); + my $hours = HOMEMODE_hourMaker(AttrNum($name,'HomeAutoAsleep',0)); + CommandDelete(undef,'atTmp_asleep_'.$dev."_$name") if (HOMEMODE_ID('atTmp_asleep_'.$dev."_$name",'at')); + CommandDefine(undef,'atTmp_asleep_'.$dev."_$name at +$hours set $dev:FILTER=state=gotosleep state asleep"); } - push @commands,AttrVal($name,"HomeCMDmode-$mode-resident","") if (AttrVal($name,"HomeCMDmode-$mode-resident",undef)); - push @commands,AttrVal($name,"HomeCMDmode-$mode-$dev","") if (AttrVal($name,"HomeCMDmode-$mode-$dev",undef)); + push @commands,AttrVal($name,"HomeCMDmode-$mode-resident",'') if (AttrVal($name,"HomeCMDmode-$mode-resident",undef)); + push @commands,AttrVal($name,"HomeCMDmode-$mode-$dev",'') if (AttrVal($name,"HomeCMDmode-$mode-$dev",undef)); readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"lastAsleepByResident",$dev) if ($mode eq "asleep"); - readingsBulkUpdate($hash,"lastAwokenByResident",$dev) if ($mode eq "awoken"); - readingsBulkUpdate($hash,"lastGoneByResident",$dev) if ($mode =~ /^[gn]one$/); - readingsBulkUpdate($hash,"lastGotosleepByResident",$dev) if ($mode eq "gotosleep"); + readingsBulkUpdate($hash,'lastAsleepByResident',$dev) if ($mode eq 'asleep'); + readingsBulkUpdate($hash,'lastAwokenByResident',$dev) if ($mode eq 'awoken'); + readingsBulkUpdate($hash,'lastGoneByResident',$dev) if ($mode =~ /^[gn]one$/); + readingsBulkUpdate($hash,'lastGotosleepByResident',$dev) if ($mode eq 'gotosleep'); readingsEndUpdate($hash,1); HOMEMODE_ContactOpenCheckAfterModeChange($hash,undef,undef,$dev); } if (@commands) { - my $delay = AttrNum($name,"HomeResidentCmdDelay",1); - my $cmd = encode_base64(HOMEMODE_serializeCMD($hash,@commands),""); - InternalTimer(gettimeofday() + $delay,"HOMEMODE_execUserCMDs","$name|$cmd|$dev"); + my $delay = AttrNum($name,'HomeResidentCmdDelay',1); + my $cmd = encode_base64(HOMEMODE_serializeCMD($hash,@commands),''); + InternalTimer(gettimeofday() + $delay,'HOMEMODE_execUserCMDs',"$name|$cmd|$dev"); } } return; @@ -1311,167 +1313,169 @@ sub HOMEMODE_Attributes($) my ($hash) = @_; my $name = $hash->{NAME}; my @attribs; - push @attribs,"disable:1,0"; - push @attribs,"disabledForIntervals"; - push @attribs,"HomeAdvancedDetails:none,detail,both,room"; - push @attribs,"HomeAdvancedUserAttr:1,0"; - push @attribs,"HomeAutoAlarmModes:0,1"; - push @attribs,"HomeAutoArrival"; - push @attribs,"HomeAutoAsleep"; - 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"; - push @attribs,"HomeCMDalarmTampered:textField-long"; - push @attribs,"HomeCMDalarmTampered-off:textField-long"; - push @attribs,"HomeCMDalarmTampered-on:textField-long"; - push @attribs,"HomeCMDalarmTriggered:textField-long"; - push @attribs,"HomeCMDalarmTriggered-off:textField-long"; - push @attribs,"HomeCMDalarmTriggered-on:textField-long"; - push @attribs,"HomeCMDanyoneElseAtHome:textField-long"; - push @attribs,"HomeCMDanyoneElseAtHome-on:textField-long"; - push @attribs,"HomeCMDanyoneElseAtHome-off:textField-long"; - push @attribs,"HomeCMDbattery:textField-long"; - push @attribs,"HomeCMDbatteryLow:textField-long"; - push @attribs,"HomeCMDbatteryNormal:textField-long"; - push @attribs,"HomeCMDcontact:textField-long"; - push @attribs,"HomeCMDcontactClosed:textField-long"; - push @attribs,"HomeCMDcontactOpen:textField-long"; - push @attribs,"HomeCMDcontactDoormain:textField-long"; - push @attribs,"HomeCMDcontactDoormainClosed:textField-long"; - push @attribs,"HomeCMDcontactDoormainOpen:textField-long"; - push @attribs,"HomeCMDcontactOpenWarning1:textField-long"; - push @attribs,"HomeCMDcontactOpenWarning2:textField-long"; - push @attribs,"HomeCMDcontactOpenWarningLast:textField-long"; - push @attribs,"HomeCMDdaytime:textField-long"; - push @attribs,"HomeCMDdeviceDisable:textField-long"; - push @attribs,"HomeCMDdeviceEnable:textField-long"; - push @attribs,"HomeCMDdnd:textField-long"; - push @attribs,"HomeCMDdnd-off:textField-long"; - push @attribs,"HomeCMDdnd-on:textField-long"; - push @attribs,"HomeCMDevent:textField-long"; - push @attribs,"HomeCMDfhemDEFINED:textField-long"; - push @attribs,"HomeCMDfhemINITIALIZED:textField-long"; - push @attribs,"HomeCMDfhemSAVE:textField-long"; - push @attribs,"HomeCMDfhemUPDATE:textField-long"; - push @attribs,"HomeCMDicewarning:textField-long"; - push @attribs,"HomeCMDicewarning-on:textField-long"; - push @attribs,"HomeCMDicewarning-off:textField-long"; - push @attribs,"HomeCMDlocation:textField-long"; + push @attribs,'disable:1,0'; + push @attribs,'disabledForIntervals'; + push @attribs,'HomeAdvancedDetails:none,detail,both,room'; + push @attribs,'HomeAdvancedUserAttr:1,0'; + push @attribs,'HomeAutoAlarmModes:0,1'; + push @attribs,'HomeAutoArrival'; + push @attribs,'HomeAutoAsleep'; + 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'; + push @attribs,'HomeCMDalarmTampered:textField-long'; + push @attribs,'HomeCMDalarmTampered-off:textField-long'; + push @attribs,'HomeCMDalarmTampered-on:textField-long'; + push @attribs,'HomeCMDalarmTriggered:textField-long'; + push @attribs,'HomeCMDalarmTriggered-off:textField-long'; + push @attribs,'HomeCMDalarmTriggered-on:textField-long'; + push @attribs,'HomeCMDanyoneElseAtHome:textField-long'; + push @attribs,'HomeCMDanyoneElseAtHome-on:textField-long'; + push @attribs,'HomeCMDanyoneElseAtHome-off:textField-long'; + push @attribs,'HomeCMDbattery:textField-long'; + push @attribs,'HomeCMDbatteryLow:textField-long'; + push @attribs,'HomeCMDbatteryNormal:textField-long'; + push @attribs,'HomeCMDcontact:textField-long'; + push @attribs,'HomeCMDcontactClosed:textField-long'; + push @attribs,'HomeCMDcontactOpen:textField-long'; + push @attribs,'HomeCMDcontactDoormain:textField-long'; + push @attribs,'HomeCMDcontactDoormainClosed:textField-long'; + push @attribs,'HomeCMDcontactDoormainOpen:textField-long'; + push @attribs,'HomeCMDcontactOpenWarning1:textField-long'; + push @attribs,'HomeCMDcontactOpenWarning2:textField-long'; + push @attribs,'HomeCMDcontactOpenWarningLast:textField-long'; + push @attribs,'HomeCMDdaytime:textField-long'; + push @attribs,'HomeCMDdeviceDisable:textField-long'; + push @attribs,'HomeCMDdeviceEnable:textField-long'; + push @attribs,'HomeCMDdnd:textField-long'; + push @attribs,'HomeCMDdnd-off:textField-long'; + push @attribs,'HomeCMDdnd-on:textField-long'; + push @attribs,'HomeCMDevent:textField-long'; + push @attribs,'HomeCMDfhemDEFINED:textField-long'; + push @attribs,'HomeCMDfhemINITIALIZED:textField-long'; + push @attribs,'HomeCMDfhemSAVE:textField-long'; + push @attribs,'HomeCMDfhemUPDATE:textField-long'; + push @attribs,'HomeCMDicewarning:textField-long'; + push @attribs,'HomeCMDicewarning-on:textField-long'; + push @attribs,'HomeCMDicewarning-off:textField-long'; + push @attribs,'HomeCMDlocation:textField-long'; for (split /,/,$HOMEMODE_Locations) { push @attribs,"HomeCMDlocation-$_:textField-long"; } - push @attribs,"HomeCMDlocation-resident:textField-long"; - push @attribs,"HomeCMDmode:textField-long"; - push @attribs,"HomeCMDmode-absent-belated:textField-long"; + push @attribs,'HomeCMDlocation-resident:textField-long'; + push @attribs,'HomeCMDmode:textField-long'; + push @attribs,'HomeCMDmode-absent-belated:textField-long'; for (split /,/,$HOMEMODE_UserModesAll) { push @attribs,"HomeCMDmode-$_:textField-long"; push @attribs,"HomeCMDmode-$_-resident:textField-long"; } - push @attribs,"HomeCMDmodeAlarm:textField-long"; + push @attribs,'HomeCMDmodeAlarm:textField-long'; for (split /,/,$HOMEMODE_AlarmModes) { push @attribs,"HomeCMDmodeAlarm-$_:textField-long"; } - push @attribs,"HomeCMDmotion:textField-long"; - push @attribs,"HomeCMDmotion-on:textField-long"; - push @attribs,"HomeCMDmotion-off:textField-long"; - push @attribs,"HomeCMDpanic:textField-long"; - push @attribs,"HomeCMDpanic-on:textField-long"; - push @attribs,"HomeCMDpanic-off:textField-long"; - push @attribs,"HomeCMDpresence-absent:textField-long"; - push @attribs,"HomeCMDpresence-present:textField-long"; - push @attribs,"HomeCMDpresence-absent-device:textField-long"; - push @attribs,"HomeCMDpresence-present-device:textField-long"; - push @attribs,"HomeCMDpresence-absent-resident:textField-long"; - push @attribs,"HomeCMDpresence-present-resident:textField-long"; - push @attribs,"HomeCMDpublic-ip-change:textField-long"; - push @attribs,"HomeCMDseason:textField-long"; - push @attribs,"HomeCMDtwilight:textField-long"; - push @attribs,"HomeCMDtwilight-sr:textField-long"; - push @attribs,"HomeCMDtwilight-sr_astro:textField-long"; - push @attribs,"HomeCMDtwilight-sr_civil:textField-long"; - push @attribs,"HomeCMDtwilight-sr_indoor:textField-long"; - push @attribs,"HomeCMDtwilight-sr_weather:textField-long"; - push @attribs,"HomeCMDtwilight-ss:textField-long"; - push @attribs,"HomeCMDtwilight-ss_astro:textField-long"; - push @attribs,"HomeCMDtwilight-ss_civil:textField-long"; - push @attribs,"HomeCMDtwilight-ss_indoor:textField-long"; - push @attribs,"HomeCMDtwilight-ss_weather:textField-long"; - push @attribs,"HomeCMDuwz-warn:textField-long"; - push @attribs,"HomeCMDuwz-warn-begin:textField-long"; - push @attribs,"HomeCMDuwz-warn-end:textField-long"; - push @attribs,"HomeDaytimes:textField-long"; - push @attribs,"HomeEventsCalendarDevices"; - push @attribs,"HomeEventsHolidayDevices"; - push @attribs,"HomeIcewarningOnOffTemps"; - push @attribs,"HomeLanguage:DE,EN"; - push @attribs,"HomeModeAlarmArmDelay"; - push @attribs,"HomeModeAbsentBelatedTime"; - push @attribs,"HomeAtTmpRoom"; - push @attribs,"HomePresenceDeviceType"; - push @attribs,"HomePublicIpCheckInterval"; - push @attribs,"HomeResidentCmdDelay"; - push @attribs,"HomeSeasons:textField-long"; - push @attribs,"HomeSensorAirpressure"; - push @attribs,"HomeSensorHumidityOutside"; - push @attribs,"HomeSensorTemperatureOutside"; - push @attribs,"HomeSensorWindspeed"; - push @attribs,"HomeSensorsBattery"; - push @attribs,"HomeSensorsBatteryLowPercentage"; - push @attribs,"HomeSensorsBatteryReading"; - push @attribs,"HomeSensorsContact"; - push @attribs,"HomeSensorsContactReadings"; - push @attribs,"HomeSensorsContactValues"; - push @attribs,"HomeSensorsContactOpenTimeDividers"; - push @attribs,"HomeSensorsContactOpenTimeMin"; - push @attribs,"HomeSensorsContactOpenTimes"; - push @attribs,"HomeSensorsLuminance"; - push @attribs,"HomeSensorsLuminanceReading"; - push @attribs,"HomeSensorsMotion"; - push @attribs,"HomeSensorsMotionReadings"; - push @attribs,"HomeSensorsMotionValues"; - push @attribs,"HomeSensorsPowerEnergy"; - push @attribs,"HomeSensorsPowerEnergyReadings"; - push @attribs,"HomeSensorsSmoke"; - push @attribs,"HomeSensorsSmokeReading"; - push @attribs,"HomeSensorsSmokeValue"; - push @attribs,"HomeSpecialLocations"; - push @attribs,"HomeSpecialModes"; - push @attribs,"HomeTextAndAreIs"; - push @attribs,"HomeTextClosedOpen"; - push @attribs,"HomeTextNosmokeSmoke"; - push @attribs,"HomeTextRisingConstantFalling"; - push @attribs,"HomeTextTodayTomorrowAfterTomorrow"; - push @attribs,"HomeTextWeatherForecastToday:textField-long"; - push @attribs,"HomeTextWeatherForecastTomorrow:textField-long"; - push @attribs,"HomeTextWeatherForecastInSpecDays:textField-long"; - push @attribs,"HomeTextWeatherNoForecast:textField-long"; - push @attribs,"HomeTextWeatherLong:textField-long"; - push @attribs,"HomeTextWeatherShort:textField-long"; - push @attribs,"HomeTrendCalcAge:900,1800,2700,3600"; - push @attribs,"HomeTriggerAnyoneElseAtHome"; - push @attribs,"HomeTriggerPanic"; - push @attribs,"HomeTwilightDevice"; - push @attribs,"HomeUWZ"; - push @attribs,"HomeWeatherDevice"; - return join(" ",@attribs); + push @attribs,'HomeCMDmotion:textField-long'; + push @attribs,'HomeCMDmotion-on:textField-long'; + push @attribs,'HomeCMDmotion-off:textField-long'; + push @attribs,'HomeCMDpanic:textField-long'; + push @attribs,'HomeCMDpanic-on:textField-long'; + push @attribs,'HomeCMDpanic-off:textField-long'; + push @attribs,'HomeCMDpresence-absent:textField-long'; + push @attribs,'HomeCMDpresence-present:textField-long'; + push @attribs,'HomeCMDpresence-absent-device:textField-long'; + push @attribs,'HomeCMDpresence-present-device:textField-long'; + push @attribs,'HomeCMDpresence-absent-resident:textField-long'; + push @attribs,'HomeCMDpresence-present-resident:textField-long'; + push @attribs,'HomeCMDpublic-ip-change:textField-long'; + push @attribs,'HomeCMDseason:textField-long'; + push @attribs,'HomeCMDtwilight:textField-long'; + push @attribs,'HomeCMDtwilight-sr:textField-long'; + push @attribs,'HomeCMDtwilight-sr_astro:textField-long'; + push @attribs,'HomeCMDtwilight-sr_civil:textField-long'; + push @attribs,'HomeCMDtwilight-sr_indoor:textField-long'; + push @attribs,'HomeCMDtwilight-sr_naut:textField-long'; + push @attribs,'HomeCMDtwilight-sr_weather:textField-long'; + push @attribs,'HomeCMDtwilight-ss:textField-long'; + push @attribs,'HomeCMDtwilight-ss_astro:textField-long'; + push @attribs,'HomeCMDtwilight-ss_civil:textField-long'; + push @attribs,'HomeCMDtwilight-ss_indoor:textField-long'; + push @attribs,'HomeCMDtwilight-ss_naut:textField-long'; + push @attribs,'HomeCMDtwilight-ss_weather:textField-long'; + push @attribs,'HomeCMDuwz-warn:textField-long'; + push @attribs,'HomeCMDuwz-warn-begin:textField-long'; + push @attribs,'HomeCMDuwz-warn-end:textField-long'; + push @attribs,'HomeDaytimes:textField-long'; + push @attribs,'HomeEventsCalendarDevices'; + push @attribs,'HomeEventsHolidayDevices'; + push @attribs,'HomeIcewarningOnOffTemps'; + push @attribs,'HomeLanguage:DE,EN'; + push @attribs,'HomeModeAlarmArmDelay'; + push @attribs,'HomeModeAbsentBelatedTime'; + push @attribs,'HomeAtTmpRoom'; + push @attribs,'HomePresenceDeviceType'; + push @attribs,'HomePublicIpCheckInterval'; + push @attribs,'HomeResidentCmdDelay'; + push @attribs,'HomeSeasons:textField-long'; + push @attribs,'HomeSensorAirpressure'; + push @attribs,'HomeSensorHumidityOutside'; + push @attribs,'HomeSensorTemperatureOutside'; + push @attribs,'HomeSensorWindspeed'; + push @attribs,'HomeSensorsBattery'; + push @attribs,'HomeSensorsBatteryLowPercentage'; + push @attribs,'HomeSensorsBatteryReading'; + push @attribs,'HomeSensorsContact'; + push @attribs,'HomeSensorsContactReadings'; + push @attribs,'HomeSensorsContactValues'; + push @attribs,'HomeSensorsContactOpenTimeDividers'; + push @attribs,'HomeSensorsContactOpenTimeMin'; + push @attribs,'HomeSensorsContactOpenTimes'; + push @attribs,'HomeSensorsLuminance'; + push @attribs,'HomeSensorsLuminanceReading'; + push @attribs,'HomeSensorsMotion'; + push @attribs,'HomeSensorsMotionReadings'; + push @attribs,'HomeSensorsMotionValues'; + push @attribs,'HomeSensorsPowerEnergy'; + push @attribs,'HomeSensorsPowerEnergyReadings'; + push @attribs,'HomeSensorsSmoke'; + push @attribs,'HomeSensorsSmokeReading'; + push @attribs,'HomeSensorsSmokeValue'; + push @attribs,'HomeSpecialLocations'; + push @attribs,'HomeSpecialModes'; + push @attribs,'HomeTextAndAreIs'; + push @attribs,'HomeTextClosedOpen'; + push @attribs,'HomeTextNosmokeSmoke'; + push @attribs,'HomeTextRisingConstantFalling'; + push @attribs,'HomeTextTodayTomorrowAfterTomorrow'; + push @attribs,'HomeTextWeatherForecastToday:textField-long'; + push @attribs,'HomeTextWeatherForecastTomorrow:textField-long'; + push @attribs,'HomeTextWeatherForecastInSpecDays:textField-long'; + push @attribs,'HomeTextWeatherNoForecast:textField-long'; + push @attribs,'HomeTextWeatherLong:textField-long'; + push @attribs,'HomeTextWeatherShort:textField-long'; + push @attribs,'HomeTrendCalcAge:900,1800,2700,3600'; + push @attribs,'HomeTriggerAnyoneElseAtHome'; + push @attribs,'HomeTriggerPanic'; + push @attribs,'HomeTwilightDevice'; + push @attribs,'HomeUWZ'; + push @attribs,'HomeWeatherDevice'; + return join(' ',@attribs); } sub HOMEMODE_userattr($) { my ($hash) = @_; my $name = $hash->{NAME}; - my $adv = HOMEMODE_AttrCheck($hash,"HomeAdvancedUserAttr",0); + my $adv = HOMEMODE_AttrCheck($hash,'HomeAdvancedUserAttr',0); my @userattrAll; my @homeattr; my @stayattr; - for (split " ",AttrVal($name,"userattr","")) + for (split ' ',AttrVal($name,'userattr','')) { if ($_ =~ /^Home/) { @@ -1482,17 +1486,17 @@ sub HOMEMODE_userattr($) push @stayattr,$_; } } - for (split /,/,HOMEMODE_AttrCheck($hash,"HomeSpecialModes")) + for (split /,/,HOMEMODE_AttrCheck($hash,'HomeSpecialModes')) { - push @userattrAll,"HomeCMDmode-$_"; + push @userattrAll,'HomeCMDmode-'.makeReadingName($_); } - for (split /,/,HOMEMODE_AttrCheck($hash,"HomeSpecialLocations")) + for (split /,/,HOMEMODE_AttrCheck($hash,'HomeSpecialLocations')) { - push @userattrAll,"HomeCMDlocation-$_"; + push @userattrAll,'HomeCMDlocation-'.makeReadingName($_); } - if (HOMEMODE_AttrCheck($hash,"HomeEventsHolidayDevices")) + if (HOMEMODE_AttrCheck($hash,'HomeEventsHolidayDevices')) { - for my $cal (devspec2array(HOMEMODE_AttrCheck($hash,"HomeEventsHolidayDevices"))) + for my $cal (devspec2array(HOMEMODE_AttrCheck($hash,'HomeEventsHolidayDevices'))) { my $events = HOMEMODE_CalendarEvents($name,$cal); push @userattrAll,"HomeCMDevent-$cal-each"; @@ -1500,15 +1504,15 @@ sub HOMEMODE_userattr($) { for my $evt (@{$events}) { - push @userattrAll,"HomeCMDevent-$cal-$evt-begin"; - push @userattrAll,"HomeCMDevent-$cal-$evt-end"; + push @userattrAll,"HomeCMDevent-$cal-".makeReadingName($evt).'-begin'; + push @userattrAll,"HomeCMDevent-$cal-".makeReadingName($evt).'-end'; } } } } - if (HOMEMODE_AttrCheck($hash,"HomeEventsCalendarDevices")) + if (HOMEMODE_AttrCheck($hash,'HomeEventsCalendarDevices')) { - for my $cal (devspec2array(HOMEMODE_AttrCheck($hash,"HomeEventsCalendarDevices"))) + for my $cal (devspec2array(HOMEMODE_AttrCheck($hash,'HomeEventsCalendarDevices'))) { my $events = HOMEMODE_CalendarEvents($name,$cal); push @userattrAll,"HomeCMDevent-$cal-each"; @@ -1516,32 +1520,33 @@ sub HOMEMODE_userattr($) { for my $evt (@{$events}) { - push @userattrAll,"HomeCMDevent-$cal-$evt-begin"; - push @userattrAll,"HomeCMDevent-$cal-$evt-end"; + push @userattrAll,"HomeCMDevent-$cal-".makeReadingName($evt).'-begin'; + push @userattrAll,"HomeCMDevent-$cal-".makeReadingName($evt).'-end'; } } } } for my $resident (split /,/,$hash->{RESIDENTS}) { - my $devtype = HOMEMODE_ID($resident,"ROOMMATE|GUEST|PET") ? $defs{$resident}->{TYPE} : ""; + my $devtype = HOMEMODE_ID($resident,'ROOMMATE|GUEST|PET') ? $defs{$resident}->{TYPE} : ''; next unless ($devtype); if ($adv) { - my $states = "absent"; + my $states = 'absent'; $states .= ",$HOMEMODE_UserModesAll" if ($devtype =~ /^ROOMMATE|PET$/); - $states .= ",home,$HOMEMODE_UserModes" if ($devtype eq "GUEST"); + $states .= ",home,$HOMEMODE_UserModes" if ($devtype eq 'GUEST'); for (split /,/,$states) { push @userattrAll,"HomeCMDmode-$_-$resident"; } push @userattrAll,"HomeCMDpresence-absent-$resident"; push @userattrAll,"HomeCMDpresence-present-$resident"; - my $locs = $devtype eq "ROOMMATE" ? AttrVal($resident,"rr_locations","") : $devtype eq "GUEST" ? AttrVal($resident,"rg_locations","") : AttrVal($resident,"rp_locations",""); + my $locs = $devtype eq 'ROOMMATE' ? AttrVal($resident,'rr_locations','') : $devtype eq 'GUEST' ? AttrVal($resident,'rg_locations','') : AttrVal($resident,'rp_locations',''); for (split/,/,$locs) { - push @userattrAll,"HomeCMDlocation-$_-$resident"; - push @userattrAll,"HomeCMDlocation-$_-resident" if (!grep(/^HomeCMDlocation-$_-resident$/,@userattrAll)); + my $loc = makeReadingName($_); + push @userattrAll,'HomeCMDlocation-'.$loc.'-'.$resident; + push @userattrAll,'HomeCMDlocation-'.$loc.'-resident' if (!grep(/^HomeCMDlocation-$loc-resident$/,@userattrAll)); } } my @presdevs = @{$hash->{helper}{presdevs}{$resident}} if ($hash->{helper}{presdevs}{$resident}); @@ -1552,7 +1557,7 @@ sub HOMEMODE_userattr($) for (@presdevs) { $count++; - $numbers .= "," if ($numbers); + $numbers .= ',' if ($numbers); $numbers .= $count; } push @userattrAll,"HomePresenceDeviceAbsentCount-$resident:$numbers"; @@ -1569,18 +1574,18 @@ sub HOMEMODE_userattr($) } } } - for (split " ",HOMEMODE_AttrCheck($hash,"HomeDaytimes",$HOMEMODE_Daytimes)) + for (split ' ',HOMEMODE_AttrCheck($hash,'HomeDaytimes',$HOMEMODE_Daytimes)) { - my $text = (split /\|/)[1]; + my $text = makeReadingName((split /\|/)[1]); my $d = "HomeCMDdaytime-$text"; my $m = "HomeCMDmode-$text"; push @userattrAll,$d if (!grep /^$d$/,@userattrAll); push @userattrAll,$m if (!grep /^$m$/,@userattrAll); } - for (split " ",HOMEMODE_AttrCheck($hash,"HomeSeasons",$HOMEMODE_Seasons)) + for (split ' ',HOMEMODE_AttrCheck($hash,'HomeSeasons',$HOMEMODE_Seasons)) { my $text = (split /\|/)[1]; - my $s = "HomeCMDseason-$text"; + my $s = 'HomeCMDseason-'.makeReadingName($text); push @userattrAll,$s if (!grep /^$s$/,@userattrAll); } my @list; @@ -1589,14 +1594,14 @@ sub HOMEMODE_userattr($) $attrib = $attrib =~ /^.+:.+$/ ? $attrib : "$attrib:textField-long"; push @list,$attrib if (!grep /^$attrib$/,@list); } - my $lo = join " ",sort @homeattr; - my $ln = join " ",sort @list; + my $lo = join ' ',sort @homeattr; + my $ln = join ' ',sort @list; return if ($lo eq $ln); for (@stayattr) { push @list,$_; } - CommandAttr(undef,"$name userattr ".join " ",sort @list); + CommandAttr(undef,"$name userattr ".join ' ',sort @list); return; } @@ -1609,23 +1614,23 @@ sub HOMEMODE_cleanUserattr($$;$) my @newdevspec = devspec2array($newdevs) if ($newdevs); for my $dev (@devspec) { - my $userattr = AttrVal($dev,"userattr",""); + my $userattr = AttrVal($dev,'userattr',''); if ($userattr) { my @stayattr; - for (split " ",$userattr) + for (split ' ',$userattr) { if ($_ =~ /^Home/) { $_ =~ s/:.*//; - CommandDeleteAttr(undef,"$dev $_") if ((AttrVal($dev,$_,"") && !@newdevspec) || (AttrVal($dev,$_,"") && @newdevspec && !grep /^$dev$/,@newdevspec)); + CommandDeleteAttr(undef,"$dev $_") if ((AttrVal($dev,$_,'') && !@newdevspec) || (AttrVal($dev,$_,'') && @newdevspec && !grep /^$dev$/,@newdevspec)); next; } push @stayattr,$_ if (!grep /^$_$/,@stayattr); } if (@stayattr) { - CommandAttr(undef,"$dev userattr ".join(" ",@stayattr)); + CommandAttr(undef,"$dev userattr ".join(' ',@stayattr)); } else { @@ -1642,10 +1647,10 @@ sub HOMEMODE_Attr(@) my $hash = $defs{$name}; delete $hash->{helper}{lastChangedAttr}; delete $hash->{helper}{lastChangedAttrValue}; - my $attr_value_old = AttrVal($name,$attr_name,""); + my $attr_value_old = AttrVal($name,$attr_name,''); $hash->{helper}{lastChangedAttr} = $attr_name; my $trans; - if ($cmd eq "set") + if ($cmd eq 'set') { $hash->{helper}{lastChangedAttrValue} = $attr_value; if ($attr_name =~ /^(HomeAutoAwoken|HomeAutoAsleep|HomeAutoArrival|HomeModeAbsentBelatedTime)$/) @@ -1655,22 +1660,22 @@ sub HOMEMODE_Attr(@) "Invalid value $attr_value for attribute $attr_name. Must be a number from 0 to 5999.99."; return $trans if ($attr_value !~ /^(\d{1,4})(\.\d{1,2})?$/ || $1 >= 6000 || $1 < 0); } - elsif ($attr_name eq "HomeLanguage") + elsif ($attr_name eq 'HomeLanguage') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Kann nur \"EN\" oder \"DE\" sein, Vorgabewert ist Sprache aus global.": "Invalid value $attr_value for attribute $attr_name. Must be \"EN\" or \"DE\", default is language from global."; return $trans if ($attr_value !~ /^(DE|EN)$/); - $HOMEMODE_de = 1 if ($attr_value eq "DE"); - $HOMEMODE_de = undef if ($attr_value eq "EN"); + $HOMEMODE_de = 1 if ($attr_value eq 'DE'); + $HOMEMODE_de = undef if ($attr_value eq 'EN'); } - elsif ($attr_name eq "HomeAdvancedDetails") + elsif ($attr_name eq 'HomeAdvancedDetails') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Kann nur \"none\", \"detail\", \"both\" oder \"room\" sein, Vorgabewert ist \"none\".": "Invalid value $attr_value for attribute $attr_name. Must be \"none\", \"detail\", \"both\" or \"room\", default is \"none\"."; return $trans if ($attr_value !~ /^(none|detail|both|room)$/); - if ($attr_value eq "detail") + if ($attr_value eq 'detail') { $modules{HOMEMODE}->{FW_deviceOverview} = 1; $modules{HOMEMODE}->{FW_addDetailToSummary} = 0; @@ -1687,8 +1692,8 @@ sub HOMEMODE_Attr(@) "Ungültiger Wert $attr_value für Attribut $attr_name. Kann nur 1 oder 0 sein, Vorgabewert ist 0.": "Invalid value $attr_value for attribute $attr_name. Must be 1 or 0, default is 0."; return $trans if ($attr_value !~ /^[01]$/); - RemoveInternalTimer($hash) if ($attr_name eq "disable" && $attr_value == 1); - HOMEMODE_GetUpdate($hash) if ($attr_name eq "disable" && !$attr_value); + RemoveInternalTimer($hash) if ($attr_name eq 'disable' && $attr_value == 1); + HOMEMODE_GetUpdate($hash) if ($attr_name eq 'disable' && !$attr_value); HOMEMODE_updateInternals($hash,1) if ($attr_name =~ /^(HomeAdvancedUserAttr|HomeAutoPresence)$/ && $init_done); } elsif ($attr_name =~ /^HomeCMD/ && $init_done) @@ -1711,15 +1716,15 @@ sub HOMEMODE_Attr(@) my @wd; for (devspec2array($attr_value)) { - next unless (!HOMEMODE_ID($_,"holiday|Calendar")); + next unless (!HOMEMODE_ID($_,'holiday|Calendar')); push @wd,$_ ; } if (@wd) { $trans = $HOMEMODE_de? - "Ungültige Calendar/holiday Geräte gefunden: ": - "Invalid Calendar/holiday device(s) found: "; - return $trans.join(",",@wd); + 'Ungültige Calendar/holiday Geräte gefunden: ': + 'Invalid Calendar/holiday device(s) found: '; + return $trans.join(',',@wd); } else { @@ -1731,7 +1736,7 @@ sub HOMEMODE_Attr(@) $trans = $HOMEMODE_de? "$attr_value muss ein gültiger TYPE sein": "$attr_value must be a valid TYPE"; - return $trans if (!HOMEMODE_CheckIfIsValidDevspec("TYPE=$attr_value","presence")); + return $trans if (!HOMEMODE_CheckIfIsValidDevspec("TYPE=$attr_value",'presence')); HOMEMODE_updateInternals($hash,1); } elsif ($attr_name =~ /^(HomeSensorsContactReadings|HomeSensorsMotionReadings)$/) @@ -1741,7 +1746,7 @@ sub HOMEMODE_Attr(@) "Invalid value $attr_value for attribute $attr_name. You have to provide at least 2 space separated readings, e.g. state sabotageError"; return $trans if ($attr_value !~ /^[\w\-\.]+\s[\w\-\.]+$/); } - elsif ($attr_name eq "HomeSensorsSmokeReading") + elsif ($attr_name eq 'HomeSensorsSmokeReading') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Es wird ein einzelnes Reading benötigt! z.B. state": @@ -1755,21 +1760,21 @@ sub HOMEMODE_Attr(@) "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); } - elsif ($attr_name eq "HomeIcewarningOnOffTemps") + elsif ($attr_name eq 'HomeIcewarningOnOffTemps') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Es werden 2 Leerzeichen separierte Temperaturen benötigt, z.B. -0.1 2.5": "Invalid value $attr_value for attribute $attr_name. You have to provide 2 space separated temperatures, e.g. -0.1 2.5"; return $trans if ($attr_value !~ /^-?\d{1,2}(\.\d)?\s-?\d{1,2}(\.\d)?$/); } - elsif ($attr_name eq "HomeSensorsContactOpenTimeDividers") + elsif ($attr_name eq 'HomeSensorsContactOpenTimeDividers') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Es werden Leerzeichen separierte Zahlen für jede Jahreszeit (aus Attribut HomeSeasons) benötigt, z.B. 2 1 2 3.333": "Invalid value $attr_value for attribute $attr_name. You have to provide space separated numbers for each season in order of the seasons provided in attribute HomeSeasons, e.g. 2 1 2 3.333"; return $trans if ($attr_value !~ /^\d{1,2}(\.\d{1,3})?(\s\d{1,2}(\.\d{1,3})?){0,}$/); - my @times = split " ",$attr_value; - my $s = scalar split " ",AttrVal($name,"HomeSeasons",$HOMEMODE_Seasons); + my @times = split ' ',$attr_value; + my $s = scalar split ' ',AttrVal($name,'HomeSeasons',$HOMEMODE_Seasons); my $t = scalar @times; $trans = $HOMEMODE_de? "Anzahl von $attr_name Werten ($t) ungleich zu den verfügbaren Jahreszeiten ($s) im Attribut HomeSeasons!": @@ -1778,33 +1783,33 @@ sub HOMEMODE_Attr(@) for (@times) { $trans = $HOMEMODE_de? - "Teiler dürfen nicht 0 sein, denn Division durch 0 ist nicht definiert!": - "Dividers can't be zero, because division by zero is not defined!"; + 'Teiler dürfen nicht 0 sein, denn Division durch 0 ist nicht definiert!': + 'Dividers can´t be zero, because division by zero is not defined!'; return $trans if ($_ == 0); } } - elsif ($attr_name eq "HomeSensorsContactOpenTimeMin") + elsif ($attr_name eq 'HomeSensorsContactOpenTimeMin') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Zahlen von 1 bis 9.9 sind nur erlaubt!": "Invalid value $attr_value for attribute $attr_name. Numbers from 1 to 9.9 are allowed only!"; return $trans if ($attr_value !~ /^[1-9](\.\d)?$/); } - elsif ($attr_name eq "HomeSensorsContactOpenTimes") + elsif ($attr_name eq 'HomeSensorsContactOpenTimes') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Es werden Leerzeichen separierte Zahlen benötigt, z.B. 5 10 15 17.5": "Invalid value $attr_value for attribute $attr_name. You have to provide space separated numbers, e.g. 5 10 15 17.5"; return $trans if ($attr_value !~ /^\d{1,4}(\.\d)?((\s\d{1,4}(\.\d)?)?){0,}$/); - for (split " ",$attr_value) + for (split ' ',$attr_value) { $trans = $HOMEMODE_de? - "Teiler dürfen nicht 0 sein, denn Division durch 0 ist nicht definiert!": - "Dividers can't be zero, because division by zero is not defined!"; + 'Teiler dürfen nicht 0 sein, denn Division durch 0 ist nicht definiert!': + 'Dividers can´t be zero, because division by zero is not defined!'; return $trans if ($_ == 0); } } - elsif ($attr_name eq "HomeResidentCmdDelay") + elsif ($attr_name eq 'HomeResidentCmdDelay') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Zahlen von 0 bis 9999 sind nur erlaubt!": @@ -1819,7 +1824,7 @@ sub HOMEMODE_Attr(@) return $trans if ($attr_value !~ /^[\w\-äöüß\.]+(,[\w\-äöüß\.]+){0,}$/i); HOMEMODE_userattr($hash); } - elsif ($attr_name eq "HomePublicIpCheckInterval") + elsif ($attr_name eq 'HomePublicIpCheckInterval') { $trans = $HOMEMODE_de? "Ungültiger Wert $attr_value für Attribut $attr_name. Muss eine Zahl von 1 bis 99999 für das Interval in Minuten sein!": @@ -1834,16 +1839,16 @@ sub HOMEMODE_Attr(@) return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value)); HOMEMODE_updateInternals($hash,1) if ($attr_value ne $attr_value_old); } - elsif ($attr_name eq "HomeSensorsPowerEnergy" && $init_done) + elsif ($attr_name eq 'HomeSensorsPowerEnergy' && $init_done) { - my ($p,$e) = split " ",AttrVal($name,"HomeSensorsPowerEnergyReadings","power energy"); + my ($p,$e) = split ' ',AttrVal($name,'HomeSensorsPowerEnergyReadings','power energy'); $trans = $HOMEMODE_de? "$attr_value muss ein gültiger Devspec mit $p und $e Readings sein!": "$attr_value must be a valid devspec with $p and $e readings!"; return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value,$p) || !HOMEMODE_CheckIfIsValidDevspec($attr_value,$e)); HOMEMODE_updateInternals($hash); } - elsif ($attr_name eq "HomeTwilightDevice" && $init_done) + elsif ($attr_name eq 'HomeTwilightDevice' && $init_done) { $trans = $HOMEMODE_de? "$attr_value muss ein gültiges Gerät vom TYPE Twilight sein!": @@ -1855,7 +1860,7 @@ sub HOMEMODE_Attr(@) HOMEMODE_updateInternals($hash); } } - elsif ($attr_name eq "HomeWeatherDevice" && $init_done) + elsif ($attr_name eq 'HomeWeatherDevice' && $init_done) { $trans = $HOMEMODE_de? "$attr_value muss ein gültiges Gerät vom TYPE Weather sein!": @@ -1863,43 +1868,43 @@ sub HOMEMODE_Attr(@) return $trans if (!HOMEMODE_CheckIfIsValidDevspec("$attr_value:FILTER=TYPE=Weather")); if ($attr_value_old ne $attr_value) { - CommandDeleteReading(undef,"$name pressure") if (!AttrVal($name,"HomeSensorAirpressure",undef)); - CommandDeleteReading(undef,"$name wind") if (!AttrVal($name,"HomeSensorWindspeed",undef)); - CommandDeleteReading(undef,"$name temperature") if (!AttrVal($name,"HomeSensorTemperatureOutside",undef)); - CommandDeleteReading(undef,"$name humidity") if (!AttrVal($name,"HomeSensorHumidityOutside",undef)); + CommandDeleteReading(undef,"$name pressure") if (!AttrVal($name,'HomeSensorAirpressure',undef)); + CommandDeleteReading(undef,"$name wind") if (!AttrVal($name,'HomeSensorWindspeed',undef)); + CommandDeleteReading(undef,"$name temperature") if (!AttrVal($name,'HomeSensorTemperatureOutside',undef)); + CommandDeleteReading(undef,"$name humidity") if (!AttrVal($name,'HomeSensorHumidityOutside',undef)); HOMEMODE_updateInternals($hash); } } - elsif ($attr_name eq "HomeSensorTemperatureOutside" && $init_done) + elsif ($attr_name eq 'HomeSensorTemperatureOutside' && $init_done) { $trans = $HOMEMODE_de? "$attr_value muss ein gültiger Devspec mit temperature Reading sein!": "$attr_value must be a valid device with temperature reading!"; - return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value,"temperature")); - CommandDeleteAttr(undef,"$name HomeSensorHumidityOutside") if (AttrVal($name,"HomeSensorHumidityOutside",undef) && $attr_value eq AttrVal($name,"HomeSensorHumidityOutside",undef)); + return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value,'temperature')); + CommandDeleteAttr(undef,"$name HomeSensorHumidityOutside") if (AttrVal($name,'HomeSensorHumidityOutside',undef) && $attr_value eq AttrVal($name,'HomeSensorHumidityOutside',undef)); if ($attr_value_old ne $attr_value) { - CommandDeleteReading(undef,"$name temperature") if (!AttrVal($name,"HomeWeatherDevice",undef)); + CommandDeleteReading(undef,"$name temperature") if (!AttrVal($name,'HomeWeatherDevice',undef)); HOMEMODE_updateInternals($hash); } } - elsif ($attr_name eq "HomeSensorHumidityOutside" && $init_done) + elsif ($attr_name eq 'HomeSensorHumidityOutside' && $init_done) { $trans = $HOMEMODE_de? - "Dieses Attribut ist wegzulassen wenn es den gleichen Wert haben sollte wie HomeSensorTemperatureOutside!": - "You have to omit this attribute if it should have the same value like HomeSensorTemperatureOutside!"; - return $trans if ($attr_value eq AttrVal($name,"HomeSensorTemperatureOutside",undef)); + 'Dieses Attribut ist wegzulassen wenn es den gleichen Wert haben sollte wie HomeSensorTemperatureOutside!': + 'You have to omit this attribute if it should have the same value like HomeSensorTemperatureOutside!'; + return $trans if ($attr_value eq AttrVal($name,'HomeSensorTemperatureOutside',undef)); $trans = $HOMEMODE_de? "$attr_value muss ein gültiger Devspec mit humidity Reading sein!": "$attr_value must be a valid device with humidity reading!"; - return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value,"humidity")); + return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value,'humidity')); if ($attr_value_old ne $attr_value) { - CommandDeleteReading(undef,"$name humidity") if (!AttrVal($name,"HomeWeatherDevice",undef)); + CommandDeleteReading(undef,"$name humidity") if (!AttrVal($name,'HomeWeatherDevice',undef)); HOMEMODE_updateInternals($hash); } } - elsif ($attr_name eq "HomeDaytimes" && $init_done) + elsif ($attr_name eq 'HomeDaytimes' && $init_done) { $trans = $HOMEMODE_de? "$attr_value für $attr_name muss eine Leerzeichen separierte Liste aus Uhrzeit|Text Paaren sein! z.B. $HOMEMODE_Daytimes": @@ -1908,7 +1913,7 @@ sub HOMEMODE_Attr(@) if ($attr_value_old ne $attr_value) { my @ts; - for (split " ",$attr_value) + for (split ' ',$attr_value) { my $time = (split /\|/)[0]; my ($h,$m) = split /:/,$time; @@ -1929,16 +1934,16 @@ sub HOMEMODE_Attr(@) HOMEMODE_userattr($hash); } } - elsif ($attr_name eq "HomeSeasons" && $init_done) + elsif ($attr_name eq 'HomeSeasons' && $init_done) { $trans = $HOMEMODE_de? "$attr_value für $attr_name muss eine Leerzeichen separierte Liste aus Datum|Text Paaren mit mindestens 4 Werten sein! z.B. $HOMEMODE_Seasons": "$attr_value for $attr_name must be a space separated list of date|text pairs with at least 4 values! e.g. $HOMEMODE_Seasons"; - return $trans if (scalar (split " ",$attr_value) < 4 || scalar (split /\|/,$attr_value) < 5); + return $trans if (scalar (split ' ',$attr_value) < 4 || scalar (split /\|/,$attr_value) < 5); if ($attr_value_old ne $attr_value) { my @ds; - for (split " ",$attr_value) + for (split ' ',$attr_value) { my $time = (split /\|/)[0]; my ($m,$d) = split /\./,$time; @@ -1959,7 +1964,7 @@ sub HOMEMODE_Attr(@) HOMEMODE_userattr($hash); } } - elsif ($attr_name eq "HomeModeAlarmArmDelay") + elsif ($attr_name eq 'HomeModeAlarmArmDelay') { $trans = $HOMEMODE_de? "$attr_value für $attr_name muss eine einzelne Zahl sein für die Verzögerung in Sekunden oder 3 Leerzeichen separierte Zeiten in Sekunden für jeden modeAlarm individuell (Reihenfolge: armaway armnight armhome), höhster Wert ist 99999": @@ -1973,14 +1978,14 @@ sub HOMEMODE_Attr(@) "$attr_value for $attr_name must be a pipe separated list with 3 values!"; return $trans if (scalar (split /\|/,$attr_value) != 3); } - elsif ($attr_name eq "HomeTextClosedOpen") + elsif ($attr_name eq 'HomeTextClosedOpen') { $trans = $HOMEMODE_de? "$attr_value für $attr_name muss eine Pipe separierte Liste mit 2 Werten sein!": "$attr_value for $attr_name must be a pipe separated list with 2 values!"; return $trans if (scalar (split /\|/,$attr_value) != 2); } - elsif ($attr_name eq "HomeUWZ" && $init_done) + elsif ($attr_name eq 'HomeUWZ' && $init_done) { $trans = $HOMEMODE_de? "$attr_value muss ein gültiges Gerät vom TYPE Weather sein!": @@ -1988,16 +1993,16 @@ sub HOMEMODE_Attr(@) return "$attr_value must be a valid device of TYPE UWZ!" if (!HOMEMODE_CheckIfIsValidDevspec("$attr_value:FILTER=TYPE=UWZ")); HOMEMODE_updateInternals($hash) if ($attr_value_old ne $attr_value); } - elsif ($attr_name eq "HomeSensorsLuminance" && $init_done) + elsif ($attr_name eq 'HomeSensorsLuminance' && $init_done) { - my $read = AttrVal($name,"HomeSensorsLuminanceReading","luminance"); + my $read = AttrVal($name,'HomeSensorsLuminanceReading','luminance'); $trans = $HOMEMODE_de? "$attr_value muss ein gültiges Gerät mit $read Reading sein!": "$attr_name must be a valid device with $read reading!"; return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value,$read)); HOMEMODE_updateInternals($hash); } - elsif ($attr_name eq "HomeSensorsPowerEnergyReadings" && $init_done) + elsif ($attr_name eq 'HomeSensorsPowerEnergyReadings' && $init_done) { $trans = $HOMEMODE_de? "$attr_name müssen zwei gültige Readings für power und energy sein!": @@ -2021,23 +2026,23 @@ sub HOMEMODE_Attr(@) return $trans if ($attr_value !~ /^([\w\.]+):([\w\-\.]+)$/ || !HOMEMODE_CheckIfIsValidDevspec($1,$2)); HOMEMODE_updateInternals($hash) if ($attr_value_old ne $attr_value); } - elsif ($attr_name eq "HomeSensorsBattery" && $init_done) + elsif ($attr_name eq 'HomeSensorsBattery' && $init_done) { - my $read = AttrVal($name,"HomeSensorsBatteryReading","battery"); + my $read = AttrVal($name,'HomeSensorsBatteryReading','battery'); $trans = $HOMEMODE_de? "$attr_value muss ein gültiges Gerät mit $read Reading sein!": "$attr_name must be a valid device with $read reading!"; return $trans if (!HOMEMODE_CheckIfIsValidDevspec($attr_value,$read)); HOMEMODE_updateInternals($hash); } - elsif ($attr_name eq "HomeSensorsBatteryLowPercentage") + elsif ($attr_name eq 'HomeSensorsBatteryLowPercentage') { $trans = $HOMEMODE_de? "$attr_value muss ein Wert zwischen 0 und 99 sein!": "$attr_name must be a value from 0 to 99!"; return $trans if ($attr_value !~ /^\d{1,2}$/); } - elsif ($attr_name eq "HomeTriggerPanic" && $init_done) + elsif ($attr_name eq 'HomeTriggerPanic' && $init_done) { $trans = $HOMEMODE_de? "$attr_value muss ein gültiges Gerät, Reading und Wert in Form von \"Gerät:Reading:WertAn:WertAus\" (WertAus ist optional) sein!": @@ -2045,7 +2050,7 @@ sub HOMEMODE_Attr(@) return $trans if ($attr_value !~ /^([\w\.]+):([\w\.]+):[\w\-\.]+(:[\w\-\.]+)?$/ || !HOMEMODE_CheckIfIsValidDevspec($1,$2)); HOMEMODE_updateInternals($hash); } - elsif ($attr_name eq "HomeTriggerAnyoneElseAtHome" && $init_done) + elsif ($attr_name eq 'HomeTriggerAnyoneElseAtHome' && $init_done) { $trans = $HOMEMODE_de? "$attr_value muss ein gültiges Gerät, Reading und Wert in Form von \"Gerät:Reading:WertAn:WertAus\" sein!": @@ -2056,52 +2061,52 @@ sub HOMEMODE_Attr(@) } else { - $hash->{helper}{lastChangedAttrValue} = "---"; - if ($attr_name eq "disable") + $hash->{helper}{lastChangedAttrValue} = '---'; + if ($attr_name eq 'disable') { HOMEMODE_GetUpdate($hash); } - elsif ($attr_name eq "HomeLanguage") + elsif ($attr_name eq 'HomeLanguage') { - $HOMEMODE_de = AttrVal("global","language","DE") ? 1 : undef; + $HOMEMODE_de = AttrVal('global','language','DE') ? 1 : undef; } elsif ($attr_name =~ /^(HomeAdvancedUserAttr|HomeAutoPresence|HomePresenceDeviceType|HomeEvents(Holiday|Calendar)Devices|HomeSensorAirpressure|HomeSensorWindspeed|HomeSensorsBattery|HomeSensorsBatteryReading)$/) { CommandDeleteReading(undef,"$name event-.+") if ($attr_name =~ /^HomeEvents(Holiday|Calendar)Devices$/); - CommandDeleteReading(undef,"$name battery.*|lastBatteryLow") if ($attr_name eq "HomeSensorsBattery"); + CommandDeleteReading(undef,"$name battery.*|lastBatteryLow") if ($attr_name eq 'HomeSensorsBattery'); HOMEMODE_updateInternals($hash,1); } elsif ($attr_name =~ /^(HomeSensorsContact|HomeSensorsMotion)$/) { my $olddevs = $hash->{SENSORSCONTACT}; - $olddevs = $hash->{SENSORSMOTION} if ($attr_name eq "HomeSensorsMotion"); - my $read = "lastContact|prevContact|contacts.*"; - $read = "lastMotion|prevMotion|motions.*" if ($attr_name eq "HomeSensorsMotion"); + $olddevs = $hash->{SENSORSMOTION} if ($attr_name eq 'HomeSensorsMotion'); + my $read = 'lastContact|prevContact|contacts.*'; + $read = 'lastMotion|prevMotion|motions.*' if ($attr_name eq 'HomeSensorsMotion'); CommandDeleteReading(undef,"$name $read"); HOMEMODE_updateInternals($hash); HOMEMODE_cleanUserattr($hash,$olddevs); } - elsif ($attr_name eq "HomeSensorsSmoke") + elsif ($attr_name eq 'HomeSensorsSmoke') { CommandDeleteReading(undef,"$name alarmSmoke"); HOMEMODE_updateInternals($hash); } - elsif ($attr_name eq "HomeSensorsPowerEnergy") + elsif ($attr_name eq 'HomeSensorsPowerEnergy') { CommandDeleteReading(undef,"$name energy|power"); HOMEMODE_updateInternals($hash); } - elsif ($attr_name eq "HomePublicIpCheckInterval") + elsif ($attr_name eq 'HomePublicIpCheckInterval') { - delete $hash->{".IP_TRIGGERTIME_NEXT"}; + delete $hash->{'.IP_TRIGGERTIME_NEXT'}; } elsif ($attr_name =~ /^(HomeWeatherDevice|HomeTwilightDevice)$/) { - if ($attr_name eq "HomeWeatherDevice") + if ($attr_name eq 'HomeWeatherDevice') { CommandDeleteReading(undef,"$name pressure|wind"); - CommandDeleteReading(undef,"$name temperature") if (!AttrVal($name,"HomeSensorTemperatureOutside",undef)); - CommandDeleteReading(undef,"$name humidity") if (!AttrVal($name,"HomeSensorHumidityOutside",undef)); + CommandDeleteReading(undef,"$name temperature") if (!AttrVal($name,'HomeSensorTemperatureOutside',undef)); + CommandDeleteReading(undef,"$name humidity") if (!AttrVal($name,'HomeSensorHumidityOutside',undef)); } else { @@ -2111,8 +2116,8 @@ sub HOMEMODE_Attr(@) } elsif ($attr_name =~ /^(HomeSensorTemperatureOutside|HomeSensorHumidityOutside)$/) { - CommandDeleteReading(undef,"$name .*temperature.*") if (!AttrVal($name,"HomeWeatherDevice",undef) && $attr_name eq "HomeSensorTemperatureOutside"); - CommandDeleteReading(undef,"$name .*humidity.*") if (!AttrVal($name,"HomeWeatherDevice",undef) && $attr_name eq "HomeSensorHumidityOutside"); + CommandDeleteReading(undef,"$name .*temperature.*") if (!AttrVal($name,'HomeWeatherDevice',undef) && $attr_name eq 'HomeSensorTemperatureOutside'); + CommandDeleteReading(undef,"$name .*humidity.*") if (!AttrVal($name,'HomeWeatherDevice',undef) && $attr_name eq 'HomeSensorHumidityOutside'); HOMEMODE_updateInternals($hash); } elsif ($attr_name =~ /^(HomeDaytimes|HomeSeasons|HomeSpecialLocations|HomeSpecialModes)$/ && $init_done) @@ -2121,8 +2126,8 @@ sub HOMEMODE_Attr(@) } elsif ($attr_name =~ /^(HomeUWZ|HomeSensorsLuminance|HomeSensorsLuminanceReading|HomeSensorsPowerEnergyReadings)$/) { - CommandDeleteReading(undef,"$name uwz.*") if ($attr_name eq "HomeUWZ"); - CommandDeleteReading(undef,"$name .*luminance.*") if ($attr_name eq "HomeSensorsLuminance"); + CommandDeleteReading(undef,"$name uwz.*") if ($attr_name eq 'HomeUWZ'); + CommandDeleteReading(undef,"$name .*luminance.*") if ($attr_name eq 'HomeSensorsLuminance'); HOMEMODE_updateInternals($hash); } } @@ -2133,79 +2138,79 @@ sub HOMEMODE_replacePlaceholders($$;$) { my ($hash,$cmd,$resident) = @_; my $name = $hash->{NAME}; - my $sensor = AttrVal($name,"HomeWeatherDevice",""); - $resident = $resident ? $resident : ReadingsVal($name,"lastActivityByResident",""); - my $alias = AttrVal($resident,"alias",""); - my $audio = AttrVal($resident,"msgContactAudio",""); - $audio = AttrVal("globalMsg","msgContactAudio","no msg audio device available") if (!$audio); - my $lastabsencedur = ReadingsVal($resident,"lastDurAbsence_cr",0); - my $lastpresencedur = ReadingsVal($resident,"lastDurPresence_cr",0); - my $lastsleepdur = ReadingsVal($resident,"lastDurSleep_cr",0); - my $durabsence = ReadingsVal($resident,"durTimerAbsence_cr",0); - my $durpresence = ReadingsVal($resident,"durTimerPresence_cr",0); - my $dursleep = ReadingsVal($resident,"durTimerSleep_cr",0); - my $condition = ReadingsVal($sensor,"condition",""); - my $conditionart = ReadingsVal($name,".be",""); - my $contactsOpen = ReadingsVal($name,"contactsOutsideOpen",""); - my $contactsOpenCt = ReadingsVal($name,"contactsOutsideOpen_ct",0); - my $contactsOpenHr = ReadingsVal($name,"contactsOutsideOpen_hr",0); - my $dnd = ReadingsVal($name,"dnd","off") eq "on" ? 1 : 0; - my $aeah = ReadingsVal($name,"anyoneElseAtHome","off") eq "on" ? 1 : 0; - my $panic = ReadingsVal($name,"panic","off") eq "on" ? 1 : 0; - my $tampered = ReadingsVal($name,"sensorsTampered_hr",""); - my $tamperedc = ReadingsVal($name,"sensorsTampered_ct",""); - my $tamperedhr = ReadingsVal($name,"sensorsTampered_hr",""); - my $ice = ReadingsVal($name,"icewarning",0); - my $ip = ReadingsVal($name,"publicIP",""); - my $light = ReadingsVal($name,"light",0); - my $twilight = ReadingsVal($name,"twilight",0); - my $twilightevent = ReadingsVal($name,"twilightEvent",""); - my $location = ReadingsVal($name,"location",""); - my $rlocation = ReadingsVal($resident,"location",""); - my $alarm = ReadingsVal($name,"alarmTriggered",0); - my $alarmc = ReadingsVal($name,"alarmTriggered_ct",0); - my $alarmhr = ReadingsVal($name,"alarmTriggered_hr",0); - my $smoke = ReadingsVal($name,"alarmSmoke",0); - my $smokec = ReadingsVal($name,"alarmSmoke_ct",0); - my $smokehr = ReadingsVal($name,"alarmSmoke_hr",0); + my $sensor = AttrVal($name,'HomeWeatherDevice',''); + $resident = $resident ? $resident : ReadingsVal($name,'lastActivityByResident',''); + my $alias = AttrVal($resident,'alias',''); + my $audio = AttrVal($resident,'msgContactAudio',''); + $audio = AttrVal('globalMsg','msgContactAudio','no msg audio device available') if (!$audio); + my $lastabsencedur = ReadingsVal($resident,'lastDurAbsence_cr',0); + my $lastpresencedur = ReadingsVal($resident,'lastDurPresence_cr',0); + my $lastsleepdur = ReadingsVal($resident,'lastDurSleep_cr',0); + my $durabsence = ReadingsVal($resident,'durTimerAbsence_cr',0); + my $durpresence = ReadingsVal($resident,'durTimerPresence_cr',0); + my $dursleep = ReadingsVal($resident,'durTimerSleep_cr',0); + my $condition = ReadingsVal($sensor,'condition',''); + my $conditionart = ReadingsVal($name,'.be',''); + my $contactsOpen = ReadingsVal($name,'contactsOutsideOpen',''); + my $contactsOpenCt = ReadingsVal($name,'contactsOutsideOpen_ct',0); + my $contactsOpenHr = ReadingsVal($name,'contactsOutsideOpen_hr',0); + my $dnd = ReadingsVal($name,'dnd','off') eq 'on' ? 1 : 0; + my $aeah = ReadingsVal($name,'anyoneElseAtHome','off') eq 'on' ? 1 : 0; + my $panic = ReadingsVal($name,'panic','off') eq 'on' ? 1 : 0; + my $tampered = ReadingsVal($name,'sensorsTampered_hr',''); + my $tamperedc = ReadingsVal($name,'sensorsTampered_ct',''); + my $tamperedhr = ReadingsVal($name,'sensorsTampered_hr',''); + my $ice = ReadingsVal($name,'icewarning',0); + my $ip = ReadingsVal($name,'publicIP',''); + my $light = ReadingsVal($name,'light',0); + my $twilight = ReadingsVal($name,'twilight',0); + my $twilightevent = ReadingsVal($name,'twilightEvent',''); + my $location = ReadingsVal($name,'location',''); + my $rlocation = ReadingsVal($resident,'location',''); + my $alarm = ReadingsVal($name,'alarmTriggered',0); + my $alarmc = ReadingsVal($name,'alarmTriggered_ct',0); + my $alarmhr = ReadingsVal($name,'alarmTriggered_hr',0); + my $smoke = ReadingsVal($name,'alarmSmoke',0); + my $smokec = ReadingsVal($name,'alarmSmoke_ct',0); + my $smokehr = ReadingsVal($name,'alarmSmoke_hr',0); my $daytime = HOMEMODE_DayTime($hash); - my $mode = ReadingsVal($name,"mode",""); - my $amode = ReadingsVal($name,"modeAlarm",""); - my $pamode = ReadingsVal($name,"prevModeAlarm",""); - my $season = ReadingsVal($name,"season",""); - my $pmode = ReadingsVal($name,"prevMode",""); - my $rpmode = ReadingsVal($resident,"lastState",""); - my $pres = ReadingsVal($name,"presence","") eq "present" ? 1 : 0; - my $rpres = ReadingsVal($resident,"presence","") eq "present" ? 1 : 0; - my $pdevice = ReadingsVal($name,"lastActivityByPresenceDevice",""); - my $apdevice = ReadingsVal($name,"lastAbsentByPresenceDevice",""); - my $ppdevice = ReadingsVal($name,"lastPresentByPresenceDevice",""); - my $paddress = InternalVal($pdevice,"ADDRESS",""); - my $pressure = ReadingsVal($name,"pressure",""); - my $weatherlong = HOMEMODE_WeatherTXT($hash,AttrVal($name,"HomeTextWeatherLong","")); - my $weathershort = HOMEMODE_WeatherTXT($hash,AttrVal($name,"HomeTextWeatherShort","")); + my $mode = ReadingsVal($name,'mode',''); + my $amode = ReadingsVal($name,'modeAlarm',''); + my $pamode = ReadingsVal($name,'prevModeAlarm',''); + my $season = ReadingsVal($name,'season',''); + my $pmode = ReadingsVal($name,'prevMode',''); + my $rpmode = ReadingsVal($resident,'lastState',''); + my $pres = ReadingsVal($name,'presence','') eq 'present' ? 1 : 0; + my $rpres = ReadingsVal($resident,'presence','') eq 'present' ? 1 : 0; + my $pdevice = ReadingsVal($name,'lastActivityByPresenceDevice',''); + my $apdevice = ReadingsVal($name,'lastAbsentByPresenceDevice',''); + my $ppdevice = ReadingsVal($name,'lastPresentByPresenceDevice',''); + my $paddress = InternalVal($pdevice,'ADDRESS',''); + my $pressure = ReadingsVal($name,'pressure',''); + my $weatherlong = HOMEMODE_WeatherTXT($hash,AttrVal($name,'HomeTextWeatherLong','')); + my $weathershort = HOMEMODE_WeatherTXT($hash,AttrVal($name,'HomeTextWeatherShort','')); my $forecast = HOMEMODE_ForecastTXT($hash); my $forecasttoday = HOMEMODE_ForecastTXT($hash,1); - my $luminance = ReadingsVal($name,"luminance",0); - my $luminancetrend = ReadingsVal($name,"luminanceTrend",0); - my $humi = ReadingsVal($name,"humidity",0); - my $humitrend = ReadingsVal($name,"humidityTrend",0); - my $temp = ReadingsVal($name,"temperature",0); - my $temptrend = ReadingsVal($name,"temperatureTrend","constant"); - my $wind = ReadingsVal($name,"wind",0); - my $windchill = ReadingsNum($sensor,"apparentTemperature",0); - my $motion = ReadingsVal($name,"lastMotion",""); - my $pmotion = ReadingsVal($name,"prevMotion",""); - my $contact = ReadingsVal($name,"lastContact",""); - my $pcontact = ReadingsVal($name,"prevContact",""); - my $uwzc = ReadingsVal($name,"uwz_warnCount",0); + my $luminance = ReadingsVal($name,'luminance',0); + my $luminancetrend = ReadingsVal($name,'luminanceTrend',0); + my $humi = ReadingsVal($name,'humidity',0); + my $humitrend = ReadingsVal($name,'humidityTrend',0); + my $temp = ReadingsVal($name,'temperature',0); + my $temptrend = ReadingsVal($name,'temperatureTrend','constant'); + my $wind = ReadingsVal($name,'wind',0); + my $windchill = ReadingsNum($sensor,'apparentTemperature',0); + my $motion = ReadingsVal($name,'lastMotion',''); + my $pmotion = ReadingsVal($name,'prevMotion',''); + my $contact = ReadingsVal($name,'lastContact',''); + my $pcontact = ReadingsVal($name,'prevContact',''); + my $uwzc = ReadingsVal($name,'uwz_warnCount',0); my $uwzs = HOMEMODE_uwzTXT($hash,$uwzc,undef); my $uwzl = HOMEMODE_uwzTXT($hash,$uwzc,1); - my $lowBat = HOMEMODE_name2alias(ReadingsVal($name,"lastBatteryLow","")); - my $normBat = HOMEMODE_name2alias(ReadingsVal($name,"lastBatteryNormal","")); - my $lowBatAll = ReadingsVal($name,"batteryLow_hr",""); - my $lowBatCount = ReadingsVal($name,"batteryLow_ct",0); - my $disabled = ReadingsVal($name,"devicesDisabled",""); + my $lowBat = HOMEMODE_name2alias(ReadingsVal($name,'lastBatteryLow','')); + my $normBat = HOMEMODE_name2alias(ReadingsVal($name,'lastBatteryNormal','')); + my $lowBatAll = ReadingsVal($name,'batteryLow_hr',''); + my $lowBatCount = ReadingsVal($name,'batteryLow_ct',0); + my $disabled = ReadingsVal($name,'devicesDisabled',''); my $sensorsbattery = $hash->{SENSORSBATTERY}; my $sensorscontact = $hash->{SENSORSCONTACT}; my $sensorsenergy = $hash->{SENSORSENERGY}; @@ -2235,33 +2240,33 @@ sub HOMEMODE_replacePlaceholders($$;$) $cmd =~ s/%DEVICEP%/$ppdevice/g; $cmd =~ s/%DISABLED%/$disabled/g; $cmd =~ s/%DND%/$dnd/g; - if (AttrVal($name,"HomeEventsHolidayDevices",undef) || AttrVal($name,"HomeEventsCalendarDevices",undef)) + if (AttrVal($name,'HomeEventsHolidayDevices',undef) || AttrVal($name,'HomeEventsCalendarDevices',undef)) { my @cals; - if (AttrVal($name,"HomeEventsHolidayDevices","")) + if (AttrVal($name,'HomeEventsHolidayDevices','')) { - for my $c (devspec2array(AttrVal($name,"HomeEventsHolidayDevices",""))) + for my $c (devspec2array(AttrVal($name,'HomeEventsHolidayDevices',''))) { push @cals,$c if (!grep /^$c$/,@cals); } } else { - for my $c (devspec2array(AttrVal($name,"HomeEventsCalendarDevices",""))) + for my $c (devspec2array(AttrVal($name,'HomeEventsCalendarDevices',''))) { push @cals,$c if (!grep /^$c$/,@cals); } } for my $cal (@cals) { - my $state = ReadingsVal($name,"event-$cal","none") ne "none" ? ReadingsVal($name,"event-$cal","") : ""; + my $state = ReadingsVal($name,"event-$cal",'none') ne 'none' ? ReadingsVal($name,"event-$cal",'') : ''; $cmd =~ s/%$cal%/$state/g; my $events = HOMEMODE_CalendarEvents($name,$cal); - if (HOMEMODE_ID($cal,"holiday")) + if (HOMEMODE_ID($cal,'holiday')) { for my $evt (@{$events}) { - my $val = $state eq $evt ? 1 : ""; + my $val = $state eq $evt ? 1 : ''; $cmd =~ s/%$cal-$evt%/$val/g; } } @@ -2271,7 +2276,7 @@ sub HOMEMODE_replacePlaceholders($$;$) { for my $e (split /,/,$state) { - my $val = $e eq $evt ? 1 : ""; + my $val = $e eq $evt ? 1 : ''; $cmd =~ s/%$cal-$evt%/$val/g; } } @@ -2355,11 +2360,11 @@ sub HOMEMODE_serializeCMD($@) $_ =~ s/\s{2,}/ /g; push @newcmd,$_; } - $cmd = join(" ",@newcmd); + $cmd = join(' ',@newcmd); Log3 $name,5,"$name: cmdnew: $cmd"; push @newcmds,SemicolonEscape($cmd) if ($cmd !~ /^[\t\s]*$/); } - my $cmd = join(";",@newcmds); + my $cmd = join(';',@newcmds); $cmd =~ s/\}\s{0,1};\s{0,1}\{/\};;\{/g; return $cmd; } @@ -2369,17 +2374,17 @@ sub HOMEMODE_ReadingTrend($$;$) my ($hash,$read,$val) = @_; my $name = $hash->{NAME}; $val = ReadingsNum($name,$read,5) if (!$val); - my $time = AttrNum($name,"HomeTrendCalcAge",900); + my $time = AttrNum($name,'HomeTrendCalcAge',900); my $pval = ReadingsNum($name,".$read",undef); if (defined $pval && ReadingsAge($name,".$read",0) >= $time) { - my ($rising,$constant,$falling) = split /\|/,AttrVal($name,"HomeTextRisingConstantFalling","rising|constant|falling"); + my ($rising,$constant,$falling) = split /\|/,AttrVal($name,'HomeTextRisingConstantFalling','rising|constant|falling'); my $trend = $constant; $trend = $rising if ($val > $pval); $trend = $falling if ($val < $pval); readingsBeginUpdate($hash); readingsBulkUpdate($hash,".$read",$val); - readingsBulkUpdate($hash,$read."Trend",$trend); + readingsBulkUpdate($hash,$read.'Trend',$trend); readingsEndUpdate($hash,1); } elsif (!defined $pval) @@ -2392,14 +2397,14 @@ sub HOMEMODE_WeatherTXT($$) { my ($hash,$text) = @_; my $name = $hash->{NAME}; - my $weather = AttrVal($name,"HomeWeatherDevice",""); - my $condition = ReadingsVal($weather,"condition",""); - my $conditionart = ReadingsVal($name,".be",""); - my $pressure = ReadingsVal($name,"pressure",""); - my $humi = ReadingsVal($name,"humidity",0); - my $temp = ReadingsVal($name,"temperature",0); - my $windchill = ReadingsNum($weather,"apparentTemperature",0); - my $wind = ReadingsVal($name,"wind",0); + my $weather = AttrVal($name,'HomeWeatherDevice',''); + my $condition = ReadingsVal($weather,'condition',''); + my $conditionart = ReadingsVal($name,'.be',''); + my $pressure = ReadingsVal($name,'pressure',''); + my $humi = ReadingsVal($name,'humidity',0); + my $temp = ReadingsVal($name,'temperature',0); + my $windchill = ReadingsNum($weather,'apparentTemperature',0); + my $wind = ReadingsVal($name,'wind',0); $text =~ s/%CONDITION%/$condition/gm; $text =~ s/%TOBE%/$conditionart/gm; $text =~ s/%HUMIDITY%/$humi/gm; @@ -2415,25 +2420,25 @@ sub HOMEMODE_ForecastTXT($;$) my ($hash,$day) = @_; $day = 2 if (!$day); my $name = $hash->{NAME}; - my $weather = AttrVal($name,"HomeWeatherDevice",""); - my $cond = ReadingsVal($weather,"fc".$day."_condition",""); - my $low = ReadingsVal($weather,"fc".$day."_low_c",""); - my $high = ReadingsVal($weather,"fc".$day."_high_c",""); - my $temp = ReadingsVal($name,"temperature",""); - my $hum = ReadingsVal($name,"humidity",""); - my $chill = ReadingsNum($weather,"apparentTemperature",0); - my $wind = ReadingsVal($name,"wind",""); + my $weather = AttrVal($name,'HomeWeatherDevice',''); + my $cond = ReadingsVal($weather,'fc'.$day.'_condition',''); + my $low = ReadingsVal($weather,'fc'.$day.'_low_c',''); + my $high = ReadingsVal($weather,'fc'.$day.'_high_c',''); + my $temp = ReadingsVal($name,'temperature',''); + my $hum = ReadingsVal($name,'humidity',''); + my $chill = ReadingsNum($weather,'apparentTemperature',0); + my $wind = ReadingsVal($name,'wind',''); my $text; if (defined $cond && defined $low && defined $high) { - my ($today,$tomorrow,$atomorrow) = split /\|/,AttrVal($name,"HomeTextTodayTomorrowAfterTomorrow","today|tomorrow|day after tomorrow"); + my ($today,$tomorrow,$atomorrow) = split /\|/,AttrVal($name,'HomeTextTodayTomorrowAfterTomorrow','today|tomorrow|day after tomorrow'); my $d = $today; $d = $tomorrow if ($day == 2); $d = $atomorrow if ($day == 3); $d = $day-1 if ($day > 3); - $text = AttrVal($name,"HomeTextWeatherForecastToday",""); - $text = AttrVal($name,"HomeTextWeatherForecastTomorrow","") if ($day =~ /^[23]$/); - $text = AttrVal($name,"HomeTextWeatherForecastInSpecDays","") if ($day > 3); + $text = AttrVal($name,'HomeTextWeatherForecastToday',''); + $text = AttrVal($name,'HomeTextWeatherForecastTomorrow','') if ($day =~ /^[23]$/); + $text = AttrVal($name,'HomeTextWeatherForecastInSpecDays','') if ($day > 3); $text =~ s/%CONDITION%/$cond/gm; $text =~ s/%DAY%/$d/gm; $text =~ s/%HIGH%/$high/gm; @@ -2442,7 +2447,7 @@ sub HOMEMODE_ForecastTXT($;$) } else { - $text = AttrVal($name,"HomeTextWeatherNoForecast","No forecast available"); + $text = AttrVal($name,'HomeTextWeatherNoForecast','No forecast available'); } return $text; } @@ -2451,14 +2456,14 @@ sub HOMEMODE_uwzTXT($;$$) { my ($hash,$count,$sl) = @_; my $name = $hash->{NAME}; - $count = defined $count ? $count : ReadingsVal($name,"uwz_warnCount",0); - my $text = ""; + $count = defined $count ? $count : ReadingsVal($name,'uwz_warnCount',0); + my $text = ''; for (my $i = 0; $i < $count; $i++) { - $text .= " " if ($i > 0); - $text .= $i + 1 . " " if ($count > 1); - $sl = $sl ? "LongText" : "ShortText"; - $text .= ReadingsVal(AttrVal($name,"HomeUWZ",""),"Warn_".$i."_$sl",""); + $text .= ' ' if ($i > 0); + $text .= $i + 1 . ' ' if ($count > 1); + $sl = $sl ? 'LongText' : 'ShortText'; + $text .= ReadingsVal(AttrVal($name,'HomeUWZ',''),'Warn_'.$i.'_'.$sl,''); } return $text; } @@ -2473,7 +2478,7 @@ sub HOMEMODE_ID($;$$$) return 0 if (defined($devread) && !defined(ReadingsVal($devname,$devread,undef))); return 0 - if (defined($readval) && ReadingsVal($devname,$devread,"") !~ /^$readval$/); + if (defined($readval) && ReadingsVal($devname,$devread,'') !~ /^$readval$/); return $devname; } @@ -2510,7 +2515,7 @@ sub HOMEMODE_execCMDs($$;$) { Log3 $name,3,"$name: error: $err"; Log3 $name,3,"$name: error in command: $cmd"; - readingsSingleUpdate($hash,"lastCMDerror","error: >$err< in CMD: $cmd",1); + readingsSingleUpdate($hash,'lastCMDerror',"error: >$err< in CMD: $cmd",1); } Log3 $name,4,"$name: executed CMDs: $cmd"; return; @@ -2519,12 +2524,12 @@ sub HOMEMODE_execCMDs($$;$) sub HOMEMODE_AttrCheck($$;$) { my ($hash,$attribute,$default) = @_; - $default = "" if (!defined $default); + $default = '' if (!defined $default); my $name = $hash->{NAME}; my $value; if ($hash->{helper}{lastChangedAttr} && $hash->{helper}{lastChangedAttr} eq $attribute) { - $value = defined $hash->{helper}{lastChangedAttrValue} && $hash->{helper}{lastChangedAttrValue} ne "---" ? $hash->{helper}{lastChangedAttrValue} : $default; + $value = defined $hash->{helper}{lastChangedAttrValue} && $hash->{helper}{lastChangedAttrValue} ne '---' ? $hash->{helper}{lastChangedAttrValue} : $default; } else { @@ -2537,12 +2542,12 @@ sub HOMEMODE_DayTime($) { my ($hash) = @_; my $name = $hash->{NAME}; - my $daytimes = HOMEMODE_AttrCheck($hash,"HomeDaytimes",$HOMEMODE_Daytimes); + my $daytimes = HOMEMODE_AttrCheck($hash,'HomeDaytimes',$HOMEMODE_Daytimes); my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime; my $loctime = $hour * 60 + $min; my @texts; my @times; - for (split " ",$daytimes) + for (split ' ',$daytimes) { my ($dt,$text) = split /\|/; my ($h,$m) = split /:/,$dt; @@ -2564,12 +2569,13 @@ sub HOMEMODE_SetDaytime($) my ($hash) = @_; my $name = $hash->{NAME}; my $dt = HOMEMODE_DayTime($hash); - if (ReadingsVal($name,"daytime","") ne $dt) + my $dtr = makeReadingName($dt); + if (ReadingsVal($name,'daytime','') ne $dt) { my @commands; - push @commands,AttrVal($name,"HomeCMDdaytime","") if (AttrVal($name,"HomeCMDdaytime",undef)); - push @commands,AttrVal($name,"HomeCMDdaytime-$dt","") if (AttrVal($name,"HomeCMDdaytime-$dt",undef)); - readingsSingleUpdate($hash,"daytime",$dt,1); + push @commands,AttrVal($name,'HomeCMDdaytime','') if (AttrVal($name,'HomeCMDdaytime',undef)); + push @commands,AttrVal($name,"HomeCMDdaytime-$dtr",'') if (AttrVal($name,"HomeCMDdaytime-$dtr",undef)); + readingsSingleUpdate($hash,'daytime',$dt,1); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); } } @@ -2578,12 +2584,12 @@ sub HOMEMODE_SetSeason($) { my ($hash) = @_; my $name = $hash->{NAME}; - my $seasons = HOMEMODE_AttrCheck($hash,"HomeSeasons",$HOMEMODE_Seasons); + my $seasons = HOMEMODE_AttrCheck($hash,'HomeSeasons',$HOMEMODE_Seasons); my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime; my $locdays = ($month + 1) * 31 + $mday; my @texts; my @dates; - for (split " ",$seasons) + for (split ' ',$seasons) { my ($date,$text) = split /\|/; my ($m,$d) = split /\./,$date; @@ -2597,12 +2603,12 @@ sub HOMEMODE_SetSeason($) my $y = $x==scalar(@dates)-1?0:$x+1; $season = $texts[$x] if ($y > $x && $locdays >= $dates[$x] && $locdays < $dates[$y]); } - if (ReadingsVal($name,"season","") ne $season) + if (ReadingsVal($name,'season','') ne $season) { my @commands; - push @commands,AttrVal($name,"HomeCMDseason","") if (AttrVal($name,"HomeCMDseason",undef)); - push @commands,AttrVal($name,"HomeCMDseason-$season","") if (AttrVal($name,"HomeCMDseason-$season",undef)); - readingsSingleUpdate($hash,"season",$season,1); + push @commands,AttrVal($name,'HomeCMDseason','') if (AttrVal($name,'HomeCMDseason',undef)); + push @commands,AttrVal($name,'HomeCMDseason-'.makeReadingName($season),'') if (AttrVal($name,'HomeCMDseason-'.makeReadingName($season),undef)); + readingsSingleUpdate($hash,'season',$season,1); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); } } @@ -2611,8 +2617,8 @@ sub HOMEMODE_hourMaker($) { my ($minutes) = @_; my $trans = $HOMEMODE_de? - "keine gültigen Minuten übergeben": - "no valid minutes given"; + 'keine gültigen Minuten übergeben': + 'no valid minutes given'; return $trans if ($minutes !~ /^(\d{1,4})(\.\d{0,2})?$/ || $1 >= 6000 || $minutes < 0.01); my $hours = int($minutes / 60); $hours = length $hours > 1 ? $hours : "0$hours"; @@ -2634,39 +2640,39 @@ sub HOMEMODE_addSensorsuserattr($$;$) for my $sensor (@devspec) { my $inolddevspec = @olddevspec && grep /^$sensor$/,@olddevspec ? 1 : 0; - my $alias = AttrVal($sensor,"alias",""); + my $alias = AttrVal($sensor,'alias',''); my @list; - push @list,"HomeModeAlarmActive"; - push @list,"HomeReadings"; - push @list,"HomeValues"; + push @list,'HomeModeAlarmActive'; + push @list,'HomeReadings'; + push @list,'HomeValues'; if ($hash->{SENSORSCONTACT} && grep(/^$sensor$/,split /,/,$hash->{SENSORSCONTACT})) { - push @list,"HomeContactType:doorinside,dooroutside,doormain,window"; - push @list,"HomeOpenMaxTrigger"; - push @list,"HomeOpenDontTriggerModes"; - push @list,"HomeOpenDontTriggerModesResidents"; - push @list,"HomeOpenTimeDividers"; - push @list,"HomeOpenTimes"; + push @list,'HomeContactType:doorinside,dooroutside,doormain,window'; + push @list,'HomeOpenMaxTrigger'; + push @list,'HomeOpenDontTriggerModes'; + push @list,'HomeOpenDontTriggerModesResidents'; + push @list,'HomeOpenTimeDividers'; + push @list,'HomeOpenTimes'; HOMEMODE_set_userattr($sensor,\@list); if (!$inolddevspec) { - my $dr = "[Dd]oor|[Tt](ü|ue)r"; - my $wr = "[Ww]indow|[Ff]enster"; - CommandAttr(undef,"$sensor HomeContactType doorinside") if (($alias =~ /$dr/ || $sensor =~ /$dr/) && !AttrVal($sensor,"HomeContactType","")); - CommandAttr(undef,"$sensor HomeContactType window") if (($alias =~ /$wr/ || $sensor =~ /$wr/) && !AttrVal($sensor,"HomeContactType","")); - CommandAttr(undef,"$sensor HomeModeAlarmActive armaway") if (!AttrVal($sensor,"HomeModeAlarmActive","")); + my $dr = '[Dd]oor|[Tt](ü|ue)r'; + my $wr = '[Ww]indow|[Ff]enster'; + CommandAttr(undef,"$sensor HomeContactType doorinside") if (($alias =~ /$dr/ || $sensor =~ /$dr/) && !AttrVal($sensor,'HomeContactType','')); + CommandAttr(undef,"$sensor HomeContactType window") if (($alias =~ /$wr/ || $sensor =~ /$wr/) && !AttrVal($sensor,'HomeContactType','')); + CommandAttr(undef,"$sensor HomeModeAlarmActive armaway") if (!AttrVal($sensor,'HomeModeAlarmActive','')); } } if ($hash->{SENSORSMOTION} && grep(/^$sensor$/,split /,/,$hash->{SENSORSMOTION})) { - push @list,"HomeSensorLocation:inside,outside"; + push @list,'HomeSensorLocation:inside,outside'; HOMEMODE_set_userattr($sensor,\@list); if (!$inolddevspec) { - my $loc = "inside"; - $loc = "outside" if ($alias =~ /([Aa]u(ss|ß)en)|([Oo]ut)/ || $sensor =~ /([Aa]u(ss|ß)en)|([Oo]ut)/); - CommandAttr(undef,"$sensor HomeSensorLocation $loc") if (!AttrVal($sensor,"HomeSensorLocation","")); - CommandAttr(undef,"$sensor HomeModeAlarmActive armaway") if (!AttrVal($sensor,"HomeModeAlarmActive","") && $loc eq "inside"); + my $loc = 'inside'; + $loc = 'outside' if ($alias =~ /([Aa]u(ss|ß)en)|([Oo]ut)/ || $sensor =~ /([Aa]u(ss|ß)en)|([Oo]ut)/); + CommandAttr(undef,"$sensor HomeSensorLocation $loc") if (!AttrVal($sensor,'HomeSensorLocation','')); + CommandAttr(undef,"$sensor HomeModeAlarmActive armaway") if (!AttrVal($sensor,'HomeModeAlarmActive','') && $loc eq 'inside'); } } } @@ -2676,9 +2682,9 @@ sub HOMEMODE_addSensorsuserattr($$;$) sub HOMEMODE_set_userattr($$) { my ($name,$list) = @_; - my $val = AttrVal($name,"userattr",""); - my $l = join " ",@{$list}; - $l .= $val?" $val":""; + my $val = AttrVal($name,'userattr',''); + my $l = join ' ',@{$list}; + $l .= $val?" $val":''; CommandAttr(undef,"$name userattr $l"); return; } @@ -2688,7 +2694,7 @@ sub HOMEMODE_Luminance($;$$) my ($hash,$dev,$lum) = @_; my $name = $hash->{NAME}; my @sensors = split /,/,$hash->{SENSORSLUMINANCE}; - my $read = AttrVal($name,"HomeSensorsLuminanceReading","luminance"); + my $read = AttrVal($name,'HomeSensorsLuminanceReading','luminance'); $lum = 0 if (!$lum); my @sensorsa; for (@sensors) @@ -2703,8 +2709,8 @@ sub HOMEMODE_Luminance($;$$) my $lumval = defined $lum ? int ($lum / scalar @sensorsa) : undef; if (defined $lumval && $lumval >= 0) { - readingsSingleUpdate($hash,"luminance",$lumval,1); - HOMEMODE_ReadingTrend($hash,"luminance",$lumval); + readingsSingleUpdate($hash,'luminance',$lumval,1); + HOMEMODE_ReadingTrend($hash,'luminance',$lumval); } } @@ -2712,14 +2718,14 @@ sub HOMEMODE_TriggerState($;$$$) { my ($hash,$getter,$type,$trigger) = @_; my $exit = 1 if (!$getter && !$type && $trigger); - $getter = "contactsOpen" if (!$getter); - $type = "all" if (!$type); + $getter = 'contactsOpen' if (!$getter); + $type = 'all' if (!$type); my $name = $hash->{NAME}; my $events = deviceEvents($defs{$trigger},1) if ($trigger); my $contacts = $hash->{SENSORSCONTACT}; my $motions = $hash->{SENSORSMOTION}; - my $tampered = ReadingsVal($name,"sensorsTampered",""); - my $alarm = ReadingsVal($name,"alarmTriggered",""); + my $tampered = ReadingsVal($name,'sensorsTampered',''); + my $alarm = ReadingsVal($name,'alarmTriggered',''); my @contactsOpen; my @sensorsTampered; my @doorsOOpen; @@ -2732,27 +2738,27 @@ sub HOMEMODE_TriggerState($;$$$) my @motionsOutsideOpen; my @alarmSensors; my @lightSensors; - my $amode = ReadingsVal($name,"modeAlarm",""); + my $amode = ReadingsVal($name,'modeAlarm',''); if ($contacts) { for my $sensor (devspec2array($contacts)) { next if (HOMEMODE_IsDisabled($hash,$sensor)); - my ($oread,$tread) = split " ",AttrVal($sensor,"HomeReadings",AttrVal($name,"HomeSensorsContactReadings","state sabotageError")),2; - my $otcmd = AttrVal($sensor,"HomeValues",AttrVal($name,"HomeSensorsContactValues","open|tilted|on")); - my $amodea = AttrVal($sensor,"HomeModeAlarmActive","-"); - my $ostate = ReadingsVal($sensor,$oread,""); - my $tstate = ReadingsVal($sensor,$tread,"") if ($tread); - my $kind = AttrVal($sensor,"HomeContactType","window"); + my ($oread,$tread) = split ' ',AttrVal($sensor,'HomeReadings',AttrVal($name,'HomeSensorsContactReadings','state sabotageError')),2; + my $otcmd = AttrVal($sensor,'HomeValues',AttrVal($name,'HomeSensorsContactValues','open|tilted|on')); + my $amodea = AttrVal($sensor,'HomeModeAlarmActive','-'); + my $ostate = ReadingsVal($sensor,$oread,''); + my $tstate = ReadingsVal($sensor,$tread,'') if ($tread); + my $kind = AttrVal($sensor,'HomeContactType','window'); next if (!$ostate && !$tstate); if ($ostate =~ /^($otcmd)$/) { push @contactsOpen,$sensor; - push @insideOpen,$sensor if ($kind eq "doorinside"); - push @doorsOOpen,$sensor if ($kind && $kind eq "dooroutside"); - push @doorsMOpen,$sensor if ($kind && $kind eq "doormain"); + push @insideOpen,$sensor if ($kind eq 'doorinside'); + push @doorsOOpen,$sensor if ($kind && $kind eq 'dooroutside'); + push @doorsMOpen,$sensor if ($kind && $kind eq 'doormain'); push @outsideOpen,$sensor if ($kind =~ /^(dooroutside|doormain|window)$/); - push @windowsOpen,$sensor if ($kind eq "window"); + push @windowsOpen,$sensor if ($kind eq 'window'); if (grep /^($amodea)$/,$amode) { push @alarmSensors,$sensor; @@ -2760,11 +2766,11 @@ sub HOMEMODE_TriggerState($;$$$) if (defined $exit && $trigger eq $sensor && grep /^$oread:/,@{$events}) { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"prevContact",ReadingsVal($name,"lastContact","")); - readingsBulkUpdate($hash,"lastContact",$sensor); + readingsBulkUpdate($hash,'prevContact',ReadingsVal($name,'lastContact','')); + readingsBulkUpdate($hash,'lastContact',$sensor); readingsEndUpdate($hash,1); - HOMEMODE_ContactCommands($hash,$sensor,"open",$kind); - HOMEMODE_ContactOpenCheck($name,$sensor,"open"); + HOMEMODE_ContactCommands($hash,$sensor,'open',$kind); + HOMEMODE_ContactOpenCheck($name,$sensor,'open'); } } else @@ -2772,12 +2778,12 @@ sub HOMEMODE_TriggerState($;$$$) if (defined $exit && $trigger eq $sensor && grep /^$oread:/,@{$events}) { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"prevContactClosed",ReadingsVal($name,"lastContactClosed","")); - readingsBulkUpdate($hash,"lastContactClosed",$sensor); + readingsBulkUpdate($hash,'prevContactClosed',ReadingsVal($name,'lastContactClosed','')); + readingsBulkUpdate($hash,'lastContactClosed',$sensor); readingsEndUpdate($hash,1); - HOMEMODE_ContactCommands($hash,$sensor,"closed",$kind); - my $timer = "atTmp_HomeOpenTimer_".$sensor."_$name"; - CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,"at")); + HOMEMODE_ContactCommands($hash,$sensor,'closed',$kind); + my $timer = 'atTmp_HomeOpenTimer_'.$sensor.'_'.$name; + CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,'at')); } } if ($tread && $tstate =~ /^($otcmd)$/) @@ -2791,18 +2797,18 @@ sub HOMEMODE_TriggerState($;$$$) for my $sensor (devspec2array($motions)) { next if (HOMEMODE_IsDisabled($hash,$sensor)); - my ($oread,$tread) = split " ",AttrVal($sensor,"HomeReadings",AttrVal($name,"HomeSensorsMotionReadings","state sabotageError")),2; - my $otcmd = AttrVal($sensor,"HomeValues",AttrVal($name,"HomeSensorsMotionValues","open|on")); - my $amodea = AttrVal($sensor,"HomeModeAlarmActive","-"); - my $ostate = ReadingsVal($sensor,$oread,""); - my $tstate = ReadingsVal($sensor,$tread,"") if ($tread); - my $kind = AttrVal($sensor,"HomeSensorLocation","inside"); + my ($oread,$tread) = split ' ',AttrVal($sensor,'HomeReadings',AttrVal($name,'HomeSensorsMotionReadings','state sabotageError')),2; + my $otcmd = AttrVal($sensor,'HomeValues',AttrVal($name,'HomeSensorsMotionValues','open|on')); + my $amodea = AttrVal($sensor,'HomeModeAlarmActive','-'); + my $ostate = ReadingsVal($sensor,$oread,''); + my $tstate = ReadingsVal($sensor,$tread,'') if ($tread); + my $kind = AttrVal($sensor,'HomeSensorLocation','inside'); next if (!$ostate && !$tstate); if ($ostate =~ /^($otcmd)$/) { push @motionsOpen,$sensor; - push @motionsInsideOpen,$sensor if ($kind eq "inside"); - push @motionsOutsideOpen,$sensor if ($kind eq "outside"); + push @motionsInsideOpen,$sensor if ($kind eq 'inside'); + push @motionsOutsideOpen,$sensor if ($kind eq 'outside'); if (grep /^($amodea)$/,$amode) { push @alarmSensors,$sensor; @@ -2810,10 +2816,10 @@ sub HOMEMODE_TriggerState($;$$$) if (defined $exit && $trigger eq $sensor && grep /^$oread:/,@{$events}) { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"prevMotion",ReadingsVal($name,"lastMotion","")); - readingsBulkUpdate($hash,"lastMotion",$sensor); + readingsBulkUpdate($hash,'prevMotion',ReadingsVal($name,'lastMotion','')); + readingsBulkUpdate($hash,'lastMotion',$sensor); readingsEndUpdate($hash,1); - HOMEMODE_MotionCommands($hash,$sensor,"open"); + HOMEMODE_MotionCommands($hash,$sensor,'open'); } } else @@ -2821,10 +2827,10 @@ sub HOMEMODE_TriggerState($;$$$) if (defined $exit && $trigger eq $sensor && grep /^$oread:/,@{$events}) { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"prevMotionClosed",ReadingsVal($name,"lastMotionClosed","")); - readingsBulkUpdate($hash,"lastMotionClosed",$sensor); + readingsBulkUpdate($hash,'prevMotionClosed',ReadingsVal($name,'lastMotionClosed','')); + readingsBulkUpdate($hash,'lastMotionClosed',$sensor); readingsEndUpdate($hash,1); - HOMEMODE_MotionCommands($hash,$sensor,"closed"); + HOMEMODE_MotionCommands($hash,$sensor,'closed'); } } if ($tread && $tstate =~ /^($otcmd)$/) @@ -2833,75 +2839,75 @@ sub HOMEMODE_TriggerState($;$$$) } } } - HOMEMODE_alarmTriggered($hash,@alarmSensors) if (join(",",@alarmSensors) ne $alarm); - my $open = @contactsOpen ? join(",",@contactsOpen) : ""; - my $opendo = @doorsOOpen ? join(",",@doorsOOpen) : ""; - my $opendm = @doorsMOpen ? join(",",@doorsMOpen) : ""; - my $openi = @insideOpen ? join(",",@insideOpen) : ""; - my $openm = @motionsOpen ? join(",",@motionsOpen) : ""; - my $openmi = @motionsInsideOpen ? join(",",@motionsInsideOpen) : ""; - my $openmo = @motionsOutsideOpen ? join(",",@motionsOutsideOpen) : ""; - my $openo = @outsideOpen ? join(",",@outsideOpen) : ""; - my $openw = @windowsOpen ? join(",",@windowsOpen) : ""; - my $tamp = @sensorsTampered ? join(",",@sensorsTampered) : ""; + HOMEMODE_alarmTriggered($hash,@alarmSensors) if (join(',',@alarmSensors) ne $alarm); + my $open = @contactsOpen ? join(',',@contactsOpen) : ''; + my $opendo = @doorsOOpen ? join(',',@doorsOOpen) : ''; + my $opendm = @doorsMOpen ? join(',',@doorsMOpen) : ''; + my $openi = @insideOpen ? join(',',@insideOpen) : ''; + my $openm = @motionsOpen ? join(',',@motionsOpen) : ''; + my $openmi = @motionsInsideOpen ? join(',',@motionsInsideOpen) : ''; + my $openmo = @motionsOutsideOpen ? join(',',@motionsOutsideOpen) : ''; + my $openo = @outsideOpen ? join(',',@outsideOpen) : ''; + my $openw = @windowsOpen ? join(',',@windowsOpen) : ''; + my $tamp = @sensorsTampered ? join(',',@sensorsTampered) : ''; readingsBeginUpdate($hash); if ($contacts) { - readingsBulkUpdateIfChanged($hash,"contactsDoorsInsideOpen",$openi); - readingsBulkUpdateIfChanged($hash,"contactsDoorsInsideOpen_ct",@insideOpen); - readingsBulkUpdateIfChanged($hash,"contactsDoorsInsideOpen_hr",HOMEMODE_makeHR($hash,0,@insideOpen)); - readingsBulkUpdateIfChanged($hash,"contactsDoorsOutsideOpen",$opendo); - readingsBulkUpdateIfChanged($hash,"contactsDoorsOutsideOpen_ct",@doorsOOpen); - readingsBulkUpdateIfChanged($hash,"contactsDoorsOutsideOpen_hr",HOMEMODE_makeHR($hash,0,@doorsOOpen)); - readingsBulkUpdateIfChanged($hash,"contactsDoorsMainOpen",$opendm); - readingsBulkUpdateIfChanged($hash,"contactsDoorsMainOpen_ct",@doorsMOpen); - readingsBulkUpdateIfChanged($hash,"contactsDoorsMainOpen_hr",HOMEMODE_makeHR($hash,0,@doorsMOpen)); - readingsBulkUpdateIfChanged($hash,"contactsOpen",$open); - readingsBulkUpdateIfChanged($hash,"contactsOpen_ct",@contactsOpen); - readingsBulkUpdateIfChanged($hash,"contactsOpen_hr",HOMEMODE_makeHR($hash,0,@contactsOpen)); - readingsBulkUpdateIfChanged($hash,"contactsOutsideOpen",$openo); - readingsBulkUpdateIfChanged($hash,"contactsOutsideOpen_ct",@outsideOpen); - readingsBulkUpdateIfChanged($hash,"contactsOutsideOpen_hr",HOMEMODE_makeHR($hash,0,@outsideOpen)); - readingsBulkUpdateIfChanged($hash,"contactsWindowsOpen",$openw); - readingsBulkUpdateIfChanged($hash,"contactsWindowsOpen_ct",@windowsOpen); - readingsBulkUpdateIfChanged($hash,"contactsWindowsOpen_hr",HOMEMODE_makeHR($hash,0,@windowsOpen)); + readingsBulkUpdateIfChanged($hash,'contactsDoorsInsideOpen',$openi); + readingsBulkUpdateIfChanged($hash,'contactsDoorsInsideOpen_ct',@insideOpen); + readingsBulkUpdateIfChanged($hash,'contactsDoorsInsideOpen_hr',HOMEMODE_makeHR($hash,0,@insideOpen)); + readingsBulkUpdateIfChanged($hash,'contactsDoorsOutsideOpen',$opendo); + readingsBulkUpdateIfChanged($hash,'contactsDoorsOutsideOpen_ct',@doorsOOpen); + readingsBulkUpdateIfChanged($hash,'contactsDoorsOutsideOpen_hr',HOMEMODE_makeHR($hash,0,@doorsOOpen)); + readingsBulkUpdateIfChanged($hash,'contactsDoorsMainOpen',$opendm); + readingsBulkUpdateIfChanged($hash,'contactsDoorsMainOpen_ct',@doorsMOpen); + readingsBulkUpdateIfChanged($hash,'contactsDoorsMainOpen_hr',HOMEMODE_makeHR($hash,0,@doorsMOpen)); + readingsBulkUpdateIfChanged($hash,'contactsOpen',$open); + readingsBulkUpdateIfChanged($hash,'contactsOpen_ct',@contactsOpen); + readingsBulkUpdateIfChanged($hash,'contactsOpen_hr',HOMEMODE_makeHR($hash,0,@contactsOpen)); + readingsBulkUpdateIfChanged($hash,'contactsOutsideOpen',$openo); + readingsBulkUpdateIfChanged($hash,'contactsOutsideOpen_ct',@outsideOpen); + readingsBulkUpdateIfChanged($hash,'contactsOutsideOpen_hr',HOMEMODE_makeHR($hash,0,@outsideOpen)); + readingsBulkUpdateIfChanged($hash,'contactsWindowsOpen',$openw); + readingsBulkUpdateIfChanged($hash,'contactsWindowsOpen_ct',@windowsOpen); + readingsBulkUpdateIfChanged($hash,'contactsWindowsOpen_hr',HOMEMODE_makeHR($hash,0,@windowsOpen)); } - readingsBulkUpdateIfChanged($hash,"sensorsTampered",$tamp); - readingsBulkUpdateIfChanged($hash,"sensorsTampered_ct",@sensorsTampered); - readingsBulkUpdateIfChanged($hash,"sensorsTampered_hr",HOMEMODE_makeHR($hash,0,@sensorsTampered)); + readingsBulkUpdateIfChanged($hash,'sensorsTampered',$tamp); + readingsBulkUpdateIfChanged($hash,'sensorsTampered_ct',@sensorsTampered); + readingsBulkUpdateIfChanged($hash,'sensorsTampered_hr',HOMEMODE_makeHR($hash,0,@sensorsTampered)); if ($motions) { - readingsBulkUpdateIfChanged($hash,"motionsSensors",$openm); - readingsBulkUpdateIfChanged($hash,"motionsSensors_ct",@motionsOpen); - readingsBulkUpdateIfChanged($hash,"motionsSensors_hr",HOMEMODE_makeHR($hash,0,@motionsOpen)); - readingsBulkUpdateIfChanged($hash,"motionsInside",$openmi); - readingsBulkUpdateIfChanged($hash,"motionsInside_ct",@motionsInsideOpen); - readingsBulkUpdateIfChanged($hash,"motionsInside_hr",HOMEMODE_makeHR($hash,0,@motionsInsideOpen)); - readingsBulkUpdateIfChanged($hash,"motionsOutside",$openmo); - readingsBulkUpdateIfChanged($hash,"motionsOutside_ct",@motionsOutsideOpen); - readingsBulkUpdateIfChanged($hash,"motionsOutside_hr",HOMEMODE_makeHR($hash,0,@motionsOutsideOpen)); + readingsBulkUpdateIfChanged($hash,'motionsSensors',$openm); + readingsBulkUpdateIfChanged($hash,'motionsSensors_ct',@motionsOpen); + readingsBulkUpdateIfChanged($hash,'motionsSensors_hr',HOMEMODE_makeHR($hash,0,@motionsOpen)); + readingsBulkUpdateIfChanged($hash,'motionsInside',$openmi); + readingsBulkUpdateIfChanged($hash,'motionsInside_ct',@motionsInsideOpen); + readingsBulkUpdateIfChanged($hash,'motionsInside_hr',HOMEMODE_makeHR($hash,0,@motionsInsideOpen)); + readingsBulkUpdateIfChanged($hash,'motionsOutside',$openmo); + readingsBulkUpdateIfChanged($hash,'motionsOutside_ct',@motionsOutsideOpen); + readingsBulkUpdateIfChanged($hash,'motionsOutside_hr',HOMEMODE_makeHR($hash,0,@motionsOutsideOpen)); } readingsEndUpdate($hash,1); - HOMEMODE_alarmTampered($hash,@sensorsTampered) if (join(",",@sensorsTampered) ne $tampered); - if ($getter eq "contactsOpen") + HOMEMODE_alarmTampered($hash,@sensorsTampered) if (join(',',@sensorsTampered) ne $tampered); + if ($getter eq 'contactsOpen') { - return "open contacts: $open" if ($open && $type eq "all"); - return "no open contacts" if (!$open && $type eq "all"); - return "open doorsinside: $openi" if ($openi && $type eq "doorsinside"); - return "no open doorsinside" if (!$openi && $type eq "doorsinside"); - return "open doorsoutside: $opendo" if ($opendo && $type eq "doorsoutside"); - return "no open doorsoutside" if (!$opendo && $type eq "doorsoutside"); - return "open doorsmain: $opendm" if ($opendm && $type eq "doorsmain"); - return "no open doorsmain" if (!$opendm && $type eq "doorsmain"); - return "open outside: $openo" if ($openo && $type eq "outside"); - return "no open outside" if (!$openo && $type eq "outside"); - return "open windows: $openw" if ($openw && $type eq "windows"); - return "no open windows" if (!$openw && $type eq "windows"); + return "open contacts: $open" if ($open && $type eq 'all'); + return 'no open contacts' if (!$open && $type eq 'all'); + return "open doorsinside: $openi" if ($openi && $type eq 'doorsinside'); + return 'no open doorsinside' if (!$openi && $type eq 'doorsinside'); + return "open doorsoutside: $opendo" if ($opendo && $type eq 'doorsoutside'); + return 'no open doorsoutside' if (!$opendo && $type eq 'doorsoutside'); + return "open doorsmain: $opendm" if ($opendm && $type eq 'doorsmain'); + return 'no open doorsmain' if (!$opendm && $type eq 'doorsmain'); + return "open outside: $openo" if ($openo && $type eq 'outside'); + return 'no open outside' if (!$openo && $type eq 'outside'); + return "open windows: $openw" if ($openw && $type eq 'windows'); + return 'no open windows' if (!$openw && $type eq 'windows'); } - elsif ($getter eq "sensorsTampered") + elsif ($getter eq 'sensorsTampered') { return "tampered sensors: $tamp" if ($tamp); - return "no tampered sensors" if (!$tamp); + return 'no tampered sensors' if (!$tamp); } return; } @@ -2909,12 +2915,12 @@ sub HOMEMODE_TriggerState($;$$$) sub HOMEMODE_name2alias($;$) { my ($name,$witharticle) = @_; - my $alias = AttrVal($name,"alias",$name); + my $alias = AttrVal($name,'alias',$name); my $art; - $art = "die" if ($alias =~ /t(ü|ue)r/i); - $art = "das" if ($alias =~ /fenster/i); - $art = "der" if ($alias =~ /(sensor|dete[ck]tor|melder|kontakt)$/i); - $art = "der" if ($alias =~ /^(sensor|dete[ck]tor|melder|kontakt)\s.+/i); + $art = 'die' if ($alias =~ /t(ü|ue)r/i); + $art = 'das' if ($alias =~ /fenster/i); + $art = 'der' if ($alias =~ /(sensor|dete[ck]tor|melder|kontakt)$/i); + $art = 'der' if ($alias =~ /^(sensor|dete[ck]tor|melder|kontakt)\s.+/i); my $ret = $witharticle && $art ? "$art $alias" : $alias; return $ret; } @@ -2923,12 +2929,12 @@ sub HOMEMODE_ContactOpenCheck($$;$$) { my ($name,$contact,$state,$retrigger) = @_; $retrigger = 0 if (!$retrigger); - my $maxtrigger = AttrNum($contact,"HomeOpenMaxTrigger",0); + my $maxtrigger = AttrNum($contact,'HomeOpenMaxTrigger',0); if ($maxtrigger) { - my $mode = ReadingsVal($name,"state",""); - my $dtmode = AttrVal($contact,"HomeOpenDontTriggerModes",undef); - my $dtres = AttrVal($contact,"HomeOpenDontTriggerModesResidents",undef); + my $mode = ReadingsVal($name,'state',''); + my $dtmode = AttrVal($contact,'HomeOpenDontTriggerModes',undef); + my $dtres = AttrVal($contact,'HomeOpenDontTriggerModesResidents',undef); my $donttrigger; $donttrigger = 1 if ($dtmode && $mode =~ /^($dtmode)$/); if (!$donttrigger && $dtmode && $dtres) @@ -2936,28 +2942,28 @@ sub HOMEMODE_ContactOpenCheck($$;$$) for (devspec2array($dtres)) { next if (HOMEMODE_IsDisabled(undef,$_)); - $donttrigger = 1 if (ReadingsVal($_,"state","") =~ /^($dtmode)$/); + $donttrigger = 1 if (ReadingsVal($_,'state','') =~ /^($dtmode)$/); } } - my $timer = "atTmp_HomeOpenTimer_".$contact."_$name"; - CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,"at") && ($retrigger || $donttrigger)); + my $timer = 'atTmp_HomeOpenTimer_'.$contact."_$name"; + CommandDelete(undef,$timer) if (HOMEMODE_ID($timer,'at') && ($retrigger || $donttrigger)); return if ((!$retrigger && $donttrigger) || $donttrigger); - my $season = ReadingsVal($name,"season",""); - my $seasons = AttrVal($name,"HomeSeasons",$HOMEMODE_Seasons); - my $dividers = AttrVal($contact,"HomeOpenTimeDividers",AttrVal($name,"HomeSensorsContactOpenTimeDividers","")); - my $mintime = AttrNum($name,"HomeSensorsContactOpenTimeMin",0); - my @wt = split " ",AttrVal($contact,"HomeOpenTimes",AttrVal($name,"HomeSensorsContactOpenTimes","10")); + my $season = ReadingsVal($name,'season',''); + my $seasons = AttrVal($name,'HomeSeasons',$HOMEMODE_Seasons); + my $dividers = AttrVal($contact,'HomeOpenTimeDividers',AttrVal($name,'HomeSensorsContactOpenTimeDividers','')); + my $mintime = AttrNum($name,'HomeSensorsContactOpenTimeMin',0); + my @wt = split ' ',AttrVal($contact,'HomeOpenTimes',AttrVal($name,'HomeSensorsContactOpenTimes','10')); my $waittime; Log3 $name,5,"$name: retrigger: $retrigger"; $waittime = $wt[$retrigger] if ($wt[$retrigger]); $waittime = $wt[scalar @wt - 1] if (!defined $waittime); Log3 $name,5,"$name: waittime real: $waittime"; - if ($dividers && AttrVal($contact,"HomeContactType","window") !~ /^door(inside|main)$/) + if ($dividers && AttrVal($contact,'HomeContactType','window') !~ /^door(inside|main)$/) { - my @divs = split " ",$dividers; - my $divider; + my @divs = split ' ',$dividers; + my $divider = 0; my $count = 0; - for (split " ",$seasons) + for (split ' ',$seasons) { my ($date,$text) = split /\|/; $divider = $divs[$count] if ($season eq $text); @@ -2965,7 +2971,7 @@ sub HOMEMODE_ContactOpenCheck($$;$$) } return if ($divider == 0); $waittime = $waittime / $divider; - $waittime = sprintf("%.2f",$waittime) * 1; + $waittime = sprintf('%.2f',$waittime) * 1; } $waittime = $mintime if ($mintime && $waittime < $mintime); $retrigger++; @@ -2973,9 +2979,9 @@ sub HOMEMODE_ContactOpenCheck($$;$$) $waittime = HOMEMODE_hourMaker($waittime); my $at = "{HOMEMODE_ContactOpenCheck(\"$name\",\"$contact\",undef,$retrigger)}" if ($retrigger <= $maxtrigger); my $contactname = HOMEMODE_name2alias($contact,1); - my $contactread = (split " ",AttrVal($contact,"HomeReadings",AttrVal($name,"HomeSensorsContactReadings","state sabotageError")))[0]; - $state = $state ? $state : ReadingsVal($contact,$contactread,""); - my $opencmds = AttrVal($contact,"HomeValues",AttrVal($name,"HomeSensorsContactValues","open|tilted|on")); + my $contactread = (split ' ',AttrVal($contact,'HomeReadings',AttrVal($name,'HomeSensorsContactReadings','state sabotageError')))[0]; + $state = $state ? $state : ReadingsVal($contact,$contactread,''); + my $opencmds = AttrVal($contact,'HomeValues',AttrVal($name,'HomeSensorsContactValues','open|tilted|on')); if ($state =~ /^($opencmds|open)$/) { CommandDefine(undef,"$timer at +$waittime $at") if ($at && !HOMEMODE_ID($timer)); @@ -2984,12 +2990,12 @@ sub HOMEMODE_ContactOpenCheck($$;$$) my @commands; my $hash = $defs{$name}; Log3 $name,5,"$name: maxtrigger: $maxtrigger"; - my $cmd = AttrVal($name,"HomeCMDcontactOpenWarning1",""); - $cmd = AttrVal($name,"HomeCMDcontactOpenWarning2","") if (AttrVal($name,"HomeCMDcontactOpenWarning2",undef) && $retrigger > 2); - $cmd = AttrVal($name,"HomeCMDcontactOpenWarningLast","") if (AttrVal($name,"HomeCMDcontactOpenWarningLast",undef) && $retrigger == $maxtrigger + 1); + my $cmd = AttrVal($name,'HomeCMDcontactOpenWarning1',''); + $cmd = AttrVal($name,'HomeCMDcontactOpenWarning2','') if (AttrVal($name,'HomeCMDcontactOpenWarning2',undef) && $retrigger > 2); + $cmd = AttrVal($name,'HomeCMDcontactOpenWarningLast','') if (AttrVal($name,'HomeCMDcontactOpenWarningLast',undef) && $retrigger == $maxtrigger + 1); if ($cmd) { - my ($c,$o) = split /\|/,AttrVal($name,"HomeTextClosedOpen","closed|open"); + my ($c,$o) = split /\|/,AttrVal($name,'HomeTextClosedOpen','closed|open'); $state = $state =~ /^($opencmds)$/ ? $o : $c; $cmd =~ s/%ALIAS%/$contactname/gm; $cmd =~ s/%SENSOR%/$contact/gm; @@ -3006,25 +3012,25 @@ sub HOMEMODE_ContactOpenCheckAfterModeChange($$$;$) { my ($hash,$mode,$pmode,$resident) = @_; my $name = $hash->{NAME}; - my $contacts = ReadingsVal($name,"contactsOpen",""); - $mode = ReadingsVal($name,"mode","") if (!$mode); - $pmode = ReadingsVal($name,"prevMode","") if (!$pmode); - my $state = ReadingsVal($resident,"state","") if ($resident); - my $pstate = ReadingsVal($resident,"lastState","") if ($resident); + my $contacts = ReadingsVal($name,'contactsOpen',''); + $mode = ReadingsVal($name,'mode','') if (!$mode); + $pmode = ReadingsVal($name,'prevMode','') if (!$pmode); + my $state = ReadingsVal($resident,'state','') if ($resident); + my $pstate = ReadingsVal($resident,'lastState','') if ($resident); if ($contacts) { for (split /,/,$contacts) { - my $m = AttrVal($_,"HomeOpenDontTriggerModes",""); - my $r = AttrVal($_,"HomeOpenDontTriggerModesResidents",""); + my $m = AttrVal($_,'HomeOpenDontTriggerModes',''); + my $r = AttrVal($_,'HomeOpenDontTriggerModesResidents',''); $r = s/,/\|/g; if ($resident && $m && $r && $resident =~ /^($r)$/ && $state =~ /^($m)$/ && $pstate !~ /^($m)$/) { - HOMEMODE_ContactOpenCheck($name,$_,"open"); + HOMEMODE_ContactOpenCheck($name,$_,'open'); } elsif ($m && !$r && $pmode =~ /^($m)$/ && $mode !~ /^($m)$/) { - HOMEMODE_ContactOpenCheck($name,$_,"open"); + HOMEMODE_ContactOpenCheck($name,$_,'open'); } } } @@ -3036,18 +3042,18 @@ sub HOMEMODE_ContactCommands($$$$) my $name = $hash->{NAME}; my $alias = HOMEMODE_name2alias($contact,1); my @cmds; - push @cmds,AttrVal($name,"HomeCMDcontact","") if (AttrVal($name,"HomeCMDcontact",undef)); - push @cmds,AttrVal($name,"HomeCMDcontactOpen","") if (AttrVal($name,"HomeCMDcontactOpen",undef) && $state eq "open"); - push @cmds,AttrVal($name,"HomeCMDcontactClosed","") if (AttrVal($name,"HomeCMDcontactClosed",undef) && $state eq "closed"); - push @cmds,AttrVal($name,"HomeCMDcontactDoormain","") if (AttrVal($name,"HomeCMDcontactDoormain",undef) && $kind eq "doormain"); - push @cmds,AttrVal($name,"HomeCMDcontactDoormainOpen","") if (AttrVal($name,"HomeCMDcontactDoormainOpen",undef) && $kind eq "doormain" && $state eq "open"); - push @cmds,AttrVal($name,"HomeCMDcontactDoormainClosed","") if (AttrVal($name,"HomeCMDcontactDoormainClosed",undef) && $kind eq "doormain" && $state eq "closed"); + push @cmds,AttrVal($name,'HomeCMDcontact','') if (AttrVal($name,'HomeCMDcontact',undef)); + push @cmds,AttrVal($name,'HomeCMDcontactOpen','') if (AttrVal($name,'HomeCMDcontactOpen',undef) && $state eq 'open'); + push @cmds,AttrVal($name,'HomeCMDcontactClosed','') if (AttrVal($name,'HomeCMDcontactClosed',undef) && $state eq 'closed'); + push @cmds,AttrVal($name,'HomeCMDcontactDoormain','') if (AttrVal($name,'HomeCMDcontactDoormain',undef) && $kind eq 'doormain'); + push @cmds,AttrVal($name,'HomeCMDcontactDoormainOpen','') if (AttrVal($name,'HomeCMDcontactDoormainOpen',undef) && $kind eq 'doormain' && $state eq 'open'); + push @cmds,AttrVal($name,'HomeCMDcontactDoormainClosed','') if (AttrVal($name,'HomeCMDcontactDoormainClosed',undef) && $kind eq 'doormain' && $state eq 'closed'); if (@cmds) { for (@cmds) { - my ($c,$o) = split /\|/,AttrVal($name,"HomeTextClosedOpen","closed|open"); - my $sta = $state eq "open" ? $o : $c; + my ($c,$o) = split /\|/,AttrVal($name,'HomeTextClosedOpen','closed|open'); + my $sta = $state eq 'open' ? $o : $c; $_ =~ s/%ALIAS%/$alias/gm; $_ =~ s/%SENSOR%/$contact/gm; $_ =~ s/%STATE%/$sta/gm; @@ -3062,15 +3068,15 @@ sub HOMEMODE_MotionCommands($$$) my $name = $hash->{NAME}; my $alias = HOMEMODE_name2alias($sensor,1); my @cmds; - push @cmds,AttrVal($name,"HomeCMDmotion","") if (AttrVal($name,"HomeCMDmotion",undef)); - push @cmds,AttrVal($name,"HomeCMDmotion-on","") if (AttrVal($name,"HomeCMDmotion-on",undef) && $state eq "open"); - push @cmds,AttrVal($name,"HomeCMDmotion-off","") if (AttrVal($name,"HomeCMDmotion-off",undef) && $state eq "closed"); + push @cmds,AttrVal($name,'HomeCMDmotion','') if (AttrVal($name,'HomeCMDmotion',undef)); + push @cmds,AttrVal($name,'HomeCMDmotion-on','') if (AttrVal($name,'HomeCMDmotion-on',undef) && $state eq 'open'); + push @cmds,AttrVal($name,'HomeCMDmotion-off','') if (AttrVal($name,'HomeCMDmotion-off',undef) && $state eq 'closed'); if (@cmds) { for (@cmds) { - my ($c,$o) = split /\|/,AttrVal($name,"HomeTextClosedOpen","closed|open"); - $state = $state eq "open" ? $o : $c; + my ($c,$o) = split /\|/,AttrVal($name,'HomeTextClosedOpen','closed|open'); + $state = $state eq 'open' ? $o : $c; $_ =~ s/%ALIAS%/$alias/gm; $_ =~ s/%SENSOR%/$sensor/gm; $_ =~ s/%STATE%/$state/gm; @@ -3083,24 +3089,24 @@ sub HOMEMODE_EventCommands($$$$) { my ($hash,$cal,$read,$event) = @_; my $name = $hash->{NAME}; - my $prevevent = ReadingsVal($name,"event-$cal",""); + my $prevevent = ReadingsVal($name,"event-$cal",''); my @cmds; - if ($read ne "modeStarted") + if ($read ne 'modeStarted') { - push @cmds,AttrVal($name,"HomeCMDevent","") if (AttrVal($name,"HomeCMDevent",undef)); - push @cmds,AttrVal($name,"HomeCMDevent-$cal-each","") if (AttrVal($name,"HomeCMDevent-$cal-each",undef)); + push @cmds,AttrVal($name,'HomeCMDevent','') if (AttrVal($name,'HomeCMDevent',undef)); + push @cmds,AttrVal($name,"HomeCMDevent-$cal-each",'') if (AttrVal($name,"HomeCMDevent-$cal-each",undef)); } - if (HOMEMODE_ID($cal,"holiday")) + if (HOMEMODE_ID($cal,'holiday')) { if ($event ne $prevevent) { - $event =~ s/[,;]//g; + $event =~ s/[,;\?\!\|\\\/\^\$]/-/g; my $evt = $event; $evt =~ s/[\s ]+/-/g; my $pevt = $prevevent; $pevt =~ s/[\s ]+/-/g; - push @cmds,AttrVal($name,"HomeCMDevent-$cal-$pevt-end","") if (AttrVal($name,"HomeCMDevent-$cal-$pevt-end",undef)); - push @cmds,AttrVal($name,"HomeCMDevent-$cal-$evt-begin","") if (AttrVal($name,"HomeCMDevent-$cal-$evt-begin",undef)); + push @cmds,AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($pevt).'-end','') if (AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($pevt).'-end',undef)); + push @cmds,AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($evt).'-begin','') if (AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($evt).'-begin',undef)); readingsSingleUpdate($hash,"event-$cal",$event,1); for (@cmds) { @@ -3112,12 +3118,12 @@ sub HOMEMODE_EventCommands($$$$) else { my @prevevents; - @prevevents = split /,/,$prevevent if ($prevevent ne "none"); + @prevevents = split /,/,$prevevent if ($prevevent ne 'none'); for (split /;/,$event) { $event =~ s/[\s ]//g; my $summary; - my $description = ""; + my $description = ''; my $t = time(); my @filters = ( { ref => \&filter_true, param => undef } ); for (Calendar_GetEvents($defs{$cal},$t,@filters)) @@ -3128,18 +3134,18 @@ sub HOMEMODE_EventCommands($$$$) last; } next unless $summary; - $summary =~ s/[,;]//g; + $summary =~ s/[,;\?\!\|\\\/\^\$]/-/g; Log3 $name,5,"Calendar_GetEvents event: $summary"; my $sum = $summary; $sum =~ s/[\s ]+/-/g; - if ($read eq "start") + if ($read eq 'start') { push @prevevents,$summary if (!grep /^$summary$/,@prevevents); - push @cmds,AttrVal($name,"HomeCMDevent-$cal-$sum-begin","") if (AttrVal($name,"HomeCMDevent-$cal-$sum-begin",undef)); + push @cmds,AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($sum).'-begin','') if (AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($sum).'-begin',undef)); } - elsif ($read eq "end") + elsif ($read eq 'end') { - push @cmds,AttrVal($name,"HomeCMDevent-$cal-$sum-end","") if (AttrVal($name,"HomeCMDevent-$cal-$sum-end",undef)); + push @cmds,AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($sum).'-end','') if (AttrVal($name,"HomeCMDevent-$cal-".makeReadingName($sum).'-end',undef)); if (grep /^$summary$/,@prevevents) { my @sevents; @@ -3150,19 +3156,19 @@ sub HOMEMODE_EventCommands($$$$) @prevevents = @sevents; } } - elsif ($read eq "modeStarted") + elsif ($read eq 'modeStarted') { push @prevevents,$summary if (!grep /^$summary$/,@prevevents); } for (@cmds) { - if ($read eq "start") + if ($read eq 'start') { $_ =~ s/%EVENT%/$summary/gm; $_ =~ s/%PREVEVENT%/none/gm; $_ =~ s/%DESCRIPTION%/$description/gm; } - elsif ($read eq "end") + elsif ($read eq 'end') { $_ =~ s/%EVENT%/none/gm; $_ =~ s/%PREVEVENT%/$summary/gm; @@ -3170,8 +3176,8 @@ sub HOMEMODE_EventCommands($$$$) } } } - my $update = "none"; - $update = join ",",@prevevents if (@prevevents); + my $update = 'none'; + $update = join ',',@prevevents if (@prevevents); readingsSingleUpdate($hash,"event-$cal",$update,1); } for (@cmds) @@ -3185,8 +3191,8 @@ sub HOMEMODE_UWZCommands($$) { my ($hash,$events) = @_; my $name = $hash->{NAME}; - my $prev = ReadingsNum($name,"uwz_warnCount",-1); - my $uwz = AttrVal($name,"HomeUWZ",""); + my $prev = ReadingsNum($name,'uwz_warnCount',-1); + my $uwz = AttrVal($name,'HomeUWZ',''); my $count; my $warning; for my $evt (@{$events}) @@ -3198,13 +3204,13 @@ sub HOMEMODE_UWZCommands($$) } if (defined $count) { - readingsSingleUpdate($hash,"uwz_warnCount",$count,1); + readingsSingleUpdate($hash,'uwz_warnCount',$count,1); if ($count != $prev) { - my $se = $count > 0 ? "begin" : "end"; + my $se = $count > 0 ? 'begin' : 'end'; my @cmds; - push @cmds,AttrVal($name,"HomeCMDuwz-warn","") if (AttrVal($name,"HomeCMDuwz-warn",undef)); - push @cmds,AttrVal($name,"HomeCMDuwz-warn-$se","") if (AttrVal($name,"HomeCMDuwz-warn-$se",undef)); + push @cmds,AttrVal($name,'HomeCMDuwz-warn','') if (AttrVal($name,'HomeCMDuwz-warn',undef)); + push @cmds,AttrVal($name,"HomeCMDuwz-warn-$se",'') if (AttrVal($name,"HomeCMDuwz-warn-$se",undef)); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@cmds)) if (@cmds); } } @@ -3214,20 +3220,20 @@ sub HOMEMODE_HomebridgeMapping($) { my ($hash) = @_; my $name = $hash->{NAME}; - my $mapping = "SecuritySystemCurrentState=alarmState,values=armhome:0;armaway:1;armnight:2;disarm:3;alarm:4"; - $mapping .= "\nSecuritySystemTargetState=modeAlarm,values=armhome:0;armaway:1;armnight:2;disarm:3,cmds=0:modeAlarm+armhome;1:modeAlarm+armaway;2:modeAlarm+armnight;3:modeAlarm+disarm,delay=1"; - $mapping .= "\nSecuritySystemAlarmType=alarmTriggered_ct,values=0:0;/.*/:1"; - $mapping .= "\nOccupancyDetected=presence,values=present:1;absent:0"; - $mapping .= "\nMute=dnd,valueOn=on,cmdOn=dnd+on,cmdOff=dnd+off"; - $mapping .= "\nOn=anyoneElseAtHome,valueOn=on,cmdOn=anyoneElseAtHome+on,cmdOff=anyoneElseAtHome+off"; - $mapping .= "\nContactSensorState=contactsOutsideOpen_ct,values=0:0;/.*/:1" if (HOMEMODE_ID($name,undef,"contactsOutsideOpen_ct")); - $mapping .= "\nStatusTampered=sensorsTampered_ct,values=0:0;/.*/:1" if (HOMEMODE_ID($name,undef,"sensorsTampered_ct")); - $mapping .= "\nMotionDetected=motionsInside_ct,values=0:0;/.*/:1" if (HOMEMODE_ID($name,undef,"motionsInside_ct")); - $mapping .= "\nStatusLowBattery=batteryLow_ct,values=0:0;/.*/:1" if (HOMEMODE_ID($name,undef,"batteryLow_ct")); - $mapping .= "\nSmokeDetected=alarmSmoke_ct,values=0:0;/.*/:1" if (HOMEMODE_ID($name,undef,"alarmSmoke_ct")); - $mapping .= "\nAirPressure=pressure" if (HOMEMODE_ID($name,undef,"pressure")); - addToDevAttrList($name,"genericDeviceType") if (!grep /^genericDeviceType/,split(" ",AttrVal("global","userattr",""))); - addToDevAttrList($name,"homebridgeMapping:textField-long") if (!grep /^homebridgeMapping/,split(" ",AttrVal("global","userattr",""))); + my $mapping = 'SecuritySystemCurrentState=alarmState,values=armhome:0;armaway:1;armnight:2;disarm:3;alarm:4'; + $mapping .= '\nSecuritySystemTargetState=modeAlarm,values=armhome:0;armaway:1;armnight:2;disarm:3,cmds=0:modeAlarm+armhome;1:modeAlarm+armaway;2:modeAlarm+armnight;3:modeAlarm+disarm,delay=1'; + $mapping .= '\nSecuritySystemAlarmType=alarmTriggered_ct,values=0:0;/.*/:1'; + $mapping .= '\nOccupancyDetected=presence,values=present:1;absent:0'; + $mapping .= '\nMute=dnd,valueOn=on,cmdOn=dnd+on,cmdOff=dnd+off'; + $mapping .= '\nOn=anyoneElseAtHome,valueOn=on,cmdOn=anyoneElseAtHome+on,cmdOff=anyoneElseAtHome+off'; + $mapping .= '\nContactSensorState=contactsOutsideOpen_ct,values=0:0;/.*/:1' if (HOMEMODE_ID($name,undef,'contactsOutsideOpen_ct')); + $mapping .= '\nStatusTampered=sensorsTampered_ct,values=0:0;/.*/:1' if (HOMEMODE_ID($name,undef,'sensorsTampered_ct')); + $mapping .= '\nMotionDetected=motionsInside_ct,values=0:0;/.*/:1' if (HOMEMODE_ID($name,undef,'motionsInside_ct')); + $mapping .= '\nStatusLowBattery=batteryLow_ct,values=0:0;/.*/:1' if (HOMEMODE_ID($name,undef,'batteryLow_ct')); + $mapping .= '\nSmokeDetected=alarmSmoke_ct,values=0:0;/.*/:1' if (HOMEMODE_ID($name,undef,'alarmSmoke_ct')); + $mapping .= '\nAirPressure=pressure' if (HOMEMODE_ID($name,undef,'pressure')); + addToDevAttrList($name,'genericDeviceType') if (!grep /^genericDeviceType/,split(' ',AttrVal('global','userattr',''))); + addToDevAttrList($name,'homebridgeMapping:textField-long') if (!grep /^homebridgeMapping/,split(' ',AttrVal('global','userattr',''))); CommandAttr(undef,"$name genericDeviceType security"); CommandAttr(undef,"$name homebridgeMapping $mapping"); return; @@ -3250,15 +3256,15 @@ sub HOMEMODE_PowerEnergy($;$$$) } } return if ($val < 0); - $val = sprintf("%.2f",$val); - my $r = $read eq (split " ",AttrVal($name,"HomeSensorsPowerEnergyReadings","power energy"))[0] ? "power" : "energy"; + $val = sprintf('%.2f',$val); + my $r = $read eq (split ' ',AttrVal($name,'HomeSensorsPowerEnergyReadings','power energy'))[0] ? 'power' : 'energy'; readingsSingleUpdate($hash,$r,$val,1); } else { my $power = 0; my $energy = 0; - my ($pr,$er) = split " ",AttrVal($name,"HomeSensorsPowerEnergyReadings","power energy"); + my ($pr,$er) = split ' ',AttrVal($name,'HomeSensorsPowerEnergyReadings','power energy'); for (split /,/,$hash->{SENSORSENERGY}) { my $p = ReadingsNum($_,$pr,0); @@ -3266,11 +3272,11 @@ sub HOMEMODE_PowerEnergy($;$$$) $power += $p if ($p && $p > 0); $energy += $e if ($e && $e > 0); } - $power = sprintf("%.2f",$power); - $energy = sprintf("%.2f",$energy); + $power = sprintf('%.2f',$power); + $energy = sprintf('%.2f',$energy); readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"power",$power) if ($power * 1 > 0); - readingsBulkUpdate($hash,"energy",$energy) if ($energy * 1 > 0); + readingsBulkUpdate($hash,'power',$power) if ($power * 1 > 0); + readingsBulkUpdate($hash,'energy',$energy) if ($energy * 1 > 0); readingsEndUpdate($hash,1); } } @@ -3279,30 +3285,30 @@ sub HOMEMODE_Smoke($;$$) { my ($hash,$trigger,$state) = @_; my $name = $hash->{NAME}; - my $r = AttrVal($name,"HomeSensorsSmokeReading","state"); - my $v = AttrVal($name,"HomeSensorsSmokeValue","on"); + my $r = AttrVal($name,'HomeSensorsSmokeReading','state'); + my $v = AttrVal($name,'HomeSensorsSmokeValue','on'); my @sensors; for (split /,/,$hash->{SENSORSSMOKE}) { - push @sensors,$_ if (ReadingsVal($_,$r,"") =~ /^$v$/); + push @sensors,$_ if (ReadingsVal($_,$r,'') =~ /^$v$/); } if ($trigger && $state) { my @cmds; - push @cmds,AttrVal($name,"HomeCMDalarmSmoke","") if (AttrVal($name,"HomeCMDalarmSmoke","")); + push @cmds,AttrVal($name,'HomeCMDalarmSmoke','') if (AttrVal($name,'HomeCMDalarmSmoke','')); if (@sensors) { - push @cmds,AttrVal($name,"HomeCMDalarmSmoke-on","") if (AttrVal($name,"HomeCMDalarmSmoke-on","")); + push @cmds,AttrVal($name,'HomeCMDalarmSmoke-on','') if (AttrVal($name,'HomeCMDalarmSmoke-on','')); } else { - push @cmds,AttrVal($name,"HomeCMDalarmSmoke-off","") if (AttrVal($name,"HomeCMDalarmSmoke-off","")); + push @cmds,AttrVal($name,'HomeCMDalarmSmoke-off','') if (AttrVal($name,'HomeCMDalarmSmoke-off','')); } if (@cmds) { for (@cmds) { - my ($n,$s) = split /\|/,AttrVal($name,"HomeTextNosmokeSmoke","no smoke|smoke"); + my ($n,$s) = split /\|/,AttrVal($name,'HomeTextNosmokeSmoke','no smoke|smoke'); my $sta = $state eq $v ? $s : $n; my $alias = HOMEMODE_name2alias($trigger,1); $_ =~ s/%ALIAS%/$alias/gm; @@ -3313,9 +3319,9 @@ sub HOMEMODE_Smoke($;$$) } } readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"alarmSmoke",join(",",@sensors)); - readingsBulkUpdate($hash,"alarmSmoke_ct",scalar @sensors); - readingsBulkUpdate($hash,"alarmSmoke_hr",HOMEMODE_makeHR($hash,0,@sensors)); + readingsBulkUpdate($hash,'alarmSmoke',join(',',@sensors)); + readingsBulkUpdate($hash,'alarmSmoke_ct',scalar @sensors); + readingsBulkUpdate($hash,'alarmSmoke_hr',HOMEMODE_makeHR($hash,0,@sensors)); readingsEndUpdate($hash,1); } @@ -3323,18 +3329,18 @@ sub HOMEMODE_Weather($$) { my ($hash,$dev) = @_; my $name = $hash->{NAME}; - my $cond = ReadingsVal($dev,"condition",""); - my ($and,$are,$is) = split /\|/,AttrVal($name,"HomeTextAndAreIs","and|are|is"); + my $cond = ReadingsVal($dev,'condition',''); + my ($and,$are,$is) = split /\|/,AttrVal($name,'HomeTextAndAreIs','and|are|is'); my $be = $cond =~ /(und|and|[Gg]ewitter|[Tt]hunderstorm|[Ss]chauer|[Ss]hower)/ ? $are : $is; readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"humidity",ReadingsNum($dev,"humidity",5)) if (!$hash->{helper}{externalHumidity}); - readingsBulkUpdate($hash,"temperature",ReadingsNum($dev,"temperature",5)) if (!AttrVal($name,"HomeSensorTemperatureOutside",undef)); - readingsBulkUpdate($hash,"wind",ReadingsNum($dev,"wind",0)) if (!AttrVal($name,"HomeSensorWindspeed",undef)); - readingsBulkUpdate($hash,"pressure",ReadingsNum($dev,"pressure",5)) if (!AttrVal($name,"HomeSensorAirpressure",undef)); - readingsBulkUpdate($hash,".be",$be); + readingsBulkUpdate($hash,'humidity',ReadingsNum($dev,'humidity',5)) if ((!AttrVal($name,'HomeSensorTemperatureOutside',undef) || (AttrVal($name,'HomeSensorTemperatureOutside',undef) && !HOMEMODE_ID(AttrVal($name,'HomeSensorTemperatureOutside',undef),'.*','humidity'))) && !AttrVal($name,'HomeSensorHumidityOutside',undef)); + readingsBulkUpdate($hash,'temperature',ReadingsNum($dev,'temperature',5)) if (!AttrVal($name,'HomeSensorTemperatureOutside',undef)); + readingsBulkUpdate($hash,'wind',ReadingsNum($dev,'wind',0)) if (!AttrVal($name,'HomeSensorWindspeed',undef)); + readingsBulkUpdate($hash,'pressure',ReadingsNum($dev,'pressure',5)) if (!AttrVal($name,'HomeSensorAirpressure',undef)); + readingsBulkUpdate($hash,'.be',$be); readingsEndUpdate($hash,1); - HOMEMODE_ReadingTrend($hash,"humidity") if (!$hash->{helper}{externalHumidity}); - HOMEMODE_ReadingTrend($hash,"temperature") if (!AttrVal($name,"HomeSensorTemperatureOutside",undef)); + HOMEMODE_ReadingTrend($hash,'humidity') if (!AttrVal($name,'HomeSensorHumidityOutside',undef)); + HOMEMODE_ReadingTrend($hash,'temperature') if (!AttrVal($name,'HomeSensorTemperatureOutside',undef)); HOMEMODE_Icewarning($hash); } @@ -3346,28 +3352,28 @@ sub HOMEMODE_Twilight($$;$) if ($force) { readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"light",ReadingsVal($dev,"light",5)); - readingsBulkUpdate($hash,"twilight",ReadingsVal($dev,"twilight",5)); - readingsBulkUpdate($hash,"twilightEvent",ReadingsVal($dev,"aktEvent",5)); + readingsBulkUpdate($hash,'light',ReadingsVal($dev,'light',5)); + readingsBulkUpdate($hash,'twilight',ReadingsVal($dev,'twilight',5)); + readingsBulkUpdate($hash,'twilightEvent',ReadingsVal($dev,'aktEvent',5)); readingsEndUpdate($hash,1); } else { - my $pevent = ReadingsVal($name,"twilightEvent",""); + my $pevent = ReadingsVal($name,'twilightEvent',''); for my $event (@{$events}) { - my $val = (split " ",$event)[1]; + my $val = (split ' ',$event)[1]; readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"light",$val) if ($event =~ /^light:/); - readingsBulkUpdate($hash,"twilight",$val) if ($event =~ /^twilight:/); + readingsBulkUpdate($hash,'light',$val) if ($event =~ /^light:/); + readingsBulkUpdate($hash,'twilight',$val) if ($event =~ /^twilight:/); if ($event =~ /^aktEvent:/) { - readingsBulkUpdate($hash,"twilightEvent",$val); + readingsBulkUpdate($hash,'twilightEvent',$val); if ($val ne $pevent) { my @commands; - push @commands,AttrVal($name,"HomeCMDtwilight","") if (AttrVal($name,"HomeCMDtwilight",undef)); - push @commands,AttrVal($name,"HomeCMDtwilight-$val","") if (AttrVal($name,"HomeCMDtwilight-$val",undef)); + push @commands,AttrVal($name,'HomeCMDtwilight','') if (AttrVal($name,'HomeCMDtwilight',undef)); + push @commands,AttrVal($name,"HomeCMDtwilight-$val",'') if (AttrVal($name,"HomeCMDtwilight-$val",undef)); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); } } @@ -3380,21 +3386,21 @@ sub HOMEMODE_Icewarning($) { my ($hash) = @_; my $name = $hash->{NAME}; - my $ice = ReadingsVal($name,"icewarning",2); - my $temp = ReadingsVal($name,"temperature",5); - my $temps = AttrVal($name,"HomeIcewarningOnOffTemps","2 3"); - my $iceon = (split " ",$temps)[0] * 1; - my $iceoff = (split " ",$temps)[1] ? (split " ",$temps)[1] * 1 : $iceon; + my $ice = ReadingsVal($name,'icewarning',2); + my $temp = ReadingsVal($name,'temperature',5); + my $temps = AttrVal($name,'HomeIcewarningOnOffTemps','2 3'); + my $iceon = (split ' ',$temps)[0] * 1; + my $iceoff = (split ' ',$temps)[1] ? (split ' ',$temps)[1] * 1 : $iceon; my $icewarning = 0; - my $icewarningcmd = "off"; + my $icewarningcmd = 'off'; $icewarning = 1 if ((!$ice && $temp <= $iceon) || ($ice && $temp <= $iceoff)); - $icewarningcmd = "on" if ($icewarning == 1); + $icewarningcmd = 'on' if ($icewarning == 1); if ($ice != $icewarning) { my @commands; - push @commands,AttrVal($name,"HomeCMDicewarning","") if (AttrVal($name,"HomeCMDicewarning",undef)); - push @commands,AttrVal($name,"HomeCMDicewarning-$icewarningcmd","") if (AttrVal($name,"HomeCMDicewarning-$icewarningcmd",undef)); - readingsSingleUpdate($hash,"icewarning",$icewarning,1); + push @commands,AttrVal($name,'HomeCMDicewarning','') if (AttrVal($name,'HomeCMDicewarning',undef)); + push @commands,AttrVal($name,"HomeCMDicewarning-$icewarningcmd",'') if (AttrVal($name,"HomeCMDicewarning-$icewarningcmd",undef)); + readingsSingleUpdate($hash,'icewarning',$icewarning,1); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); } } @@ -3403,9 +3409,9 @@ sub HOMEMODE_CalendarEvents($$) { my ($name,$cal) = @_; my @events; - if (HOMEMODE_ID($cal,"holiday")) + if (HOMEMODE_ID($cal,'holiday')) { - my $fname = AttrVal("global","modpath",".")."/FHEM/".$cal.".holiday"; + my $fname = AttrVal('global','modpath','.').'/FHEM/'.$cal.'.holiday'; my (undef,@holidayfile) = FileRead($fname); for (@holidayfile) { @@ -3416,7 +3422,7 @@ sub HOMEMODE_CalendarEvents($$) { shift @parts; } - my $evt = join("-",@parts); + my $evt = join('-',@parts); push @events,$evt if (!grep /^$evt$/,@events); } } @@ -3428,7 +3434,7 @@ sub HOMEMODE_CalendarEvents($$) { my $evt = $_->{summary}; Log3 $name,5,"Calendar_GetEvents event: $evt"; - $evt =~ s/[,;]//g; + $evt =~ s/[,;\?\!\|\\\/\^\$]/-/g; $evt =~ s/[\s ]+/-/g; push @events,$evt if (!grep /^$evt$/,@events); } @@ -3443,7 +3449,7 @@ sub HOMEMODE_checkIP($) $hash->{helper}{RUNNING_IPCHECK} = 1; my $name = $hash->{NAME}; my $param = { - url => "http://icanhazip.com/", + url => 'http://icanhazip.com/', timeout => 5, hash => $hash, callback => \&HOMEMODE_setIP @@ -3457,32 +3463,32 @@ sub HOMEMODE_setIP($) my $hash = $param->{hash}; delete $hash->{helper}{RUNNING_IPCHECK}; my $name = $hash->{NAME}; - if ($err ne "") + if ($err ne '') { Log3 $name,3,"$name: Error while requesting ".$param->{url}." - $err"; } if (!$data || $data =~ /[<>]/) { - $err = "Error - publicIP service check is temporary not available"; - readingsSingleUpdate($hash,"publicIP",$err,1); + $err = 'Error - publicIP service check is temporary not available'; + readingsSingleUpdate($hash,'publicIP',$err,1); Log3 $name,3,"$name: $err"; } - elsif ($data ne "") + elsif ($data ne '') { $data =~ s/\s+//g; chomp $data; - if (ReadingsVal($name,"publicIP","") ne $data) + if (ReadingsVal($name,'publicIP','') ne $data) { my @commands; - readingsSingleUpdate($hash,"publicIP",$data,1); - push @commands,AttrVal($name,"HomeCMDpublic-ip-change","") if (AttrVal($name,"HomeCMDpublic-ip-change",undef)); + readingsSingleUpdate($hash,'publicIP',$data,1); + push @commands,AttrVal($name,'HomeCMDpublic-ip-change','') if (AttrVal($name,'HomeCMDpublic-ip-change',undef)); HOMEMODE_execCMDs($hash,HOMEMODE_serializeCMD($hash,@commands)) if (@commands); } } - if (AttrNum($name,"HomePublicIpCheckInterval",0)) + if (AttrNum($name,'HomePublicIpCheckInterval',0)) { - my $timer = gettimeofday() + 60 * AttrNum($name,"HomePublicIpCheckInterval",0); - $hash->{".IP_TRIGGERTIME_NEXT"} = $timer; + my $timer = gettimeofday() + 60 * AttrNum($name,'HomePublicIpCheckInterval',0); + $hash->{'.IP_TRIGGERTIME_NEXT'} = $timer; } } @@ -3491,13 +3497,13 @@ sub HOMEMODE_ToggleDevice($$) my ($hash,$devname) = @_; my $name = $hash->{NAME}; my @disabled; - @disabled = split /,/,ReadingsVal($name,"devicesDisabled","") if (ReadingsVal($name,"devicesDisabled","")); + @disabled = split /,/,ReadingsVal($name,'devicesDisabled','') if (ReadingsVal($name,'devicesDisabled','')); if ($devname) { my @cmds; if (grep /^$devname$/,@disabled) { - push @cmds,AttrVal($name,"HomeCMDdeviceEnable","") if (AttrVal($name,"HomeCMDdeviceEnable","")); + push @cmds,AttrVal($name,'HomeCMDdeviceEnable','') if (AttrVal($name,'HomeCMDdeviceEnable','')); my @new; for (@disabled) { @@ -3507,11 +3513,11 @@ sub HOMEMODE_ToggleDevice($$) } else { - push @cmds,AttrVal($name,"HomeCMDdeviceDisable","") if (AttrVal($name,"HomeCMDdeviceDisable","")); + push @cmds,AttrVal($name,'HomeCMDdeviceDisable','') if (AttrVal($name,'HomeCMDdeviceDisable','')); push @disabled,$devname; } - my $dis = @disabled?join(",",@disabled):""; - readingsSingleUpdate($hash,"devicesDisabled",$dis,1); + my $dis = @disabled?join(',',@disabled):''; + readingsSingleUpdate($hash,'devicesDisabled',$dis,1); if (@cmds) { for (@cmds) @@ -3528,7 +3534,7 @@ sub HOMEMODE_ToggleDevice($$) { push @list,$d if (!grep /^$d$/,@disabled); } - $hash->{helper}{enabledDevices} = join ",",@list; + $hash->{helper}{enabledDevices} = join ',',@list; return; } @@ -3536,74 +3542,74 @@ sub HOMEMODE_IsDisabled($$) { my ($hash,$devname) = @_; return 1 if (IsDisabled($devname)); - return 1 if ($hash && grep /^$devname$/,split /,/,ReadingsVal($hash->{NAME},"devicesDisabled","")); + return 1 if ($hash && grep /^$devname$/,split /,/,ReadingsVal($hash->{NAME},'devicesDisabled','')); return 0; } sub HOMEMODE_Details($$$) { my ($FW_name,$name,$room) = @_; - return if (AttrVal($name,"HomeAdvancedDetails","none") eq "none" || (AttrVal($name,"HomeAdvancedDetails","") eq "room" && $FW_detail eq $name)); + return if (AttrVal($name,'HomeAdvancedDetails','none') eq 'none' || (AttrVal($name,'HomeAdvancedDetails','') eq 'room' && $FW_detail eq $name)); my $hash = $defs{$name}; - my $iid = ReadingsVal($name,"lastInfo","") ? ReadingsVal($name,"lastInfo","") : ""; - my $info = ReadingsVal($name,$iid,""); - my $html = "
"; - $html .= ""; + my $iid = ReadingsVal($name,'lastInfo','') ? ReadingsVal($name,'lastInfo','') : ''; + my $info = ReadingsVal($name,$iid,''); + my $html = '
'; + $html .= ''; $html .= "
$info
"; - $html .= ""; - if (AttrVal($name,"HomeWeatherDevice","") || - (AttrVal($name,"HomeSensorAirpressure","") && AttrVal($name,"HomeSensorHumidityOutside","") && AttrVal($name,"HomeSensorTemperatureOutside","")) || - (AttrVal($name,"HomeSensorAirpressure","") && AttrVal($name,"HomeSensorTemperatureOutside","") && HOMEMODE_ID(AttrVal($name,"HomeSensorTemperatureOutside",""),undef,"humidity"))) + $html .= '
'; + if (AttrVal($name,'HomeWeatherDevice','') || + (AttrVal($name,'HomeSensorAirpressure','') && AttrVal($name,'HomeSensorHumidityOutside','') && AttrVal($name,'HomeSensorTemperatureOutside','')) || + (AttrVal($name,'HomeSensorAirpressure','') && AttrVal($name,'HomeSensorTemperatureOutside','') && HOMEMODE_ID(AttrVal($name,'HomeSensorTemperatureOutside',''),undef,'humidity'))) { - $html .= ""; - my $temp = $HOMEMODE_de ? "Temperatur" : "Temperature"; + $html .= ''; + my $temp = $HOMEMODE_de ? 'Temperatur' : 'Temperature'; $html .= ""; - $html .= ""; - my $humi = $HOMEMODE_de ? "Luftfeuchte" : "Humidity"; + $html .= ""; + my $humi = $HOMEMODE_de ? 'Luftfeuchte' : 'Humidity'; $html .= ""; - my $pres = $HOMEMODE_de ? "Luftdruck" : "Air pressure"; + $html .= "'; + my $pres = $HOMEMODE_de ? 'Luftdruck' : 'Air pressure'; $html .= ""; - $html .= ""; - $html .= ""; + $html .= "'; + $html .= ''; } - if (AttrVal($name,"HomeSensorsPowerEnergy","") && AttrVal($name,"HomeSensorsLuminance","")) + if (AttrVal($name,'HomeSensorsPowerEnergy','') && AttrVal($name,'HomeSensorsLuminance','')) { - $html .= ""; - my $power = $HOMEMODE_de ? "Leistung" : "Power"; + $html .= ''; + my $power = $HOMEMODE_de ? 'Leistung' : 'Power'; $html .= ""; - $html .= ""; - my $energy = $HOMEMODE_de ? "Energie" : "Energy"; + $html .= "'; + my $energy = $HOMEMODE_de ? 'Energie' : 'Energy'; $html .= ""; - my $lum = $HOMEMODE_de ? "Licht" : "Luminance"; + $html .= "'; + my $lum = $HOMEMODE_de ? 'Licht' : 'Luminance'; $html .= ""; - $html .= ""; - $html .= ""; + $html .= "'; + $html .= ''; } - if (AttrVal($name,"HomeSensorsContact","")) + if (AttrVal($name,'HomeSensorsContact','')) { - $html .= ""; - my $open = $HOMEMODE_de ? "Offen" : "Open"; + $html .= ''; + my $open = $HOMEMODE_de ? 'Offen' : 'Open'; $html .= ""; - $html .= ""; - my $tamp = $HOMEMODE_de ? "Sabotiert" : "Tampered"; + $html .= "'; + my $tamp = $HOMEMODE_de ? 'Sabotiert' : 'Tampered'; $html .= ""; - $html .= ""; + $html .= "'; $html .= ""; - $html .= ""; - $html .= ""; + $html .= "'; + $html .= ''; } - $html .= "
$temp:".ReadingsVal($name,"temperature","")." °C".HOMEMODE_ForecastTXT($hash,1)."".ReadingsVal($name,'temperature','')." °C".HOMEMODE_ForecastTXT($hash,1)."$humi:"; - $html .= "".ReadingsVal($name,"humidity","")." %".ReadingsVal($name,'humidity','').' %$pres:".ReadingsVal($name,"pressure","")." hPa
".ReadingsVal($name,'pressure','').' hPa
$power:".ReadingsVal($name,"power","")." W".ReadingsVal($name,'power','').' W$energy:"; - $html .= "".ReadingsVal($name,"energy","")." kWh".ReadingsVal($name,'energy','').' kWh$lum:".ReadingsVal($name,"luminance","")." lux
".ReadingsVal($name,'luminance','').' lux
$open:".ReadingsVal($name,"contactsOpen_ct","")."".ReadingsVal($name,"contactsOpen_hr","")."".ReadingsVal($name,'contactsOpen_ct','')."".ReadingsVal($name,'contactsOpen_hr','').'$tamp:".ReadingsVal($name,"sensorsTampered_ct","")."".ReadingsVal($name,"sensorsTampered_hr","")."".ReadingsVal($name,'sensorsTampered_ct','')."".ReadingsVal($name,'sensorsTampered_hr','').'Alarm:".ReadingsVal($name,"alarmTriggered_ct","")."".ReadingsVal($name,"alarmTriggered_hr","")."
".ReadingsVal($name,'alarmTriggered_ct','')."".ReadingsVal($name,'alarmTriggered_hr','').'
"; - $html .= "
"; - $html .= ""; + $html .= ''; + $html .= '
'; + $html .= ''; return $html; } @@ -3641,7 +3647,7 @@ sub HOMEMODE_Details($$$) All automations triggered by external events (other devices monitored by HOMEMODE) and the execution of the HomeCMD attributes will not be delayed.
  • - Each created timer will be created as at device and its name will start with "atTmp_" and end with "_<name of your HOMEMODE device>". You may list them with "list TYPE=at:FILTER=NAME=atTmp_.*_<name of your HOMEMODE device>". + Each created timer will be created as at device and its name will start with 'atTmp_' and end with '_<name of your HOMEMODE device>'. You may list them with 'list TYPE=at:FILTER=NAME=atTmp_.*_<name of your HOMEMODE device>'.
  • Seasons can also be adjusted (date and text) in attribute HomeSeasons @@ -3655,125 +3661,125 @@ sub HOMEMODE_Details($$$)

  • -

    A german Wiki page is also available at https://wiki.fhem.de/wiki/Modul_HOMEMODE. There you can find lots of example code.

    +

    A german Wiki page is also available at https://wiki.fhem.de/wiki/Modul_HOMEMODE. There you can find lots of example code.


    - +

    define [optional]

      define <name> HOMEMODE

      define <name> HOMEMODE [RESIDENTS-MASTER-DEVICE]

    - +

    set <required> [optional]


    - +

    get <required> [optional]


    - +

    Attributes


    - +

    Readings

    - +

    Placeholders

    These placeholders can be used in all HomeCMD attributes

    • - %ADDRESS%
      + %ADDRESS%
      mac address of the last triggered presence device
    • - %ALIAS%
      + %ALIAS%
      alias of the last triggered resident
    • - %ALARM%
      + %ALARM%
      value of the alarmTriggered reading of the HOMEMODE device
      will return 0 if no alarm is triggered or a list of triggered sensors if alarm is triggered
    • - %ALARMCT%
      + %ALARMCT%
      value of the alarmTriggered_ct reading of the HOMEMODE device
    • - %ALARMHR%
      + %ALARMHR%
      value of the alarmTriggered_hr reading of the HOMEMODE device
      will return 0 if no alarm is triggered or a (human readable) list of triggered sensors if alarm is triggered
      can be used for sending msg e.g.
    • - %AMODE%
      + %AMODE%
      current alarm mode
    • - %AEAH%
      + %AEAH%
      state of anyoneElseAtHome, will return 1 if on and 0 if off
    • - %ARRIVERS%
      + %ARRIVERS%
      will return a list of aliases of all registered residents/guests with location arrival
      this can be used to welcome residents after main door open/close
      e.g. Peter, Paul and Marry
    • - %AUDIO%
      + %AUDIO%
      audio device of the last triggered resident (attribute msgContactAudio)
      if attribute msgContactAudio of the resident has no value the value is trying to be taken from device globalMsg (if available)
      can be used to address resident specific msg(s) of type audio, e.g. night/morning wishes
    • - %BE%
      + %BE%
      is or are of condition reading of monitored Weather device
      can be used for weather (forecast) output
    • - %BATTERYLOW%
      + %BATTERYLOW%
      alias (or name if alias is not set) of the last battery sensor which reported low battery
    • - %BATTERYLOWALL%
      + %BATTERYLOWALL%
      list of aliases (or names if alias is not set) of all battery sensor which reported low battery currently
    • - %BATTERYLOWCT%
      + %BATTERYLOWCT%
      number of battery sensors which reported low battery currently
    • - %BATTERYNORMAL%
      + %BATTERYNORMAL%
      alias (or name if alias is not set) of the last battery sensor which reported normal battery
    • - %CONDITION%
      + %CONDITION%
      value of the condition reading of monitored Weather device
      can be used for weather (forecast) output
    • - %CONTACT%
      + %CONTACT%
      value of the lastContact reading (last opened sensor)
    • - %DEFINED%
      + %DEFINED%
      name of the previously defined device
      can be used to trigger actions based on the name of the defined device
      only available within HomeCMDfhemDEFINED
    • - %DAYTIME%
      + %DAYTIME%
      value of the daytime reading of the HOMEMODE device
      can be used to trigger day time specific actions
    • - %DEVICE%
      + %DEVICE%
      name of the last triggered presence device
      can be used to trigger actions depending on the last present/absent presence device
    • - %DEVICEA%
      + %DEVICEA%
      name of the last triggered absent presence device
    • - %DEVICEP%
      + %DEVICEP%
      name of the last triggered present presence device
    • - %DISABLED%
      + %DISABLED%
      comma separated list of disabled devices
    • - %DND%
      + %DND%
      state of dnd, will return 1 if on and 0 if off
    • - %DURABSENCE%
      + %DURABSENCE%
      value of the durTimerAbsence_cr reading of the last triggered resident
    • - %DURABSENCELAST%
      + %DURABSENCELAST%
      value of the lastDurAbsence_cr reading of the last triggered resident
    • - %DURPRESENCE%
      + %DURPRESENCE%
      value of the durTimerPresence_cr reading of the last triggered resident
    • - %DURPRESENCELAST%
      + %DURPRESENCELAST%
      value of the lastDurPresence_cr reading of the last triggered resident
    • - %DURSLEEP%
      + %DURSLEEP%
      value of the durTimerSleep_cr reading of the last triggered resident
    • - %DURSLEEPLAST%
      + %DURSLEEPLAST%
      value of the lastDurSleep_cr reading of the last triggered resident
    • - %CALENDARNAME%
      + %CALENDARNAME%
      will return the current event of the given calendar name, will return 0 if event is none
      can be used to trigger actions on any event of the given calendar
    • - %CALENDARNAME-EVENTNAME%
      + %CALENDARNAME-EVENTNAME%
      will return 1 if given event of given calendar is current, will return 0 if event is not current
      can be used to trigger actions during specific events only (Christmas?)
    • - %FORECAST%
      + %FORECAST%
      will return the weather forecast for tomorrow
      can be used in msg or tts
    • - %FORECASTTODAY%
      + %FORECASTTODAY%
      will return the weather forecast for today
      can be used in msg or tts
    • - %HUMIDITY%
      + %HUMIDITY%
      value of the humidity reading of the HOMEMODE device
      can be used for weather info in HomeTextWeather attributes e.g.
    • - %HUMIDITYTREND%
      + %HUMIDITYTREND%
      value of the humidityTrend reading of the HOMEMODE device
      possible values: constant, rising, falling
    • - %ICE%
      + %ICE%
      will return 1 if ice warning is on, will return 0 if ice warning is off
      can be used to send ice warning specific msg(s) in specific situations, e.g. to warn leaving residents
    • - %IP%
      + %IP%
      value of reading publicIP
      can be used to send msg(s) with (new) IP address
    • - %LIGHT%
      + %LIGHT%
      value of the light reading of the HOMEMODE device
    • - %LOCATION%
      + %LOCATION%
      value of the location reading of the HOMEMODE device
    • - %LOCATIONR%
      + %LOCATIONR%
      value of the location reading of the last triggered resident
    • - %LUMINANCE%
      + %LUMINANCE%
      average luminance of motion sensors (if available)
    • - %LUMINANCETREND%
      + %LUMINANCETREND%
      value of the luminanceTrend reading of the HOMEMODE device
      possible values: constant, rising, falling
    • - %MODE%
      + %MODE%
      current mode of the HOMEMODE device
    • - %MODEALARM%
      + %MODEALARM%
      current alarm mode
    • - %MOTION%
      + %MOTION%
      value of the lastMotion reading (last opened sensor)
    • - %NAME%
      + %NAME%
      name of the HOMEMODE device itself (same as %SELF%)
    • - %OPEN%
      + %OPEN%
      value of the contactsOutsideOpen reading of the HOMEMODE device
      can be used to send msg(s) in specific situations, e.g. to warn leaving residents of open contact sensors
    • - %OPENCT%
      + %OPENCT%
      value of the contactsOutsideOpen_ct reading of the HOMEMODE device
      can be used to send msg(s) in specific situations depending on the number of open contact sensors, maybe in combination with placeholder %OPEN%
    • - %OPENHR%
      + %OPENHR%
      value of the contactsOutsideOpen_hr reading of the HOMEMODE device
      can be used to send msg(s)
    • - %PANIC%
      + %PANIC%
      state of panic, will return 1 if on and 0 if off
    • - %RESIDENT%
      + %RESIDENT%
      name of the last triggered resident
    • - %PRESENT%
      + %PRESENT%
      presence of the HOMEMODE device
      will return 1 if present or 0 if absent
    • - %PRESENTR%
      + %PRESENTR%
      presence of last triggered resident
      will return 1 if present or 0 if absent
    • - %PRESSURE%
      + %PRESSURE%
      value of the pressure reading of the HOMEMODE device
      can be used for weather info in HomeTextWeather attributes e.g.
    • - %PREVAMODE%
      + %PREVAMODE%
      previous alarm mode of the HOMEMODE device
    • - %PREVCONTACT%
      + %PREVCONTACT%
      previous open contact sensor
    • - %PREVMODE%
      + %PREVMODE%
      previous mode of the HOMEMODE device
    • - %PREVMODER%
      + %PREVMODER%
      previous state of last triggered resident
    • - %PREVMOTION%
      + %PREVMOTION%
      previous open motion sensor
    • - %SEASON%
      + %SEASON%
      value of the season reading of the HOMEMODE device
    • - %SELF%
      + %SELF%
      name of the HOMEMODE device itself (same as %NAME%)
    • - %SENSORSBATTERY%
      + %SENSORSBATTERY%
      all battery sensors from internal SENSORSBATTERY
    • - %SENSORSCONTACT%
      + %SENSORSCONTACT%
      all contact sensors from internal SENSORSCONTACT
    • - %SENSORSENERGY%
      + %SENSORSENERGY%
      all energy sensors from internal SENSORSENERGY
    • - %SENSORSMOTION%
      + %SENSORSMOTION%
      all motion sensors from internal SENSORSMOTION
    • - %SENSORSSMOKE%
      + %SENSORSSMOKE%
      all smoke sensors from internal SENSORSSMOKE
    • - %SMOKE%
      + %SMOKE%
      value of the alarmSmoke reading of the HOMEMODE device
      will return 0 if no smoke alarm is triggered or a list of triggered sensors if smoke alarm is triggered
    • - %SMOKECT%
      + %SMOKECT%
      value of the alarmSmoke_ct reading of the HOMEMODE device
    • - %SMOKEHR%
      + %SMOKEHR%
      value of the alarmSmoke_hr reading of the HOMEMODE device
      will return 0 if no smoke alarm is triggered or a (human readable) list of triggered sensors if smoke alarm is triggered
      can be used for sending msg e.g.
    • - %TAMPERED%
      + %TAMPERED%
      value of the sensorsTampered reading of the HOMEMODE device
    • - %TAMPEREDCT%
      + %TAMPEREDCT%
      value of the sensorsTampered_ct reading of the HOMEMODE device
    • - %TAMPEREDHR%
      + %TAMPEREDHR%
      value of the sensorsTampered_hr reading of the HOMEMODE device
      can be used for sending msg e.g.
    • - %TEMPERATURE%
      + %TEMPERATURE%
      value of the temperature reading of the HOMEMODE device
      can be used for weather info in HomeTextWeather attributes e.g.
    • - %TEMPERATURETREND%
      + %TEMPERATURETREND%
      value of the temperatureTrend reading of the HOMEMODE device
      possible values: constant, rising, falling
    • - %TWILIGHT%
      + %TWILIGHT%
      value of the twilight reading of the HOMEMODE device
    • - %TWILIGHTEVENT%
      + %TWILIGHTEVENT%
      current twilight event
    • - %TOBE%
      + %TOBE%
      are or is of the weather condition
      useful for phrasing sentences
    • - %UWZ%
      + %UWZ%
      UWZ warnings count
    • - %UWZLONG%
      + %UWZLONG%
      all current UWZ warnings as long text
    • - %UWZSHORT%
      + %UWZSHORT%
      all current UWZ warnings as short text
    • - %WEATHER%
      - value of "get <HOMEMODE> weather short"
      + %WEATHER%
      + value of 'get <HOMEMODE> weather short'
      can be used for for msg weather info e.g.
    • - %WEATHERLONG%
      - value of "get <HOMEMODE> weather long"
      + %WEATHERLONG%
      + value of 'get <HOMEMODE> weather long'
      can be used for for msg weather info e.g.
    • - %WIND%
      + %WIND%
      value of the wind reading of the HOMEMODE device
      can be used for weather info in HomeTextWeather attributes e.g.
    • - %WINDCHILL%
      + %WINDCHILL%
      value of the apparentTemperature reading of the Weather device
      can be used for weather info in HomeTextWeather attributes e.g.
    • @@ -5261,64 +5267,64 @@ sub HOMEMODE_Details($$$)

      These placeholders can only be used within HomeTextWeatherForecast attributes

      These placeholders can only be used within HomeCMDcontact, HomeCMDmotion and HomeCMDalarm attributes

      • - %ALIAS%
        + %ALIAS%
        alias of the last triggered contact/motion/smoke sensor
      • - %SENSOR%
        + %SENSOR%
        name of the last triggered contact/motion/smoke sensor
      • - %STATE%
        + %STATE%
        state of the last triggered contact/motion/smoke sensor

      These placeholders can only be used within calendar event related HomeCMDevent attributes

      These placeholders can only be used within HomeCMDdeviceDisable and HomeCMDdeviceEnable attributes