diff --git a/fhem/CHANGED b/fhem/CHANGED index 3a68de235..4e0d4446c 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. + - bugfix: 73_AutoShuttersControl: fix logical bugs, + change Antifreeze values - change: DOIFtools: forced change to li-tags in direct help (Forum #93243) - feature: 74_AMADautomagicFlowset: new readings for Caller - bugfix: 73_AutoShuttersControl: fix multiple NOTIFYDEV entry's then set diff --git a/fhem/FHEM/73_AutoShuttersControl.pm b/fhem/FHEM/73_AutoShuttersControl.pm index 7e5e3d7e5..17a02c8a5 100644 --- a/fhem/FHEM/73_AutoShuttersControl.pm +++ b/fhem/FHEM/73_AutoShuttersControl.pm @@ -8,6 +8,9 @@ # Special thanks goes to: # - Bernd (Cluni) this module is based on the logic of his script "Rollladensteuerung für HM/ROLLO inkl. Abschattung und Komfortfunktionen in Perl" (https://forum.fhem.de/index.php/topic,73964.0.html) # - Beta-User for many tests and ideas +# - pc1246 write english commandref +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs # # # This script is free software; you can redistribute it and/or modify @@ -38,7 +41,7 @@ package main; use strict; use warnings; -my $version = "0.2.0.5"; +my $version = "0.2.0.6"; sub AutoShuttersControl_Initialize($) { my ($hash) = @_; @@ -61,12 +64,8 @@ sub AutoShuttersControl_Initialize($) { . "ASC_brightnessMaxVal " . "ASC_autoShuttersControlMorning:on,off " . "ASC_autoShuttersControlEvening:on,off " - . "ASC_autoShuttersControl_Shading:on,off " + . "ASC_autoShuttersControlShading:on,off " . "ASC_autoShuttersControlComfort:on,off " - . "ASC_sunPosDevice " - . "ASC_sunPosReading " - . "ASC_sunElevationDevice " - . "ASC_sunElevationReading " . "ASC_residentsDevice " . "ASC_residentsDeviceReading " . "ASC_rainSensorDevice " @@ -166,43 +165,44 @@ my %userAttrList = ( 'ASC_Time_Down_Late' => '22:30', 'ASC_WindowRec' => 'none', 'ASC_Ventilate_Window_Open:on,off' => 'on', - 'ASC_lock-out:soft,hard' => 'soft', - 'ASC_lock-outCmd:inhibit,blocked' => 'none', + 'ASC_LockOut:soft,hard,off' => 'off', + 'ASC_LockOut_Cmd:inhibit,blocked' => 'none', # 'ASC_Shading_Direction' => 178, -# 'ASC_Shading_Pos:10,20,30,40,50,60,70,80,90,100' => 30, -# 'ASC_Shading:on,off,delayed,present,absent' => 'off', -# 'ASC_Shading_Pos_after_Shading:-1,0,10,20,30,40,50,60,70,80,90,100' => -1, +# 'ASC_Shading_Pos:10,20,30,40,50,60,70,80,90,100' => [ '', 70, 30 ], +# 'ASC_Shading_Mode:on,off,home,absent' => 'off', # 'ASC_Shading_Angle_Left:0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90' # => 85, # 'ASC_Shading_Angle_Right:0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90' # => 85, - 'ASC_Shading_Brightness_Sensor' => 'none', - 'ASC_Shading_Brightness_Reading' => 'brightness', - - # 'ASC_Shading_StateChange_Sunny' => '6000', - # 'ASC_Shading_StateChange_Cloudy' => '4000', - # 'ASC_Shading_WaitingPeriod' => 20, - # 'ASC_Shading_Min_Elevation' => 'none', - # 'ASC_Shading_Min_OutsideTemperature' => 18, - # 'ASC_Shading_BlockingTime_After_Manual' => 20, - # 'ASC_Shading_BlockingTime_Twilight' => 45, - # 'ASC_Shading_Fast_Open:on,off' => 'none', - # 'ASC_Shading_Fast_Close:on,off' => 'none', +# 'ASC_Shading_Brightness_Sensor' => 'none', +# 'ASC_Shading_Brightness_Reading' => 'brightness', +# +# 'ASC_Shading_StateChange_Sunny' => '6000', +# 'ASC_Shading_StateChange_Cloudy' => '4000', +# 'ASC_Shading_WaitingPeriod' => 20, +# 'ASC_Shading_Min_Elevation' => 'none', +# 'ASC_Shading_Min_OutsideTemperature' => 18, +# 'ASC_Shading_BlockingTime_After_Manual' => 20, +# 'ASC_Shading_BlockingTime_Twilight' => 45, +# 'ASC_Shading_Fast_Open:on,off' => 'none', +# 'ASC_Shading_Fast_Close:on,off' => 'none', 'ASC_Drive_Offset' => -1, 'ASC_WindowRec_subType:twostate,threestate' => 'twostate', 'ASC_ShuttersPlace:window,terrace' => 'window', 'ASC_Ventilate_Pos:10,20,30,40,50,60,70,80,90,100' => [ '', 70, 30 ], - 'ASC_Pos_after_ComfortOpen:0,10,20,30,40,50,60,70,80,90,100' => + 'ASC_ComfortOpen_Pos:0,10,20,30,40,50,60,70,80,90,100' => [ '', 20, 80 ], 'ASC_GuestRoom:on,off' => 'none', - 'ASC_Antifreeze:off,on' => 'off', + 'ASC_Antifreeze:off,soft,hard,am,pm' => 'off', + 'ASC_AntifreezePos: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' => 'off', 'ASC_Roommate_Device' => 'none', 'ASC_Roommate_Reading' => 'state', 'ASC_Self_Defense_Exclude:on,off' => 'off', 'ASC_BrightnessMinVal' => -1, 'ASC_BrightnessMaxVal' => -1, + 'ASC_WiggleValue' => 5, ); my %posSetCmds = ( @@ -247,6 +247,7 @@ sub Define($$) { "please set attribute ASC with value 1 or 2 in all auto controlled shutter devices and then execute 'set DEVICENAME scanForShutters'", 1 ); + CommandAttr( undef, $name . ' room ASC' ) if ( AttrVal( $name, 'room', 'none' ) eq 'none' ); CommandAttr( undef, $name . ' icon fts_shutter_automatic' ) @@ -262,7 +263,7 @@ sub Define($$) { CommandAttr( undef, $name . ' ASC_temperatureReading temperature' ) if ( $ascDev->getTempReading eq 'none' ); CommandAttr( undef, $name . ' ASC_freezeTemp 3' ) - if ( $ascDev->getAntifreezeTemp eq 'none' ); + if ( $ascDev->getFreezeTemp eq 'none' ); 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' @@ -333,7 +334,7 @@ sub Notify($$) { my $events = deviceEvents( $dev, 1 ); return if ( !$events ); - Log3( $name, 5, + Log3( $name, 4, "AutoShuttersControl ($name) - Devname: " . $devname . " Name: " @@ -363,13 +364,6 @@ sub Notify($$) { if ( $ascDev->getSunriseTimeWeHoliday eq 'none' ); readingsSingleUpdate( $hash, 'selfDefense', 'off', 0 ) if ( $ascDev->getSelfDefense eq 'none' ); - CommandDeleteReading( undef, $name . ' selfDefence' ) - if ( ReadingsVal( $name, 'selfDefence', 'none' ) ne 'none' ) - ; # temporär kann später entfernt werden. - if ( devspec2array('TYPE=(Astro|Twilight)') > 0 ) { - CommandAttr( undef, $name . ' ASC_twilightDevice ' . ( devspec2array('TYPE=(Astro|Twilight)'))[0] ) - if ( AttrVal($name,'ASC_twilightDevice','none') eq 'none' ); - } # Ist der Event ein globaler und passt zum Rest der Abfrage oben wird nach neuen Rolläden Devices gescannt und eine Liste im Rolladenmodul sortiert nach Raum generiert ShuttersDeviceScan($hash) @@ -389,10 +383,13 @@ sub Notify($$) { InternalTimer( gettimeofday() + 3, 'AutoShuttersControl::RenewSunRiseSetShuttersTimer', $hash ); + InternalTimer( gettimeofday() + 5, + 'AutoShuttersControl::AutoSearchTwilightDev', + $hash ); } } elsif ( grep /^partyMode:.off$/, @{$events} ) { - PartyModeEventProcessing($hash); + EventProcessingPartyMode($hash); } elsif ( grep /^sunriseTimeWeHoliday:.(on|off)$/, @{$events} ) { RenewSunRiseSetShuttersTimer($hash); @@ -402,11 +399,11 @@ sub Notify($$) { { # Kommt ein globales Event und beinhaltet folgende Syntax wird die Funktion zur Verarbeitung aufgerufen if ( grep -/^(ATTR|DELETEATTR)\s(.*ASC_Roommate_Device|.*ASC_WindowRec|.*ASC_residentsDevice|.*ASC_rainSensorDevice|.*ASC_Shading_Brightness_Sensor)(\s.*|$)/, +/^(ATTR|DELETEATTR)\s(.*ASC_Roommate_Device|.*ASC_WindowRec|.*ASC_residentsDevice|.*ASC_rainSensorDevice|.*ASC_Shading_Brightness_Sensor|.*ASC_twilightDevice)(\s.*|$)/, @{$events} ) { - GeneralEventProcessing( $hash, undef, join( ' ', @{$events} ) ); + EventProcessingGeneral( $hash, undef, join( ' ', @{$events} ) ); } elsif ( grep @@ -414,20 +411,20 @@ sub Notify($$) { @{$events} ) { - GeneralEventProcessing( $hash, undef, join( ' ', @{$events} ) ); + EventProcessingGeneral( $hash, undef, join( ' ', @{$events} ) ); } } elsif ( grep /^($posReading):\s\d+$/, @{$events} ) { - ShuttersEventProcessing( $hash, $devname, join( ' ', @{$events} ) ); + EventProcessingShutters( $hash, $devname, join( ' ', @{$events} ) ); } else { - GeneralEventProcessing( $hash, $devname, join( ' ', @{$events} ) ) + EventProcessingGeneral( $hash, $devname, join( ' ', @{$events} ) ) ; # bei allen anderen Events wird die entsprechende Funktion zur Verarbeitung aufgerufen } return; } -sub GeneralEventProcessing($$$) { +sub EventProcessingGeneral($$$) { my ( $hash, $devname, $events ) = @_; my $name = $hash->{NAME}; @@ -436,30 +433,37 @@ sub GeneralEventProcessing($$$) { while ( my ( $device, $deviceAttr ) = each %{ $hash->{monitoredDevs}{$devname} } ) { - WindowRecEventProcessing( $hash, $device, $events ) + EventProcessingWindowRec( $hash, $device, $events ) if ( $deviceAttr eq 'ASC_WindowRec' ) ; # ist es ein Fensterdevice wird die Funktion gestartet - RoommateEventProcessing( $hash, $device, $events ) + EventProcessingRoommate( $hash, $device, $events ) if ( $deviceAttr eq 'ASC_Roommate_Device' ) ; # ist es ein Bewohner Device wird diese Funktion gestartet - ResidentsEventProcessing( $hash, $device, $events ) + EventProcessingResidents( $hash, $device, $events ) if ( $deviceAttr eq 'ASC_residentsDevice' ); - RainEventProcessing( $hash, $device, $events ) + EventProcessingRain( $hash, $device, $events ) if ( $deviceAttr eq 'ASC_rainSensorDevice' ); + EventProcessingTwilightDevice( $hash, $device, $events ) + if ( $deviceAttr eq 'ASC_twilightDevice' ); $shutters->setShuttersDev($device) if ( $deviceAttr eq 'ASC_Shading_Brightness_Sensor' ); - BrightnessEventProcessing( $hash, $device, $events ) - if ( - $deviceAttr eq 'ASC_Shading_Brightness_Sensor' - and ( $shutters->getDown eq 'brightness' - or $shutters->getUp eq 'brightness' ) - ); + + if ( + $deviceAttr eq 'ASC_Shading_Brightness_Sensor' + and ( $shutters->getDown eq 'brightness' + or $shutters->getUp eq 'brightness' ) + ) { + EventProcessingBrightness( $hash, $device, $events ); + } + elsif ( $deviceAttr eq 'ASC_Shading_Brightness_Sensor' ) { + EventProcessingShadingBrightness( $hash, $device, $events ); + } } } else { # alles was kein Devicenamen mit übergeben hat landet hier if ( $events =~ -m#^ATTR\s(.*)\s(ASC_Roommate_Device|ASC_WindowRec|ASC_residentsDevice|ASC_rainSensorDevice|ASC_Shading_Brightness_Sensor)\s(.*)$# +m#^ATTR\s(.*)\s(ASC_Roommate_Device|ASC_WindowRec|ASC_residentsDevice|ASC_rainSensorDevice|ASC_Shading_Brightness_Sensor|ASC_twilightDevice)\s(.*)$# ) { # wurde den Attributen unserer Rolläden ein Wert zugewiesen ? AddNotifyDev( $hash, $3, $1, $2 ) if ( $3 ne 'none' ); @@ -467,7 +471,7 @@ m#^ATTR\s(.*)\s(ASC_Roommate_Device|ASC_WindowRec|ASC_residentsDevice|ASC_rainSe "AutoShuttersControl ($name) - EventProcessing: ATTR" ); } elsif ( $events =~ -m#^DELETEATTR\s(.*)\s(ASC_Roommate_Device|ASC_WindowRec|ASC_residentsDevice|ASC_rainSensorDevice|ASC_Shading_Brightness_Sensor)$# +m#^DELETEATTR\s(.*)\s(ASC_Roommate_Device|ASC_WindowRec|ASC_residentsDevice|ASC_rainSensorDevice|ASC_Shading_Brightness_Sensor|ASC_twilightDevice)$# ) { # wurde das Attribut unserer Rolläden gelöscht ? Log3( $name, 4, @@ -597,29 +601,6 @@ sub ShuttersDeviceScan($) { push( @{ $hash->{helper}{shuttersList} }, $_ ) ; ## einem Hash wird ein Array zugewiesen welches die Liste der erkannten Rollos beinhaltet - delFromDevAttrList( $_, 'ASC_Up:time,astro' ) - if ( - AttrVal( $_, 'userattr', 'none' ) =~ /\sASC_Up:time,astro\sASC_/ ) - ; # temporär muss später gelöscht werden ab Version 0.1.80 - delFromDevAttrList( $_, 'ASC_Down:time,astro' ) - if ( - AttrVal( $_, 'userattr', 'none' ) =~ /\sASC_Down:time,astro\sASC_/ ) - ; # temporär muss später gelöscht werden ab Version 0.1.80 - delFromDevAttrList( $_, 'ASC_Mode_Up:absent,always,off' ) - if ( AttrVal( $_, 'userattr', 'none' ) =~ - /\sASC_Mode_Up:absent,always,off\sASC_/ ) - ; # temporär muss später gelöscht werden ab Version 0.1.81 - delFromDevAttrList( $_, 'ASC_Mode_Down:absent,always,off' ) - if ( AttrVal( $_, 'userattr', 'none' ) =~ - /\sASC_Mode_Down:absent,always,off\sASC_/ ) - ; # temporär muss später gelöscht werden ab Version 0.1.81 - delFromDevAttrList( $_, 'ASC_Self_Defence_Exclude:on,off' ) - ; # temporär muss später gelöscht werden ab Version 0.1.80 - delFromDevAttrList( $_, 'ASC_Offset_Minutes_Morning' ) - ; # temporär muss später gelöscht werden ab Version 0.1.81 - delFromDevAttrList( $_, 'ASC_Offset_Minutes_Evening' ) - ; # temporär muss später gelöscht werden ab Version 0.1.81 - delFromDevAttrList( $_, 'ASC_Direction' ) ; # temporär muss später gelöscht werden ab Version 0.1.89 delFromDevAttrList( $_, @@ -658,15 +639,18 @@ sub ShuttersDeviceScan($) { ; # temporär muss später gelöscht werden ab Version 0.1.89 delFromDevAttrList( $_, 'ASC_Pos_Cmd' ) ; # temporär muss später gelöscht werden ab Version 0.1.93 + delFromDevAttrList( $_, 'ASC_lock-out:soft,hard' ) + ; # temporär muss später gelöscht werden ab Version 0.2.0.6 + delFromDevAttrList( $_, 'ASC_lock-outCmd:inhibit,blocked' ) + ; # temporär muss später gelöscht werden ab Version 0.2.0.6 + delFromDevAttrList( $_, 'ASC_Pos_after_ComfortOpen:0,10,20,30,40,50,60,70,80,90,100' ) + ; # temporär muss später gelöscht werden ab Version 0.2.0.6 - CommandDeleteReading( undef, - $_ . ' .AutoShuttersControl_InternalTimerFuncHash' ) - ; # temporär muss später gelöscht werden ab Version 0.1.81 - CommandDeleteReading( undef, - $_ . ' .AutoShuttersControl_LastPosition' ) - ; # temporär muss später gelöscht werden ab Version 0.1.81 - CommandDeleteReading( undef, $_ . ' .AutoShuttersControl_DelayCmd' ) - ; # temporär muss später gelöscht werden ab Version 0.1.82 + delFromDevAttrList( $_, 'ASC_Antifreeze:off,on' ) + if ( AttrVal( $_, 'ASC_Antifreeze', 'on' ) eq 'on' + or AttrVal( $_, 'ASC_Antifreeze', 'on' ) eq 'off' + ) + ; # temporär muss später gelöscht werden ab Version 0.2.0.6 $shuttersList = $shuttersList . ',' . $_; $shutters->setShuttersDev($_); @@ -679,6 +663,7 @@ sub ShuttersDeviceScan($) { # $hash->{NOTIFYDEV} = $hash->{NOTIFYDEV} . $shuttersList; $hash->{NOTIFYDEV} = "global," . $name . $shuttersList; + if ( $ascDev->getMonitoredDevs ne 'none' ) { $hash->{monitoredDevs} = eval { decode_json( $ascDev->getMonitoredDevs ) }; @@ -825,7 +810,7 @@ sub DeleteNotifyDev($@) { } ## Sub zum steuern der Rolläden bei einem Fenster Event -sub WindowRecEventProcessing($@) { +sub EventProcessingWindowRec($@) { my ( $hash, $shuttersDev, $events ) = @_; my $name = $hash->{NAME}; @@ -838,6 +823,11 @@ sub WindowRecEventProcessing($@) { ? $shutters->getStatus > $shutters->getVentilatePos : $shutters->getStatus < $shutters->getVentilatePos ); + my $queryShuttersPosWinRecComfort = ( + $shutters->getShuttersPosCmdValueNegate + ? $shutters->getStatus > $shutters->getComfortOpenPos + : $shutters->getStatus < $shutters->getComfortOpenPos + ); if ( $shutters->getDelayCmd ne 'none' ) { # Es wird geschaut ob wärend der Fenster offen Phase ein Fahrbefehl über das Modul kam,wenn ja wird dieser aus geführt @@ -863,9 +853,10 @@ sub WindowRecEventProcessing($@) { elsif ( $1 eq 'closed' ) # wenn nicht dann wird entsprechend dem Fensterkontakt Event der Rolladen geschlossen oder zum lüften geöffnet { + $shutters->setLastDrive('window closed'); ShuttersCommandSet( $hash, $shuttersDev, $shutters->getClosedPos ) if ( $shutters->getStatus == $shutters->getVentilatePos - or $shutters->getStatus == $shutters->getPosAfterComfortOpen ); + or $shutters->getStatus == $shutters->getComfortOpenPos ); } elsif ( ( @@ -883,17 +874,17 @@ sub WindowRecEventProcessing($@) { elsif ( $1 eq 'open' and $shutters->getSubTyp eq 'threestate' and $ascDev->getAutoShuttersControlComfort eq 'on' - and $queryShuttersPosWinRecTilted ) + and $queryShuttersPosWinRecComfort ) { $shutters->setLastDrive('comfort open'); ShuttersCommandSet( $hash, $shuttersDev, - $shutters->getPosAfterComfortOpen ); + $shutters->getComfortOpenPos ); } } } ## Sub zum steuern der Rolladen bei einem Bewohner/Roommate Event -sub RoommateEventProcessing($@) { +sub EventProcessingRoommate($@) { my ( $hash, $shuttersDev, $events ) = @_; my $name = $hash->{NAME}; @@ -902,10 +893,10 @@ sub RoommateEventProcessing($@) { if ( $events =~ m#$reading:\s(absent|gotosleep|asleep|awoken|home)# ) { Log3( $name, 4, -"AutoShuttersControl ($name) - RoommateEventProcessing: $shutters->getRoommatesReading" + "AutoShuttersControl ($name) - EventProcessingRoommate: " . $shutters->getRoommatesReading ); Log3( $name, 4, -"AutoShuttersControl ($name) - RoommateEventProcessing: $shuttersDev und Events $events" + "AutoShuttersControl ($name) - EventProcessingRoommate: $shuttersDev und Events $events" ); if ( @@ -918,7 +909,9 @@ sub RoommateEventProcessing($@) { or $shutters->getModeUp eq 'home' ) ) { - + Log3( $name, 4, + "AutoShuttersControl ($name) - EventProcessingRoommate_1: $shuttersDev und Events $events" + ); if ( ( $shutters->getRoommatesLastStatus eq 'asleep' @@ -927,6 +920,9 @@ sub RoommateEventProcessing($@) { and IsDay( $hash, $shuttersDev ) ) { + Log3( $name, 4, + "AutoShuttersControl ($name) - EventProcessingRoommate_2: $shuttersDev und Events $events" + ); $shutters->setLastDrive('roommate awoken'); ShuttersCommandSet( $hash, $shuttersDev, $shutters->getOpenPos ); @@ -947,14 +943,18 @@ sub RoommateEventProcessing($@) { { if ( not IsDay( $hash, $shuttersDev ) ) { my $position; + $shutters->setLastDrive('roommate home'); + if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0 or $shutters->getVentilateOpen eq 'off' ) { $position = $shutters->getClosedPos; } - else { $position = $shutters->getVentilatePos; } - - $shutters->setLastDrive('roommate home'); + else { + $position = $shutters->getVentilatePos; + $shutters->setLastDrive($shutters->getLastDrive . ' - ventilate mode'); + } + ShuttersCommandSet( $hash, $shuttersDev, $position ); } elsif ( IsDay( $hash, $shuttersDev ) @@ -976,14 +976,18 @@ sub RoommateEventProcessing($@) { ) { my $position; + $shutters->setLastDrive('roommate asleep'); + if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0 or $shutters->getVentilateOpen eq 'off' ) { $position = $shutters->getClosedPos; } - else { $position = $shutters->getVentilatePos; } + else { + $position = $shutters->getVentilatePos; + $shutters->setLastDrive($shutters->getLastDrive . ' - ventilate mode'); + } - $shutters->setLastDrive('roommate asleep'); ShuttersCommandSet( $hash, $shuttersDev, $position ); } elsif ( $shutters->getModeDown eq 'absent' @@ -995,7 +999,7 @@ sub RoommateEventProcessing($@) { } } -sub ResidentsEventProcessing($@) { +sub EventProcessingResidents($@) { my ( $hash, $device, $events ) = @_; my $name = $device; @@ -1059,6 +1063,8 @@ sub ResidentsEventProcessing($@) { and $shutters->getRoommatesStatus eq 'none' and ( $shutters->getModeDown eq 'home' or $shutters->getModeDown eq 'always' ) + and ( $ascDev->getResidentsLastStatus ne 'asleep' + or $ascDev->getResidentsLastStatus ne 'awoken' ) ) { $shutters->setLastDrive('residents home'); @@ -1097,7 +1103,7 @@ sub ResidentsEventProcessing($@) { } } -sub RainEventProcessing($@) { +sub EventProcessingRain($@) { my ( $hash, $device, $events ) = @_; my $name = $device; my $reading = $ascDev->getRainSensorReading; @@ -1129,22 +1135,22 @@ sub RainEventProcessing($@) { } } -sub BrightnessEventProcessing($@) { +sub EventProcessingBrightness($@) { my ( $hash, $shuttersDev, $events ) = @_; my $name = $hash->{NAME}; $shutters->setShuttersDev($shuttersDev); - return - unless ( - int( gettimeofday() / 86400 ) != - int( computeAlignTime( '24:00', $shutters->getTimeUpEarly ) / 86400 ) - and int( gettimeofday() / 86400 ) == - int( computeAlignTime( '24:00', $shutters->getTimeUpLate ) / 86400 ) - or int( gettimeofday() / 86400 ) != - int( computeAlignTime( '24:00', $shutters->getTimeDownEarly ) / 86400 ) - and int( gettimeofday() / 86400 ) == - int( computeAlignTime( '24:00', $shutters->getTimeDownLate ) / 86400 ) - ); + return EventProcessingShadingBrightness($hash, $shuttersDev, $events) + unless ( + int( gettimeofday() / 86400 ) != + int( computeAlignTime( '24:00', $shutters->getTimeUpEarly ) / 86400 ) + and int( gettimeofday() / 86400 ) == + int( computeAlignTime( '24:00', $shutters->getTimeUpLate ) / 86400 ) + or int( gettimeofday() / 86400 ) != + int( computeAlignTime( '24:00', $shutters->getTimeDownEarly ) / 86400 ) + and int( gettimeofday() / 86400 ) == + int( computeAlignTime( '24:00', $shutters->getTimeDownLate ) / 86400 ) + ); my $reading = $shutters->getShadingBrightnessReading; if ( $events =~ m#$reading:\s(\d+)# ) { @@ -1168,7 +1174,7 @@ sub BrightnessEventProcessing($@) { ) { Log3( $name, 4, -"AutoShuttersControl ($shuttersDev) - BrightnessEventProcessing: Steuerung für Morgens" +"AutoShuttersControl ($shuttersDev) - EventProcessingBrightness: Steuerung für Morgens" ); my $homemode = $shutters->getRoommatesStatus; $homemode = $ascDev->getResidentsStatus @@ -1179,8 +1185,7 @@ sub BrightnessEventProcessing($@) { or $homemode eq 'none' or $shutters->getModeUp eq 'always' ) { - ShuttersCommandSet( $hash, $shuttersDev, $shutters->getOpenPos ) - if ( + if ( ( $shutters->getRoommatesStatus eq 'home' or $shutters->getRoommatesStatus eq 'awoken' @@ -1191,7 +1196,9 @@ sub BrightnessEventProcessing($@) { and $ascDev->getSelfDefense eq 'off' or ( $ascDev->getSelfDefense eq 'on' and CheckIfShuttersWindowRecOpen($shuttersDev) == 0 ) - ); + ) { + ShuttersCommandSet( $hash, $shuttersDev, $shutters->getOpenPos ); + } else { EventProcessingShadingBrightness($hash, $shuttersDev, $events); } } } elsif ( @@ -1206,7 +1213,7 @@ sub BrightnessEventProcessing($@) { ) { Log3( $name, 4, -"AutoShuttersControl ($shuttersDev) - BrightnessEventProcessing: Steuerung für Abends" +"AutoShuttersControl ($shuttersDev) - EventProcessingBrightness: Steuerung für Abends" ); my $posValue; @@ -1222,15 +1229,84 @@ sub BrightnessEventProcessing($@) { if ( $homemode eq 'none' ); $shutters->setLastDrive('minimum brightness threshold fell below'); - ShuttersCommandSet( $hash, $shuttersDev, $shutters->getClosedPos ) - if ( $shutters->getModeDown eq $homemode - or $homemode eq 'none' - or $shutters->getModeDown eq 'always' ); + if ( $shutters->getModeDown eq $homemode + or $homemode eq 'none' + or $shutters->getModeDown eq 'always' + ) { + ShuttersCommandSet( $hash, $shuttersDev, $shutters->getClosedPos ); + } else { EventProcessingShadingBrightness($hash, $shuttersDev, $events); } + } + } else { EventProcessingShadingBrightness($hash, $shuttersDev, $events); } +} + +sub EventProcessingShadingBrightness($@) { + my ( $hash, $shuttersDev, $events ) = @_; + my $name = $hash->{NAME}; + $shutters->setShuttersDev($shuttersDev); + my $reading = $shutters->getShadingBrightnessReading; + + if ( $events =~ m#$reading:\s(\d+)# ) { + ShadingProcessing($hash,$shuttersDev,$ascDev->getAzimuth,$ascDev->getElevation,$1,$ascDev->getOutTemp,$shutters->getDirection,$shutters->getShadingAngleLeft,$shutters->getShadingAngleRight) + if ( $shutters->getShadingMode eq 'on' or $shutters->getShadingMode eq $ascDev->getResidentsStatus and IsDay( $hash, $shuttersDev ) ); + } +} + +sub EventProcessingTwilightDevice($@) { + my ( $hash, $device, $events ) = @_; + +# Twilight +# azimuth = azimuth = Sonnenwinkel +# elevation = elevation = Sonnenhöhe +# +# Astro +# SunAz = azimuth = Sonnenwinkel +# SunAlt = evaluation = Sonnenhöhe + + if ( $events =~ m#(azimuth|evaluation|SunAz|SunAlt):\s(\d+.\d+)# ) { + my $name = $device; + my ($azimuth,$elevation, $outTemp, $brightness); + + $azimuth = $2 if ( $1 eq 'azimuth' or $1 eq 'SunAz' ); + $elevation = $2 if ( $1 eq 'evaluation' or $1 eq 'SunAlt' ); + + $azimuth = $ascDev->getAzimuth if (not defined($azimuth) and not $azimuth ); + $elevation = $ascDev->getElevation if (not defined($elevation) and not $elevation ); + + foreach my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) { + $shutters->setShuttersDev($shuttersDev); + ShadingProcessing($hash,$shuttersDev,$azimuth,$elevation,$shutters->getBrightness,$ascDev->getOutTemp,$shutters->getDirection,$shutters->getShadingAngleLeft,$shutters->getShadingAngleRight) + if ( ($shutters->getShadingMode eq 'on' or $shutters->getShadingMode eq $ascDev->getResidentsStatus) and IsDay( $hash, $shuttersDev ) ); } } } -sub PartyModeEventProcessing($) { +sub ShadingProcessing($@) { + my ($hash,$shuttersDev,$azimuth,$elevation,$brightness,$outTemp,$shuttersDirection,$shuttersShadingAngleLeft,$shuttersShadingAngleRight) = @_; + my $name = $hash->{NAME}; + +# Log3( $name, 1, +# "AutoShuttersControl ($name) - Shading Processing, Rollladen: " . $shuttersDev . " Azimuth: " . $azimuth . " Elevation: " . $elevation . " Brightness: " . $brightness . " OutTemp: " . $outTemp +# ); +# +# return +# if ( $azimuth == -1 or $elevation == -1 or $brightness == -1 or $outTemp == -100 ); +# +# +# # brightness -1 +# # outTemp -100 +# # azimuth -1 +# # elevation -1 +# +# +# +# +# +# Log3( $name, 1, +# "AutoShuttersControl ($name) - Shading Processing hinter dem return"); + +} + +sub EventProcessingPartyMode($) { my ($hash) = @_; my $name = $hash->{NAME}; @@ -1241,17 +1317,18 @@ sub PartyModeEventProcessing($) { and $shutters->getSubTyp eq 'threestate' ) { Log3( $name, 4, -"AutoShuttersControl ($name) - PartyModeEventProcessing Fenster offen" +"AutoShuttersControl ($name) - EventProcessingPartyMode Fenster offen" ); $shutters->setDelayCmd( $shutters->getClosedPos ); Log3( $name, 4, -"AutoShuttersControl ($name) - PartyModeEventProcessing - Spring in ShuttersCommandDelaySet" +"AutoShuttersControl ($name) - EventProcessingPartyMode - Spring in ShuttersCommandDelaySet" ); } else { Log3( $name, 4, -"AutoShuttersControl ($name) - PartyModeEventProcessing Fenster nicht offen" +"AutoShuttersControl ($name) - EventProcessingPartyMode Fenster nicht offen" ); + $shutters->setLastDrive('drive after party mode'); ShuttersCommandSet( $hash, $shuttersDev, @@ -1266,7 +1343,7 @@ sub PartyModeEventProcessing($) { } } -sub ShuttersEventProcessing($@) { +sub EventProcessingShutters($@) { my ( $hash, $shuttersDev, $events ) = @_; my $name = $hash->{NAME}; @@ -1290,6 +1367,12 @@ sub ShuttersCommandSet($$$) { my $name = $hash->{NAME}; $shutters->setShuttersDev($shuttersDev); + + my $queryShuttersPosValue = ( + $shutters->getShuttersPosCmdValueNegate + ? $shutters->getStatus > $posValue + : $shutters->getStatus < $posValue + ); if ( ( $shutters->getPartyMode eq 'on' and $ascDev->getPartyMode eq 'on' ) @@ -1302,13 +1385,14 @@ sub ShuttersCommandSet($$$) { and ( $shutters->getLockOut eq 'soft' or $shutters->getLockOut eq 'hard' ) and $ascDev->getLockOut eq 'on' + and not $queryShuttersPosValue ) - or ( $shutters->getAntiFreeze eq 'on' - and $ascDev->getOutTemp <= $ascDev->getAntifreezeTemp ) ) { $shutters->setDelayCmd($posValue); $ascDev->setDelayCmdReading; + Log3( $name, 4, +"AutoShuttersControl ($name) - ShuttersCommandSet in Delay"); } else { $shutters->setDriveCmd($posValue); @@ -1316,6 +1400,8 @@ sub ShuttersCommandSet($$$) { if ( $shutters->getDelayCmd ne 'none' ) ; # setzt den Wert auf none da der Rolladen nun gesteuert werden kann. $ascDev->setLastPosReading; + Log3( $name, 4, +"AutoShuttersControl ($name) - ShuttersCommandSet setDriveCmd wird aufgerufen"); } } @@ -1378,32 +1464,6 @@ sub CreateSunRiseSetShuttersTimer($$) { ); readingsEndUpdate( $hash, 1 ); - CommandDeleteReading( undef, - $name . ' ' . $shuttersDev . '_nextAstroEvent' ) - if ( ReadingsVal( $name, $shuttersDev . '_nextAstroEvent', 'none' ) ne - 'none' ); # temporär - CommandDeleteReading( undef, - $shuttersDev . ' AutoShuttersControl_Time_Sunrise' ) - if ( - ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_Sunrise', 'none' ) - ne 'none' ); # temporär - CommandDeleteReading( undef, - $shuttersDev . ' AutoShuttersControl_Time_Sunset' ) - if ( - ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_Sunset', 'none' ) - ne 'none' ); # temporär - CommandDeleteReading( undef, - $shuttersDev . ' AutoShuttersControl_Time_DriveDown' ) - if ( - ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_DriveDown', - 'none' ) ne 'none' - ); # temporär - CommandDeleteReading( undef, - $shuttersDev . ' AutoShuttersControl_Time_DriveUp' ) - if ( - ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_DriveUp', 'none' ) - ne 'none' ); # temporär - RemoveInternalTimer( $shutters->getInTimerFuncHash ) if ( defined( $shutters->getInTimerFuncHash ) ); @@ -1445,14 +1505,15 @@ sub RenewSunRiseSetShuttersTimer($) { sub SetHardewareBlockForShutters($$) { my ( $hash, $cmd ) = @_; foreach ( @{ $hash->{helper}{shuttersList} } ) { - if ( AttrVal( $_, 'ASC_lock-out', 'soft' ) eq 'hard' - and AttrVal( $_, 'ASC_lock-outCmd', 'none' ) ne 'none' ) + $shutters->setShuttersDev($_); + if ( $shutters->getLockOut eq 'hard' + and $shutters->getLockOutCmd ne 'none' ) { CommandSet( undef, $_ . ' inhibit ' . $cmd ) - if ( AttrVal( $_, 'ASC_lock-outCmd', 'none' ) eq 'inhibit' ); + if ( $shutters->getLockOutCmd eq 'inhibit' ); CommandSet( undef, $_ . ' ' . ( $cmd eq 'on' ? 'blocked' : 'unblocked' ) ) - if ( AttrVal( $_, 'ASC_lock-outCmd', 'none' ) eq 'blocked' ); + if ( $shutters->getLockOutCmd eq 'blocked' ); } } } @@ -1478,15 +1539,15 @@ sub wiggle($$) { if ( $shutters->getShuttersPosCmdValueNegate ) { if ( $shutters->getStatus >= $shutters->getOpenPos / 2 ) { - $shutters->setDriveCmd( $shutters->getStatus + 5 ); + $shutters->setDriveCmd( $shutters->getStatus + $shutters->getWiggleValue ); } - else { $shutters->setDriveCmd( $shutters->getStatus - 5 ); } + else { $shutters->setDriveCmd( $shutters->getStatus - $shutters->getWiggleValue ); } } else { if ( $shutters->getStatus >= $shutters->getOpenPos / 2 ) { - $shutters->setDriveCmd( $shutters->getStatus - 5 ); + $shutters->setDriveCmd( $shutters->getStatus - $shutters->getWiggleValue ); } - else { $shutters->setDriveCmd( $shutters->getStatus + 5 ); } + else { $shutters->setDriveCmd( $shutters->getStatus + $shutters->getWiggleValue ); } } InternalTimer( gettimeofday() + 60, 'AutoShuttersControl::SetCmdFn', \%h ); @@ -1585,6 +1646,9 @@ sub CreateNewNotifyDev($) { AddNotifyDev( $hash, AttrVal( $name, 'ASC_rainSensorDevice', 'none' ), $name, 'ASC_rainSensorDevice' ) if ( AttrVal( $name, 'ASC_rainSensorDevice', 'none' ) ne 'none' ); + AddNotifyDev( $hash, AttrVal( $name, 'ASC_twilightDevice', 'none' ), + $name, 'ASC_twilightDevice' ) + if ( AttrVal( $name, 'ASC_twilightDevice', 'none' ) ne 'none' ); $hash->{NOTIFYDEV} = $hash->{NOTIFYDEV} . $shuttersList; } @@ -1724,6 +1788,19 @@ sub GetMonitoredDevs($) { ## my little helper ################################# +sub AutoSearchTwilightDev($) { + my $hash = shift; + my $name = $hash->{NAME}; + + if ( devspec2array('TYPE=(Astro|Twilight)') > 0 ) { + CommandAttr( undef, + $name + . ' ASC_twilightDevice ' + . ( devspec2array('TYPE=(Astro|Twilight)') )[0] ) + if ( AttrVal( $name, 'ASC_twilightDevice', 'none' ) eq 'none' ); + } +} + # Hilfsfunktion welche meinen ReadingString zum finden der getriggerten Devices und der Zurdnung was das Device überhaupt ist und zu welchen Rolladen es gehört aus liest und das Device extraiert sub ExtractNotifyDevFromEvent($$$) { my ( $hash, $shuttersDev, $shuttersAttr ) = @_; @@ -2079,8 +2156,11 @@ sub IsHoliday($) { my $name = $hash->{NAME}; return ( - ReadingsVal( AttrVal( $name, 'ASC_timeUpHolidayDevice', 'none' ), - AttrVal( $name, 'ASC_timeUpHolidayReading', 'state' ), 0 ) == 1 ? 1 : 0 + ReadingsVal( + AttrVal( $name, 'ASC_timeUpHolidayDevice', 'none' ), + AttrVal( $name, 'ASC_timeUpHolidayReading', 'state' ), + 0 + ) == 1 ? 1 : 0 ); } @@ -2168,6 +2248,21 @@ sub setNoOffset { sub setDriveCmd { my ( $self, $posValue ) = @_; my $offSet = 0; + + ### antifreeze Routine + if ( $shutters->getFreezeStatus > 0 ) { + if ( $shutters->getFreezeStatus != 1 ) { + $posValue = $shutters->getStatus; + $shutters->setLastDrive('no drive - antifreeze defense'); + $shutters->setLastDriveReading; + $ascDev->setStateReading; + } + elsif ( $posValue == $shutters->getClosedPos ) { + $posValue = $shutters->getAntiFreezePos; + $shutters->setLastDrive($shutters->getLastDrive . ' - antifreeze mode'); + } + } + my %h = ( shuttersDev => $self->{shuttersDev}, posValue => $posValue, @@ -2274,6 +2369,29 @@ sub setInTimerFuncHash { return 0; } +sub getFreezeStatus { + use POSIX qw(strftime); + my $self = shift; + my $daytime = strftime("%P", localtime()); + + if ( $shutters->getAntiFreeze ne 'off' + and $ascDev->getOutTemp <= $ascDev->getFreezeTemp ) { + + if ( $shutters->getAntiFreeze eq 'soft') { + return 1; + } + elsif ( $shutters->getAntiFreeze eq $daytime + or $shutters->getAntiFreeze eq $daytime ) + { + return 2; + } + elsif ( $shutters->getAntiFreeze eq 'hard' ) { + return 3; + } + } + else { return 0; } +} + sub getShuttersPosCmdValueNegate { my $self = shift; @@ -2286,7 +2404,8 @@ sub getPosSetCmd { return ( defined( $self->{ $self->{shuttersDev} }{posSetCmd} ) ? $self->{ $self->{shuttersDev} }{posSetCmd} - : $shutters->getPosCmd ); + : $shutters->getPosCmd + ); } sub getNoOffset { @@ -2425,6 +2544,12 @@ BEGIN { ); } +sub getAntiFreezePos { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_AntifreezePos', 50 ); +} + sub getShuttersPlace { my $self = shift; @@ -2437,7 +2562,29 @@ sub getSelfDefenseExclude { return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_Exclude', 'off' ); } -sub getShadingBrightnessSensor { +sub getWiggleValue { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_WiggleValue', 5 ); +} + +sub getShadingPos { + my $self = shift; + my $default = $self->{defaultarg}; + + $default = 10 if ( not defined($default) ); + return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Pos', $default ); +} + +sub getShadingMode { + my $self = shift; + my $default = $self->{defaultarg}; + + $default = 'off' if ( not defined($default) ); + return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Mode', $default ); +} + +sub _getShadingBrightnessSensor { my $self = shift; my $default = $self->{defaultarg}; @@ -2455,6 +2602,24 @@ sub getShadingBrightnessReading { $default ); } +sub getDirection { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Direction', -1 ); +} + +sub getShadingAngleLeft { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Angle_Left', -1 ); +} + +sub getShadingAngleRight { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Angle_Right', -1 ); +} + sub getOffset { my $self = shift; @@ -2491,10 +2656,10 @@ sub getVentilateOpen { return AttrVal( $self->{shuttersDev}, 'ASC_Ventilate_Window_Open', 'off' ); } -sub getPosAfterComfortOpen { +sub getComfortOpenPos { my $self = shift; - return AttrVal( $self->{shuttersDev}, 'ASC_Pos_after_ComfortOpen', 50 ); + return AttrVal( $self->{shuttersDev}, 'ASC_ComfortOpen_Pos', 50 ); } sub getPartyMode { @@ -2534,7 +2699,13 @@ sub getModeDown { sub getLockOut { my $self = shift; - return AttrVal( $self->{shuttersDev}, 'ASC_lock-out', 'soft' ); + return AttrVal( $self->{shuttersDev}, 'ASC_LockOut', 'off' ); +} + +sub getLockOutCmd { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_LockOut_Cmd', 'none' ); } sub getAntiFreeze { @@ -2649,8 +2820,8 @@ BEGIN { sub getBrightness { my $self = shift; - return ReadingsVal( $shutters->getShadingBrightnessSensor, - $shutters->getShadingBrightnessReading, 0 ); + return ReadingsVal( $shutters->_getShadingBrightnessSensor, + $shutters->getShadingBrightnessReading, -1 ); } sub getStatus { @@ -2886,14 +3057,12 @@ sub getMonitoredDevs { sub getOutTemp { my $self = shift; - my $name = $self->{name}; - return ReadingsVal( $ascDev->getTempSensor, $ascDev->getTempReading, 100 ); + return ReadingsVal( $ascDev->_getTempSensor, $ascDev->getTempReading, -100 ); } sub getResidentsStatus { my $self = shift; - my $name = $self->{name}; return ReadingsVal( $ascDev->_getResidentsDev, $ascDev->getResidentsReading, 'none' ); @@ -2901,7 +3070,6 @@ sub getResidentsStatus { sub getResidentsLastStatus { my $self = shift; - my $name = $self->{name}; return ReadingsVal( $ascDev->_getResidentsDev, 'lastState', 'none' ); } @@ -2913,6 +3081,26 @@ sub getSelfDefense { return ReadingsVal( $name, 'selfDefense', 'none' ); } +sub getAzimuth { + my $self = shift; + my $azimuth; + + $azimuth = ReadingsVal( $ascDev->_getTwilightDevice, 'azimuth', -1 ) if ( $defs{$ascDev->_getTwilightDevice}->{TYPE} eq 'Twilight' ); + $azimuth = ReadingsVal( $ascDev->_getTwilightDevice, 'SunAz', -1 ) if ( $defs{$ascDev->_getTwilightDevice}->{TYPE} eq 'Astro' ); + + return $azimuth; +} + +sub getElevation { + my $self = shift; + my $elevation; + + $elevation = ReadingsVal( $ascDev->_getTwilightDevice, 'elevation', -1 ) if ( $defs{$ascDev->_getTwilightDevice}->{TYPE} eq 'Twilight' ); + $elevation = ReadingsVal( $ascDev->_getTwilightDevice, 'SunAlt', -1 ) if ( $defs{$ascDev->_getTwilightDevice}->{TYPE} eq 'Astro' ); + + return $elevation; +} + ## Subklasse Attr ## package ASC_Dev::Attr; @@ -2954,6 +3142,13 @@ sub getBrightnessMaxVal { return AttrVal( $name, 'ASC_brightnessMaxVal', $default ); } +sub _getTwilightDevice { + my $self = shift; + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_twilightDevice', 'none' ); +} + sub getAutoAstroModeEvening { my $self = shift; my $name = $self->{name}; @@ -3011,16 +3206,16 @@ sub getAutoShuttersControlComfort { return AttrVal( $name, 'ASC_autoShuttersControlComfort', 'off' ); } -sub getAntifreezeTemp { +sub getFreezeTemp { my $self = shift; my $name = $self->{name}; my $default = $self->{defaultarg}; $default = 'none' if ( not defined($default) ); - return AttrVal( $name, 'ASC_antifreezeTemp', $default ); + return AttrVal( $name, 'ASC_freezeTemp', $default ); } -sub getTempSensor { +sub _getTempSensor { my $self = shift; my $name = $self->{name}; my $default = $self->{defaultarg}; @@ -3103,12 +3298,12 @@ sub getRainSensorShuttersClosedPos {

Example:
- This command creates a AutoShuttersControl device named shutter.
- After creating the device, all shutter devices which shall be controlled have to get set the attribut ASC with value 1 or 2.
- Value 1 means "Inverse or shutter e.g.: shutter up 0,shutter down 100 and the command for percentual movement is position",2 = "Homematic Style e.g.: shutter up 100,shutter down 0 and the command for percentual movement is pct.
+ This command creates a AutoShuttersControl device named myASControl.
+ After creating the device, all shutter devices which shall be controlled have to get set the attribut AutoShuttersControl with value 1 or 2.
+ Value 1 means "Inverse or shutter e.g.: shutter up 0,shutter down 100 and the command for percentual movement is position",2 = "Homematic Style e.g.: shutter up 100,shutter down 0 and the command for percentual movement istpct.
If the attribute is set, you may start automatic scan for your devices .

@@ -3142,9 +3337,9 @@ sub getRainSensorShuttersClosedPos {
  • partyMode - on/off activates the global party mode. see reading partyMode
  • lockOut - on/off activates the global lock out mode. see reading lockOut
  • renewSetSunriseSunsetTimer - refreshes the timer for sunset, sunrise and the internal timers.
  • -
  • scanForShutters - searches all FHEM devices with attribute "AutoShuttersControl" 1/2
  • +
  • scanForShutters - searches all FHEM devices with attribute "ASC" 1/2
  • sunriseTimeWeHoliday - on/off activates/deactivates respecting attribute ASC_Time_Up_WE_Holiday
  • -
  • createNewNotifyDev - recreates the internal structure for NOTIFYDEV - attribute verbose has to be greater than 3.
  • +
  • createNewNotifyDev - recreates the internal structure for NOTIFYDEV - attribute ASC_expert has value 1.
  • selfDefense - on/off,activates/deactivates the mode self defense. If the resident device says absent and selfDefense is active, each shutter for open windows will be closed.
  • wiggle - moves any shutter (for deterrence purposes) by 5% up, and after 1 minute down again to last position.
  • @@ -3153,7 +3348,7 @@ sub getRainSensorShuttersClosedPos { Get

    @@ -3161,12 +3356,12 @@ sub getRainSensorShuttersClosedPos {