From 7446304981c2c6019134469f344aeb3bdf4d56e1 Mon Sep 17 00:00:00 2001 From: LeonGaultier Date: Fri, 5 Jul 2019 09:25:16 +0000 Subject: [PATCH] 73_AutoShuttersControl: delayed self defense drive then absent, fix many of little bugs, change shading logic git-svn-id: https://svn.fhem.de/fhem/trunk@19783 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/73_AutoShuttersControl.pm | 991 +++++++++++++++++----------- 2 files changed, 618 insertions(+), 375 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index f1a2d7cc1..6a8b20c6a 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 73_AutoShuttersControl: delayed self defense drive then absent, + fix many of little bugs, change shading logic - feature: 59_WUup: add Meta support - new: 10_FS10: New module for controling FS10 devices - change: 59_WUup: replaced link to API documentation diff --git a/fhem/FHEM/73_AutoShuttersControl.pm b/fhem/FHEM/73_AutoShuttersControl.pm index bddf0b84f..9d0756a19 100644 --- a/fhem/FHEM/73_AutoShuttersControl.pm +++ b/fhem/FHEM/73_AutoShuttersControl.pm @@ -61,12 +61,9 @@ use warnings; use POSIX; use utf8; use FHEM::Meta; - -use GPUtils qw(:all) - ; # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt +use GPUtils qw(GP_Import GP_Export); use Data::Dumper; #only for Debugging use Date::Parse; -our $VERSION = 'v0.6.19'; # try to use JSON::MaybeXS wrapper # for chance of better performance + open code @@ -181,19 +178,8 @@ BEGIN { ); } -# _Export - Export references to main context using a different naming schema -sub _Export { - no strict qw/refs/; ## no critic - my $pkg = caller(0); - my $main = $pkg; - $main =~ s/^(?:.+::)?([^:]+)$/main::$1\_/g; - foreach (@_) { - *{ $main . $_ } = *{ $pkg . '::' . $_ }; - } -} - #-- Export to main context with different name -_Export( +GP_Export( qw( Initialize ascAPIget @@ -223,6 +209,7 @@ my %userAttrList = ( 'ASC_PrivacyDownTime_beforNightClose' => '-', 'ASC_PrivacyDown_Pos' => '-', 'ASC_WindowRec' => '-', + 'ASC_TempSensor' => '-', 'ASC_Ventilate_Window_Open:on,off' => '-', 'ASC_LockOut:soft,hard,off' => '-', 'ASC_LockOut_Cmd:inhibit,blocked,protection' => '-', @@ -250,15 +237,17 @@ my %userAttrList = ( 'ASC_Antifreeze:off,soft,hard,am,pm' => '-', 'ASC_Antifreeze_Pos:5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100' => [ '', 85, 15 ], - 'ASC_Partymode:on,off' => '-', - 'ASC_Roommate_Device' => '-', - 'ASC_Roommate_Reading' => '-', - 'ASC_Self_Defense_Exclude:on,off' => '-', - 'ASC_WiggleValue' => '-', - 'ASC_WindParameters' => '-', - 'ASC_DriveUpMaxDuration' => '-', - 'ASC_WindProtection:on,off' => '-', - 'ASC_RainProtection:on,off' => '-', + 'ASC_Partymode:on,off' => '-', + 'ASC_Roommate_Device' => '-', + 'ASC_Roommate_Reading' => '-', + 'ASC_Self_Defense_Exclude:on,off' => '-', + 'ASC_Self_Defense_Mode:absent,gone' => '-', + 'ASC_Self_Defense_AbsentDelay' => '-', + 'ASC_WiggleValue' => '-', + 'ASC_WindParameters' => '-', + 'ASC_DriveUpMaxDuration' => '-', + 'ASC_WindProtection:on,off' => '-', + 'ASC_RainProtection:on,off' => '-' ); my %posSetCmds = ( @@ -344,23 +333,25 @@ sub Define($$) { my @a = split( '[ \t][ \t]*', $def ); return $@ unless ( FHEM::Meta::SetInternals($hash) ); + use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' ); + return 'only one AutoShuttersControl instance allowed' if ( devspec2array('TYPE=AutoShuttersControl') > 1 ) ; # es wird geprüft ob bereits eine Instanz unseres Modules existiert,wenn ja wird abgebrochen return 'too few parameters: define ShuttersControl' if ( @a != 2 ); -# return -# 'Cannot define ShuttersControl device. Perl modul ' -# . ${missingModul} -# . 'is missing.' -# if ($missingModul) -# ; # Abbruch wenn benötigte Hilfsmodule nicht vorhanden sind / vorerst unwichtig - my $name = $a[0]; - $hash->{VERSION} = $VERSION; - $hash->{MID} = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' + $hash->{MID} = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' ; # eine Ein Eindeutige ID für interne FHEM Belange / nicht weiter wichtig + + # ### Versionierung ### + # Stable Version + $hash->{VERSION} = version->parse($VERSION)->normal; + + # Developer Version + # $hash->{DEV_VERSION} = FHEM::Meta::Get( $hash, 'x_developmentversion' ); + $hash->{NOTIFYDEV} = 'global,' . $name; # Liste aller Devices auf deren Events gehört werden sollen #$hash->{shutters} = $shutters; @@ -381,7 +372,7 @@ sub Define($$) { CommandAttr( undef, $name - . ' devStateIcon selfeDefense.terrace:fts_door_tilt created.new.drive.timer:clock .*asleep:scene_sleeping roommate.(awoken|home):user_available residents.(home|awoken):status_available manual:fts_shutter_manual selfeDefense.active:status_locked selfeDefense.inactive:status_open day.open:scene_day night.close:scene_night shading.in:weather_sun shading.out:weather_cloudy' + . ' devStateIcon selfDefense.terrace:fts_door_tilt created.new.drive.timer:clock .*asleep:scene_sleeping roommate.(awoken|home):user_available residents.(home|awoken):status_available manual:fts_shutter_manual selfDefense.active:status_locked selfDefense.inactive:status_open day.open:scene_day night.close:scene_night shading.in:weather_sun shading.out:weather_cloudy' ) if ( AttrVal( $name, 'devStateIcon', 'none' ) eq 'none' ); addToAttrList('ASC:0,1,2'); @@ -718,12 +709,6 @@ sub ShuttersDeviceScan($) { # delFromDevAttrList( $_, 'ASC_Wind_SensorDevice' ) # ; # temporär muss später gelöscht werden ab Version 0.4.0.10 -# delFromDevAttrList( $_, 'ASC_Wind_SensorReading' ) -# ; # temporär muss später gelöscht werden ab Version 0.4.0.10 -# delFromDevAttrList( $_, 'ASC_Wind_minMaxSpeed' ) -# ; # temporär muss später gelöscht werden ab Version 0.4.11beta6 -# delFromDevAttrList( $_, 'ASC_Wind_Pos' ) -# ; # temporär muss später gelöscht werden ab Version 0.4.11beta6 # CommandDeleteReading( undef, $_ . ' ASC_Time_PrivacyDriveUp' ) # if ( ReadingsVal( $_, 'ASC_Time_PrivacyDriveUp', 'none' ) ne 'none' ) # ; # temporär muss später gelöscht werden ab Version 0.6.3 @@ -734,6 +719,7 @@ sub ShuttersDeviceScan($) { $shutters->setLastPos( $shutters->getStatus ); $shutters->setDelayCmd('none'); $shutters->setNoOffset(0); + $shutters->setSelfDefenseAbsent( 0, 0 ); $shutters->setPosSetCmd( $posSetCmds{ $defs{$_}->{TYPE} } ); $shutters->setShadingStatus( ( $shutters->getStatus != $shutters->getShadingPos ? 'out' : 'in' ) @@ -745,52 +731,16 @@ sub ShuttersDeviceScan($) { if ( ReadingsVal( $_, 'ASC_Enable', 'none' ) eq 'none' ); } -# ### Temporär und muss später entfernt werden -# CommandAttr( undef, -# $name -# . ' ASC_tempSensor ' -# . AttrVal( $name, 'ASC_temperatureSensor', 'none' ) . ':' -# . AttrVal( $name, 'ASC_temperatureReading', 'temperature' ) ) -# if ( AttrVal( $name, 'ASC_temperatureSensor', 'none' ) ne 'none' ); -# CommandAttr( undef, -# $name -# . ' ASC_residentsDev ' -# . AttrVal( $name, 'ASC_residentsDevice', 'none' ) . ':' -# . AttrVal( $name, 'ASC_residentsDeviceReading', 'state' ) ) -# if ( AttrVal( $name, 'ASC_residentsDevice', 'none' ) ne 'none' ); -# CommandAttr( undef, -# $name -# . ' ASC_rainSensor ' -# . AttrVal( $name, 'ASC_rainSensorDevice', 'none' ) . ':' -# . AttrVal( $name, 'ASC_rainSensorReading', 'rain' ) . ' 100 ' -# . AttrVal( $name, 'ASC_rainSensorShuttersClosedPos', 50 ) ) -# if ( AttrVal( $name, 'ASC_rainSensorDevice', 'none' ) ne 'none' ); -# CommandAttr( undef, -# $name -# . ' ASC_brightnessDriveUpDown ' -# . AttrVal( $name, 'ASC_brightnessMinVal', 500 ) . ':' -# . AttrVal( $name, 'ASC_brightnessMaxVal', 800 ) ) -# if ( AttrVal( $name, 'ASC_brightnessMinVal', 'none' ) ne 'none' ); -# -# CommandDeleteAttr( undef, $name . ' ASC_temperatureSensor' ) -# if ( AttrVal( $name, 'ASC_temperatureSensor', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_temperatureReading' ) -# if ( AttrVal( $name, 'ASC_temperatureReading', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_residentsDevice' ) -# if ( AttrVal( $name, 'ASC_residentsDevice', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_residentsDeviceReading' ) -# if ( AttrVal( $name, 'ASC_residentsDeviceReading', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_rainSensorDevice' ) -# if ( AttrVal( $name, 'ASC_rainSensorDevice', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_rainSensorReading' ) -# if ( AttrVal( $name, 'ASC_rainSensorReading', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_rainSensorShuttersClosedPos' ) -# if ( -# AttrVal( $name, 'ASC_rainSensorShuttersClosedPos', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_brightnessMinVal' ) -# if ( AttrVal( $name, 'ASC_brightnessMinVal', 'none' ) ne 'none' ); -# CommandDeleteAttr( undef, $name . ' ASC_brightnessMaxVal' ) -# if ( AttrVal( $name, 'ASC_brightnessMaxVal', 'none' ) ne 'none' ); + # ### Temporär und muss später entfernt werden + # CommandAttr( undef, + # $name + # . ' ASC_brightnessDriveUpDown ' + # . AttrVal( $name, 'ASC_brightnessMinVal', 500 ) . ':' + # . AttrVal( $name, 'ASC_brightnessMaxVal', 800 ) ) + # if ( AttrVal( $name, 'ASC_brightnessMinVal', 'none' ) ne 'none' ); + # + # CommandDeleteAttr( undef, $name . ' ASC_brightnessMaxVal' ) + # if ( AttrVal( $name, 'ASC_brightnessMaxVal', 'none' ) ne 'none' ); $hash->{NOTIFYDEV} = "global," . $name . $shuttersList; @@ -1011,17 +961,6 @@ sub EventProcessingWindowRec($@) { if ( $match =~ /[Oo]pen/ and $shutters->getShuttersPlace eq 'terrace' ); - # my $queryShuttersPosWinRecTilted = ( - # $shutters->getShuttersPosCmdValueNegate - # ? $shutters->getStatus > $shutters->getVentilatePos - # : $shutters->getStatus < $shutters->getVentilatePos - # ); - # my $queryShuttersPosWinRecComfort = ( - # $shutters->getShuttersPosCmdValueNegate - # ? $shutters->getStatus > $shutters->getComfortOpenPos - # : $shutters->getStatus < $shutters->getComfortOpenPos - # ); - ASC_Debug( 'EventProcessingWindowRec: ' . $shutters->getShuttersDev . ' - HOMEMODE: ' @@ -1045,7 +984,7 @@ sub EventProcessingWindowRec($@) { . ' Event Closed' ); if ( - IsDay($shuttersDev) + $shutters->getIsDay and ( ( $homemode ne 'asleep' and $homemode ne 'gotosleep' ) or $homemode eq 'none' ) and $shutters->getModeUp ne 'absent' @@ -1053,7 +992,6 @@ sub EventProcessingWindowRec($@) { ) { if ( $shutters->getShadingStatus eq 'in' - and $shutters->getShuttersPlace eq 'terrace' and $shutters->getShadingPos != $shutters->getStatus ) { $shutters->setLastDrive('shading in'); @@ -1066,11 +1004,10 @@ sub EventProcessingWindowRec($@) { $shutters->setDriveCmd( $shutters->getOpenPos ); } } - elsif ( $shutters->getModeUp ne 'absent' and $shutters->getModeUp ne 'off' - and ( not IsDay($shuttersDev) + and ( not $shutters->getIsDay or $homemode eq 'asleep' or $homemode eq 'gotosleep' ) and $shutters->getModeDown ne 'absent' @@ -1143,6 +1080,7 @@ sub EventProcessingRoommate($@) { my $getModeUp = $shutters->getModeUp; my $getModeDown = $shutters->getModeDown; my $getRoommatesLastStatus = $shutters->getRoommatesLastStatus; + my $posValue; if ( ( $1 eq 'home' or $1 eq 'awoken' ) @@ -1164,7 +1102,7 @@ sub EventProcessingRoommate($@) { $getRoommatesLastStatus eq 'asleep' or $getRoommatesLastStatus eq 'awoken' ) - and IsDay($shuttersDev) + and $shutters->getIsDay and IsAfterShuttersTimeBlocking($shuttersDev) and ( $getModeUp eq 'home' or $getModeUp eq 'always' ) @@ -1173,56 +1111,85 @@ sub EventProcessingRoommate($@) { Log3( $name, 4, "AutoShuttersControl ($name) - EventProcessingRoommate_2: $shuttersDev und Events $events" ); - $shutters->setLastDrive('roommate awoken'); - ShuttersCommandSet( $hash, $shuttersDev, - $shutters->getOpenPos ); - } - if ( + if ( $shutters->getIfInShading + and not $shutters->getShadingManualDriveStatus + and $shutters->getStatus != $shutters->getShadingPos ) + { + $shutters->setLastDrive('shading in'); + $posValue = $shutters->getShadingPos; + } + else { + $shutters->setLastDrive('roommate awoken'); + $posValue = $shutters->getOpenPos; + } + + ShuttersCommandSet( $hash, $shuttersDev, $posValue ); + } + elsif ( ( $getRoommatesLastStatus eq 'absent' or $getRoommatesLastStatus eq 'gone' - - # or $getRoommatesLastStatus eq 'home' ) and $shutters->getRoommatesStatus eq 'home' ) { if ( - not IsDay($shuttersDev) + not $shutters->getIsDay and IsAfterShuttersTimeBlocking($shuttersDev) and ( $getModeDown eq 'home' or $getModeDown eq 'always' ) ) { - my $position; $shutters->setLastDrive('roommate home'); if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0 or $shutters->getVentilateOpen eq 'off' ) { - $position = $shutters->getClosedPos; + $posValue = $shutters->getClosedPos; } else { - $position = $shutters->getVentilatePos; + $posValue = $shutters->getVentilatePos; $shutters->setLastDrive( $shutters->getLastDrive . ' - ventilate mode' ); } - ShuttersCommandSet( $hash, $shuttersDev, $position ); + ShuttersCommandSet( $hash, $shuttersDev, $posValue ); } elsif ( - IsDay($shuttersDev) - and $shutters->getStatus == $shutters->getClosedPos + $shutters->getIsDay and IsAfterShuttersTimeBlocking($shuttersDev) and ( $getModeUp eq 'home' or $getModeUp eq 'always' ) - and not $shutters->getIfInShading ) { - $shutters->setLastDrive('roommate home'); - ShuttersCommandSet( $hash, $shuttersDev, - $shutters->getOpenPos ); + if ( $shutters->getIfInShading + and not $shutters->getShadingManualDriveStatus + and $shutters->getStatus == $shutters->getOpenPos ) + { + $shutters->setLastDrive('shading in'); + $posValue = $shutters->getShadingPos; + + ShuttersCommandSet( $hash, $shuttersDev, $posValue ); + } + elsif ( + not $shutters->getIfInShading + and ( $shutters->getStatus == $shutters->getClosedPos + or $shutters->getStatus == + $shutters->getShadingPos ) + ) + { + $shutters->setLastDrive( + ( + $shutters->getStatus == $shutters->getClosedPos + ? 'roommate home' + : 'shading out' + ) + ); + $posValue = $shutters->getOpenPos; + + ShuttersCommandSet( $hash, $shuttersDev, $posValue ); + } } } } @@ -1236,28 +1203,43 @@ sub EventProcessingRoommate($@) { and IsAfterShuttersManualBlocking($shuttersDev) ) { - my $position; $shutters->setLastDrive('roommate asleep'); if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0 or $shutters->getVentilateOpen eq 'off' ) { - $position = $shutters->getClosedPos; + $posValue = $shutters->getClosedPos; } else { - $position = $shutters->getVentilatePos; + $posValue = $shutters->getVentilatePos; $shutters->setLastDrive( $shutters->getLastDrive . ' - ventilate mode' ); } - ShuttersCommandSet( $hash, $shuttersDev, $position ); + ShuttersCommandSet( $hash, $shuttersDev, $posValue ); } - elsif ( $getModeDown eq 'absent' + elsif ( + $getModeDown eq 'absent' and $1 eq 'absent' - and not IsDay($shuttersDev) ) + and ( not $shutters->getIsDay + or $shutters->getShadingMode eq 'absent' ) + ) { - $shutters->setLastDrive('roommate absent'); - ShuttersCommandSet( $hash, $shuttersDev, $shutters->getClosedPos ); + if ( $shutters->getIsDay + and $shutters->getIfInShading + and + not $shutters->getQueryShuttersPos( $shutters->getShadingPos ) + and $shutters->getShadingMode eq 'absent' ) + { + $posValue = $shutters->getShadingPos; + $shutters->setLastDrive('shading in'); + } + else { + $posValue = $shutters->getClosedPos; + $shutters->setLastDrive('roommate absent'); + } + + ShuttersCommandSet( $hash, $shuttersDev, $$posValue ); } } } @@ -1276,33 +1258,48 @@ sub EventProcessingResidents($@) { my $getModeDown = $shutters->getModeDown; $shutters->setHardLockOut('off'); if ( - CheckIfShuttersWindowRecOpen($shuttersDev) != 0 - and $ascDev->getSelfDefense eq 'on' + $ascDev->getSelfDefense eq 'on' and $shutters->getSelfDefenseExclude eq 'off' - or ( + or ( $getModeDown eq 'absent' + or $getModeDown eq 'always' ) + ) + { + if ( + ( + CheckIfShuttersWindowRecOpen($shuttersDev) != 0 + or $shutters->getSelfDefenseMode eq 'absent' + ) + and $ascDev->getSelfDefense eq 'on' + and $shutters->getSelfDefenseExclude eq 'off' + ) + { + $shutters->setLastDrive('selfDefense active'); + $shutters->setSelfDefenseAbsent( 0, 1 + ) # der erste Wert ist ob der timer schon läuft, der zweite ist ob self defense aktiv ist durch die Bedingungen + if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0 + and $shutters->getSelfDefenseMode eq 'absent' ); + $shutters->setDriveCmd( $shutters->getClosedPos ); + } + elsif ( ( $getModeDown eq 'absent' or $getModeDown eq 'always' ) - and not IsDay($shuttersDev) + and not $shutters->getIsDay and IsAfterShuttersTimeBlocking($shuttersDev) - ) - ) - { - if ( CheckIfShuttersWindowRecOpen($shuttersDev) != 0 - and $ascDev->getSelfDefense eq 'on' - and $shutters->getSelfDefenseExclude eq 'off' ) + and $shutters->getRoommatesStatus eq 'none' + ) { - $shutters->setLastDrive('selfeDefense active'); + $shutters->setLastDrive('residents absent'); + $shutters->setDriveCmd( $shutters->getClosedPos ); } - else { $shutters->setLastDrive('residents absent'); } - - $shutters->setDriveCmd( $shutters->getClosedPos ); } } } elsif ( $events =~ m#$reading:\s(gone)# - and $ascDev->getSelfDefense eq 'on' ) + and $ascDev->getSelfDefense eq 'on' + and $shutters->getSelfDefenseMode eq 'gone' + and $shutters->getSelfDefenseExclude eq 'off' ) { foreach my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) { $shutters->setShuttersDev($shuttersDev); @@ -1310,7 +1307,7 @@ sub EventProcessingResidents($@) { my $getModeDown = $shutters->getModeDown; $shutters->setHardLockOut('off'); if ( $shutters->getShuttersPlace eq 'terrace' ) { - $shutters->setLastDrive('selfeDefense terrace'); + $shutters->setLastDrive('selfDefense terrace'); $shutters->setDriveCmd( $shutters->getClosedPos ); } } @@ -1330,23 +1327,29 @@ sub EventProcessingResidents($@) { if ( $shutters->getStatus != $shutters->getClosedPos - and not IsDay($shuttersDev) + and not $shutters->getIsDay and $shutters->getRoommatesStatus eq 'none' and ( $getModeDown eq 'home' or $getModeDown eq 'always' ) and ( $getResidentsLastStatus ne 'asleep' or $getResidentsLastStatus ne 'awoken' ) and IsAfterShuttersTimeBlocking($shuttersDev) + and $shutters->getRoommatesStatus eq 'none' ) { $shutters->setLastDrive('residents home'); $shutters->setDriveCmd( $shutters->getClosedPos ); } elsif ( - $shutters->getShadingMode eq 'home' - and IsDay($shuttersDev) + ( + $shutters->getShadingMode eq 'home' + or $shutters->getShadingMode eq 'always' + ) + and $shutters->getIsDay and $shutters->getIfInShading + and $shutters->getRoommatesStatus eq 'none' and $shutters->getStatus != $shutters->getShadingPos + and not $shutters->getShadingManualDriveStatus and not( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 and $shutters->getShuttersPlace eq 'terrace' ) ) @@ -1356,9 +1359,11 @@ sub EventProcessingResidents($@) { } elsif ( $shutters->getShadingMode eq 'absent' - and IsDay($shuttersDev) + and $shutters->getIsDay and $shutters->getIfInShading and $shutters->getStatus == $shutters->getShadingPos + and $shutters->getRoommatesStatus eq 'none' + and not $shutters->getShadingManualDriveStatus and not( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 and $shutters->getShuttersPlace eq 'terrace' ) ) @@ -1367,29 +1372,54 @@ sub EventProcessingResidents($@) { $shutters->setDriveCmd( $shutters->getLastPos ); } elsif ( - $ascDev->getSelfDefense eq 'on' - and CheckIfShuttersWindowRecOpen($shuttersDev) != 0 - and $shutters->getSelfDefenseExclude eq 'off' - or ( $getResidentsLastStatus eq 'gone' - and $shutters->getShuttersPlace eq 'terrace' ) - and ( $getModeUp eq 'absent' - or $getModeUp eq 'off' ) + ( + $ascDev->getSelfDefense eq 'on' + and $shutters->getSelfDefenseExclude eq 'off' + or ( $getResidentsLastStatus eq 'gone' + and $shutters->getShuttersPlace eq 'terrace' ) + ) and not $shutters->getIfInShading + and ( $getResidentsLastStatus eq 'gone' + or $getResidentsLastStatus eq 'absent' ) + and $shutters->getLastDrive eq 'selfDefense active' ) { - $shutters->setLastDrive('selfeDefense inactive'); - $shutters->setDriveCmd( $shutters->getLastPos ); - $shutters->setHardLockOut('on') - if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 - and $shutters->getShuttersPlace eq 'terrace' ); + RemoveInternalTimer( $shutters->getSelfDefenseAbsentTimerhash ) + if ( $getResidentsLastStatus eq 'absent' + and $ascDev->getSelfDefense eq 'on' + and $shutters->getSelfDefenseExclude eq 'off' + and CheckIfShuttersWindowRecOpen($shuttersDev) == 0 + and not $shutters->getSelfDefenseAbsent + and $shutters->getSelfDefenseAbsentTimerrun ); + + if ( $shutters->getStatus == $shutters->getClosedPos ) { + $shutters->setHardLockOut('on') + if ( + CheckIfShuttersWindowRecOpen($shuttersDev) == 2 + and $shutters->getShuttersPlace eq 'terrace' + and ( $getModeUp eq 'absent' + or $getModeUp eq 'off' ) + and CheckIfShuttersWindowRecOpen($shuttersDev) != 0 + ); + + $shutters->setLastDrive('selfDefense inactive'); + $shutters->setDriveCmd( + ( + $shutters->getPrivacyDownStatus == 2 + ? $shutters->getPrivacyDownPos + : $shutters->getOpenPos + ) + ); + } } elsif ( $shutters->getStatus == $shutters->getClosedPos - and IsDay($shuttersDev) + and $shutters->getIsDay and $shutters->getRoommatesStatus eq 'none' and ( $getModeUp eq 'home' or $getModeUp eq 'always' ) and IsAfterShuttersTimeBlocking($shuttersDev) + and $shutters->getRoommatesStatus eq 'none' and not $shutters->getIfInShading ) { @@ -1441,7 +1471,16 @@ sub EventProcessingRain($@) { and $shutters->getRainProtectionStatus eq 'protected' ) { $shutters->setLastDrive('rain un-protected'); - $shutters->setDriveCmd( $shutters->getLastPos ); + $shutters->setDriveCmd( + ( + $shutters->getIsDay ? $shutters->getLastPos + : ( + $shutters->getPrivacyDownStatus == 2 + ? $shutters->getPrivacyDownPos + : $shutters->getClosedPos + ) + ) + ); $shutters->setRainProtectionStatus('unprotected'); } } @@ -1489,7 +1528,16 @@ sub EventProcessingWind($@) { and $shutters->getWindProtectionStatus eq 'protected' ) { $shutters->setLastDrive('wind un-protected'); - $shutters->setDriveCmd( $shutters->getLastPos ); + $shutters->setDriveCmd( + ( + $shutters->getIsDay ? $shutters->getLastPos + : ( + $shutters->getPrivacyDownStatus == 2 + ? $shutters->getPrivacyDownPos + : $shutters->getClosedPos + ) + ) + ); $shutters->setWindProtectionStatus('unprotected'); } @@ -1768,8 +1816,6 @@ sub EventProcessingBrightness($@) { ); } } - ### Wenn es kein Brightness Reading ist muss auch die Shading Funktion nicht aufgerufen werden. -# else { EventProcessingShadingBrightness( $hash, $shuttersDev, $events ); } else { ASC_Debug( 'EventProcessingBrightness: ' . $shutters->getShuttersDev @@ -1783,6 +1829,7 @@ sub EventProcessingShadingBrightness($@) { my $name = $hash->{NAME}; $shutters->setShuttersDev($shuttersDev); my $reading = $shutters->getBrightnessReading; + my $outTemp = $ascDev->getOutTemp; Log3( $name, 4, "AutoShuttersControl ($shuttersDev) - EventProcessingShadingBrightness" @@ -1809,27 +1856,19 @@ sub EventProcessingShadingBrightness($@) { . ' WindProtection: ' . $shutters->getWindProtectionStatus ); - my $homemode = $shutters->getRoommatesStatus; - $homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' ); - - if ( - ( - $shutters->getShadingMode eq 'always' - or $shutters->getShadingMode eq $homemode - ) - and IsDay($shuttersDev) - and $ascDev->getAutoShuttersControlShading eq 'on' + if ( $ascDev->getAutoShuttersControlShading eq 'on' and $shutters->getRainProtectionStatus eq 'unprotected' - and $shutters->getWindProtectionStatus eq 'unprotected' - ) + and $shutters->getWindProtectionStatus eq 'unprotected' ) { + $outTemp = $shutters->getOutTemp + if ( $shutters->getOutTemp != -100 ); ShadingProcessing( $hash, $shuttersDev, $ascDev->getAzimuth, $ascDev->getElevation, $1, - $ascDev->getOutTemp, + $outTemp, $shutters->getDirection, $shutters->getShadingAngleLeft, $shutters->getShadingAngleRight @@ -1840,15 +1879,6 @@ sub EventProcessingShadingBrightness($@) { . ' - Alle Bedingungen zur weiteren Beschattungsverarbeitung sind erfüllt. Es wird nun die eigentliche Beschattungsfunktion aufgerufen' ); } - elsif ( $shutters->getShadingStatus eq 'in' - and $shutters->getShadingMode ne $homemode - and $shutters->getRainProtectionStatus eq 'unprotected' - and $shutters->getWindProtectionStatus eq 'unprotected' ) - { - $shutters->setShadingStatus('out'); - $shutters->setShadingLastStatus('in'); - ShadingProcessingDriveCommand( $hash, $shuttersDev ); - } } } @@ -1871,6 +1901,7 @@ sub EventProcessingTwilightDevice($@) { if ( $events =~ m#(azimuth|elevation|SunAz|SunAlt):\s(\d+.\d+)# ) { my $name = $device; my ( $azimuth, $elevation ); + my $outTemp = $ascDev->getOutTemp; $azimuth = $2 if ( $1 eq 'azimuth' or $1 eq 'SunAz' ); $elevation = $2 if ( $1 eq 'elevation' or $1 eq 'SunAlt' ); @@ -1890,6 +1921,8 @@ sub EventProcessingTwilightDevice($@) { my $homemode = $shutters->getRoommatesStatus; $homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' ); + $outTemp = $shutters->getOutTemp + if ( $shutters->getOutTemp != -100 ); ASC_Debug( 'EventProcessingTwilightDevice: ' . $shutters->getShuttersDev @@ -1898,16 +1931,9 @@ sub EventProcessingTwilightDevice($@) { . ' WindProtection: ' . $shutters->getWindProtectionStatus ); - if ( - ( - $shutters->getShadingMode eq 'always' - or $shutters->getShadingMode eq $homemode - ) - and IsDay($shuttersDev) - and $ascDev->getAutoShuttersControlShading eq 'on' + if ( $ascDev->getAutoShuttersControlShading eq 'on' and $shutters->getRainProtectionStatus eq 'unprotected' - and $shutters->getWindProtectionStatus eq 'unprotected' - ) + and $shutters->getWindProtectionStatus eq 'unprotected' ) { ShadingProcessing( $hash, @@ -1915,7 +1941,7 @@ sub EventProcessingTwilightDevice($@) { $azimuth, $elevation, $shutters->getBrightness, - $ascDev->getOutTemp, + $outTemp, $shutters->getDirection, $shutters->getShadingAngleLeft, $shutters->getShadingAngleRight @@ -1926,13 +1952,6 @@ sub EventProcessingTwilightDevice($@) { . ' - Alle Bedingungen zur weiteren Beschattungsverarbeitung sind erfüllt. Es wird nun die Beschattungsfunktion ausgeführt' ); } - - if ( not IsDay($shuttersDev) - and $shutters->getShadingStatus ne 'out' ) - { - $shutters->setShadingStatus('out'); - $shutters->setShadingLastStatus('in'); - } } } } @@ -1947,12 +1966,6 @@ sub ShadingProcessing($@) { ) = @_; my $name = $hash->{NAME}; $shutters->setShuttersDev($shuttersDev); - $shutters->setShadingLastStatus( $shutters->getShadingStatus ) - if ( - $shutters->getShadingLastStatus ne $shutters->getShadingStatus - and ( $shutters->getShadingStatus eq 'in' - or $shutters->getShadingStatus eq 'out' ) - ); ASC_Debug( 'ShadingProcessing: ' @@ -1973,8 +1986,8 @@ sub ShadingProcessing($@) { . $anglePlus . ', Ist es nach der Zeitblockadezeit: ' . ( IsAfterShuttersTimeBlocking($shuttersDev) ? 'JA' : 'NEIN' ) - . ', Ist es nach der manuellen Blockadezeit: ' - . ( IsAfterShuttersManualBlocking($shuttersDev) ? 'JA' : 'NEIN' ) + . ', Das Rollo ist in der Beschattung und wurde manuell gefahren: ' + . ( $shutters->getShadingManualDriveStatus ? 'JA' : 'NEIN' ) . ', Ist es nach der Hälfte der Beschattungswartezeit: ' . ( ( int( gettimeofday() ) - $shutters->getShadingStatusTimestamp ) < @@ -1982,10 +1995,6 @@ sub ShadingProcessing($@) { ) ); - $shutters->setShadingStatus('out') - if ( not IsDay($shuttersDev) - and $shutters->getShadingStatus ne 'out' ); - Log3( $name, 4, "AutoShuttersControl ($name) - Shading Processing, Rollladen: " . $shuttersDev @@ -2005,8 +2014,7 @@ sub ShadingProcessing($@) { or $outTemp == -100 or ( int( gettimeofday() ) - $shutters->getShadingStatusTimestamp ) < ( $shutters->getShadingWaitingPeriod / 2 ) - or not IsAfterShuttersTimeBlocking($shuttersDev) - or not IsAfterShuttersManualBlocking($shuttersDev) ); + or $shutters->getShadingMode eq 'off' ); Log3( $name, 4, "AutoShuttersControl ($name) - Shading Processing, Rollladen: " @@ -2029,30 +2037,25 @@ sub ShadingProcessing($@) { if ( ( $outTemp < $shutters->getShadingMinOutsideTemperature - 3 - or not IsDay($shuttersDev) or $azimuth < $winPosMin or $azimuth > $winPosMax ) and $shutters->getShadingStatus ne 'out' - and $getStatus != $getShadingPos ) { + $shutters->setShadingLastStatus('in'); $shutters->setShadingStatus('out'); - $shutters->setLastDrive('shading out'); - - ShuttersCommandSet( $hash, $shuttersDev, $shutters->getLastPos ); ASC_Debug( 'ShadingProcessing: ' . $shutters->getShuttersDev . ' - Es ist Nacht oder die Aussentemperatur unterhalb der Shading Temperatur. Die Beschattung wird Zwangsbeendet' ); - return Log3( $name, 4, -"AutoShuttersControl ($name) - Shading Processing - Es ist Sonnenuntergang vorbei oder die Aussentemperatur unterhalb der Shading Temperatur " + Log3( $name, 4, +"AutoShuttersControl ($name) - Shading Processing - Der Sonnenstand ist ausserhalb der Winkelangaben oder die Aussentemperatur unterhalb der Shading Temperatur " ); } - - if ( $azimuth < $winPosMin + elsif ($azimuth < $winPosMin or $azimuth > $winPosMax or $elevation < $shutters->getShadingMinElevation or $elevation > $shutters->getShadingMaxElevation @@ -2063,16 +2066,19 @@ sub ShadingProcessing($@) { if ( $shutters->getShadingStatus eq 'in' or $shutters->getShadingStatus eq 'in reserved' ); - $shutters->setShadingStatus('out') - if ( + if ( ( $shutters->getShadingStatus eq 'out reserved' and ( int( gettimeofday() ) - $shutters->getShadingStatusTimestamp ) - > $shutters->getShadingWaitingPeriod - ) - or $azimuth > $winPosMax - ); + ) > $shutters->getShadingWaitingPeriod + ) + { + $shutters->setShadingStatus('out'); + $shutters->setShadingLastStatus('in') + if ( $shutters->getShadingLastStatus eq 'out' ); + } + Log3( $name, 4, "AutoShuttersControl ($name) - Shading Processing, Rollladen: " . $shuttersDev @@ -2099,11 +2105,16 @@ sub ShadingProcessing($@) { if ( $shutters->getShadingStatus eq 'out' or $shutters->getShadingStatus eq 'out reserved' ); - $shutters->setShadingStatus('in') - if ( $shutters->getShadingStatus eq 'in reserved' + if ( $shutters->getShadingStatus eq 'in reserved' and ( int( gettimeofday() ) - $shutters->getShadingStatusTimestamp ) > - ( $shutters->getShadingWaitingPeriod / 2 ) ); + ( $shutters->getShadingWaitingPeriod / 2 ) ) + { + $shutters->setShadingStatus('in'); + $shutters->setShadingLastStatus('out') + if ( $shutters->getShadingLastStatus eq 'in' ); + } + Log3( $name, 4, "AutoShuttersControl ($name) - Shading Processing, Rollladen: " . $shuttersDev @@ -2122,12 +2133,17 @@ sub ShadingProcessing($@) { ShadingProcessingDriveCommand( $hash, $shuttersDev ) if ( - ( - $shutters->getShadingStatus eq 'out' - and $shutters->getShadingLastStatus eq 'in' + $shutters->getIsDay + and IsAfterShuttersTimeBlocking($shuttersDev) + and not $shutters->getShadingManualDriveStatus + and ( + ( + $shutters->getShadingStatus eq 'out' + and $shutters->getShadingLastStatus eq 'in' + ) + or ( $shutters->getShadingStatus eq 'in' + and $shutters->getShadingLastStatus eq 'out' ) ) - or ( $shutters->getShadingStatus eq 'in' - and $shutters->getShadingLastStatus eq 'out' ) ); } @@ -2140,28 +2156,56 @@ sub ShadingProcessingDriveCommand($$) { my $getShadingPos = $shutters->getShadingPos; my $getStatus = $shutters->getStatus; - $shutters->setShadingStatus( $shutters->getShadingStatus ) - if ( - ( int( gettimeofday() ) - $shutters->getShadingStatusTimestamp ) > - ( $shutters->getShadingWaitingPeriod / 2 ) ); + my $homemode = $shutters->getRoommatesStatus; + $homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' ); - if ( $shutters->getShadingStatus eq 'in' - and $getShadingPos != $getStatus ) + if ( $shutters->getShadingMode eq 'always' + or $shutters->getShadingMode eq $homemode ) { - # my $queryShuttersShadingPos = ( - # $shutters->getShuttersPosCmdValueNegate - # ? $getStatus > $getShadingPos - # : $getStatus < $getShadingPos - # ); + $shutters->setShadingStatus( $shutters->getShadingStatus ) + if ( + ( int( gettimeofday() ) - $shutters->getShadingStatusTimestamp ) > + ( $shutters->getShadingWaitingPeriod / 2 ) ); - if ( - not $shutters->getQueryShuttersPos( $shutters->getShadingPos ) - and not( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 - and $shutters->getShuttersPlace eq 'terrace' ) - ) + if ( $shutters->getShadingStatus eq 'in' + and $getShadingPos != $getStatus ) { - $shutters->setLastDrive('shading in'); - ShuttersCommandSet( $hash, $shuttersDev, $getShadingPos ); + if ( + not $shutters->getQueryShuttersPos($getShadingPos) + and not( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 + and $shutters->getShuttersPlace eq 'terrace' ) + ) + { + $shutters->setLastDrive('shading in'); + ShuttersCommandSet( $hash, $shuttersDev, $getShadingPos ); + + ASC_Debug( 'ShadingProcessing: ' + . $shutters->getShuttersDev + . ' - Der aktuelle Beschattungsstatus ist: ' + . $shutters->getShadingStatus + . ' und somit wird nun in die Position: ' + . $getShadingPos + . ' zum Beschatten gefahren' ); + } + } + elsif ( $shutters->getShadingStatus eq 'out' + and $getShadingPos == $getStatus ) + { + $shutters->setLastDrive('shading out'); + + ShuttersCommandSet( + $hash, + $shuttersDev, + ( + $getShadingPos == $shutters->getLastPos + ? $shutters->getOpenPos + : ( + $shutters->getQueryShuttersPos( $shutters->getLastPos ) + ? $shutters->getLastPos + : $shutters->getOpenPos + ) + ) + ); ASC_Debug( 'ShadingProcessing: ' . $shutters->getShuttersDev @@ -2169,46 +2213,24 @@ sub ShadingProcessingDriveCommand($$) { . $shutters->getShadingStatus . ' und somit wird nun in die Position: ' . $getShadingPos - . ' zum Beschatten gefahren' ); + . ' zum beenden der Beschattung gefahren' ); } - } - elsif ( $shutters->getShadingStatus eq 'out' - and $getShadingPos == $getStatus ) - { - $shutters->setLastDrive('shading out'); - ShuttersCommandSet( - $hash, - $shuttersDev, - ( - $shutters->getShadingPos == $shutters->getLastPos - ? $shutters->getOpenPos - : $shutters->getLastPos - ) - ); - ASC_Debug( 'ShadingProcessing: ' + Log3( $name, 4, +"AutoShuttersControl ($name) - Shading Processing - In der Routine zum fahren der Rollläden, Shading Wert: " + . $shutters->getShadingStatus ); + + ASC_Debug( + 'ShadingProcessing: ' . $shutters->getShuttersDev . ' - Der aktuelle Beschattungsstatus ist: ' . $shutters->getShadingStatus - . ' und somit wird nun in die Position: ' - . $getShadingPos - . ' zum beenden der Beschattung gefahren' ); + . ', Beschattungsstatus Zeitstempel: ' + . strftime( + "%Y.%m.%e %T", localtime( $shutters->getShadingStatusTimestamp ) + ) + ); } - - Log3( $name, 4, -"AutoShuttersControl ($name) - Shading Processing - In der Routine zum fahren der Rollläden, Shading Wert: " - . $shutters->getShadingStatus ); - - ASC_Debug( - 'ShadingProcessing: ' - . $shutters->getShuttersDev - . ' - Der aktuelle Beschattungsstatus ist: ' - . $shutters->getShadingStatus - . ', Beschattungsstatus Zeitstempel: ' - . strftime( - "%Y.%m.%e %T", localtime( $shutters->getShadingStatusTimestamp ) - ) - ); } sub EventProcessingPartyMode($) { @@ -2220,7 +2242,7 @@ sub EventProcessingPartyMode($) { next if ( $shutters->getPartyMode eq 'off' ); - if ( not IsDay($shuttersDev) + if ( not $shutters->getIsDay and $shutters->getModeDown ne 'off' and IsAfterShuttersManualBlocking($shuttersDev) ) { @@ -2251,7 +2273,7 @@ sub EventProcessingPartyMode($) { ); } } - elsif ( IsDay($shuttersDev) + elsif ( $shutters->getIsDay and IsAfterShuttersManualBlocking($shuttersDev) ) { $shutters->setLastDrive('drive after party mode'); @@ -2292,6 +2314,10 @@ sub EventProcessingShutters($@) { $ascDev->setStateReading; $shutters->setLastManPos($1); + $shutters->setShadingManualDriveStatus(1) + if ( $shutters->getIsDay + and $shutters->getIfInShading ); + ASC_Debug( 'EventProcessingShutters: eine manualle Fahrt wurde erkannt!'); } @@ -2312,12 +2338,6 @@ sub ShuttersCommandSet($$$) { my $name = $hash->{NAME}; $shutters->setShuttersDev($shuttersDev); - # my $queryShuttersPosValue = ( - # $shutters->getShuttersPosCmdValueNegate - # ? $shutters->getStatus > $posValue - # : $shutters->getStatus < $posValue - # ); - if ( $posValue != $shutters->getShadingPos and ( @@ -2331,21 +2351,26 @@ sub ShuttersCommandSet($$$) { and ( $ascDev->getAutoShuttersControlComfort eq 'off' or $shutters->getComfortOpenPos != $posValue ) and $shutters->getVentilateOpen eq 'on' + and $shutters->getShuttersPlace eq 'window' + and $shutters->getLockOut ne 'off' ) or ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 and $shutters->getSubTyp eq 'threestate' and $ascDev->getAutoShuttersControlComfort eq 'on' - and $shutters->getVentilateOpen eq 'off' ) + and $shutters->getVentilateOpen eq 'off' + and $shutters->getShuttersPlace eq 'window' + and $shutters->getLockOut ne 'off' ) or ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 and ( $shutters->getLockOut eq 'soft' or $shutters->getLockOut eq 'hard' ) - and $ascDev->getHardLockOut eq 'on' and not $shutters->getQueryShuttersPos($posValue) ) or ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 and $shutters->getShuttersPlace eq 'terrace' - and $shutters->getQueryShuttersPos($posValue) ) + and not $shutters->getQueryShuttersPos($posValue) ) + or ( $shutters->getRainProtectionStatus eq 'protected' + and $shutters->getWindProtectionStatus eq 'protected' ) ) ) { @@ -2439,11 +2464,16 @@ sub CreateSunRiseSetShuttersTimer($$) { my %funcHash = ( hash => $hash, shuttersdevice => $shuttersDev, - privacyMode => 0, sunsettime => $shuttersSunsetUnixtime, sunrisetime => $shuttersSunriseUnixtime ); + ## Setzt den PrivacyDown Modus für die Sichtschutzfahrt auf den Status 0 + ## 1 bedeutet das PrivacyDown Timer aktiviert wurde, 2 beudet das er im privacyDown ist + ## also das Rollo in privacyDown Position steht und VOR der endgültigen Nachfahrt + $shutters->setPrivacyDownStatus(0) + if ( not defined( $shutters->getPrivacyDownStatus ) ); + ## Ich brauche beim löschen des InternalTimer den Hash welchen ich mitgegeben habe,dieser muss gesichert werden $shutters->setInTimerFuncHash( \%funcHash ); @@ -2463,7 +2493,8 @@ sub CreateSunRiseSetShuttersTimer($$) { ), 0 ); - $funcHash{privacyMode} = 1; + ## Setzt den PrivacyDown Modus für die Sichtschutzfahrt auf den Status 1 + $shutters->setPrivacyDownStatus(1); } } @@ -2487,23 +2518,6 @@ sub RenewSunRiseSetShuttersTimer($) { CreateSunRiseSetShuttersTimer( $hash, $_ ); # ### Temporär angelegt damit die neue Attributs Parameter Syntax verteilt werden kann -# CommandAttr(undef, $_ . ' ASC_BrightnessSensor '.AttrVal($_, 'ASC_Brightness_Sensor', 'none').':'.AttrVal($_, 'ASC_Brightness_Reading', 'brightness').' '.AttrVal($_, 'ASC_BrightnessMinVal', 500).':'.AttrVal($_, 'ASC_BrightnessMaxVal', 700)) if ( AttrVal($_, 'ASC_Brightness_Sensor', 'none') ne 'none' ); - -# $attr{$_}{'ASC_BrightnessSensor'} = -# AttrVal( $_, 'ASC_Brightness_Sensor', 'none' ) . ':' -# . AttrVal( $_, 'ASC_Brightness_Reading', 'brightness' ) . ' ' -# . AttrVal( $_, 'ASC_BrightnessMinVal', 500 ) . ':' -# . AttrVal( $_, 'ASC_BrightnessMaxVal', 700 ) -# if ( AttrVal( $_, 'ASC_Brightness_Sensor', 'none' ) ne 'none' ); -# -# delFromDevAttrList( $_, 'ASC_Brightness_Sensor' ) -# ; # temporär muss später gelöscht werden ab Version 0.4.11beta9 -# delFromDevAttrList( $_, 'ASC_Brightness_Reading' ) -# ; # temporär muss später gelöscht werden ab Version 0.4.11beta9 -# delFromDevAttrList( $_, 'ASC_BrightnessMinVal' ) -# ; # temporär muss später gelöscht werden ab Version 0.4.11beta9 -# delFromDevAttrList( $_, 'ASC_BrightnessMaxVal' ) -# ; # temporär muss später gelöscht werden ab Version 0.4.11beta9 $attr{$_}{'ASC_Shading_MinMax_Elevation'} = AttrVal( $_, 'ASC_Shading_Min_Elevation', 'none' ) if ( AttrVal( $_, 'ASC_Shading_Min_Elevation', 'none' ) ne 'none' ); @@ -2565,7 +2579,7 @@ sub wiggle($$) { } InternalTimer( gettimeofday() + 60, - 'FHEM::AutoShuttersControl::SetCmdFn', \%h ); + 'FHEM::AutoShuttersControl::_SetCmdFn', \%h ); } #### @@ -2579,18 +2593,6 @@ sub SunSetShuttersAfterTimerFn($) { $shutters->setSunset(1); $shutters->setSunrise(0); - my $posValue; - - if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0 - or $shutters->getVentilateOpen eq 'off' ) - { - $posValue = $shutters->getClosedPos; - } - elsif ( $shutters->getQueryShuttersPos( $shutters->getVentilatePos ) ) { - $posValue = $shutters->getStatus; - } - else { $posValue = $shutters->getVentilatePos; } - my $homemode = $shutters->getRoommatesStatus; $homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' ); @@ -2605,23 +2607,24 @@ sub SunSetShuttersAfterTimerFn($) { ) ) { - # my $queryShuttersPosPrivacyDown = ( - # $shutters->getShuttersPosCmdValueNegate - # ? $shutters->getStatus > $shutters->getPrivacyDownPos - # : $shutters->getStatus < $shutters->getPrivacyDownPos - # ); - if ( $funcHash->{privacyMode} == 1 - and - not $shutters->getQueryShuttersPos( $shutters->getPrivacyDownPos ) ) - { + if ( $shutters->getPrivacyDownStatus == 1 ) { + $shutters->setPrivacyDownStatus(2); $shutters->setLastDrive('privacy position'); - ShuttersCommandSet( $hash, $shuttersDev, - $shutters->getPrivacyDownPos ); + ShuttersCommandSet( + $hash, + $shuttersDev, + PositionValueWindowRec( + $shuttersDev, $shutters->getPrivacyDownPos + ) + ); } - elsif ( $funcHash->{privacyMode} == 0 ) { + else { + $shutters->setPrivacyDownStatus(0); $shutters->setLastDrive('night close'); - ShuttersCommandSet( $hash, $shuttersDev, $posValue ); + ShuttersCommandSet( $hash, $shuttersDev, + PositionValueWindowRec( $shuttersDev, $shutters->getClosedPos ) + ); } } @@ -2664,6 +2667,9 @@ sub SunRiseShuttersAfterTimerFn($) { $ascDev->getSelfDefense eq 'off' or ( $ascDev->getSelfDefense eq 'on' and CheckIfShuttersWindowRecOpen($shuttersDev) == 0 ) + or ( $ascDev->getSelfDefense eq 'on' + and CheckIfShuttersWindowRecOpen($shuttersDev) != 0 + and $ascDev->getResidentsStatus eq 'home' ) ) ) { @@ -2784,7 +2790,8 @@ sub GetShuttersInformation($) { $ret .= " "; $ret .= "" . $shutters->getLockOut . ""; $ret .= " "; - $ret .= "" . $shutters->getLastDrive . ""; + $ret .= "" + . ReadingsVal( $shutter, 'ASC_ShuttersLastDrive', 'none' ) . ""; $ret .= " "; $ret .= "" . $shutters->getStatus . ""; $ret .= " "; @@ -2851,6 +2858,37 @@ sub GetMonitoredDevs($) { ## my little helper ################################# +sub PositionValueWindowRec($$) { + my ( $shuttersDev, $posValue ) = @_; + + if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 1 + and $shutters->getVentilateOpen eq 'on' ) + { + $posValue = $shutters->getVentilatePos; + } + elsif ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 + and $shutters->getSubTyp eq 'threestate' + and $ascDev->getAutoShuttersControlComfort eq 'on' ) + { + $posValue = $shutters->getComfortOpenPos; + } + elsif ( + CheckIfShuttersWindowRecOpen($shuttersDev) == 2 + and ( $shutters->getSubTyp eq 'threestate' + or $shutters->getSubTyp eq 'twostate' ) + and $shutters->getVentilateOpen eq 'on' + ) + { + $posValue = $shutters->getVentilatePos; + } + + if ( $shutters->getQueryShuttersPos($posValue) ) { + $posValue = $shutters->getStatus; + } + + return $posValue; +} + sub AutoSearchTwilightDev($) { my $hash = shift; my $name = $hash->{NAME}; @@ -2918,7 +2956,7 @@ sub ExtractNotifyDevFromEvent($$$) { } ## Ist Tag oder Nacht für den entsprechende Rolladen -sub IsDay($) { +sub _IsDay($) { my ($shuttersDev) = @_; $shutters->setShuttersDev($shuttersDev); @@ -3387,10 +3425,10 @@ sub IsAfterShuttersTimeBlocking($) { if ( ( int( gettimeofday() ) - $shutters->getLastManPosTimestamp ) < $shutters->getBlockingTimeAfterManual - or ( not IsDay($shuttersDev) + or ( not $shutters->getIsDay and $shutters->getSunriseUnixTime - ( int( gettimeofday() ) ) < $shutters->getBlockingTimeBeforDayOpen ) - or ( IsDay($shuttersDev) + or ( $shutters->getIsDay and $shutters->getSunsetUnixTime - ( int( gettimeofday() ) ) < $shutters->getBlockingTimeBeforNightClose ) ) @@ -3544,7 +3582,7 @@ sub IsWeTomorrow() { return $we; } -sub SetCmdFn($) { +sub _SetCmdFn($) { my $h = shift; my $shuttersDev = $h->{shuttersDev}; my $posValue = $h->{posValue}; @@ -3587,6 +3625,22 @@ sub SetCmdFn($) { . $posValue . ' ' . $shutters->getPosSetCmd . ' ' . $posValue ); + + $shutters->setSelfDefenseAbsent( 0, 0 ) + if ( not $shutters->getSelfDefenseAbsent + and $shutters->getSelfDefenseAbsentTimerrun ); +} + +sub _setShuttersLastDriveDelayed($) { + my $h = shift; + + my $shuttersDevHash = $h->{devHash}; + my $lastDrive = $h->{lastDrive}; + + readingsSingleUpdate( $shuttersDevHash, 'ASC_ShuttersLastDrive', + $lastDrive, 1 ); + +# print('Ausgabe Funktion wurde aufgerufen - LastDrive: ' . $lastDrive . ', DevHash and Name: ' . $shuttersDevHash . ':: ' . $shuttersDevHash->{NAME} . "\n"); } sub ASC_Debug($) { @@ -3681,6 +3735,16 @@ sub setNoOffset { return 0; } +sub setSelfDefenseAbsent { + my ( $self, $timerrun, $active, $timerhash ) = @_; + + $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerrun} = $timerrun; + $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{active} = $active; + $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerhash} = $timerhash + if ( defined($timerhash) ); + return 0; +} + sub setDriveCmd { my ( $self, $posValue ) = @_; my $offSet; @@ -3711,17 +3775,27 @@ sub setDriveCmd { $offSet = $ascDev->getShuttersOffset if ( $shutters->getOffset < 0 ); $offSetStart = $shutters->getOffsetStart; - if ( $offSetStart > 0 and not $shutters->getNoOffset ) { + if ( $shutters->getSelfDefenseAbsent + and not $shutters->getSelfDefenseAbsentTimerrun + and $shutters->getSelfDefenseExclude eq 'off' + and $shutters->getLastDrive eq 'selfDefense active' + and $ascDev->getSelfDefense eq 'on' ) + { + InternalTimer( gettimeofday() + $shutters->getSelfDefenseAbsentDelay, + 'FHEM::AutoShuttersControl::_SetCmdFn', \%h ); + $shutters->setSelfDefenseAbsent( 1, 0, \%h ); + } + elsif ( $offSetStart > 0 and not $shutters->getNoOffset ) { InternalTimer( gettimeofday() + int( rand($offSet) + $shutters->getOffsetStart ), - 'FHEM::AutoShuttersControl::SetCmdFn', \%h ); + 'FHEM::AutoShuttersControl::_SetCmdFn', \%h ); FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' . $shutters->getShuttersDev . ' - versetztes fahren' ); } elsif ( $offSetStart < 1 or $shutters->getNoOffset ) { - FHEM::AutoShuttersControl::SetCmdFn( \%h ); + FHEM::AutoShuttersControl::_SetCmdFn( \%h ); FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' . $shutters->getShuttersDev . ' - NICHT versetztes fahren' ); @@ -3788,8 +3862,13 @@ sub setLastDriveReading { my $self = shift; my $shuttersDevHash = $defs{ $self->{shuttersDev} }; - readingsSingleUpdate( $shuttersDevHash, 'ASC_ShuttersLastDrive', - $shutters->getLastDrive, 1 ); + my %h = ( + devHash => $shuttersDevHash, + lastDrive => $shutters->getLastDrive, + ); + + InternalTimer( gettimeofday() + 0.1, + 'FHEM::AutoShuttersControl::_setShuttersLastDriveDelayed', \%h ); return 0; } @@ -3841,19 +3920,38 @@ sub setInTimerFuncHash { return 0; } +sub setPrivacyDownStatus { + my ( $self, $statusValue ) = @_; + + $self->{ $self->{shuttersDev} }->{privacyDownStatus} = $statusValue; + return 0; +} + +sub getPrivacyDownStatus { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }->{privacyDownStatus} ) + ? $self->{ $self->{shuttersDev} }->{privacyDownStatus} + : undef + ); +} + sub getIsDay { my $self = shift; - return FHEM::AutoShuttersControl::IsDay( $self->{shuttersDev} ); + return FHEM::AutoShuttersControl::_IsDay( $self->{shuttersDev} ); } sub getFreezeStatus { use POSIX qw(strftime); - my $self = shift; + my $self = shift; my $daytime = strftime( "%P", localtime() ); + my $outTemp = $ascDev->getOutTemp; + $outTemp = $shutters->getOutTemp if ( $shutters->getOutTemp != -100 ); if ( $shutters->getAntiFreeze ne 'off' - and $ascDev->getOutTemp <= $ascDev->getFreezeTemp ) + and $outTemp <= $ascDev->getFreezeTemp ) { if ( $shutters->getAntiFreeze eq 'soft' ) { @@ -3903,6 +4001,29 @@ sub getNoOffset { return $self->{ $self->{shuttersDev} }{noOffset}; } +sub getSelfDefenseAbsent { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{active}; +} + +sub getSelfDefenseAbsentTimerrun { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerrun}; +} + +sub getSelfDefenseAbsentTimerhash { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerhash} + if ( + defined( + $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerhash} + ) + ); +} + sub getLastDrive { my $self = shift; @@ -4020,9 +4141,9 @@ sub getRoommatesLastStatus { 'asleep' => 1, 'gotosleep' => 2, 'awoken' => 3, - 'home' => 4, + 'home' => 6, 'absent' => 5, - 'gone' => 6, + 'gone' => 4, 'none' => 7 ); my $minPrio = 10; @@ -4037,6 +4158,13 @@ sub getRoommatesLastStatus { return $revStatePrio{$minPrio}; } +sub getOutTemp { + my $self = shift; + + return ReadingsVal( $shutters->_getTempSensor, + $shutters->getTempSensorReading, -100 ); +} + ### Begin Beschattung Objekt mit Daten befüllen sub setShadingStatus { my ( $self, $value ) = @_; @@ -4058,6 +4186,17 @@ sub setShadingLastStatus { $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} = int( gettimeofday() ) if ( defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) ); + $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} = 0 + if ( $value eq 'out' ); + return 0; +} + +sub setShadingManualDriveStatus { + my ( $self, $value ) = @_; + ### Werte für value = in, out + + $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} = $value + if ( defined($value) ); return 0; } @@ -4094,13 +4233,26 @@ sub getShadingLastStatus { # Werte für value = in, out ); } +sub getShadingManualDriveStatus { # Werte für value = in, out + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus} ) + and defined( + $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} + ) + ? $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} + : 0 + ); +} + sub getIfInShading { my $self = shift; return ( ( $shutters->getShadingMode ne 'off' - and $shutters->getShadingStatus eq 'in' + and $shutters->getShadingLastStatus eq 'out' ) ? 1 : 0 ); } @@ -4143,6 +4295,16 @@ sub getShadingStatusTimestamp { and defined( $self->{ $self->{shuttersDev} }{ShadingStatus} ) and defined( $self->{ $self->{shuttersDev} }{ShadingStatus}{TIME} ) ); } + +sub getShadingLastStatusTimestamp { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} + if ( defined( $self->{ $self->{shuttersDev} } ) + and defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) + and defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} ) + ); +} ### Ende Beschattung ## Subklasse Attr von ASC_Shutters## @@ -4195,6 +4357,18 @@ sub getSelfDefenseExclude { return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_Exclude', 'off' ); } +sub getSelfDefenseMode { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_Mode', 'gone' ); +} + +sub getSelfDefenseAbsentDelay { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_AbsentDelay', 300 ); +} + sub getWiggleValue { my $self = shift; @@ -4216,6 +4390,54 @@ sub getShadingMode { return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Mode', 'off' ); } +sub _getTempSensor { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{device} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{LASTGETTIME} + ) + and ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{LASTGETTIME} ) + < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{LASTGETTIME} = + int( gettimeofday() ); + my ( $device, $reading ) = + FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_TempSensor', 'none' ); + + ### erwartetes Ergebnis + # DEVICE:READING + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{device} = $device; + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{reading} = + ( $reading ne 'none' ? $reading : 'temperature' ); + + return $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{device}; +} + +sub getTempSensorReading { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{reading} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{LASTGETTIME} + ) + and ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{LASTGETTIME} ) + < 2 + ); + $shutters->_getTempSensor; + + return ( + defined( $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{reading} ) + ? $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{reading} + : 'temperature' + ); +} + sub _getBrightnessSensor { my $self = shift; @@ -4949,7 +5171,7 @@ sub getMonitoredDevs { sub getOutTemp { my $self = shift; - return ReadingsVal( $ascDev->_getTempSensor, $ascDev->getTempReading, + return ReadingsVal( $ascDev->_getTempSensor, $ascDev->getTempSensorReading, -100 ); } @@ -5186,7 +5408,7 @@ sub _getTempSensor { return $self->{ASC_tempSensor}->{device}; } -sub getTempReading { +sub getTempSensorReading { my $self = shift; my $name = $self->{name}; @@ -5447,9 +5669,7 @@ sub getblockAscDrivesAfterManual { the ASC_Expert attribute is set to 1. -
  • hardLockOut on|off - controls the global hard lock out protection for shutters, whose - ASC_LockOut - attribute is set accordingly. See the attributes section below. +
  • hardLockOut on|off -
  • hardLockOut - on/off - Aktiviert den hardwareseitigen Aussperrschutz für die Rollläden, bei denen das Attributs ASC_LockOut entsprechend auf hard gesetzt ist. Mehr Informationen in der Beschreibung bei den Attributen für die Rollladengeräten.
  • partyMode on|off - controls the global party mode for shutters. Every shutters whose ASC_Partymode attribute is set to on, is not longer controlled by ASC. The last saved @@ -5741,6 +5961,12 @@ sub getblockAscDrivesAfterManual {
  • ASC_Self_Defense_Exclude on|off - If set to on, the shutter will not be closed if the self defense mode is activated and residents are absent. Defaults to off.
  • +
  • ASC_Self_Defense_Mode - absent/gone - which Residents status Self Defense should become + active without the window being open. (default: gone) +
  • +
  • ASC_Self_Defense_AbsentDelay - How many seconds should drive in Self Defense be delayed at + Residents absent. (default: 300) +
  • ASC_ShuttersPlace window|terrace - If set to terrace, and the residents device is set to gone, and selfDefense is activated, the shutter will be closed. If set to window, will not. Defaults to window. @@ -5960,6 +6186,14 @@ sub getblockAscDrivesAfterManual { ASCenable Does ASC control the shutter? + + PrivacyDownStatus + Is the shutter currently in privacyDown mode + + + outTemp + Current temperature of a configured temperature device, return -100 is no device configured +

    Data points of the ASC device @@ -5973,7 +6207,7 @@ sub getblockAscDrivesAfterManual { - + @@ -6039,7 +6273,7 @@ sub getblockAscDrivesAfterManual {
  • partyMode - on/off - Partymodus-Status
  • ascEnable - on/off - globale ASC Steuerung bei den Rollläden aktiv oder inaktiv
  • controlShading - on/off - globale Beschattungsfunktion aktiv oder inaktiv
  • -
  • hardLockOut - on/off - Aussperrschutz-Status
  • +
  • hardLockOut - on/off - Status des hardwareseitigen Aussperrschutzes / gilt nur für Rolläden mit dem Attribut bei denen das Attributs ASC_LockOut entsprechend auf hard gesetzt ist
  • room_... - Auflistung aller Rollläden, die in den jeweiligen Rämen gefunden wurde. Beispiel: room_Schlafzimmer: Terrasse
  • selfDefense - Selbstschutz-Status
  • state - Status des ASC-Devices: active, enabled, disabled oder weitere Statusinformationen
  • @@ -6061,7 +6295,7 @@ sub getblockAscDrivesAfterManual {
  • ascEnable - on/off - Aktivieren oder deaktivieren der globalen ASC Steuerung
  • controlShading - on/off - Aktiviert oder deaktiviert die globale Beschattungssteuerung
  • createNewNotifyDev - Legt die interne Struktur für NOTIFYDEV neu an. Diese Funktion steht nur zur Verfügung, wenn Attribut ASC_expert auf 1 gesetzt ist.
  • -
  • hardLockOut - on/off - Aktiviert den globalen Aussperrschutz für die Rollläden, bei denen das Attributs ASC_LockOut entsprechend gesetzt ist. Mehr Informationen in der Beschreibung bei den Attributen für die Rollladengeräten.
  • +
  • hardLockOut - on/off - Aktiviert den hardwareseitigen Aussperrschutz für die Rollläden, bei denen das Attributs ASC_LockOut entsprechend auf hard gesetzt ist. Mehr Informationen in der Beschreibung bei den Attributen für die Rollladengeräten.
  • partyMode - on/off - Aktiviert den globalen Partymodus. Alle Rollladen-Geräten, in welchen das Attribut ASC_Partymode auf on gesetzt ist, werden durch ASC nicht mehr gesteuert. Der letzte Schaltbefehl, der bspw. durch ein Fensterevent oder Wechsel des Bewohnerstatus an die Rollläden gesendet wurde, wird beim Deaktivieren des Partymodus ausgeführt
  • renewSetSunriseSunsetTimer - erneuert bei allen Rollläden die Zeiten für Sonnenauf- und -untergang und setzt die internen Timer neu.
  • scanForShutters - Durchsucht das System nach GerätenRo mit dem Attribut ASC = 1 oder ASC = 2
  • @@ -6174,6 +6408,9 @@ sub getblockAscDrivesAfterManual {
  • ASC_WindProtection - on/off - soll der Rollladen beim Regenschutz beachtet werden. on=JA, off=NEIN.
  • ASC_Roommate_Device - mit Komma getrennte Namen des/der Roommate Device/s, welche den/die Bewohner des Raumes vom Rollladen wiedergibt. Es macht nur Sinn in Schlaf- oder Kinderzimmern (default: none)
  • ASC_Roommate_Reading - das Reading zum Roommate Device, welches den Status wieder gibt (default: state)
  • +
  • ASC_Self_Defense_Exclude - on/off - bei on Wert wird dieser Rollladen bei aktiven Self Defense und offenen Fenster nicht runter gefahren, wenn Residents absent ist. (default: off)
  • +
  • ASC_Self_Defense_Mode - absent/gone - ab welchen Residents Status soll Selfdefense aktiv werden ohne das Fenster auf sind. (default: gone)
  • +
  • ASC_Self_Defense_AbsentDelay - um wie viele Sekunden soll das fahren in Selfdefense bei Residents absent verzögert werden. (default: 300)
  • ASC_Self_Defense_Exclude - on/off - bei on Wert wird dieser Rollladen bei aktiven Self Defense und offenen Fenster nicht runter gefahren, wenn Residents absent ist. (default: off)
    • Beschreibung der Beschattungsfunktion @@ -6239,6 +6476,8 @@ sub getblockAscDrivesAfterManual {
    + +
    outTempCurrent temperature of a configured temperature deviceCurrent temperature of a configured temperature device, return -100 is no device configured
    ResidentsStatus
    StatusPosition des Rollladens
    ASCenableAbfrage ob für den Rollladen die ASC Steuerung aktiv ist.
    IsDayAbfrage ob das Rollo im Tag oder Nachtmodus ist. Also nach Sunset oder nach Sunrise
    PrivacyDownStatusAbfrage ob das Rollo aktuell im PrivacyDown Status steht
    OutTempaktuelle Außentemperatur sofern ein Sensor definiert ist, wenn nicht kommt -100 als Wert zurück

    Übersicht für das ASC Device @@ -6247,7 +6486,7 @@ sub getblockAscDrivesAfterManual {
    - + @@ -6277,6 +6516,8 @@ sub getblockAscDrivesAfterManual { ], "release_status": "under develop", "license": "GPL_2", + "version": "v0.6.20", + "x_developmentversion": "v0.6.19.34", "author": [ "Marko Oldenburg " ],
    GetterErläuterung
    outTemp aktuelle Außentemperatur sofern Sensor definiert
    outTemp aktuelle Außentemperatur sofern ein Sensor definiert ist, wenn nicht kommt -100 als Wert zurück
    ResidentsStatusaktueller Status des Residents Devices
    ResidentsLastStatusletzter Status des Residents Devices
    AzimuthAzimut Wert