diff --git a/FHEM/73_AutoShuttersControl.pm b/FHEM/73_AutoShuttersControl.pm new file mode 100644 index 0000000..c8c716f --- /dev/null +++ b/FHEM/73_AutoShuttersControl.pm @@ -0,0 +1,1184 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +### Notizen +# !!!!! - Innerhalb einer Shutterschleife kein CommandAttr verwenden. Bring Fehler!!! Kommen Raumnamen in die Shutterliste !!!!!! +# + +package FHEM::AutoShuttersControl; + +use strict; +use warnings; +use utf8; + +use FHEM::Automation::ShuttersControl; +use FHEM::Meta; +use GPUtils qw(GP_Import GP_Export); + +## Import der FHEM Funktionen +#-- Run before package compilation +BEGIN { + #-- Export to main context with different name + GP_Export( + qw( + Initialize + ) + ); +} + +sub Initialize { + my $hash = shift; + +## Da ich mit package arbeite müssen in die Initialize für die jeweiligen hash Fn Funktionen der Funktionsname + # und davor mit :: getrennt der eigentliche package Name des Modules + $hash->{SetFn} = \&Set; + $hash->{GetFn} = \&Get; + $hash->{DefFn} = \&Define; + $hash->{NotifyFn} = \&Notify; + $hash->{UndefFn} = \&Undef; + $hash->{AttrList} = + 'ASC_tempSensor ' + . 'ASC_brightnessDriveUpDown ' + . 'ASC_autoShuttersControlMorning:on,off ' + . 'ASC_autoShuttersControlEvening:on,off ' + . 'ASC_autoShuttersControlComfort:on,off ' + . 'ASC_residentsDev ' + . 'ASC_rainSensor ' + . 'ASC_autoAstroModeMorning:REAL,CIVIL,NAUTIC,ASTRONOMIC,HORIZON ' + . 'ASC_autoAstroModeMorningHorizon:-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9 ' + . 'ASC_autoAstroModeEvening:REAL,CIVIL,NAUTIC,ASTRONOMIC,HORIZON ' + . 'ASC_autoAstroModeEveningHorizon:-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9 ' + . 'ASC_freezeTemp:-5,-4,-3,-2,-1,0,1,2,3,4,5 ' + . 'ASC_shuttersDriveDelay ' + . 'ASC_twilightDevice ' + . 'ASC_windSensor ' + . 'ASC_expert:1 ' + . 'ASC_blockAscDrivesAfterManual:0,1 ' + . 'ASC_debug:1 ' + . 'ASC_slatDriveCmdInverse:0,1 ' + . $readingFnAttributes; + $hash->{NotifyOrderPrefix} = '51-'; # Order Nummer für NotifyFn + $hash->{FW_detailFn} = \&ShuttersInformation; + $hash->{parseParams} = 1; + + return FHEM::Meta::InitMod( __FILE__, $hash ); +} + + +1; + +=pod +=item device +=item summary Module for controlling shutters depending on various conditions +=item summary_DE Modul zur automatischen Rolladensteuerung auf Basis bestimmter Ereignisse + + +=begin html + + +

AutoShuttersControl

+ + +=end html + +=begin html_DE + + +

AutoShuttersControl

+ + +=end html_DE + +=for :application/json;q=META.json 73_AutoShuttersControl.pm +{ + "abstract": "Module for controlling shutters depending on various conditions", + "x_lang": { + "de": { + "abstract": "Modul zur Automatischen Rolladensteuerung auf Basis bestimmter Ereignisse" + } + }, + "keywords": [ + "fhem-mod-device", + "fhem-core", + "Shutter", + "Automation", + "Rollladen", + "Rollo", + "Control" + ], + "release_status": "testing", + "license": "GPL_2", + "version": "v0.9.20", + "author": [ + "Marko Oldenburg " + ], + "x_fhem_maintainer": [ + "CoolTux" + ], + "x_fhem_maintainer_github": [ + "LeonGaultier" + ], + "prereqs": { + "runtime": { + "requires": { + "FHEM": 5.00918799, + "perl": 5.016, + "Meta": 0, + "JSON": 0, + "Date::Parse": 0 + }, + "recommends": { + }, + "suggests": { + } + } + } +} +=end :application/json;q=META.json + +=cut diff --git a/73_AutoShuttersControl.pm b/lib/FHEM/Automation/ShuttersControl.pm similarity index 51% rename from 73_AutoShuttersControl.pm rename to lib/FHEM/Automation/ShuttersControl.pm index 83d2248..e9d29f0 100644 --- a/73_AutoShuttersControl.pm +++ b/lib/FHEM/Automation/ShuttersControl.pm @@ -60,7 +60,7 @@ sub ascAPIset { } ## unserer packagename -package FHEM::AutoShuttersControl; +package FHEM::Automation::ShuttersControl; use strict; use warnings; @@ -73,6 +73,9 @@ use GPUtils qw(GP_Import GP_Export); use Data::Dumper; #only for Debugging use Date::Parse; +use FHEM::Automation::ShuttersControl::Shutters; +use FHEM::Automation::ShuttersControl::Dev; + # try to use JSON::MaybeXS wrapper # for chance of better performance + open code eval { @@ -185,17 +188,18 @@ BEGIN { computeAlignTime ReplaceEventMap) ); + + #-- Export to main context with different name + GP_Export( + qw( + ascAPIget + ascAPIset + DevStateIcon + ) + ); } -#-- Export to main context with different name -GP_Export( - qw( - Initialize - ascAPIget - ascAPIset - DevStateIcon - ) -); + ## Die Attributsliste welche an die Rolläden verteilt wird. Zusammen mit Default Werten my %userAttrList = ( @@ -496,10 +500,10 @@ sub Notify { WriteReadingsShuttersList($hash); UserAttributs_Readings_ForShutters( $hash, 'add' ); InternalTimer( gettimeofday() + 3, - 'FHEM::AutoShuttersControl::RenewSunRiseSetShuttersTimer', + 'FHEM::Automation::ShuttersControl::RenewSunRiseSetShuttersTimer', $hash ); InternalTimer( gettimeofday() + 5, - 'FHEM::AutoShuttersControl::AutoSearchTwilightDev', $hash ); + 'FHEM::Automation::ShuttersControl::AutoSearchTwilightDev', $hash ); InternalTimer( gettimeofday() + 5, sub() { CommandSet( undef, $name . ' controlShading on' ) }, @@ -4944,7 +4948,7 @@ sub _CheckASC_ConditionsForShadingFn { my $count = 1; for my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) { InternalTimer( gettimeofday() + $count, - 'FHEM::AutoShuttersControl::_CheckShuttersConditionsForShadingFn', + 'FHEM::Automation::ShuttersControl::_CheckShuttersConditionsForShadingFn', $shuttersDev ); $count++; @@ -5022,4679 +5026,5 @@ sub _CheckShuttersConditionsForShadingFn { readingsEndUpdate( $shuttersDevHash, 1 ); } -###################################### -###################################### -########## Begin der Klassendeklarierungen für OOP (Objektorientierte Programmierung) ######################### -## Klasse Rolläden (Shutters) und die Subklassen Attr und Readings ## -## desweiteren wird noch die Klasse ASC_Roommate mit eingebunden - -package ASC_Shutters; -our @ISA = - qw(ASC_Shutters::Readings ASC_Shutters::Attr ASC_Roommate ASC_Window); - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - defs - ReadingsVal - readingsSingleUpdate - gettimeofday - InternalTimer - CommandSet - Log3) - ); -} - -sub new { - my $class = shift; - my $self = { - shuttersDev => undef, - defaultarg => undef, - roommate => undef, - }; - - bless $self, $class; - return $self; -} - -sub setShuttersDev { - my $self = shift; - my $shuttersDev = shift; - - $self->{shuttersDev} = $shuttersDev if ( defined($shuttersDev) ); - return $self->{shuttersDev}; -} - -sub getShuttersDev { - my $self = shift; - - return $self->{shuttersDev}; -} - -sub setAttrUpdateChanges { - my ( $self, $attr, $value ) = @_; - - $self->{ $self->{shuttersDev} }{AttrUpdateChanges}{$attr} = $value; - return; -} - -sub setHardLockOut { - my $self = shift; - my $cmd = shift; - - if ( $shutters->getLockOut eq 'hard' - && $shutters->getLockOutCmd ne 'none' ) - { - CommandSet( undef, $self->{shuttersDev} . ' inhibit ' . $cmd ) - if ( $shutters->getLockOutCmd eq 'inhibit' ); - CommandSet( undef, - $self->{shuttersDev} . ' ' - . ( $cmd eq 'on' ? 'blocked' : 'unblocked' ) ) - if ( $shutters->getLockOutCmd eq 'blocked' ); - CommandSet( undef, - $self->{shuttersDev} . ' ' - . ( $cmd eq 'on' ? 'protectionOn' : 'protectionOff' ) ) - if ( $shutters->getLockOutCmd eq 'protected' ); - } - return; -} - -sub setNoDelay { - my $self = shift; - my $noDelay = shift; - - $self->{ $self->{shuttersDev} }{noDelay} = $noDelay; - return; -} - -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; -} - -sub setDriveCmd { - my $self = shift; - my $posValue = shift; - - my $offSet; - my $offSetStart; - - if ( - ( $shutters->getPartyMode eq 'on' && $ascDev->getPartyMode eq 'on' ) - || ( $shutters->getAdv - && !$shutters->getQueryShuttersPos($posValue) - && !$shutters->getAdvDelay - && !$shutters->getExternalTriggerState - && !$shutters->getSelfDefenseState ) - ) - { - $shutters->setDelayCmd($posValue); - $ascDev->setDelayCmdReading; - $shutters->setNoDelay(0); - $shutters->setExternalTriggerState(0) - if ( $shutters->getExternalTriggerState ); - - FHEM::AutoShuttersControl::ASC_Debug( 'setDriveCmd: ' - . $shutters->getShuttersDev - . ' - Die Fahrt wird zurückgestellt. Grund kann ein geöffnetes Fenster sein oder ein aktivierter Party Modus oder Weihnachtszeit' - ); - } - else { - $shutters->setAdvDelay(0) - if ( $shutters->getAdvDelay ); - $shutters->setDelayCmd('none') - if ( $shutters->getDelayCmd ne 'none' ) - ; # setzt den Wert auf none da der Rolladen nun gesteuert werden kann. - $shutters->setExternalTriggerState(0) - if ( $shutters->getExternalTriggerState ); - - ### antifreeze Routine - if ( $shutters->getAntiFreezeStatus > 0 ) { - if ( $shutters->getAntiFreezeStatus != 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, - ); - - $offSet = $shutters->getDelay if ( $shutters->getDelay > -1 ); - $offSet = $ascDev->getShuttersOffset if ( $shutters->getDelay < 0 ); - $offSetStart = $shutters->getDelayStart; - - if ( $shutters->getSelfDefenseAbsent - && !$shutters->getSelfDefenseAbsentTimerrun - && $shutters->getSelfDefenseMode ne 'off' - && $shutters->getSelfDefenseState - && $ascDev->getSelfDefense eq 'on' ) - { - InternalTimer( - gettimeofday() + $shutters->getSelfDefenseAbsentDelay, - \&FHEM::AutoShuttersControl::_SetCmdFn, \%h ); - $shutters->setSelfDefenseAbsent( 1, 0, \%h ); - } - elsif ( $offSetStart > 0 && !$shutters->getNoDelay ) { - InternalTimer( - gettimeofday() + - int( rand($offSet) + $shutters->getDelayStart ), - \&FHEM::AutoShuttersControl::_SetCmdFn, \%h - ); - - FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' - . $shutters->getShuttersDev - . ' - versetztes fahren' ); - } - elsif ( $offSetStart < 1 || $shutters->getNoDelay ) { - FHEM::AutoShuttersControl::_SetCmdFn( \%h ); - FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' - . $shutters->getShuttersDev - . ' - NICHT versetztes fahren' ); - } - - FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' - . $shutters->getShuttersDev - . ' - NoDelay: ' - . ( $shutters->getNoDelay ? 'JA' : 'NEIN' ) ); - $shutters->setNoDelay(0); - } - - return; -} - -sub setSunsetUnixTime { - my $self = shift; - my $unixtime = shift; - - $self->{ $self->{shuttersDev} }{sunsettime} = $unixtime; - return; -} - -sub setSunset { - my $self = shift; - my $value = shift; - - $self->{ $self->{shuttersDev} }{sunset} = $value; - return; -} - -sub setSunriseUnixTime { - my $self = shift; - my $unixtime = shift; - - $self->{ $self->{shuttersDev} }{sunrisetime} = $unixtime; - return; -} - -sub setSunrise { - my $self = shift; - my $value = shift; - - $self->{ $self->{shuttersDev} }{sunrise} = $value; - return; -} - -sub setDelayCmd { - my $self = shift; - my $posValue = shift; - - $self->{ $self->{shuttersDev} }{delayCmd} = $posValue; - return; -} - -sub setLastDrive { - my $self = shift; - my $lastDrive = shift; - - $self->{ $self->{shuttersDev} }{lastDrive} = $lastDrive; - return; -} - -sub setPosSetCmd { - my $self = shift; - my $posSetCmd = shift; - - $self->{ $self->{shuttersDev} }{posSetCmd} = $posSetCmd; - return; -} - -sub setLastDriveReading { - my $self = shift; - my $shuttersDevHash = $defs{ $self->{shuttersDev} }; - - my %h = ( - devHash => $shuttersDevHash, - lastDrive => $shutters->getLastDrive, - ); - - InternalTimer( gettimeofday() + 0.1, - \&FHEM::AutoShuttersControl::_setShuttersLastDriveDelayed, \%h ); - return; -} - -sub setLastPos { - -# letzte ermittelte Position bevor die Position des Rolladen über ASC geändert wurde - my $self = shift; - my $position = shift; - - $self->{ $self->{shuttersDev} }{lastPos}{VAL} = $position - if ( defined($position) ); - $self->{ $self->{shuttersDev} }{lastPos}{TIME} = int( gettimeofday() ) - if ( defined( $self->{ $self->{shuttersDev} }{lastPos} ) ); - return; -} - -sub setLastManPos { - my $self = shift; - my $position = shift; - - $self->{ $self->{shuttersDev} }{lastManPos}{VAL} = $position - if ( defined($position) ); - $self->{ $self->{shuttersDev} }{lastManPos}{TIME} = int( gettimeofday() ) - if ( defined( $self->{ $self->{shuttersDev} }{lastManPos} ) - && defined( $self->{ $self->{shuttersDev} }{lastManPos}{TIME} ) ); - $self->{ $self->{shuttersDev} }{lastManPos}{TIME} = - int( gettimeofday() ) - 86400 - if ( defined( $self->{ $self->{shuttersDev} }{lastManPos} ) - && !defined( $self->{ $self->{shuttersDev} }{lastManPos}{TIME} ) ); - return; -} - -sub setDefault { - my $self = shift; - my $defaultarg = shift; - - $self->{defaultarg} = $defaultarg if ( defined($defaultarg) ); - return $self->{defaultarg}; -} - -sub setRoommate { - my $self = shift; - my $roommate = shift; - - $self->{roommate} = $roommate if ( defined($roommate) ); - return $self->{roommate}; -} - -sub setInTimerFuncHash { - my $self = shift; - my $inTimerFuncHash = shift; - - $self->{ $self->{shuttersDev} }{inTimerFuncHash} = $inTimerFuncHash - if ( defined($inTimerFuncHash) ); - return; -} - -sub setPrivacyDownStatus { - my $self = shift; - my $statusValue = shift; - - $self->{ $self->{shuttersDev} }->{privacyDownStatus} = $statusValue; - return; -} - -sub setPrivacyUpStatus { - my $self = shift; - my $statusValue = shift; - - $self->{ $self->{shuttersDev} }->{privacyUpStatus} = $statusValue; - return; -} - -sub setSelfDefenseState { - my $self = shift; - my $value = shift; - - $self->{ $self->{shuttersDev} }{selfDefenseState} = $value; - return; -} - -sub setAdvDelay { - my $self = shift; - my $advDelay = shift; - - $self->{ $self->{shuttersDev} }->{AdvDelay} = $advDelay; - return; -} - -sub getHomemode { - my $self = shift; - - my $homemode = $shutters->getRoommatesStatus; - $homemode = $ascDev->getResidentsStatus - if ( $homemode eq 'none' ); - return $homemode; -} - -sub getAdvDelay { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }->{AdvDelay} ) - ? $self->{ $self->{shuttersDev} }->{AdvDelay} - : 0 - ); -} - -sub getPrivacyDownStatus { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }->{privacyDownStatus} ) - ? $self->{ $self->{shuttersDev} }->{privacyDownStatus} - : undef - ); -} - -sub getPrivacyUpStatus { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }->{privacyUpStatus} ) - ? $self->{ $self->{shuttersDev} }->{privacyUpStatus} - : undef - ); -} - -sub getAttrUpdateChanges { - my $self = shift; - my $attr = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{AttrUpdateChanges} ) - && defined( - $self->{ $self->{shuttersDev} }{AttrUpdateChanges}{$attr} ) - ? $self->{ $self->{shuttersDev} }{AttrUpdateChanges}{$attr} - : 'none' - ); -} - -sub getIsDay { - my $self = shift; - - return FHEM::AutoShuttersControl::_IsDay( $self->{shuttersDev} ); -} - -sub getAntiFreezeStatus { - use POSIX qw(strftime); - my $self = shift; - my $daytime = strftime( "%P", localtime() ); - $daytime = ( - defined($daytime) && $daytime - ? $daytime - : ( strftime( "%k", localtime() ) < 12 ? 'am' : 'pm' ) - ); - my $outTemp = $ascDev->getOutTemp; - -# $outTemp = $shutters->getOutTemp if ( $shutters->getOutTemp != -100 ); sollte raus das der Sensor im Rollo auch ein Innentemperatursensor sein kann. - - if ( $shutters->getAntiFreeze ne 'off' - && $outTemp <= $ascDev->getFreezeTemp ) - { - - if ( $shutters->getAntiFreeze eq 'soft' ) { - return 1; - } - elsif ( $shutters->getAntiFreeze eq $daytime ) { - return 2; - } - elsif ( $shutters->getAntiFreeze eq 'hard' ) { - return 3; - } - } - else { return 0; } -} - -sub getShuttersPosCmdValueNegate { - my $self = shift; - - return ( $shutters->getOpenPos < $shutters->getClosedPos ? 1 : 0 ); -} - -sub getQueryShuttersPos -{ # Es wird geschaut ob die aktuelle Position des Rollos unterhalb der Zielposition ist - my $self = shift; - my $posValue = shift; # wenn dem so ist wird 1 zurück gegeben ansonsten 0 - - return ( - $shutters->getShuttersPosCmdValueNegate - ? $shutters->getStatus > $posValue - : $shutters->getStatus < $posValue - ); -} - -sub getPosSetCmd { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{posSetCmd} ) - ? $self->{ $self->{shuttersDev} }{posSetCmd} - : $shutters->getPosCmd - ); -} - -sub getNoDelay { - my $self = shift; - - return $self->{ $self->{shuttersDev} }{noDelay}; -} - -sub getSelfDefenseState { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{selfDefenseState} ) - ? $self->{ $self->{shuttersDev} }{selfDefenseState} - : 0 - ); -} - -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 ( - defined( - $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerhash} - ) - ? $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerhash} - : undef - ); -} - -sub getLastDrive { - my $self = shift; - - $self->{ $self->{shuttersDev} }{lastDrive} = - ReadingsVal( $self->{shuttersDev}, 'ASC_ShuttersLastDrive', 'none' ) - if ( !defined( $self->{ $self->{shuttersDev} }{lastDrive} ) ); - - return $self->{ $self->{shuttersDev} }{lastDrive}; -} - -sub getLastPos -{ # letzte ermittelte Position bevor die Position des Rolladen über ASC geändert wurde - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{lastPos} ) - && defined( $self->{ $self->{shuttersDev} }{lastPos}{VAL} ) - ? $self->{ $self->{shuttersDev} }{lastPos}{VAL} - : 50 - ); -} - -sub getLastPosTimestamp { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} } ) - && defined( $self->{ $self->{shuttersDev} }{lastPos} ) - && defined( $self->{ $self->{shuttersDev} }{lastPos}{TIME} ) - ? $self->{ $self->{shuttersDev} }{lastPos}{TIME} - : 0 - ); -} - -sub getLastManPos -{ # letzte ermittelte Position bevor die Position des Rolladen manuell (nicht über ASC) geändert wurde - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{lastManPos} ) - && defined( $self->{ $self->{shuttersDev} }{lastManPos}{VAL} ) - ? $self->{ $self->{shuttersDev} }{lastManPos}{VAL} - : 50 - ); -} - -sub getLastManPosTimestamp { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} } ) - && defined( $self->{ $self->{shuttersDev} }{lastManPos} ) - && defined( $self->{ $self->{shuttersDev} }{lastManPos}{TIME} ) - ? $self->{ $self->{shuttersDev} }{lastManPos}{TIME} - : 0 - ); -} - -sub getInTimerFuncHash { - my $self = shift; - - return $self->{ $self->{shuttersDev} }{inTimerFuncHash}; -} - -sub getSunsetUnixTime { - my $self = shift; - - return $self->{ $self->{shuttersDev} }{sunsettime}; -} - -sub getSunset { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{sunset} ) - ? $self->{ $self->{shuttersDev} }{sunset} - : 0 - ); -} - -sub getSunriseUnixTime { - my $self = shift; - - return $self->{ $self->{shuttersDev} }{sunrisetime}; -} - -sub getSunrise { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{sunrise} ) - ? $self->{ $self->{shuttersDev} }{sunrise} - : 0 - ); -} - -sub getRoommatesStatus { - my $self = shift; - - my $loop = 0; - my @roState; - my %statePrio = ( - 'asleep' => 1, - 'gotosleep' => 2, - 'awoken' => 3, - 'home' => 4, - 'absent' => 5, - 'gone' => 6, - 'none' => 7 - ); - my $minPrio = 10; - - for my $ro ( split( ",", $shutters->getRoommates ) ) { - $shutters->setRoommate($ro); - my $currentPrio = $statePrio{ $shutters->_getRoommateStatus }; - $minPrio = $currentPrio if ( $minPrio > $currentPrio ); - } - - my %revStatePrio = reverse %statePrio; - return $revStatePrio{$minPrio}; -} - -sub getRoommatesLastStatus { - my $self = shift; - - my $loop = 0; - my @roState; - my %statePrio = ( - 'asleep' => 1, - 'gotosleep' => 2, - 'awoken' => 3, - 'home' => 6, - 'absent' => 5, - 'gone' => 4, - 'none' => 7 - ); - my $minPrio = 10; - - for my $ro ( split( ",", $shutters->getRoommates ) ) { - $shutters->setRoommate($ro); - my $currentPrio = $statePrio{ $shutters->_getRoommateLastStatus }; - $minPrio = $currentPrio if ( $minPrio > $currentPrio ); - } - - my %revStatePrio = reverse %statePrio; - return $revStatePrio{$minPrio}; -} - -sub getOutTemp { - my $self = shift; - - return ReadingsVal( $shutters->_getTempSensor, - $shutters->getTempSensorReading, -100 ); -} - -sub getIdleDetection { - my $self = shift; - - return ReadingsVal( $self->{shuttersDev}, - $shutters->_getIdleDetectionReading, 'none' ); -} - -### Begin Beschattung Objekt mit Daten befüllen -sub setShadingStatus { - my $self = shift; - my $value = shift; ### Werte für value = in, out, in reserved, out reserved - - return - if ( defined($value) - && exists( $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} ) - && $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} eq $value ); - - $shutters->setShadingLastStatus( ( $value eq 'in' ? 'out' : 'in' ) ) - if ( $value eq 'in' - || $value eq 'out' ); - - $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} = $value - if ( defined($value) ); - $self->{ $self->{shuttersDev} }{ShadingStatus}{TIME} = int( gettimeofday() ) - if ( defined( $self->{ $self->{shuttersDev} }{ShadingStatus} ) ); - - return; -} - -sub setShadingLastStatus { - my $self = shift; - my $value = shift; ### Werte für value = in, out - - return - if ( defined($value) - && exists( $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} ) - && $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} eq $value ); - - $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} = $value - if ( defined($value) ); - $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} = - int( gettimeofday() ) - if ( defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) ); - $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} = 0 - if ( $value eq 'out' ); - - return; -} - -sub setShadingManualDriveStatus { - my $self = shift; - my $value = shift; ### Werte für value = 0, 1 - - $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} = $value - if ( defined($value) ); - - return; -} - -sub setWindProtectionStatus { # Werte protected, unprotected - my $self = shift; - my $value = shift; - - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{VAL} = $value - if ( defined($value) ); - - return; -} - -sub setRainProtectionStatus { # Werte protected, unprotected - my $self = shift; - my $value = shift; - - $self->{ $self->{shuttersDev} }->{RainProtection}->{VAL} = $value - if ( defined($value) ); - return; -} - -sub setExternalTriggerState { - my $self = shift; - my $value = shift; - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} = $value - if ( defined($value) ); - - return; -} - -sub setPushBrightnessInArray { - my $self = shift; - my $value = shift; - - unshift( - @{ $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} }, - $value - ); - pop( @{ $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} } ) - if ( - scalar( - @{ - $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} - } - ) > $shutters->getMaxBrightnessAverageArrayObjects - ); - - return; -} - -sub getBrightnessAverage { - my $self = shift; - - return FHEM::AutoShuttersControl::_averageBrightness( - @{ $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} } ) - if ( - ref( $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} ) - eq 'ARRAY' - && scalar( - @{ - $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} - } - ) > 0 - ); - - return; -} - -sub getShadingStatus { # Werte für value = in, out, in reserved, out reserved - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{ShadingStatus} ) - && defined( $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} ) - ? $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} - : 'out' - ); -} - -sub getShadingLastStatus { # Werte für value = in, out - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) - && defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} ) - ? $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} - : 'out' - ); -} - -sub getShadingManualDriveStatus { # Werte für value = 0, 1 - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus} ) - && defined( - $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} - ) - ? $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} - : 0 - ); -} - -sub getIfInShading { - my $self = shift; - - return ( - ( - $shutters->getShadingMode ne 'off' - && $shutters->getShadingLastStatus eq 'out' - ) ? 1 : 0 - ); -} - -sub getWindProtectionStatus { # Werte protected, unprotected - my $self = shift; - - return ( - ( - defined( $self->{ $self->{shuttersDev} }->{ASC_WindParameters} ) - && defined( - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{VAL} - ) - ) - ? $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{VAL} - : 'unprotected' - ); -} - -sub getRainProtectionStatus { # Werte protected, unprotected - my $self = shift; - - return ( - ( - defined( $self->{ $self->{shuttersDev} }->{RainProtection} ) - && defined( - $self->{ $self->{shuttersDev} }->{RainProtection}->{VAL} - ) - ) - ? $self->{ $self->{shuttersDev} }->{RainProtection}->{VAL} - : 'unprotected' - ); -} - -sub getShadingStatusTimestamp { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} } ) - && defined( $self->{ $self->{shuttersDev} }{ShadingStatus} ) - && defined( $self->{ $self->{shuttersDev} }{ShadingStatus}{TIME} ) - ? $self->{ $self->{shuttersDev} }{ShadingStatus}{TIME} - : 0 - ); -} - -sub getShadingLastStatusTimestamp { - my $self = shift; - - return ( - defined( $self->{ $self->{shuttersDev} } ) - && defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) - && defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} ) - ? $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} - : 0 - ); -} -### Ende Beschattung - -## Subklasse Attr von ASC_Shutters## -package ASC_Shutters::Attr; - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - AttrVal - CommandAttr - gettimeofday) - ); -} - -sub _setAttributs { - my $shuttersDev = shift; - my $attr = shift; - my $attrVal = shift; - - CommandAttr( undef, $shuttersDev . ' ' . $attr . ' ' . $attrVal ); - - return; -} - -sub _getPosition { - my $self = shift; - - my $attr = shift; - my $userAttrList = shift; - - return $self->{ $self->{shuttersDev} }->{$attr}->{position} - if ( - exists( $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} = - int( gettimeofday() ); - - my $position; - my $posAssignment; - - if ( - AttrVal( $self->{shuttersDev}, $attr, - $userAttrList{$userAttrList} - [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] ) =~ - m{\A\{.+\}\z}xms - ) - { - my $response = FHEM::AutoShuttersControl::_perlCodeCheck( - AttrVal( - $self->{shuttersDev}, - $attr, - $userAttrList{$userAttrList} - [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] - ) - ); - - ( $position, $posAssignment ) = split ':', $response; - - $position = ( - $position =~ m{\A\d+(\.\d+)?\z}xms - ? $position - : $userAttrList{$userAttrList} - [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] - ); - - $posAssignment = ( - $posAssignment =~ m{\A\d+(\.\d+)?\z}xms - ? $posAssignment - : 'none' - ); - } - else { - ( $position, $posAssignment ) = - FHEM::AutoShuttersControl::GetAttrValues( - $self->{shuttersDev}, - $attr, - $userAttrList{$userAttrList} - [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] - ); - } - - ### erwartetes Ergebnis - # DEVICE:READING - $self->{ $self->{shuttersDev} }->{$attr}->{position} = $position; - $self->{ $self->{shuttersDev} }->{$attr}->{posAssignment} = - $posAssignment; - - return $self->{ $self->{shuttersDev} }->{$attr}->{position}; - - if ( - defined( - FHEM::AutoShuttersControl::_perlCodeCheck( - $self->{ $self->{shuttersDev} }->{$attr}->{position} - ) - ) - ) - { - $self->{ $self->{shuttersDev} }->{$attr}->{position} = - FHEM::AutoShuttersControl::_perlCodeCheck( - $self->{ $self->{shuttersDev} }->{$attr}->{position} ); - } - - return ( - $self->{ $self->{shuttersDev} }->{$attr}->{position} =~ - m{^\d+(\.\d+)?$}xms - ? $self->{ $self->{shuttersDev} }->{$attr}->{position} - : $userAttrList{$userAttrList} - [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] - ); -} - -sub _getPositionAssignment { - my $self = shift; - - my $attr = shift; - my $getFn = shift; - - return $self->{ $self->{shuttersDev} }->{$attr}->{posAssignment} - if ( - exists( $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) < 2 - ); - $shutters->$getFn; - - return ( $self->{ $self->{shuttersDev} }->{$attr}->{posAssignment} ); -} - -sub setAntiFreezePos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Antifreeze_Pos', $attrVal ); - - return; -} - -sub getAntiFreezePos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_Antifreeze_Pos', -'ASC_Antifreeze_Pos:5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100' - ); -} - -sub getAntiFreezePosAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_Antifreeze_Pos', - 'getAntiFreezePos' ); -} - -sub setShuttersPlace { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_ShuttersPlace', $attrVal ); - - return; -} - -sub getShuttersPlace { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_ShuttersPlace', 'window' ); -} - -sub setSlatPosCmd { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_SlatPosCmd_SlatDevice', - $attrVal ); - - return; -} - -sub getSlatPosCmd { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} - ->{poscmd} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} - ->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{LASTGETTIME} - = int( gettimeofday() ); - my ( $slatPosCmd, $slatDevice ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_SlatPosCmd_SlatDevice', 'none:none' ); - - ## Erwartetes Ergebnis - # upTime:upBrightnessVal - - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{poscmd} = - $slatPosCmd; - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{device} = - $slatDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} - ->{poscmd}; -} - -sub getSlatDevice { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} - ->{device} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getSlatPosCmd; - - return ( - $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{device} - ); -} - -sub setPrivacyUpTime { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_PrivacyUpValue_beforeDayOpen', - $attrVal ); - - return; -} - -sub getPrivacyUpTime { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{uptime} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{LASTGETTIME} = int( gettimeofday() ); - my ( $upTime, $upBrightnessVal ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_PrivacyUpValue_beforeDayOpen', '-1:-1' ); - - ## Erwartetes Ergebnis - # upTime:upBrightnessVal - - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{uptime} = $upTime; - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{upbrightnessval} = - ( $upBrightnessVal ne 'none' ? $upBrightnessVal : -1 ); - - $shutters->setPrivacyUpStatus(0) - if ( defined( $shutters->getPrivacyUpStatus ) - && $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{uptime} == -1 ); - - return $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{uptime}; -} - -sub getPrivacyUpBrightnessVal { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{upbrightnessval} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getPrivacyUpTime; - - return ( - defined( - $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{upbrightnessval} - ) - ? $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} - ->{upbrightnessval} - : -1 - ); -} - -sub setPrivacyDownTime { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, - 'ASC_PrivacyDownValue_beforeNightClose', $attrVal ); - - return; -} - -sub getPrivacyDownTime { - my $self = shift; - - return $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{downtime} - if ( - exists( - $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_PrivacyDownValue_beforeNightClose} - ->{LASTGETTIME} = int( gettimeofday() ); - my ( $downTime, $downBrightnessVal ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_PrivacyDownValue_beforeNightClose', '-1:-1' ); - - ## Erwartetes Ergebnis - # downTime:downBrightnessVal - - $self->{ $self->{shuttersDev} }->{ASC_PrivacyDownValue_beforeNightClose} - ->{downtime} = $downTime; - $self->{ $self->{shuttersDev} }->{ASC_PrivacyDownValue_beforeNightClose} - ->{downbrightnessval} = - ( $downBrightnessVal ne 'none' ? $downBrightnessVal : -1 ); - - $shutters->setPrivacyDownStatus(0) - if ( defined( $shutters->getPrivacyDownStatus ) - && $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{downtime} == -1 ); - - return $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{downtime}; -} - -sub getPrivacyDownBrightnessVal { - my $self = shift; - - return $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{downbrightnessval} - if ( - exists( - $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} ) < 2 - ); - $shutters->getPrivacyDownTime; - - return ( - defined( - $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{downbrightnessval} - ) - ? $self->{ $self->{shuttersDev} } - ->{ASC_PrivacyDownValue_beforeNightClose}->{downbrightnessval} - : -1 - ); -} - -sub setPrivacyUpPos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_PrivacyUp_Pos', $attrVal ); - - return; -} - -sub getPrivacyUpPos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_PrivacyUp_Pos', 'ASC_PrivacyUp_Pos' ); -} - -sub getPrivacyUpPositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_PrivacyUp_Pos', - 'getPrivacyUpPos' ); -} - -sub setPrivacyDownPos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_PrivacyDown_Pos', $attrVal ); - - return; -} - -sub getPrivacyDownPos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_PrivacyDown_Pos', - 'ASC_PrivacyDown_Pos' ); -} - -sub getPrivacyDownPositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_PrivacyDown_Pos', - 'getPrivacyDownPos' ); -} - -sub setSelfDefenseMode { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Self_Defense_Mode', $attrVal ); - - return; -} - -sub getSelfDefenseMode { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_Mode', 'gone' ); -} - -sub setSelfDefenseAbsentDelay { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Self_Defense_AbsentDelay', - $attrVal ); - - return; -} - -sub getSelfDefenseAbsentDelay { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_AbsentDelay', 300 ); -} - -sub setWiggleValue { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_WiggleValue', $attrVal ); - - return; -} - -sub getWiggleValue { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_WiggleValue', 5 ); -} - -sub setAdv { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Adv', $attrVal ); - - return; -} - -sub getAdv { - my $self = shift; - - return ( - AttrVal( $self->{shuttersDev}, 'ASC_Adv', 'off' ) eq 'on' - ? ( FHEM::AutoShuttersControl::_IsAdv == 1 ? 1 : 0 ) - : 0 - ); -} - -### Begin Beschattung -sub setShadingPos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shading_Pos', $attrVal ); - - return; -} - -sub getShadingPos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_Shading_Pos', - 'ASC_Shading_Pos:10,20,30,40,50,60,70,80,90,100' ); -} - -sub getShadingPositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_Shading_Pos', - 'getShadingPos' ); -} - -sub setShadingMode { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shading_Mode', $attrVal ); - - return; -} - -sub getShadingMode { - my $self = shift; - - 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} - ) - && ( 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} - ) - && ( 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 setIdleDetectionReading { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shutter_IdleDetection', - $attrVal ); - - return; -} - -sub _getIdleDetectionReading { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} - ->{reading} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} - ->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{LASTGETTIME} - = int( gettimeofday() ); - my ( $reading, $value ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_Shutter_IdleDetection', 'none' ); - - ### erwartetes Ergebnis - # READING:VALUE - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{reading} = - $reading; - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{value} = - $value; - - return $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} - ->{reading}; -} - -sub getIdleDetectionValue { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{value} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} - ->{LASTGETTIME} ) < 2 - ); - $shutters->_getIdleDetectionReading; - - return ( - defined( - $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} - ->{value} - ) - ? $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{value} - : 'none' - ); -} - -sub setBrightnessSensor { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_BrightnessSensor', $attrVal ); - - return; -} - -sub _getBrightnessSensor { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{LASTGETTIME} = - int( gettimeofday() ); - my ( $device, $reading, $max, $min ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_BrightnessSensor', 'none' ); - - ### erwartetes Ergebnis - # DEVICE:READING MAX:MIN - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device} = $device; - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} = - ( $reading ne 'none' ? $reading : 'brightness' ); - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermin} = - ( $min ne 'none' ? $min : -1 ); - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermax} = - ( $max ne 'none' ? $max : -1 ); - - return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device}; -} - -sub getBrightnessReading { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} ) < 2 - ); - $shutters->_getBrightnessSensor; - - return ( - defined( - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} - ) - ? $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} - : 'brightness' - ); -} - -sub getShadingAzimuthLeft { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{leftVal} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getShadingAzimuthRight; - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{leftVal}; -} - -sub setShadingInOutAzimuth { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shading_InOutAzimuth', $attrVal ); - - return; -} - -sub getShadingAzimuthRight { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{rightVal} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth}->{LASTGETTIME} - = int( gettimeofday() ); - my ( $left, $right ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_Shading_InOutAzimuth', '95:265' ); - - ### erwartetes Ergebnis - # MIN:MAX - - $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth}->{leftVal} = - $left; - $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth}->{rightVal} = - $right; - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} - ->{rightVal}; -} - -sub setShadingMinOutsideTemperature { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shading_Min_OutsideTemperature', - $attrVal ); - - return; -} - -sub getShadingMinOutsideTemperature { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Min_OutsideTemperature', - 18 ); -} - -sub setShadingMinMaxElevation { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shading_MinMax_Elevation', - $attrVal ); - - return; -} - -sub getShadingMinElevation { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{minVal} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{LASTGETTIME} = int( gettimeofday() ); - my ( $min, $max ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_Shading_MinMax_Elevation', '25.0:100.0' ); - - ### erwartetes Ergebnis - # MIN:MAX - - $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation}->{minVal} = - $min; - $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation}->{maxVal} = - ( $max ne 'none' ? $max : 100 ); - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{minVal}; -} - -sub getShadingMaxElevation { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{maxVal} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getShadingMinElevation; - - return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} - ->{maxVal}; -} - -sub setShadingStateChangeSunnyCloudy { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shading_StateChange_SunnyCloudy', - $attrVal ); - - return; -} - -sub getShadingStateChangeSunny { - my $self = shift; - - return $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{sunny} - if ( - exists( - $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_Shading_StateChange_SunnyCloudy} - ->{LASTGETTIME} = int( gettimeofday() ); - my ( $sunny, $cloudy, $maxBrightnessAverageArrayObjects ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_Shading_StateChange_SunnyCloudy', - '35000:20000' ); - - ### erwartetes Ergebnis - # SUNNY:CLOUDY [BrightnessAverage] - - $self->{ $self->{shuttersDev} }->{ASC_Shading_StateChange_SunnyCloudy} - ->{sunny} = $sunny; - $self->{ $self->{shuttersDev} }->{ASC_Shading_StateChange_SunnyCloudy} - ->{cloudy} = $cloudy; - $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{MAXOBJECT} = ( - defined($maxBrightnessAverageArrayObjects) - && $maxBrightnessAverageArrayObjects ne 'none' - ? $maxBrightnessAverageArrayObjects - : 3 - ); - - return $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{sunny}; -} - -sub getShadingStateChangeCloudy { - my $self = shift; - - return $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{cloudy} - if ( - exists( - $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} ) < 2 - ); - $shutters->getShadingStateChangeSunny; - - return $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{cloudy}; -} - -sub getMaxBrightnessAverageArrayObjects { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{BrightnessAverageArray} - ->{MAXOBJECT} - if ( - exists( - $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} } - ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} ) < 2 - ); - $shutters->getShadingStateChangeSunny; - - return $self->{ $self->{shuttersDev} }->{BrightnessAverageArray} - ->{MAXOBJECT}; -} - -sub setShadingWaitingPeriod { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Shading_WaitingPeriod', - $attrVal ); - - return; -} - -sub getShadingWaitingPeriod { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Shading_WaitingPeriod', 1200 ); -} -### Ende Beschattung -sub setExternalTrigger { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_ExternalTrigger', $attrVal ); - - return; -} - -sub getExternalTriggerDevice { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{device} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{LASTGETTIME} = - int( gettimeofday() ); - my ( $device, $reading, $valueActive, $valueInactive, $posActive, - $posInactive, $valueActive2, $posActive2 ) - = FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_ExternalTrigger', 'none' ); - - ### erwartetes Ergebnis -# DEVICE:READING VALUEACTIVE:VALUEINACTIVE POSACTIVE:POSINACTIVE VALUEACTIVE2:POSACTIVE2 - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{device} = - $device; - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{reading} = - $reading; - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueactive} = - $valueActive; - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueinactive} = - $valueInactive; - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive} = - $posActive; - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posinactive} = - ( $posInactive ne 'none' ? $posInactive : $shutters->getLastPos ); - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueactive2} = - $valueActive2; - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive2} = - $posActive2; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{device}; - -} - -sub getExternalTriggerReading { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{reading} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getExternalTriggerDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{reading}; -} - -sub getExternalTriggerValueActive { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueactive} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getExternalTriggerDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{valueactive}; -} - -sub getExternalTriggerValueActive2 { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{valueactive2} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getExternalTriggerDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{valueactive2}; -} - -sub getExternalTriggerValueInactive { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{valueinactive} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getExternalTriggerDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{valueinactive}; -} - -sub getExternalTriggerPosActive { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getExternalTriggerDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive}; -} - -sub getExternalTriggerPosActive2 { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive2} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getExternalTriggerDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive2}; -} - -sub getExternalTriggerPosInactive { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posinactive} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{LASTGETTIME} ) < 2 - ); - $shutters->getExternalTriggerDevice; - - return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} - ->{posinactive}; -} - -sub getExternalTriggerState { - my $self = shift; - - return ( - ( - defined( - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} - ) - and - $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} - ) ? 1 : 0 - ); -} - -sub setDelay { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Drive_Delay', $attrVal ); - - return; -} - -sub getDelay { - my $self = shift; - - my $val = AttrVal( $self->{shuttersDev}, 'ASC_Drive_Delay', -1 ); - return ( $val =~ m{^\d+$}xms ? $val : -1 ); -} - -sub setDelayStart { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Drive_DelayStart', $attrVal ); - - return; -} - -sub getDelayStart { - my $self = shift; - - my $val = AttrVal( $self->{shuttersDev}, 'ASC_Drive_DelayStart', -1 ); - return ( ( $val > 0 && $val =~ m{^\d+$}xms ) ? $val : -1 ); -} - -sub setBlockingTimeAfterManual { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_BlockingTime_afterManual', - $attrVal ); - - return; -} - -sub getBlockingTimeAfterManual { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_BlockingTime_afterManual', - 1200 ); -} - -sub setBlockingTimeBeforNightClose { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_BlockingTime_beforNightClose', - $attrVal ); - - return; -} - -sub getBlockingTimeBeforNightClose { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_BlockingTime_beforNightClose', - 3600 ); -} - -sub setBlockingTimeBeforDayOpen { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_BlockingTime_beforDayOpen', - $attrVal ); - - return; -} - -sub getBlockingTimeBeforDayOpen { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_BlockingTime_beforDayOpen', - 3600 ); -} - -sub setPosCmd { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Pos_Reading', $attrVal ); - - return; -} - -sub getPosCmd { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Pos_Reading', - $userAttrList{'ASC_Pos_Reading'} - [ AttrVal( $self->{shuttersDev}, 'ASC', 1 ) ] ); -} - -sub setOpenPos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Open_Pos', $attrVal ); - - return; -} - -sub getOpenPos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_Open_Pos', - 'ASC_Open_Pos:0,10,20,30,40,50,60,70,80,90,100' ); -} - -sub getOpenPositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_Open_Pos', 'getOpenPos' ); -} - -sub setVentilatePos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Ventilate_Pos', $attrVal ); - - return; -} - -sub getVentilatePos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_Ventilate_Pos', - 'ASC_Ventilate_Pos:10,20,30,40,50,60,70,80,90,100' ); -} - -sub getVentilatePositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_Ventilate_Pos', - 'getVentilatePos' ); -} - -sub setVentilatePosAfterDayClosed { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_WindowRec_PosAfterDayClosed', - $attrVal ); - - return; -} - -sub getVentilatePosAfterDayClosed { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_WindowRec_PosAfterDayClosed', - 'open' ); -} - -sub setClosedPos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Closed_Pos', $attrVal ); - - return; -} - -sub getClosedPos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_Closed_Pos', - 'ASC_Closed_Pos:0,10,20,30,40,50,60,70,80,90,100' ); -} - -sub getClosedPositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_Closed_Pos', - 'getClosedPos' ); -} - -sub setSleepPos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Sleep_Pos', $attrVal ); - - return; -} - -sub getSleepPos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_Sleep_Pos', - 'ASC_Sleep_Pos:0,10,20,30,40,50,60,70,80,90,100' ); -} - -sub getSleepPositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_Sleep_Pos', 'getSleepPos' ); -} - -sub setVentilateOpen { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Ventilate_Window_Open', - $attrVal ); - - return; -} - -sub getVentilateOpen { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Ventilate_Window_Open', 'on' ); -} - -sub setComfortOpenPos { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_ComfortOpen_Pos', $attrVal ); - - return; -} - -sub getComfortOpenPos { - my $self = shift; - - return $shutters->_getPosition( 'ASC_ComfortOpen_Pos', - 'ASC_ComfortOpen_Pos:0,10,20,30,40,50,60,70,80,90,100' ); -} - -sub getComfortOpenPositionAssignment { - my $self = shift; - - return $shutters->_getPositionAssignment( 'ASC_ComfortOpen_Pos', - 'getComfortOpenPos' ); -} - -sub setPartyMode { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Partymode', $attrVal ); - - return; -} - -sub getPartyMode { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Partymode', 'off' ); -} - -sub setRoommates { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Roommate_Device', $attrVal ); - - return; -} - -sub getRoommates { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Roommate_Device', 'none' ); -} - -sub setRoommatesReading { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Roommate_Reading', $attrVal ); - - return; -} - -sub getRoommatesReading { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Roommate_Reading', 'state' ); -} - -sub getWindPos { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{closedPos} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} - ) < 2 - ); - $shutters->getWindMax; - - return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{closedPos}; -} - -sub getWindMax { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggermax} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} - ) < 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} = - int( gettimeofday() ); - my ( $max, $hyst, $pos ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_WindParameters', '50:20' ); - - ## Erwartetes Ergebnis - # max:hyst pos - - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggermax} = $max; - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggerhyst} = - ( $hyst ne 'none' ? $max - $hyst : $max - 20 ); - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{closedPos} = - ( $pos ne 'none' ? $pos : $shutters->getOpenPos ); - - return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggermax}; -} - -sub setWindParameters { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_WindParameters', $attrVal ); - - return; -} - -sub getWindMin { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggerhyst} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} - ) < 2 - ); - $shutters->getWindMax; - - return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggerhyst}; -} - -sub setWindProtection { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_WindProtection', $attrVal ); - - return; -} - -sub getWindProtection { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_WindProtection', 'off' ); -} - -sub setRainProtection { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_RainProtection', $attrVal ); - - return; -} - -sub getRainProtection { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_RainProtection', 'off' ); -} - -sub setModeUp { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Mode_Up', $attrVal ); - - return; -} - -sub getModeUp { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Mode_Up', 'always' ); -} - -sub setModeDown { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Mode_Down', $attrVal ); - - return; -} - -sub getModeDown { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Mode_Down', 'always' ); -} - -sub setLockOut { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_LockOut', $attrVal ); - - return; -} - -sub getLockOut { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_LockOut', 'off' ); -} - -sub setLockOutCmd { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_LockOut_Cmd', $attrVal ); - - return; -} - -sub getLockOutCmd { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_LockOut_Cmd', 'none' ); -} - -sub setAntiFreeze { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Antifreeze', $attrVal ); - - return; -} - -sub getAntiFreeze { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Antifreeze', 'off' ); -} - -sub setAutoAstroModeMorning { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeMorning', $attrVal ); - - return; -} - -sub getAutoAstroModeMorning { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeMorning', 'none' ); -} - -sub setAutoAstroModeEvening { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeEvening', $attrVal ); - - return; -} - -sub getAutoAstroModeEvening { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeEvening', 'none' ); -} - -sub setAutoAstroModeMorningHorizon { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeMorningHorizon', - $attrVal ); - - return; -} - -sub getAutoAstroModeMorningHorizon { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeMorningHorizon', - 0 ); -} - -sub setAutoAstroModeEveningHorizon { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeEveningHorizon', - $attrVal ); - - return; -} - -sub getAutoAstroModeEveningHorizon { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeEveningHorizon', - 0 ); -} - -sub setUp { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Up', $attrVal ); - - return; -} - -sub getUp { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Up', 'astro' ); -} - -sub setDown { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Down', $attrVal ); - - return; -} - -sub getDown { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_Down', 'astro' ); -} - -sub setTimeUpEarly { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Time_Up_Early', $attrVal ); - - return; -} - -sub getTimeUpEarly { - my $self = shift; - - my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_Early', '05:00' ); - - if ( defined( FHEM::AutoShuttersControl::_perlCodeCheck($val) ) ) { - $val = FHEM::AutoShuttersControl::_perlCodeCheck($val); - } - - return ( - $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms - ? $val - : '05:00' - ); -} - -sub setTimeUpLate { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Time_Up_Late', $attrVal ); - - return; -} - -sub getTimeUpLate { - my $self = shift; - - my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_Late', '08:30' ); - - if ( defined( FHEM::AutoShuttersControl::_perlCodeCheck($val) ) ) { - $val = FHEM::AutoShuttersControl::_perlCodeCheck($val); - } - - return ( - $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms - ? $val - : '08:30' - ); -} - -sub setTimeDownEarly { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Time_Down_Early', $attrVal ); - - return; -} - -sub getTimeDownEarly { - my $self = shift; - - my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Down_Early', '16:00' ); - - if ( defined( FHEM::AutoShuttersControl::_perlCodeCheck($val) ) ) { - $val = FHEM::AutoShuttersControl::_perlCodeCheck($val); - } - - return ( - $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms - ? $val - : '16:00' - ); -} - -sub setTimeDownLate { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Time_Down_Late', $attrVal ); - - return; -} - -sub getTimeDownLate { - my $self = shift; - - my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Down_Late', '22:00' ); - - if ( defined( FHEM::AutoShuttersControl::_perlCodeCheck($val) ) ) { - $val = FHEM::AutoShuttersControl::_perlCodeCheck($val); - } - - return ( - $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms - ? $val - : '22:00' - ); -} - -sub setTimeUpWeHoliday { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_Time_Up_WE_Holiday', $attrVal ); - - return; -} - -sub getTimeUpWeHoliday { - my $self = shift; - - my $val = - AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_WE_Holiday', '01:25' ); - - if ( defined( FHEM::AutoShuttersControl::_perlCodeCheck($val) ) ) { - $val = FHEM::AutoShuttersControl::_perlCodeCheck($val); - } - - return ( - $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms - ? $val - : '01:25' - ); -} - -sub getBrightnessMinVal { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermin} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} ) < 2 - ); - $shutters->_getBrightnessSensor; - - return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{triggermin}; -} - -sub getBrightnessMaxVal { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermax} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{LASTGETTIME} ) < 2 - ); - $shutters->_getBrightnessSensor; - - return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} - ->{triggermax}; -} - -sub setDriveUpMaxDuration { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_DriveUpMaxDuration', $attrVal ); - - return; -} - -sub getDriveUpMaxDuration { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_DriveUpMaxDuration', 60 ); -} - -## Subklasse Readings von ASC_Shutters ## -package ASC_Shutters::Readings; - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - ReadingsVal - ReadingsNum) - ); -} - -sub getBrightness { - my $self = shift; - - return ReadingsNum( $shutters->_getBrightnessSensor, - $shutters->getBrightnessReading, -1 ); -} - -sub getWindStatus { - my $self = shift; - - return ReadingsVal( $ascDev->_getWindSensor, - $ascDev->getWindSensorReading, -1 ); -} - -sub getStatus { - my $self = shift; - - return ReadingsNum( $self->{shuttersDev}, $shutters->getPosCmd, 0 ); -} - -sub getDelayCmd { - my $self = shift; - - return $self->{ $self->{shuttersDev} }{delayCmd}; -} - -sub getASCenable { - my $self = shift; - - return ReadingsVal( $self->{shuttersDev}, 'ASC_Enable', 'on' ); -} - -## Klasse Fenster (Window) und die Subklassen Attr und Readings ## -package ASC_Window; - -use strict; -use warnings; -use utf8; - -our @ISA = qw(ASC_Window::Attr ASC_Window::Readings); - -## Subklasse Attr von Klasse ASC_Window ## -package ASC_Window::Attr; - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - AttrVal - gettimeofday) - ); -} - -sub setSubTyp { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_WindowRec_subType', $attrVal ); - - return; -} - -sub getSubTyp { - my $self = shift; - - return AttrVal( $self->{shuttersDev}, 'ASC_WindowRec_subType', 'twostate' ); -} - -sub setWinDev { - my $self = shift; - my $attrVal = shift; - - _setAttributs( $self->{shuttersDev}, 'ASC_WindowRec', $attrVal ); - - return; -} - -sub _getWinDev { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{device} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} ) < - 2 - ); - $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} = - int( gettimeofday() ); - my ( $device, $reading ) = - FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, - 'ASC_WindowRec', 'none' ); - - ### erwartetes Ergebnis - # DEVICE:READING VALUEACTIVE:VALUEINACTIVE POSACTIVE:POSINACTIVE - - $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{device} = - $device; - $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{reading} = - ( $reading ne 'none' ? $reading : 'state' ); - - return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{device}; -} - -sub getWinDevReading { - my $self = shift; - - return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{reading} - if ( - exists( - $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} - ) - && ( gettimeofday() - - $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} ) < - 2 - ); - $shutters->_getWinDev; - - return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{reading}; -} - -## Subklasse Readings von Klasse ASC_Window ## -package ASC_Window::Readings; - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - ReadingsVal) - ); -} - -sub getWinStatus { - my $self = shift; - - return ReadingsVal( $shutters->_getWinDev, $shutters->getWinDevReading, - 'closed' ); -} - -## Klasse ASC_Roommate ## -package ASC_Roommate; - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - ReadingsVal) - ); -} - -sub _getRoommateStatus { - my $self = shift; - - my $roommate = $self->{roommate}; - - return ReadingsVal( $roommate, $shutters->getRoommatesReading, 'none' ); -} - -sub _getRoommateLastStatus { - my $self = shift; - - my $roommate = $self->{roommate}; - my $default = $self->{defaultarg}; - - $default = 'none' if ( !defined($default) ); - return ReadingsVal( $roommate, 'lastState', $default ); -} - -## Klasse ASC_Dev plus Subklassen ASC_Attr_Dev und ASC_Readings_Dev## -package ASC_Dev; -our @ISA = qw(ASC_Dev::Readings ASC_Dev::Attr); - -use strict; -use warnings; -use utf8; - -sub new { - my $class = shift; - - my $self = { name => undef, }; - - bless $self, $class; - return $self; -} - -sub setName { - my $self = shift; - my $name = shift; - - $self->{name} = $name if ( defined($name) ); - return $self->{name}; -} - -sub setDefault { - my $self = shift; - my $defaultarg = shift; - - $self->{defaultarg} = $defaultarg if ( defined($defaultarg) ); - return $self->{defaultarg}; -} - -sub getName { - my $self = shift; - return $self->{name}; -} - -## Subklasse Readings ## -package ASC_Dev::Readings; - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - readingsSingleUpdate - ReadingsVal - defs) - ); -} - -sub setDelayCmdReading { - my $self = shift; - - my $name = $self->{name}; - my $hash = $defs{$name}; - - readingsSingleUpdate( $hash, - $shutters->getShuttersDev . '_lastDelayPosValue', - $shutters->getDelayCmd, 1 ); - return; -} - -sub setStateReading { - my $self = shift; - my $value = shift; - - my $name = $self->{name}; - my $hash = $defs{$name}; - - readingsSingleUpdate( $hash, 'state', - ( defined($value) ? $value : $shutters->getLastDrive ), 1 ); - return; -} - -sub setPosReading { - my $self = shift; - - my $name = $self->{name}; - my $hash = $defs{$name}; - - readingsSingleUpdate( $hash, $shutters->getShuttersDev . '_PosValue', - $shutters->getStatus, 1 ); - return; -} - -sub setLastPosReading { - my $self = shift; - - my $name = $self->{name}; - my $hash = $defs{$name}; - - readingsSingleUpdate( $hash, $shutters->getShuttersDev . '_lastPosValue', - $shutters->getLastPos, 1 ); - return; -} - -sub getPartyMode { - my $self = shift; - - my $name = $self->{name}; - - return ReadingsVal( $name, 'partyMode', 'off' ); -} - -sub getHardLockOut { - my $self = shift; - - my $name = $self->{name}; - - return ReadingsVal( $name, 'hardLockOut', 'none' ); -} - -sub getSunriseTimeWeHoliday { - my $self = shift; - - my $name = $self->{name}; - - return ReadingsVal( $name, 'sunriseTimeWeHoliday', 'none' ); -} - -sub getMonitoredDevs { - my $self = shift; - - my $name = $self->{name}; - - $self->{monitoredDevs} = ReadingsVal( $name, '.monitoredDevs', 'none' ); - return $self->{monitoredDevs}; -} - -sub getOutTemp { - my $self = shift; - - return ReadingsVal( $ascDev->_getTempSensor, $ascDev->getTempSensorReading, - -100 ); -} - -sub getResidentsStatus { - my $self = shift; - - my $val = - ReadingsVal( $ascDev->_getResidentsDev, $ascDev->getResidentsReading, - 'none' ); - - if ( $val =~ m{^(?:(.+)_)?(.+)$}xms ) { - return ( $1, $2 ) if (wantarray); - return $1 && $1 eq 'pet' ? 'absent' : $2; - } - elsif ( - ReadingsVal( $ascDev->_getResidentsDev, 'homealoneType', '-' ) eq - 'PET' ) - { - return ( 'pet', 'absent' ) if (wantarray); - return 'absent'; - } - else { - return ( undef, $val ) if (wantarray); - return $val; - } -} - -sub getResidentsLastStatus { - my $self = shift; - - my $val = ReadingsVal( $ascDev->_getResidentsDev, 'lastState', 'none' ); - - if ( $val =~ m{^(?:(.+)_)?(.+)$}xms ) { - return ( $1, $2 ) if (wantarray); - return $1 && $1 eq 'pet' ? 'absent' : $2; - } - elsif ( - ReadingsVal( $ascDev->_getResidentsDev, 'lastHomealoneType', '-' ) eq - 'PET' ) - { - return ( 'pet', 'absent' ) if (wantarray); - return 'absent'; - } - else { - return ( undef, $val ) if (wantarray); - return $val; - } -} - -sub getAutoShuttersControlShading { - my $self = shift; - - my $name = $self->{name}; - - return ReadingsVal( $name, 'controlShading', 'none' ); -} - -sub getSelfDefense { - my $self = shift; - - my $name = $self->{name}; - - 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; -} - -sub getASCenable { - my $self = shift; - - my $name = $self->{name}; - - return ReadingsVal( $name, 'ascEnable', 'none' ); -} - -## Subklasse Attr ## -package ASC_Dev::Attr; - -use strict; -use warnings; -use utf8; - -use GPUtils qw(GP_Import); - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw( - AttrVal - gettimeofday) - ); -} - -sub getShuttersOffset { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_shuttersDriveDelay', -1 ); -} - -sub getBrightnessMinVal { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_brightness}->{triggermin} - if ( exists( $self->{ASC_brightness}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_brightness}->{LASTGETTIME} ) < 2 ); - $ascDev->getBrightnessMaxVal; - - return $self->{ASC_brightness}->{triggermin}; -} - -sub getBrightnessMaxVal { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_brightness}->{triggermax} - if ( exists( $self->{ASC_brightness}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_brightness}->{LASTGETTIME} ) < 2 ); - $self->{ASC_brightness}->{LASTGETTIME} = int( gettimeofday() ); - - my ( $triggermax, $triggermin ) = - FHEM::AutoShuttersControl::GetAttrValues( $name, - 'ASC_brightnessDriveUpDown', '800:500' ); - - ## erwartetes Ergebnis - # max:min - - $self->{ASC_brightness}->{triggermin} = $triggermin; - $self->{ASC_brightness}->{triggermax} = $triggermax; - - return $self->{ASC_brightness}->{triggermax}; -} - -sub _getTwilightDevice { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_twilightDevice', 'none' ); -} - -sub getAutoAstroModeEvening { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_autoAstroModeEvening', 'REAL' ); -} - -sub getAutoAstroModeEveningHorizon { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_autoAstroModeEveningHorizon', 0 ); -} - -sub getAutoAstroModeMorning { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_autoAstroModeMorning', 'REAL' ); -} - -sub getAutoAstroModeMorningHorizon { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_autoAstroModeMorningHorizon', 0 ); -} - -sub getAutoShuttersControlMorning { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_autoShuttersControlMorning', 'on' ); -} - -sub getAutoShuttersControlEvening { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_autoShuttersControlEvening', 'on' ); -} - -sub getAutoShuttersControlComfort { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_autoShuttersControlComfort', 'off' ); -} - -sub getFreezeTemp { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_freezeTemp', 3 ); -} - -sub getSlatDriveCmdInverse { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_slatDriveCmdInverse', 0 ); -} - -sub _getTempSensor { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_tempSensor}->{device} - if ( exists( $self->{ASC_tempSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_tempSensor}->{LASTGETTIME} ) < 2 ); - $self->{ASC_tempSensor}->{LASTGETTIME} = int( gettimeofday() ); - my ( $device, $reading ) = - FHEM::AutoShuttersControl::GetAttrValues( $name, 'ASC_tempSensor', - 'none' ); - - ## erwartetes Ergebnis - # DEVICE:READING - $self->{ASC_tempSensor}->{device} = $device; - $self->{ASC_tempSensor}->{reading} = - ( $reading ne 'none' ? $reading : 'temperature' ); - - return $self->{ASC_tempSensor}->{device}; -} - -sub getTempSensorReading { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_tempSensor}->{reading} - if ( exists( $self->{ASC_tempSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_tempSensor}->{LASTGETTIME} ) < 2 ); - $ascDev->_getTempSensor; - return $self->{ASC_tempSensor}->{reading}; -} - -sub _getResidentsDev { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_residentsDev}->{device} - if ( exists( $self->{ASC_residentsDev}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_residentsDev}->{LASTGETTIME} ) < 2 ); - $self->{ASC_residentsDev}->{LASTGETTIME} = int( gettimeofday() ); - my ( $device, $reading ) = - FHEM::AutoShuttersControl::GetAttrValues( $name, 'ASC_residentsDev', - 'none' ); - - $self->{ASC_residentsDev}->{device} = $device; - $self->{ASC_residentsDev}->{reading} = - ( $reading ne 'none' ? $reading : 'state' ); - - return $self->{ASC_residentsDev}->{device}; -} - -sub getResidentsReading { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_residentsDev}->{reading} - if ( exists( $self->{ASC_residentsDev}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_residentsDev}->{LASTGETTIME} ) < 2 ); - $ascDev->_getResidentsDev; - return $self->{ASC_residentsDev}->{reading}; -} - -sub _getRainSensor { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_rainSensor}->{device} - if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); - $self->{ASC_rainSensor}->{LASTGETTIME} = int( gettimeofday() ); - my ( $device, $reading, $max, $hyst, $pos, $wait ) = - FHEM::AutoShuttersControl::GetAttrValues( $name, 'ASC_rainSensor', - 'none' ); - - ## erwartetes Ergebnis - # DEVICE:READING MAX:HYST - - return $device if ( $device eq 'none' ); - $self->{ASC_rainSensor}->{device} = $device; - $self->{ASC_rainSensor}->{reading} = - ( $reading ne 'none' ? $reading : 'state' ); - $self->{ASC_rainSensor}->{triggermax} = ( $max ne 'none' ? $max : 1000 ); - $self->{ASC_rainSensor}->{triggerhyst} = ( - $hyst ne 'none' - ? $max - $hyst - : ( $self->{ASC_rainSensor}->{triggermax} * 0 ) - ); - $self->{ASC_rainSensor}->{shuttersClosedPos} = - ( $pos ne 'none' ? $pos : $shutters->getClosedPos ); - $self->{ASC_rainSensor}->{waitingTime} = - ( $pos ne 'none' ? $wait : 900 ); - - return $self->{ASC_rainSensor}->{device}; -} - -sub getRainSensorReading { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_rainSensor}->{reading} - if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); - $ascDev->_getRainSensor; - return $self->{ASC_rainSensor}->{reading}; -} - -sub getRainTriggerMax { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_rainSensor}->{triggermax} - if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); - $ascDev->_getRainSensor; - return $self->{ASC_rainSensor}->{triggermax}; -} - -sub getRainTriggerMin { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_rainSensor}->{triggerhyst} - if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); - $ascDev->_getRainSensor; - return $self->{ASC_rainSensor}->{triggerhyst}; -} - -sub getRainSensorShuttersClosedPos { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_rainSensor}->{shuttersClosedPos} - if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); - $ascDev->_getRainSensor; - return $self->{ASC_rainSensor}->{shuttersClosedPos}; -} - -sub getRainWaitingTime { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_rainSensor}->{waitingTime} - if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); - $ascDev->_getRainSensor; - return $self->{ASC_rainSensor}->{waitingTime}; -} - -sub _getWindSensor { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_windSensor}->{device} - if ( exists( $self->{ASC_windSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_windSensor}->{LASTGETTIME} ) < 2 ); - $self->{ASC_windSensor}->{LASTGETTIME} = int( gettimeofday() ); - my ( $device, $reading ) = - FHEM::AutoShuttersControl::GetAttrValues( $name, 'ASC_windSensor', - 'none' ); - - return $device if ( $device eq 'none' ); - $self->{ASC_windSensor}->{device} = $device; - $self->{ASC_windSensor}->{reading} = - ( $reading ne 'none' ? $reading : 'wind' ); - - return $self->{ASC_windSensor}->{device}; -} - -sub getWindSensorReading { - my $self = shift; - - my $name = $self->{name}; - - return $self->{ASC_windSensor}->{reading} - if ( exists( $self->{ASC_windSensor}->{LASTGETTIME} ) - && ( gettimeofday() - $self->{ASC_windSensor}->{LASTGETTIME} ) < 2 ); - $ascDev->_getWindSensor; - return ( - defined( $self->{ASC_windSensor}->{reading} ) - ? $self->{ASC_windSensor}->{reading} - : 'wind' - ); -} - -sub getBlockAscDrivesAfterManual { - my $self = shift; - - my $name = $self->{name}; - - return AttrVal( $name, 'ASC_blockAscDrivesAfterManual', 0 ); -} 1; - -=pod -=item device -=item summary Module for controlling shutters depending on various conditions -=item summary_DE Modul zur automatischen Rolladensteuerung auf Basis bestimmter Ereignisse - - -=begin html - - -

AutoShuttersControl

- - -=end html - -=begin html_DE - - -

AutoShuttersControl

- - -=end html_DE - -=for :application/json;q=META.json 73_AutoShuttersControl.pm -{ - "abstract": "Module for controlling shutters depending on various conditions", - "x_lang": { - "de": { - "abstract": "Modul zur Automatischen Rolladensteuerung auf Basis bestimmter Ereignisse" - } - }, - "keywords": [ - "fhem-mod-device", - "fhem-core", - "Shutter", - "Automation", - "Rollladen", - "Rollo", - "Control" - ], - "release_status": "testing", - "license": "GPL_2", - "version": "v0.9.20", - "author": [ - "Marko Oldenburg " - ], - "x_fhem_maintainer": [ - "CoolTux" - ], - "x_fhem_maintainer_github": [ - "LeonGaultier" - ], - "prereqs": { - "runtime": { - "requires": { - "FHEM": 5.00918799, - "perl": 5.016, - "Meta": 0, - "JSON": 0, - "Date::Parse": 0 - }, - "recommends": { - }, - "suggests": { - } - } - } -} -=end :application/json;q=META.json - -=cut diff --git a/lib/FHEM/Automation/ShuttersControl/Dev.pm b/lib/FHEM/Automation/ShuttersControl/Dev.pm new file mode 100644 index 0000000..71a92bb --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Dev.pm @@ -0,0 +1,79 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Klasse ASC_Dev plus Subklassen ASC_Attr_Dev und ASC_Readings_Dev## +package FHEM::Automation::ShuttersControl::Dev; +our @ISA = qw(FHEM::Automation::ShuttersControl::Dev::Readings FHEM::Automation::ShuttersControl::Dev::Attr); + +use strict; +use warnings; +use utf8; + +sub new { + my $class = shift; + + my $self = { name => undef, }; + + bless $self, $class; + return $self; +} + +sub setName { + my $self = shift; + my $name = shift; + + $self->{name} = $name if ( defined($name) ); + return $self->{name}; +} + +sub setDefault { + my $self = shift; + my $defaultarg = shift; + + $self->{defaultarg} = $defaultarg if ( defined($defaultarg) ); + return $self->{defaultarg}; +} + +sub getName { + my $self = shift; + return $self->{name}; +} + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Dev/Attr.pm b/lib/FHEM/Automation/ShuttersControl/Dev/Attr.pm new file mode 100644 index 0000000..3825771 --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Dev/Attr.pm @@ -0,0 +1,388 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Subklasse Attr ## +package ASC_Dev::Attr; + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + AttrVal + gettimeofday) + ); +} + +sub getShuttersOffset { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_shuttersDriveDelay', -1 ); +} + +sub getBrightnessMinVal { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_brightness}->{triggermin} + if ( exists( $self->{ASC_brightness}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_brightness}->{LASTGETTIME} ) < 2 ); + $ascDev->getBrightnessMaxVal; + + return $self->{ASC_brightness}->{triggermin}; +} + +sub getBrightnessMaxVal { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_brightness}->{triggermax} + if ( exists( $self->{ASC_brightness}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_brightness}->{LASTGETTIME} ) < 2 ); + $self->{ASC_brightness}->{LASTGETTIME} = int( gettimeofday() ); + + my ( $triggermax, $triggermin ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $name, + 'ASC_brightnessDriveUpDown', '800:500' ); + + ## erwartetes Ergebnis + # max:min + + $self->{ASC_brightness}->{triggermin} = $triggermin; + $self->{ASC_brightness}->{triggermax} = $triggermax; + + return $self->{ASC_brightness}->{triggermax}; +} + +sub _getTwilightDevice { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_twilightDevice', 'none' ); +} + +sub getAutoAstroModeEvening { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_autoAstroModeEvening', 'REAL' ); +} + +sub getAutoAstroModeEveningHorizon { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_autoAstroModeEveningHorizon', 0 ); +} + +sub getAutoAstroModeMorning { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_autoAstroModeMorning', 'REAL' ); +} + +sub getAutoAstroModeMorningHorizon { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_autoAstroModeMorningHorizon', 0 ); +} + +sub getAutoShuttersControlMorning { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_autoShuttersControlMorning', 'on' ); +} + +sub getAutoShuttersControlEvening { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_autoShuttersControlEvening', 'on' ); +} + +sub getAutoShuttersControlComfort { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_autoShuttersControlComfort', 'off' ); +} + +sub getFreezeTemp { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_freezeTemp', 3 ); +} + +sub getSlatDriveCmdInverse { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_slatDriveCmdInverse', 0 ); +} + +sub _getTempSensor { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_tempSensor}->{device} + if ( exists( $self->{ASC_tempSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_tempSensor}->{LASTGETTIME} ) < 2 ); + $self->{ASC_tempSensor}->{LASTGETTIME} = int( gettimeofday() ); + my ( $device, $reading ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $name, 'ASC_tempSensor', + 'none' ); + + ## erwartetes Ergebnis + # DEVICE:READING + $self->{ASC_tempSensor}->{device} = $device; + $self->{ASC_tempSensor}->{reading} = + ( $reading ne 'none' ? $reading : 'temperature' ); + + return $self->{ASC_tempSensor}->{device}; +} + +sub getTempSensorReading { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_tempSensor}->{reading} + if ( exists( $self->{ASC_tempSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_tempSensor}->{LASTGETTIME} ) < 2 ); + $ascDev->_getTempSensor; + return $self->{ASC_tempSensor}->{reading}; +} + +sub _getResidentsDev { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_residentsDev}->{device} + if ( exists( $self->{ASC_residentsDev}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_residentsDev}->{LASTGETTIME} ) < 2 ); + $self->{ASC_residentsDev}->{LASTGETTIME} = int( gettimeofday() ); + my ( $device, $reading ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $name, 'ASC_residentsDev', + 'none' ); + + $self->{ASC_residentsDev}->{device} = $device; + $self->{ASC_residentsDev}->{reading} = + ( $reading ne 'none' ? $reading : 'state' ); + + return $self->{ASC_residentsDev}->{device}; +} + +sub getResidentsReading { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_residentsDev}->{reading} + if ( exists( $self->{ASC_residentsDev}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_residentsDev}->{LASTGETTIME} ) < 2 ); + $ascDev->_getResidentsDev; + return $self->{ASC_residentsDev}->{reading}; +} + +sub _getRainSensor { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_rainSensor}->{device} + if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); + $self->{ASC_rainSensor}->{LASTGETTIME} = int( gettimeofday() ); + my ( $device, $reading, $max, $hyst, $pos, $wait ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $name, 'ASC_rainSensor', + 'none' ); + + ## erwartetes Ergebnis + # DEVICE:READING MAX:HYST + + return $device if ( $device eq 'none' ); + $self->{ASC_rainSensor}->{device} = $device; + $self->{ASC_rainSensor}->{reading} = + ( $reading ne 'none' ? $reading : 'state' ); + $self->{ASC_rainSensor}->{triggermax} = ( $max ne 'none' ? $max : 1000 ); + $self->{ASC_rainSensor}->{triggerhyst} = ( + $hyst ne 'none' + ? $max - $hyst + : ( $self->{ASC_rainSensor}->{triggermax} * 0 ) + ); + $self->{ASC_rainSensor}->{shuttersClosedPos} = + ( $pos ne 'none' ? $pos : $shutters->getClosedPos ); + $self->{ASC_rainSensor}->{waitingTime} = + ( $pos ne 'none' ? $wait : 900 ); + + return $self->{ASC_rainSensor}->{device}; +} + +sub getRainSensorReading { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_rainSensor}->{reading} + if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); + $ascDev->_getRainSensor; + return $self->{ASC_rainSensor}->{reading}; +} + +sub getRainTriggerMax { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_rainSensor}->{triggermax} + if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); + $ascDev->_getRainSensor; + return $self->{ASC_rainSensor}->{triggermax}; +} + +sub getRainTriggerMin { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_rainSensor}->{triggerhyst} + if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); + $ascDev->_getRainSensor; + return $self->{ASC_rainSensor}->{triggerhyst}; +} + +sub getRainSensorShuttersClosedPos { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_rainSensor}->{shuttersClosedPos} + if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); + $ascDev->_getRainSensor; + return $self->{ASC_rainSensor}->{shuttersClosedPos}; +} + +sub getRainWaitingTime { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_rainSensor}->{waitingTime} + if ( exists( $self->{ASC_rainSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_rainSensor}->{LASTGETTIME} ) < 2 ); + $ascDev->_getRainSensor; + return $self->{ASC_rainSensor}->{waitingTime}; +} + +sub _getWindSensor { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_windSensor}->{device} + if ( exists( $self->{ASC_windSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_windSensor}->{LASTGETTIME} ) < 2 ); + $self->{ASC_windSensor}->{LASTGETTIME} = int( gettimeofday() ); + my ( $device, $reading ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $name, 'ASC_windSensor', + 'none' ); + + return $device if ( $device eq 'none' ); + $self->{ASC_windSensor}->{device} = $device; + $self->{ASC_windSensor}->{reading} = + ( $reading ne 'none' ? $reading : 'wind' ); + + return $self->{ASC_windSensor}->{device}; +} + +sub getWindSensorReading { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ASC_windSensor}->{reading} + if ( exists( $self->{ASC_windSensor}->{LASTGETTIME} ) + && ( gettimeofday() - $self->{ASC_windSensor}->{LASTGETTIME} ) < 2 ); + $ascDev->_getWindSensor; + return ( + defined( $self->{ASC_windSensor}->{reading} ) + ? $self->{ASC_windSensor}->{reading} + : 'wind' + ); +} + +sub getBlockAscDrivesAfterManual { + my $self = shift; + + my $name = $self->{name}; + + return AttrVal( $name, 'ASC_blockAscDrivesAfterManual', 0 ); +} + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Dev/Readings.pm b/lib/FHEM/Automation/ShuttersControl/Dev/Readings.pm new file mode 100644 index 0000000..c433750 --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Dev/Readings.pm @@ -0,0 +1,242 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Subklasse Readings ## +package FHEM::Automation::ShuttersControl::Dev::Readings; + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + readingsSingleUpdate + ReadingsVal + defs) + ); +} + +sub setDelayCmdReading { + my $self = shift; + + my $name = $self->{name}; + my $hash = $defs{$name}; + + readingsSingleUpdate( $hash, + $shutters->getShuttersDev . '_lastDelayPosValue', + $shutters->getDelayCmd, 1 ); + return; +} + +sub setStateReading { + my $self = shift; + my $value = shift; + + my $name = $self->{name}; + my $hash = $defs{$name}; + + readingsSingleUpdate( $hash, 'state', + ( defined($value) ? $value : $shutters->getLastDrive ), 1 ); + return; +} + +sub setPosReading { + my $self = shift; + + my $name = $self->{name}; + my $hash = $defs{$name}; + + readingsSingleUpdate( $hash, $shutters->getShuttersDev . '_PosValue', + $shutters->getStatus, 1 ); + return; +} + +sub setLastPosReading { + my $self = shift; + + my $name = $self->{name}; + my $hash = $defs{$name}; + + readingsSingleUpdate( $hash, $shutters->getShuttersDev . '_lastPosValue', + $shutters->getLastPos, 1 ); + return; +} + +sub getPartyMode { + my $self = shift; + + my $name = $self->{name}; + + return ReadingsVal( $name, 'partyMode', 'off' ); +} + +sub getHardLockOut { + my $self = shift; + + my $name = $self->{name}; + + return ReadingsVal( $name, 'hardLockOut', 'none' ); +} + +sub getSunriseTimeWeHoliday { + my $self = shift; + + my $name = $self->{name}; + + return ReadingsVal( $name, 'sunriseTimeWeHoliday', 'none' ); +} + +sub getMonitoredDevs { + my $self = shift; + + my $name = $self->{name}; + + $self->{monitoredDevs} = ReadingsVal( $name, '.monitoredDevs', 'none' ); + return $self->{monitoredDevs}; +} + +sub getOutTemp { + my $self = shift; + + return ReadingsVal( $ascDev->_getTempSensor, $ascDev->getTempSensorReading, + -100 ); +} + +sub getResidentsStatus { + my $self = shift; + + my $val = + ReadingsVal( $ascDev->_getResidentsDev, $ascDev->getResidentsReading, + 'none' ); + + if ( $val =~ m{^(?:(.+)_)?(.+)$}xms ) { + return ( $1, $2 ) if (wantarray); + return $1 && $1 eq 'pet' ? 'absent' : $2; + } + elsif ( + ReadingsVal( $ascDev->_getResidentsDev, 'homealoneType', '-' ) eq + 'PET' ) + { + return ( 'pet', 'absent' ) if (wantarray); + return 'absent'; + } + else { + return ( undef, $val ) if (wantarray); + return $val; + } +} + +sub getResidentsLastStatus { + my $self = shift; + + my $val = ReadingsVal( $ascDev->_getResidentsDev, 'lastState', 'none' ); + + if ( $val =~ m{^(?:(.+)_)?(.+)$}xms ) { + return ( $1, $2 ) if (wantarray); + return $1 && $1 eq 'pet' ? 'absent' : $2; + } + elsif ( + ReadingsVal( $ascDev->_getResidentsDev, 'lastHomealoneType', '-' ) eq + 'PET' ) + { + return ( 'pet', 'absent' ) if (wantarray); + return 'absent'; + } + else { + return ( undef, $val ) if (wantarray); + return $val; + } +} + +sub getAutoShuttersControlShading { + my $self = shift; + + my $name = $self->{name}; + + return ReadingsVal( $name, 'controlShading', 'none' ); +} + +sub getSelfDefense { + my $self = shift; + + my $name = $self->{name}; + + 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; +} + +sub getASCenable { + my $self = shift; + + my $name = $self->{name}; + + return ReadingsVal( $name, 'ascEnable', 'none' ); +} + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Roommate.pm b/lib/FHEM/Automation/ShuttersControl/Roommate.pm new file mode 100644 index 0000000..071da3f --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Roommate.pm @@ -0,0 +1,76 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Klasse ASC_Roommate ## +package FHEM::Automation::ShuttersControl::Roommate; + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + ReadingsVal) + ); +} + +sub _getRoommateStatus { + my $self = shift; + + my $roommate = $self->{roommate}; + + return ReadingsVal( $roommate, $shutters->getRoommatesReading, 'none' ); +} + +sub _getRoommateLastStatus { + my $self = shift; + + my $roommate = $self->{roommate}; + my $default = $self->{defaultarg}; + + $default = 'none' if ( !defined($default) ); + return ReadingsVal( $roommate, 'lastState', $default ); +} + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Shutters.pm b/lib/FHEM/Automation/ShuttersControl/Shutters.pm new file mode 100644 index 0000000..058a1fa --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Shutters.pm @@ -0,0 +1,937 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +###################################### +###################################### +########## Begin der Klassendeklarierungen für OOP (Objektorientierte Programmierung) ######################### +## Klasse Rolläden (Shutters) und die Subklassen Attr und Readings ## +## desweiteren wird noch die Klasse ASC_Roommate mit eingebunden + +package FHEM::Automation::ShuttersControl::Shutters; +our @ISA = + qw(FHEM::Automation::ShuttersControl::Shutters::Readings FHEM::Automation::ShuttersControl::Shutters::Attr FHEM::Automation::ShuttersControl::Roommate FHEM::Automation::ShuttersControl::Window); + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + defs + ReadingsVal + readingsSingleUpdate + gettimeofday + InternalTimer + CommandSet + Log3) + ); +} + +sub new { + my $class = shift; + my $self = { + shuttersDev => undef, + defaultarg => undef, + roommate => undef, + }; + + bless $self, $class; + return $self; +} + +sub setShuttersDev { + my $self = shift; + my $shuttersDev = shift; + + $self->{shuttersDev} = $shuttersDev if ( defined($shuttersDev) ); + return $self->{shuttersDev}; +} + +sub getShuttersDev { + my $self = shift; + + return $self->{shuttersDev}; +} + +sub setAttrUpdateChanges { + my ( $self, $attr, $value ) = @_; + + $self->{ $self->{shuttersDev} }{AttrUpdateChanges}{$attr} = $value; + return; +} + +sub setHardLockOut { + my $self = shift; + my $cmd = shift; + + if ( $shutters->getLockOut eq 'hard' + && $shutters->getLockOutCmd ne 'none' ) + { + CommandSet( undef, $self->{shuttersDev} . ' inhibit ' . $cmd ) + if ( $shutters->getLockOutCmd eq 'inhibit' ); + CommandSet( undef, + $self->{shuttersDev} . ' ' + . ( $cmd eq 'on' ? 'blocked' : 'unblocked' ) ) + if ( $shutters->getLockOutCmd eq 'blocked' ); + CommandSet( undef, + $self->{shuttersDev} . ' ' + . ( $cmd eq 'on' ? 'protectionOn' : 'protectionOff' ) ) + if ( $shutters->getLockOutCmd eq 'protected' ); + } + return; +} + +sub setNoDelay { + my $self = shift; + my $noDelay = shift; + + $self->{ $self->{shuttersDev} }{noDelay} = $noDelay; + return; +} + +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; +} + +sub setDriveCmd { + my $self = shift; + my $posValue = shift; + + my $offSet; + my $offSetStart; + + if ( + ( $shutters->getPartyMode eq 'on' && $ascDev->getPartyMode eq 'on' ) + || ( $shutters->getAdv + && !$shutters->getQueryShuttersPos($posValue) + && !$shutters->getAdvDelay + && !$shutters->getExternalTriggerState + && !$shutters->getSelfDefenseState ) + ) + { + $shutters->setDelayCmd($posValue); + $ascDev->setDelayCmdReading; + $shutters->setNoDelay(0); + $shutters->setExternalTriggerState(0) + if ( $shutters->getExternalTriggerState ); + + FHEM::AutoShuttersControl::ASC_Debug( 'setDriveCmd: ' + . $shutters->getShuttersDev + . ' - Die Fahrt wird zurückgestellt. Grund kann ein geöffnetes Fenster sein oder ein aktivierter Party Modus oder Weihnachtszeit' + ); + } + else { + $shutters->setAdvDelay(0) + if ( $shutters->getAdvDelay ); + $shutters->setDelayCmd('none') + if ( $shutters->getDelayCmd ne 'none' ) + ; # setzt den Wert auf none da der Rolladen nun gesteuert werden kann. + $shutters->setExternalTriggerState(0) + if ( $shutters->getExternalTriggerState ); + + ### antifreeze Routine + if ( $shutters->getAntiFreezeStatus > 0 ) { + if ( $shutters->getAntiFreezeStatus != 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, + ); + + $offSet = $shutters->getDelay if ( $shutters->getDelay > -1 ); + $offSet = $ascDev->getShuttersOffset if ( $shutters->getDelay < 0 ); + $offSetStart = $shutters->getDelayStart; + + if ( $shutters->getSelfDefenseAbsent + && !$shutters->getSelfDefenseAbsentTimerrun + && $shutters->getSelfDefenseMode ne 'off' + && $shutters->getSelfDefenseState + && $ascDev->getSelfDefense eq 'on' ) + { + InternalTimer( + gettimeofday() + $shutters->getSelfDefenseAbsentDelay, + \&FHEM::Automation::ShuttersControl::_SetCmdFn, \%h ); + $shutters->setSelfDefenseAbsent( 1, 0, \%h ); + } + elsif ( $offSetStart > 0 && !$shutters->getNoDelay ) { + InternalTimer( + gettimeofday() + + int( rand($offSet) + $shutters->getDelayStart ), + \&FHEM::Automation::ShuttersControl::_SetCmdFn, \%h + ); + + FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' + . $shutters->getShuttersDev + . ' - versetztes fahren' ); + } + elsif ( $offSetStart < 1 || $shutters->getNoDelay ) { + FHEM::Automation::ShuttersControl::_SetCmdFn( \%h ); + FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' + . $shutters->getShuttersDev + . ' - NICHT versetztes fahren' ); + } + + FHEM::AutoShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' + . $shutters->getShuttersDev + . ' - NoDelay: ' + . ( $shutters->getNoDelay ? 'JA' : 'NEIN' ) ); + $shutters->setNoDelay(0); + } + + return; +} + +sub setSunsetUnixTime { + my $self = shift; + my $unixtime = shift; + + $self->{ $self->{shuttersDev} }{sunsettime} = $unixtime; + return; +} + +sub setSunset { + my $self = shift; + my $value = shift; + + $self->{ $self->{shuttersDev} }{sunset} = $value; + return; +} + +sub setSunriseUnixTime { + my $self = shift; + my $unixtime = shift; + + $self->{ $self->{shuttersDev} }{sunrisetime} = $unixtime; + return; +} + +sub setSunrise { + my $self = shift; + my $value = shift; + + $self->{ $self->{shuttersDev} }{sunrise} = $value; + return; +} + +sub setDelayCmd { + my $self = shift; + my $posValue = shift; + + $self->{ $self->{shuttersDev} }{delayCmd} = $posValue; + return; +} + +sub setLastDrive { + my $self = shift; + my $lastDrive = shift; + + $self->{ $self->{shuttersDev} }{lastDrive} = $lastDrive; + return; +} + +sub setPosSetCmd { + my $self = shift; + my $posSetCmd = shift; + + $self->{ $self->{shuttersDev} }{posSetCmd} = $posSetCmd; + return; +} + +sub setLastDriveReading { + my $self = shift; + my $shuttersDevHash = $defs{ $self->{shuttersDev} }; + + my %h = ( + devHash => $shuttersDevHash, + lastDrive => $shutters->getLastDrive, + ); + + InternalTimer( gettimeofday() + 0.1, + \&FHEM::Automation::ShuttersControl::_setShuttersLastDriveDelayed, \%h ); + return; +} + +sub setLastPos { + +# letzte ermittelte Position bevor die Position des Rolladen über ASC geändert wurde + my $self = shift; + my $position = shift; + + $self->{ $self->{shuttersDev} }{lastPos}{VAL} = $position + if ( defined($position) ); + $self->{ $self->{shuttersDev} }{lastPos}{TIME} = int( gettimeofday() ) + if ( defined( $self->{ $self->{shuttersDev} }{lastPos} ) ); + return; +} + +sub setLastManPos { + my $self = shift; + my $position = shift; + + $self->{ $self->{shuttersDev} }{lastManPos}{VAL} = $position + if ( defined($position) ); + $self->{ $self->{shuttersDev} }{lastManPos}{TIME} = int( gettimeofday() ) + if ( defined( $self->{ $self->{shuttersDev} }{lastManPos} ) + && defined( $self->{ $self->{shuttersDev} }{lastManPos}{TIME} ) ); + $self->{ $self->{shuttersDev} }{lastManPos}{TIME} = + int( gettimeofday() ) - 86400 + if ( defined( $self->{ $self->{shuttersDev} }{lastManPos} ) + && !defined( $self->{ $self->{shuttersDev} }{lastManPos}{TIME} ) ); + return; +} + +sub setDefault { + my $self = shift; + my $defaultarg = shift; + + $self->{defaultarg} = $defaultarg if ( defined($defaultarg) ); + return $self->{defaultarg}; +} + +sub setRoommate { + my $self = shift; + my $roommate = shift; + + $self->{roommate} = $roommate if ( defined($roommate) ); + return $self->{roommate}; +} + +sub setInTimerFuncHash { + my $self = shift; + my $inTimerFuncHash = shift; + + $self->{ $self->{shuttersDev} }{inTimerFuncHash} = $inTimerFuncHash + if ( defined($inTimerFuncHash) ); + return; +} + +sub setPrivacyDownStatus { + my $self = shift; + my $statusValue = shift; + + $self->{ $self->{shuttersDev} }->{privacyDownStatus} = $statusValue; + return; +} + +sub setPrivacyUpStatus { + my $self = shift; + my $statusValue = shift; + + $self->{ $self->{shuttersDev} }->{privacyUpStatus} = $statusValue; + return; +} + +sub setSelfDefenseState { + my $self = shift; + my $value = shift; + + $self->{ $self->{shuttersDev} }{selfDefenseState} = $value; + return; +} + +sub setAdvDelay { + my $self = shift; + my $advDelay = shift; + + $self->{ $self->{shuttersDev} }->{AdvDelay} = $advDelay; + return; +} + +sub getHomemode { + my $self = shift; + + my $homemode = $shutters->getRoommatesStatus; + $homemode = $ascDev->getResidentsStatus + if ( $homemode eq 'none' ); + return $homemode; +} + +sub getAdvDelay { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }->{AdvDelay} ) + ? $self->{ $self->{shuttersDev} }->{AdvDelay} + : 0 + ); +} + +sub getPrivacyDownStatus { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }->{privacyDownStatus} ) + ? $self->{ $self->{shuttersDev} }->{privacyDownStatus} + : undef + ); +} + +sub getPrivacyUpStatus { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }->{privacyUpStatus} ) + ? $self->{ $self->{shuttersDev} }->{privacyUpStatus} + : undef + ); +} + +sub getAttrUpdateChanges { + my $self = shift; + my $attr = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{AttrUpdateChanges} ) + && defined( + $self->{ $self->{shuttersDev} }{AttrUpdateChanges}{$attr} ) + ? $self->{ $self->{shuttersDev} }{AttrUpdateChanges}{$attr} + : 'none' + ); +} + +sub getIsDay { + my $self = shift; + + return FHEM::AutoShuttersControl::_IsDay( $self->{shuttersDev} ); +} + +sub getAntiFreezeStatus { + use POSIX qw(strftime); + my $self = shift; + my $daytime = strftime( "%P", localtime() ); + $daytime = ( + defined($daytime) && $daytime + ? $daytime + : ( strftime( "%k", localtime() ) < 12 ? 'am' : 'pm' ) + ); + my $outTemp = $ascDev->getOutTemp; + +# $outTemp = $shutters->getOutTemp if ( $shutters->getOutTemp != -100 ); sollte raus das der Sensor im Rollo auch ein Innentemperatursensor sein kann. + + if ( $shutters->getAntiFreeze ne 'off' + && $outTemp <= $ascDev->getFreezeTemp ) + { + + if ( $shutters->getAntiFreeze eq 'soft' ) { + return 1; + } + elsif ( $shutters->getAntiFreeze eq $daytime ) { + return 2; + } + elsif ( $shutters->getAntiFreeze eq 'hard' ) { + return 3; + } + } + else { return 0; } +} + +sub getShuttersPosCmdValueNegate { + my $self = shift; + + return ( $shutters->getOpenPos < $shutters->getClosedPos ? 1 : 0 ); +} + +sub getQueryShuttersPos +{ # Es wird geschaut ob die aktuelle Position des Rollos unterhalb der Zielposition ist + my $self = shift; + my $posValue = shift; # wenn dem so ist wird 1 zurück gegeben ansonsten 0 + + return ( + $shutters->getShuttersPosCmdValueNegate + ? $shutters->getStatus > $posValue + : $shutters->getStatus < $posValue + ); +} + +sub getPosSetCmd { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{posSetCmd} ) + ? $self->{ $self->{shuttersDev} }{posSetCmd} + : $shutters->getPosCmd + ); +} + +sub getNoDelay { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{noDelay}; +} + +sub getSelfDefenseState { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{selfDefenseState} ) + ? $self->{ $self->{shuttersDev} }{selfDefenseState} + : 0 + ); +} + +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 ( + defined( + $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerhash} + ) + ? $self->{ $self->{shuttersDev} }{selfDefenseAbsent}{timerhash} + : undef + ); +} + +sub getLastDrive { + my $self = shift; + + $self->{ $self->{shuttersDev} }{lastDrive} = + ReadingsVal( $self->{shuttersDev}, 'ASC_ShuttersLastDrive', 'none' ) + if ( !defined( $self->{ $self->{shuttersDev} }{lastDrive} ) ); + + return $self->{ $self->{shuttersDev} }{lastDrive}; +} + +sub getLastPos +{ # letzte ermittelte Position bevor die Position des Rolladen über ASC geändert wurde + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{lastPos} ) + && defined( $self->{ $self->{shuttersDev} }{lastPos}{VAL} ) + ? $self->{ $self->{shuttersDev} }{lastPos}{VAL} + : 50 + ); +} + +sub getLastPosTimestamp { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} } ) + && defined( $self->{ $self->{shuttersDev} }{lastPos} ) + && defined( $self->{ $self->{shuttersDev} }{lastPos}{TIME} ) + ? $self->{ $self->{shuttersDev} }{lastPos}{TIME} + : 0 + ); +} + +sub getLastManPos +{ # letzte ermittelte Position bevor die Position des Rolladen manuell (nicht über ASC) geändert wurde + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{lastManPos} ) + && defined( $self->{ $self->{shuttersDev} }{lastManPos}{VAL} ) + ? $self->{ $self->{shuttersDev} }{lastManPos}{VAL} + : 50 + ); +} + +sub getLastManPosTimestamp { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} } ) + && defined( $self->{ $self->{shuttersDev} }{lastManPos} ) + && defined( $self->{ $self->{shuttersDev} }{lastManPos}{TIME} ) + ? $self->{ $self->{shuttersDev} }{lastManPos}{TIME} + : 0 + ); +} + +sub getInTimerFuncHash { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{inTimerFuncHash}; +} + +sub getSunsetUnixTime { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{sunsettime}; +} + +sub getSunset { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{sunset} ) + ? $self->{ $self->{shuttersDev} }{sunset} + : 0 + ); +} + +sub getSunriseUnixTime { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{sunrisetime}; +} + +sub getSunrise { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{sunrise} ) + ? $self->{ $self->{shuttersDev} }{sunrise} + : 0 + ); +} + +sub getRoommatesStatus { + my $self = shift; + + my $loop = 0; + my @roState; + my %statePrio = ( + 'asleep' => 1, + 'gotosleep' => 2, + 'awoken' => 3, + 'home' => 4, + 'absent' => 5, + 'gone' => 6, + 'none' => 7 + ); + my $minPrio = 10; + + for my $ro ( split( ",", $shutters->getRoommates ) ) { + $shutters->setRoommate($ro); + my $currentPrio = $statePrio{ $shutters->_getRoommateStatus }; + $minPrio = $currentPrio if ( $minPrio > $currentPrio ); + } + + my %revStatePrio = reverse %statePrio; + return $revStatePrio{$minPrio}; +} + +sub getRoommatesLastStatus { + my $self = shift; + + my $loop = 0; + my @roState; + my %statePrio = ( + 'asleep' => 1, + 'gotosleep' => 2, + 'awoken' => 3, + 'home' => 6, + 'absent' => 5, + 'gone' => 4, + 'none' => 7 + ); + my $minPrio = 10; + + for my $ro ( split( ",", $shutters->getRoommates ) ) { + $shutters->setRoommate($ro); + my $currentPrio = $statePrio{ $shutters->_getRoommateLastStatus }; + $minPrio = $currentPrio if ( $minPrio > $currentPrio ); + } + + my %revStatePrio = reverse %statePrio; + return $revStatePrio{$minPrio}; +} + +sub getOutTemp { + my $self = shift; + + return ReadingsVal( $shutters->_getTempSensor, + $shutters->getTempSensorReading, -100 ); +} + +sub getIdleDetection { + my $self = shift; + + return ReadingsVal( $self->{shuttersDev}, + $shutters->_getIdleDetectionReading, 'none' ); +} + +### Begin Beschattung Objekt mit Daten befüllen +sub setShadingStatus { + my $self = shift; + my $value = shift; ### Werte für value = in, out, in reserved, out reserved + + return + if ( defined($value) + && exists( $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} ) + && $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} eq $value ); + + $shutters->setShadingLastStatus( ( $value eq 'in' ? 'out' : 'in' ) ) + if ( $value eq 'in' + || $value eq 'out' ); + + $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} = $value + if ( defined($value) ); + $self->{ $self->{shuttersDev} }{ShadingStatus}{TIME} = int( gettimeofday() ) + if ( defined( $self->{ $self->{shuttersDev} }{ShadingStatus} ) ); + + return; +} + +sub setShadingLastStatus { + my $self = shift; + my $value = shift; ### Werte für value = in, out + + return + if ( defined($value) + && exists( $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} ) + && $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} eq $value ); + + $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} = $value + if ( defined($value) ); + $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} = + int( gettimeofday() ) + if ( defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) ); + $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} = 0 + if ( $value eq 'out' ); + + return; +} + +sub setShadingManualDriveStatus { + my $self = shift; + my $value = shift; ### Werte für value = 0, 1 + + $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} = $value + if ( defined($value) ); + + return; +} + +sub setWindProtectionStatus { # Werte protected, unprotected + my $self = shift; + my $value = shift; + + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{VAL} = $value + if ( defined($value) ); + + return; +} + +sub setRainProtectionStatus { # Werte protected, unprotected + my $self = shift; + my $value = shift; + + $self->{ $self->{shuttersDev} }->{RainProtection}->{VAL} = $value + if ( defined($value) ); + return; +} + +sub setExternalTriggerState { + my $self = shift; + my $value = shift; + + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} = $value + if ( defined($value) ); + + return; +} + +sub setPushBrightnessInArray { + my $self = shift; + my $value = shift; + + unshift( + @{ $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} }, + $value + ); + pop( @{ $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} } ) + if ( + scalar( + @{ + $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} + } + ) > $shutters->getMaxBrightnessAverageArrayObjects + ); + + return; +} + +sub getBrightnessAverage { + my $self = shift; + + return FHEM::AutoShuttersControl::_averageBrightness( + @{ $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} } ) + if ( + ref( $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} ) + eq 'ARRAY' + && scalar( + @{ + $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{VAL} + } + ) > 0 + ); + + return; +} + +sub getShadingStatus { # Werte für value = in, out, in reserved, out reserved + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{ShadingStatus} ) + && defined( $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} ) + ? $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} + : 'out' + ); +} + +sub getShadingLastStatus { # Werte für value = in, out + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) + && defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} ) + ? $self->{ $self->{shuttersDev} }{ShadingLastStatus}{VAL} + : 'out' + ); +} + +sub getShadingManualDriveStatus { # Werte für value = 0, 1 + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus} ) + && defined( + $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} + ) + ? $self->{ $self->{shuttersDev} }{ShadingManualDriveStatus}{VAL} + : 0 + ); +} + +sub getIfInShading { + my $self = shift; + + return ( + ( + $shutters->getShadingMode ne 'off' + && $shutters->getShadingLastStatus eq 'out' + ) ? 1 : 0 + ); +} + +sub getWindProtectionStatus { # Werte protected, unprotected + my $self = shift; + + return ( + ( + defined( $self->{ $self->{shuttersDev} }->{ASC_WindParameters} ) + && defined( + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{VAL} + ) + ) + ? $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{VAL} + : 'unprotected' + ); +} + +sub getRainProtectionStatus { # Werte protected, unprotected + my $self = shift; + + return ( + ( + defined( $self->{ $self->{shuttersDev} }->{RainProtection} ) + && defined( + $self->{ $self->{shuttersDev} }->{RainProtection}->{VAL} + ) + ) + ? $self->{ $self->{shuttersDev} }->{RainProtection}->{VAL} + : 'unprotected' + ); +} + +sub getShadingStatusTimestamp { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} } ) + && defined( $self->{ $self->{shuttersDev} }{ShadingStatus} ) + && defined( $self->{ $self->{shuttersDev} }{ShadingStatus}{TIME} ) + ? $self->{ $self->{shuttersDev} }{ShadingStatus}{TIME} + : 0 + ); +} + +sub getShadingLastStatusTimestamp { + my $self = shift; + + return ( + defined( $self->{ $self->{shuttersDev} } ) + && defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus} ) + && defined( $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} ) + ? $self->{ $self->{shuttersDev} }{ShadingLastStatus}{TIME} + : 0 + ); +} +### Ende Beschattung + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Shutters/Attr.pm b/lib/FHEM/Automation/ShuttersControl/Shutters/Attr.pm new file mode 100644 index 0000000..d132347 --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Shutters/Attr.pm @@ -0,0 +1,1948 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Subklasse Attr von ASC_Shutters## +package FHEM::Automation::ShuttersControl::Shutters::Attr; + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + AttrVal + CommandAttr + gettimeofday) + ); +} + +sub _setAttributs { + my $shuttersDev = shift; + my $attr = shift; + my $attrVal = shift; + + CommandAttr( undef, $shuttersDev . ' ' . $attr . ' ' . $attrVal ); + + return; +} + +sub _getPosition { + my $self = shift; + + my $attr = shift; + my $userAttrList = shift; + + return $self->{ $self->{shuttersDev} }->{$attr}->{position} + if ( + exists( $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} = + int( gettimeofday() ); + + my $position; + my $posAssignment; + + if ( + AttrVal( $self->{shuttersDev}, $attr, + $userAttrList{$userAttrList} + [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] ) =~ + m{\A\{.+\}\z}xms + ) + { + my $response = FHEM::Automation::ShuttersControl::_perlCodeCheck( + AttrVal( + $self->{shuttersDev}, + $attr, + $userAttrList{$userAttrList} + [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] + ) + ); + + ( $position, $posAssignment ) = split ':', $response; + + $position = ( + $position =~ m{\A\d+(\.\d+)?\z}xms + ? $position + : $userAttrList{$userAttrList} + [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] + ); + + $posAssignment = ( + $posAssignment =~ m{\A\d+(\.\d+)?\z}xms + ? $posAssignment + : 'none' + ); + } + else { + ( $position, $posAssignment ) = + FHEM::Automation::ShuttersControl::GetAttrValues( + $self->{shuttersDev}, + $attr, + $userAttrList{$userAttrList} + [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] + ); + } + + ### erwartetes Ergebnis + # DEVICE:READING + $self->{ $self->{shuttersDev} }->{$attr}->{position} = $position; + $self->{ $self->{shuttersDev} }->{$attr}->{posAssignment} = + $posAssignment; + + return $self->{ $self->{shuttersDev} }->{$attr}->{position}; + + if ( + defined( + FHEM::Automation::ShuttersControl::_perlCodeCheck( + $self->{ $self->{shuttersDev} }->{$attr}->{position} + ) + ) + ) + { + $self->{ $self->{shuttersDev} }->{$attr}->{position} = + FHEM::Automation::ShuttersControl::_perlCodeCheck( + $self->{ $self->{shuttersDev} }->{$attr}->{position} ); + } + + return ( + $self->{ $self->{shuttersDev} }->{$attr}->{position} =~ + m{^\d+(\.\d+)?$}xms + ? $self->{ $self->{shuttersDev} }->{$attr}->{position} + : $userAttrList{$userAttrList} + [ AttrVal( $self->{shuttersDev}, 'ASC', 2 ) ] + ); +} + +sub _getPositionAssignment { + my $self = shift; + + my $attr = shift; + my $getFn = shift; + + return $self->{ $self->{shuttersDev} }->{$attr}->{posAssignment} + if ( + exists( $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{$attr}->{LASTGETTIME} ) < 2 + ); + $shutters->$getFn; + + return ( $self->{ $self->{shuttersDev} }->{$attr}->{posAssignment} ); +} + +sub setAntiFreezePos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Antifreeze_Pos', $attrVal ); + + return; +} + +sub getAntiFreezePos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_Antifreeze_Pos', +'ASC_Antifreeze_Pos:5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100' + ); +} + +sub getAntiFreezePosAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_Antifreeze_Pos', + 'getAntiFreezePos' ); +} + +sub setShuttersPlace { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_ShuttersPlace', $attrVal ); + + return; +} + +sub getShuttersPlace { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_ShuttersPlace', 'window' ); +} + +sub setSlatPosCmd { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_SlatPosCmd_SlatDevice', + $attrVal ); + + return; +} + +sub getSlatPosCmd { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} + ->{poscmd} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{LASTGETTIME} + = int( gettimeofday() ); + my ( $slatPosCmd, $slatDevice ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_SlatPosCmd_SlatDevice', 'none:none' ); + + ## Erwartetes Ergebnis + # upTime:upBrightnessVal + + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{poscmd} = + $slatPosCmd; + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{device} = + $slatDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} + ->{poscmd}; +} + +sub getSlatDevice { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} + ->{device} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getSlatPosCmd; + + return ( + $self->{ $self->{shuttersDev} }->{ASC_SlatPosCmd_SlatDevice}->{device} + ); +} + +sub setPrivacyUpTime { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_PrivacyUpValue_beforeDayOpen', + $attrVal ); + + return; +} + +sub getPrivacyUpTime { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{uptime} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{LASTGETTIME} = int( gettimeofday() ); + my ( $upTime, $upBrightnessVal ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_PrivacyUpValue_beforeDayOpen', '-1:-1' ); + + ## Erwartetes Ergebnis + # upTime:upBrightnessVal + + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{uptime} = $upTime; + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{upbrightnessval} = + ( $upBrightnessVal ne 'none' ? $upBrightnessVal : -1 ); + + $shutters->setPrivacyUpStatus(0) + if ( defined( $shutters->getPrivacyUpStatus ) + && $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{uptime} == -1 ); + + return $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{uptime}; +} + +sub getPrivacyUpBrightnessVal { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{upbrightnessval} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getPrivacyUpTime; + + return ( + defined( + $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{upbrightnessval} + ) + ? $self->{ $self->{shuttersDev} }->{ASC_PrivacyUpValue_beforeDayOpen} + ->{upbrightnessval} + : -1 + ); +} + +sub setPrivacyDownTime { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, + 'ASC_PrivacyDownValue_beforeNightClose', $attrVal ); + + return; +} + +sub getPrivacyDownTime { + my $self = shift; + + return $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{downtime} + if ( + exists( + $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_PrivacyDownValue_beforeNightClose} + ->{LASTGETTIME} = int( gettimeofday() ); + my ( $downTime, $downBrightnessVal ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_PrivacyDownValue_beforeNightClose', '-1:-1' ); + + ## Erwartetes Ergebnis + # downTime:downBrightnessVal + + $self->{ $self->{shuttersDev} }->{ASC_PrivacyDownValue_beforeNightClose} + ->{downtime} = $downTime; + $self->{ $self->{shuttersDev} }->{ASC_PrivacyDownValue_beforeNightClose} + ->{downbrightnessval} = + ( $downBrightnessVal ne 'none' ? $downBrightnessVal : -1 ); + + $shutters->setPrivacyDownStatus(0) + if ( defined( $shutters->getPrivacyDownStatus ) + && $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{downtime} == -1 ); + + return $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{downtime}; +} + +sub getPrivacyDownBrightnessVal { + my $self = shift; + + return $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{downbrightnessval} + if ( + exists( + $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{LASTGETTIME} ) < 2 + ); + $shutters->getPrivacyDownTime; + + return ( + defined( + $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{downbrightnessval} + ) + ? $self->{ $self->{shuttersDev} } + ->{ASC_PrivacyDownValue_beforeNightClose}->{downbrightnessval} + : -1 + ); +} + +sub setPrivacyUpPos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_PrivacyUp_Pos', $attrVal ); + + return; +} + +sub getPrivacyUpPos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_PrivacyUp_Pos', 'ASC_PrivacyUp_Pos' ); +} + +sub getPrivacyUpPositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_PrivacyUp_Pos', + 'getPrivacyUpPos' ); +} + +sub setPrivacyDownPos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_PrivacyDown_Pos', $attrVal ); + + return; +} + +sub getPrivacyDownPos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_PrivacyDown_Pos', + 'ASC_PrivacyDown_Pos' ); +} + +sub getPrivacyDownPositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_PrivacyDown_Pos', + 'getPrivacyDownPos' ); +} + +sub setSelfDefenseMode { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Self_Defense_Mode', $attrVal ); + + return; +} + +sub getSelfDefenseMode { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_Mode', 'gone' ); +} + +sub setSelfDefenseAbsentDelay { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Self_Defense_AbsentDelay', + $attrVal ); + + return; +} + +sub getSelfDefenseAbsentDelay { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_AbsentDelay', 300 ); +} + +sub setWiggleValue { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_WiggleValue', $attrVal ); + + return; +} + +sub getWiggleValue { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_WiggleValue', 5 ); +} + +sub setAdv { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Adv', $attrVal ); + + return; +} + +sub getAdv { + my $self = shift; + + return ( + AttrVal( $self->{shuttersDev}, 'ASC_Adv', 'off' ) eq 'on' + ? ( FHEM::Automation::ShuttersControl::_IsAdv == 1 ? 1 : 0 ) + : 0 + ); +} + +### Begin Beschattung +sub setShadingPos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shading_Pos', $attrVal ); + + return; +} + +sub getShadingPos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_Shading_Pos', + 'ASC_Shading_Pos:10,20,30,40,50,60,70,80,90,100' ); +} + +sub getShadingPositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_Shading_Pos', + 'getShadingPos' ); +} + +sub setShadingMode { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shading_Mode', $attrVal ); + + return; +} + +sub getShadingMode { + my $self = shift; + + 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} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{LASTGETTIME} ) + < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_TempSensor}->{LASTGETTIME} = + int( gettimeofday() ); + my ( $device, $reading ) = + FHEM::Automation::ShuttersControl::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} + ) + && ( 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 setIdleDetectionReading { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shutter_IdleDetection', + $attrVal ); + + return; +} + +sub _getIdleDetectionReading { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} + ->{reading} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{LASTGETTIME} + = int( gettimeofday() ); + my ( $reading, $value ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_Shutter_IdleDetection', 'none' ); + + ### erwartetes Ergebnis + # READING:VALUE + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{reading} = + $reading; + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{value} = + $value; + + return $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} + ->{reading}; +} + +sub getIdleDetectionValue { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{value} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} + ->{LASTGETTIME} ) < 2 + ); + $shutters->_getIdleDetectionReading; + + return ( + defined( + $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection} + ->{value} + ) + ? $self->{ $self->{shuttersDev} }->{ASC_Shutter_IdleDetection}->{value} + : 'none' + ); +} + +sub setBrightnessSensor { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_BrightnessSensor', $attrVal ); + + return; +} + +sub _getBrightnessSensor { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{LASTGETTIME} = + int( gettimeofday() ); + my ( $device, $reading, $max, $min ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_BrightnessSensor', 'none' ); + + ### erwartetes Ergebnis + # DEVICE:READING MAX:MIN + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device} = $device; + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} = + ( $reading ne 'none' ? $reading : 'brightness' ); + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermin} = + ( $min ne 'none' ? $min : -1 ); + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermax} = + ( $max ne 'none' ? $max : -1 ); + + return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device}; +} + +sub getBrightnessReading { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} ) < 2 + ); + $shutters->_getBrightnessSensor; + + return ( + defined( + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} + ) + ? $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} + : 'brightness' + ); +} + +sub getShadingAzimuthLeft { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{leftVal} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getShadingAzimuthRight; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{leftVal}; +} + +sub setShadingInOutAzimuth { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shading_InOutAzimuth', $attrVal ); + + return; +} + +sub getShadingAzimuthRight { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{rightVal} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth}->{LASTGETTIME} + = int( gettimeofday() ); + my ( $left, $right ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_Shading_InOutAzimuth', '95:265' ); + + ### erwartetes Ergebnis + # MIN:MAX + + $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth}->{leftVal} = + $left; + $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth}->{rightVal} = + $right; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_InOutAzimuth} + ->{rightVal}; +} + +sub setShadingMinOutsideTemperature { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shading_Min_OutsideTemperature', + $attrVal ); + + return; +} + +sub getShadingMinOutsideTemperature { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Min_OutsideTemperature', + 18 ); +} + +sub setShadingMinMaxElevation { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shading_MinMax_Elevation', + $attrVal ); + + return; +} + +sub getShadingMinElevation { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{minVal} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} = int( gettimeofday() ); + my ( $min, $max ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_Shading_MinMax_Elevation', '25.0:100.0' ); + + ### erwartetes Ergebnis + # MIN:MAX + + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation}->{minVal} = + $min; + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation}->{maxVal} = + ( $max ne 'none' ? $max : 100 ); + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{minVal}; +} + +sub getShadingMaxElevation { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{maxVal} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getShadingMinElevation; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{maxVal}; +} + +sub setShadingStateChangeSunnyCloudy { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shading_StateChange_SunnyCloudy', + $attrVal ); + + return; +} + +sub getShadingStateChangeSunny { + my $self = shift; + + return $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{sunny} + if ( + exists( + $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_Shading_StateChange_SunnyCloudy} + ->{LASTGETTIME} = int( gettimeofday() ); + my ( $sunny, $cloudy, $maxBrightnessAverageArrayObjects ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_Shading_StateChange_SunnyCloudy', + '35000:20000' ); + + ### erwartetes Ergebnis + # SUNNY:CLOUDY [BrightnessAverage] + + $self->{ $self->{shuttersDev} }->{ASC_Shading_StateChange_SunnyCloudy} + ->{sunny} = $sunny; + $self->{ $self->{shuttersDev} }->{ASC_Shading_StateChange_SunnyCloudy} + ->{cloudy} = $cloudy; + $self->{ $self->{shuttersDev} }->{BrightnessAverageArray}->{MAXOBJECT} = ( + defined($maxBrightnessAverageArrayObjects) + && $maxBrightnessAverageArrayObjects ne 'none' + ? $maxBrightnessAverageArrayObjects + : 3 + ); + + return $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{sunny}; +} + +sub getShadingStateChangeCloudy { + my $self = shift; + + return $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{cloudy} + if ( + exists( + $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} ) < 2 + ); + $shutters->getShadingStateChangeSunny; + + return $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{cloudy}; +} + +sub getMaxBrightnessAverageArrayObjects { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{BrightnessAverageArray} + ->{MAXOBJECT} + if ( + exists( + $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} } + ->{ASC_Shading_StateChange_SunnyCloudy}->{LASTGETTIME} ) < 2 + ); + $shutters->getShadingStateChangeSunny; + + return $self->{ $self->{shuttersDev} }->{BrightnessAverageArray} + ->{MAXOBJECT}; +} + +sub setShadingWaitingPeriod { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Shading_WaitingPeriod', + $attrVal ); + + return; +} + +sub getShadingWaitingPeriod { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Shading_WaitingPeriod', 1200 ); +} +### Ende Beschattung +sub setExternalTrigger { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_ExternalTrigger', $attrVal ); + + return; +} + +sub getExternalTriggerDevice { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{device} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{LASTGETTIME} = + int( gettimeofday() ); + my ( $device, $reading, $valueActive, $valueInactive, $posActive, + $posInactive, $valueActive2, $posActive2 ) + = FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_ExternalTrigger', 'none' ); + + ### erwartetes Ergebnis +# DEVICE:READING VALUEACTIVE:VALUEINACTIVE POSACTIVE:POSINACTIVE VALUEACTIVE2:POSACTIVE2 + + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{device} = + $device; + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{reading} = + $reading; + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueactive} = + $valueActive; + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueinactive} = + $valueInactive; + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive} = + $posActive; + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posinactive} = + ( $posInactive ne 'none' ? $posInactive : $shutters->getLastPos ); + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueactive2} = + $valueActive2; + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive2} = + $posActive2; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{device}; + +} + +sub getExternalTriggerReading { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{reading} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getExternalTriggerDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{reading}; +} + +sub getExternalTriggerValueActive { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{valueactive} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getExternalTriggerDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{valueactive}; +} + +sub getExternalTriggerValueActive2 { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{valueactive2} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getExternalTriggerDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{valueactive2}; +} + +sub getExternalTriggerValueInactive { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{valueinactive} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getExternalTriggerDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{valueinactive}; +} + +sub getExternalTriggerPosActive { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getExternalTriggerDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive}; +} + +sub getExternalTriggerPosActive2 { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive2} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getExternalTriggerDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posactive2}; +} + +sub getExternalTriggerPosInactive { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{posinactive} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getExternalTriggerDevice; + + return $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger} + ->{posinactive}; +} + +sub getExternalTriggerState { + my $self = shift; + + return ( + ( + defined( + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} + ) + and + $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} + ) ? 1 : 0 + ); +} + +sub setDelay { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Drive_Delay', $attrVal ); + + return; +} + +sub getDelay { + my $self = shift; + + my $val = AttrVal( $self->{shuttersDev}, 'ASC_Drive_Delay', -1 ); + return ( $val =~ m{^\d+$}xms ? $val : -1 ); +} + +sub setDelayStart { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Drive_DelayStart', $attrVal ); + + return; +} + +sub getDelayStart { + my $self = shift; + + my $val = AttrVal( $self->{shuttersDev}, 'ASC_Drive_DelayStart', -1 ); + return ( ( $val > 0 && $val =~ m{^\d+$}xms ) ? $val : -1 ); +} + +sub setBlockingTimeAfterManual { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_BlockingTime_afterManual', + $attrVal ); + + return; +} + +sub getBlockingTimeAfterManual { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_BlockingTime_afterManual', + 1200 ); +} + +sub setBlockingTimeBeforNightClose { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_BlockingTime_beforNightClose', + $attrVal ); + + return; +} + +sub getBlockingTimeBeforNightClose { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_BlockingTime_beforNightClose', + 3600 ); +} + +sub setBlockingTimeBeforDayOpen { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_BlockingTime_beforDayOpen', + $attrVal ); + + return; +} + +sub getBlockingTimeBeforDayOpen { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_BlockingTime_beforDayOpen', + 3600 ); +} + +sub setPosCmd { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Pos_Reading', $attrVal ); + + return; +} + +sub getPosCmd { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Pos_Reading', + $userAttrList{'ASC_Pos_Reading'} + [ AttrVal( $self->{shuttersDev}, 'ASC', 1 ) ] ); +} + +sub setOpenPos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Open_Pos', $attrVal ); + + return; +} + +sub getOpenPos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_Open_Pos', + 'ASC_Open_Pos:0,10,20,30,40,50,60,70,80,90,100' ); +} + +sub getOpenPositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_Open_Pos', 'getOpenPos' ); +} + +sub setVentilatePos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Ventilate_Pos', $attrVal ); + + return; +} + +sub getVentilatePos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_Ventilate_Pos', + 'ASC_Ventilate_Pos:10,20,30,40,50,60,70,80,90,100' ); +} + +sub getVentilatePositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_Ventilate_Pos', + 'getVentilatePos' ); +} + +sub setVentilatePosAfterDayClosed { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_WindowRec_PosAfterDayClosed', + $attrVal ); + + return; +} + +sub getVentilatePosAfterDayClosed { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_WindowRec_PosAfterDayClosed', + 'open' ); +} + +sub setClosedPos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Closed_Pos', $attrVal ); + + return; +} + +sub getClosedPos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_Closed_Pos', + 'ASC_Closed_Pos:0,10,20,30,40,50,60,70,80,90,100' ); +} + +sub getClosedPositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_Closed_Pos', + 'getClosedPos' ); +} + +sub setSleepPos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Sleep_Pos', $attrVal ); + + return; +} + +sub getSleepPos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_Sleep_Pos', + 'ASC_Sleep_Pos:0,10,20,30,40,50,60,70,80,90,100' ); +} + +sub getSleepPositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_Sleep_Pos', 'getSleepPos' ); +} + +sub setVentilateOpen { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Ventilate_Window_Open', + $attrVal ); + + return; +} + +sub getVentilateOpen { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Ventilate_Window_Open', 'on' ); +} + +sub setComfortOpenPos { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_ComfortOpen_Pos', $attrVal ); + + return; +} + +sub getComfortOpenPos { + my $self = shift; + + return $shutters->_getPosition( 'ASC_ComfortOpen_Pos', + 'ASC_ComfortOpen_Pos:0,10,20,30,40,50,60,70,80,90,100' ); +} + +sub getComfortOpenPositionAssignment { + my $self = shift; + + return $shutters->_getPositionAssignment( 'ASC_ComfortOpen_Pos', + 'getComfortOpenPos' ); +} + +sub setPartyMode { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Partymode', $attrVal ); + + return; +} + +sub getPartyMode { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Partymode', 'off' ); +} + +sub setRoommates { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Roommate_Device', $attrVal ); + + return; +} + +sub getRoommates { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Roommate_Device', 'none' ); +} + +sub setRoommatesReading { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Roommate_Reading', $attrVal ); + + return; +} + +sub getRoommatesReading { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Roommate_Reading', 'state' ); +} + +sub getWindPos { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{closedPos} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} + ) < 2 + ); + $shutters->getWindMax; + + return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{closedPos}; +} + +sub getWindMax { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggermax} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} + ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} = + int( gettimeofday() ); + my ( $max, $hyst, $pos ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_WindParameters', '50:20' ); + + ## Erwartetes Ergebnis + # max:hyst pos + + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggermax} = $max; + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggerhyst} = + ( $hyst ne 'none' ? $max - $hyst : $max - 20 ); + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{closedPos} = + ( $pos ne 'none' ? $pos : $shutters->getOpenPos ); + + return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggermax}; +} + +sub setWindParameters { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_WindParameters', $attrVal ); + + return; +} + +sub getWindMin { + my $self = shift; + + my $name = $self->{name}; + + return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggerhyst} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{LASTGETTIME} + ) < 2 + ); + $shutters->getWindMax; + + return $self->{ $self->{shuttersDev} }->{ASC_WindParameters}->{triggerhyst}; +} + +sub setWindProtection { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_WindProtection', $attrVal ); + + return; +} + +sub getWindProtection { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_WindProtection', 'off' ); +} + +sub setRainProtection { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_RainProtection', $attrVal ); + + return; +} + +sub getRainProtection { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_RainProtection', 'off' ); +} + +sub setModeUp { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Mode_Up', $attrVal ); + + return; +} + +sub getModeUp { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Mode_Up', 'always' ); +} + +sub setModeDown { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Mode_Down', $attrVal ); + + return; +} + +sub getModeDown { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Mode_Down', 'always' ); +} + +sub setLockOut { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_LockOut', $attrVal ); + + return; +} + +sub getLockOut { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_LockOut', 'off' ); +} + +sub setLockOutCmd { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_LockOut_Cmd', $attrVal ); + + return; +} + +sub getLockOutCmd { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_LockOut_Cmd', 'none' ); +} + +sub setAntiFreeze { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Antifreeze', $attrVal ); + + return; +} + +sub getAntiFreeze { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Antifreeze', 'off' ); +} + +sub setAutoAstroModeMorning { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeMorning', $attrVal ); + + return; +} + +sub getAutoAstroModeMorning { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeMorning', 'none' ); +} + +sub setAutoAstroModeEvening { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeEvening', $attrVal ); + + return; +} + +sub getAutoAstroModeEvening { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeEvening', 'none' ); +} + +sub setAutoAstroModeMorningHorizon { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeMorningHorizon', + $attrVal ); + + return; +} + +sub getAutoAstroModeMorningHorizon { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeMorningHorizon', + 0 ); +} + +sub setAutoAstroModeEveningHorizon { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_AutoAstroModeEveningHorizon', + $attrVal ); + + return; +} + +sub getAutoAstroModeEveningHorizon { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeEveningHorizon', + 0 ); +} + +sub setUp { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Up', $attrVal ); + + return; +} + +sub getUp { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Up', 'astro' ); +} + +sub setDown { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Down', $attrVal ); + + return; +} + +sub getDown { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_Down', 'astro' ); +} + +sub setTimeUpEarly { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Time_Up_Early', $attrVal ); + + return; +} + +sub getTimeUpEarly { + my $self = shift; + + my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_Early', '05:00' ); + + if ( defined( FHEM::Automation::ShuttersControl::_perlCodeCheck($val) ) ) { + $val = FHEM::Automation::ShuttersControl::_perlCodeCheck($val); + } + + return ( + $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms + ? $val + : '05:00' + ); +} + +sub setTimeUpLate { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Time_Up_Late', $attrVal ); + + return; +} + +sub getTimeUpLate { + my $self = shift; + + my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_Late', '08:30' ); + + if ( defined( FHEM::Automation::ShuttersControl::_perlCodeCheck($val) ) ) { + $val = FHEM::Automation::ShuttersControl::_perlCodeCheck($val); + } + + return ( + $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms + ? $val + : '08:30' + ); +} + +sub setTimeDownEarly { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Time_Down_Early', $attrVal ); + + return; +} + +sub getTimeDownEarly { + my $self = shift; + + my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Down_Early', '16:00' ); + + if ( defined( FHEM::Automation::ShuttersControl::_perlCodeCheck($val) ) ) { + $val = FHEM::Automation::ShuttersControl::_perlCodeCheck($val); + } + + return ( + $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms + ? $val + : '16:00' + ); +} + +sub setTimeDownLate { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Time_Down_Late', $attrVal ); + + return; +} + +sub getTimeDownLate { + my $self = shift; + + my $val = AttrVal( $self->{shuttersDev}, 'ASC_Time_Down_Late', '22:00' ); + + if ( defined( FHEM::Automation::ShuttersControl::_perlCodeCheck($val) ) ) { + $val = FHEM::Automation::ShuttersControl::_perlCodeCheck($val); + } + + return ( + $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms + ? $val + : '22:00' + ); +} + +sub setTimeUpWeHoliday { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_Time_Up_WE_Holiday', $attrVal ); + + return; +} + +sub getTimeUpWeHoliday { + my $self = shift; + + my $val = + AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_WE_Holiday', '01:25' ); + + if ( defined( FHEM::Automation::ShuttersControl::_perlCodeCheck($val) ) ) { + $val = FHEM::Automation::ShuttersControl::_perlCodeCheck($val); + } + + return ( + $val =~ m{^(?:[01]?\d|2[0-3]):(?:[0-5]\d)(:(?:[0-5]\d))?$}xms + ? $val + : '01:25' + ); +} + +sub getBrightnessMinVal { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermin} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} ) < 2 + ); + $shutters->_getBrightnessSensor; + + return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{triggermin}; +} + +sub getBrightnessMaxVal { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermax} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{LASTGETTIME} ) < 2 + ); + $shutters->_getBrightnessSensor; + + return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor} + ->{triggermax}; +} + +sub setDriveUpMaxDuration { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_DriveUpMaxDuration', $attrVal ); + + return; +} + +sub getDriveUpMaxDuration { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_DriveUpMaxDuration', 60 ); +} + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Shutters/Readings.pm b/lib/FHEM/Automation/ShuttersControl/Shutters/Readings.pm new file mode 100644 index 0000000..00d7e16 --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Shutters/Readings.pm @@ -0,0 +1,92 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + + +## Subklasse Readings von ASC_Shutters ## +package FHEM::Automation::ShuttersControl::Shutters::Readings; + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + ReadingsVal + ReadingsNum) + ); +} + +sub getBrightness { + my $self = shift; + + return ReadingsNum( $shutters->_getBrightnessSensor, + $shutters->getBrightnessReading, -1 ); +} + +sub getWindStatus { + my $self = shift; + + return ReadingsVal( $ascDev->_getWindSensor, + $ascDev->getWindSensorReading, -1 ); +} + +sub getStatus { + my $self = shift; + + return ReadingsNum( $self->{shuttersDev}, $shutters->getPosCmd, 0 ); +} + +sub getDelayCmd { + my $self = shift; + + return $self->{ $self->{shuttersDev} }{delayCmd}; +} + +sub getASCenable { + my $self = shift; + + return ReadingsVal( $self->{shuttersDev}, 'ASC_Enable', 'on' ); +} + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Window.pm b/lib/FHEM/Automation/ShuttersControl/Window.pm new file mode 100644 index 0000000..9b4caae --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Window.pm @@ -0,0 +1,50 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Klasse Fenster (Window) und die Subklassen Attr und Readings ## +package FHEM::Automation::ShuttersControl::Window; + +use strict; +use warnings; +use utf8; + +our @ISA = qw(FHEM::Automation::ShuttersControl::Window::Attr FHEM::Automation::ShuttersControl::Window::Readings); + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Window/Attr.pm b/lib/FHEM/Automation/ShuttersControl/Window/Attr.pm new file mode 100644 index 0000000..9e08d62 --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Window/Attr.pm @@ -0,0 +1,129 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Subklasse Attr von Klasse ASC_Window ## +package FHEM::Automation::ShuttersControl::Window::Attr; + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + AttrVal + gettimeofday) + ); +} + +sub setSubTyp { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_WindowRec_subType', $attrVal ); + + return; +} + +sub getSubTyp { + my $self = shift; + + return AttrVal( $self->{shuttersDev}, 'ASC_WindowRec_subType', 'twostate' ); +} + +sub setWinDev { + my $self = shift; + my $attrVal = shift; + + _setAttributs( $self->{shuttersDev}, 'ASC_WindowRec', $attrVal ); + + return; +} + +sub _getWinDev { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{device} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} ) < + 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} = + int( gettimeofday() ); + my ( $device, $reading ) = + FHEM::Automation::ShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_WindowRec', 'none' ); + + ### erwartetes Ergebnis + # DEVICE:READING VALUEACTIVE:VALUEINACTIVE POSACTIVE:POSINACTIVE + + $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{device} = + $device; + $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{reading} = + ( $reading ne 'none' ? $reading : 'state' ); + + return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{device}; +} + +sub getWinDevReading { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{reading} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} + ) + && ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{LASTGETTIME} ) < + 2 + ); + $shutters->_getWinDev; + + return $self->{ $self->{shuttersDev} }->{ASC_WindowRec}->{reading}; +} + + +1; diff --git a/lib/FHEM/Automation/ShuttersControl/Window/Readings.pm b/lib/FHEM/Automation/ShuttersControl/Window/Readings.pm new file mode 100644 index 0000000..5e8ff5f --- /dev/null +++ b/lib/FHEM/Automation/ShuttersControl/Window/Readings.pm @@ -0,0 +1,65 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2018-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# 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, many suggestions and good discussions +# - pc1246 write english commandref +# - FunkOdyssey commandref style +# - sledge fix many typo in commandref +# - many User that use with modul and report bugs +# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events +# - Julian (Loredo) expand Residents Events for new Residents functions +# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions +# +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License,or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +## Subklasse Readings von Klasse ASC_Window ## +package FHEM::Automation::ShuttersControl::Window::Readings; + +use strict; +use warnings; +use utf8; + +use GPUtils qw(GP_Import); + +## Import der FHEM Funktionen +BEGIN { + GP_Import( + qw( + ReadingsVal) + ); +} + +sub getWinStatus { + my $self = shift; + + return ReadingsVal( $shutters->_getWinDev, $shutters->getWinDevReading, + 'closed' ); +} + + +1;