############################################################################### # # Developed with VSCodium and richterger perl plugin # # (c) 2018-2022 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net) # 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; use strict; use warnings; use utf8; use FHEM::Automation::ShuttersControl::Shutters::Readings; use FHEM::Automation::ShuttersControl::Shutters::Attr; use FHEM::Automation::ShuttersControl::Roommate qw (:ALL); use FHEM::Automation::ShuttersControl::Window; use base qw(FHEM::Automation::ShuttersControl::Shutters::Readings FHEM::Automation::ShuttersControl::Shutters::Attr FHEM::Automation::ShuttersControl::Roommate FHEM::Automation::ShuttersControl::Window); 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 ( $FHEM::Automation::ShuttersControl::shutters->getLockOut eq 'hard' && $FHEM::Automation::ShuttersControl::shutters->getLockOutCmd ne 'none' ) { ::CommandSet( undef, $self->{shuttersDev} . ' inhibit ' . $cmd ) if ( $FHEM::Automation::ShuttersControl::shutters->getLockOutCmd eq 'inhibit' ); ::CommandSet( undef, $self->{shuttersDev} . ' ' . ( $cmd eq 'on' ? 'blocked' : 'unblocked' ) ) if ( $FHEM::Automation::ShuttersControl::shutters->getLockOutCmd eq 'blocked' ); ::CommandSet( undef, $self->{shuttersDev} . ' ' . ( $cmd eq 'on' ? 'protectionOn' : 'protectionOff' ) ) if ( $FHEM::Automation::ShuttersControl::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 ( ( $FHEM::Automation::ShuttersControl::shutters->getPartyMode eq 'on' && $FHEM::Automation::ShuttersControl::ascDev->getPartyMode eq 'on' ) || ( $FHEM::Automation::ShuttersControl::shutters->getAdv && !$FHEM::Automation::ShuttersControl::shutters ->getQueryShuttersPos( $posValue) && !$FHEM::Automation::ShuttersControl::shutters->getAdvDelay && !$FHEM::Automation::ShuttersControl::shutters ->getExternalTriggerStatus && !$FHEM::Automation::ShuttersControl::shutters ->getSelfDefenseState ) ) { $FHEM::Automation::ShuttersControl::shutters->setDelayCmd($posValue); $FHEM::Automation::ShuttersControl::ascDev->setDelayCmdReading; $FHEM::Automation::ShuttersControl::shutters->setNoDelay(0); # $FHEM::Automation::ShuttersControl::shutters->setExternalTriggerStatus(0) # if ( $FHEM::Automation::ShuttersControl::shutters # ->getExternalTriggerStatus ); FHEM::Automation::ShuttersControl::ASC_Debug( 'setDriveCmd: ' . $FHEM::Automation::ShuttersControl::shutters->getShuttersDev . ' - Die Fahrt wird zurückgestellt. Grund kann ein geöffnetes Fenster sein oder ein aktivierter Party Modus oder Weihnachtszeit' ); } else { $FHEM::Automation::ShuttersControl::shutters->setAdvDelay(0) if ( $FHEM::Automation::ShuttersControl::shutters->getAdvDelay ); $FHEM::Automation::ShuttersControl::shutters->setDelayCmd('none') if ( $FHEM::Automation::ShuttersControl::shutters->getDelayCmd ne 'none' ) ; # setzt den Wert auf none da der Rolladen nun gesteuert werden kann. $FHEM::Automation::ShuttersControl::shutters->setExternalTriggerStatus( 0) if ( $FHEM::Automation::ShuttersControl::shutters ->getExternalTriggerStatus ); ### antifreeze Routine if ( $FHEM::Automation::ShuttersControl::shutters->getAntiFreezeStatus > 0 ) { if ( $FHEM::Automation::ShuttersControl::shutters ->getAntiFreezeStatus != 1 ) { $posValue = $FHEM::Automation::ShuttersControl::shutters->getStatus; $FHEM::Automation::ShuttersControl::shutters->setLastDrive( 'no drive - antifreeze defense'); $FHEM::Automation::ShuttersControl::shutters ->setLastDriveReading; $FHEM::Automation::ShuttersControl::ascDev->setStateReading; } elsif ( $posValue == $FHEM::Automation::ShuttersControl::shutters->getClosedPos ) { $posValue = $FHEM::Automation::ShuttersControl::shutters ->getAntiFreezePos; $FHEM::Automation::ShuttersControl::shutters->setLastDrive( $FHEM::Automation::ShuttersControl::shutters->getLastDrive . ' - antifreeze mode' ); } } my %h = ( shuttersDev => $self->{shuttersDev}, posValue => $posValue, ); $offSet = $FHEM::Automation::ShuttersControl::shutters->getDelay if ( $FHEM::Automation::ShuttersControl::shutters->getDelay > -1 ); $offSet = $FHEM::Automation::ShuttersControl::ascDev->getShuttersOffset if ( $FHEM::Automation::ShuttersControl::shutters->getDelay < 0 ); $offSetStart = $FHEM::Automation::ShuttersControl::shutters->getDelayStart; if ( $FHEM::Automation::ShuttersControl::shutters->getSelfDefenseAbsent && !$FHEM::Automation::ShuttersControl::shutters ->getSelfDefenseAbsentTimerrun && $FHEM::Automation::ShuttersControl::shutters->getSelfDefenseMode ne 'off' && $FHEM::Automation::ShuttersControl::shutters->getSelfDefenseState && $FHEM::Automation::ShuttersControl::ascDev->getSelfDefense eq 'on' ) { ::InternalTimer( ::gettimeofday() + $FHEM::Automation::ShuttersControl::shutters ->getSelfDefenseAbsentDelay, \&FHEM::Automation::ShuttersControl::SetCmdFn, \%h ); $FHEM::Automation::ShuttersControl::shutters->setSelfDefenseAbsent( 1, 0, \%h ); } elsif ( $offSetStart > 0 && !$FHEM::Automation::ShuttersControl::shutters->getNoDelay ) { ::InternalTimer( ::gettimeofday() + int( rand($offSet) + $FHEM::Automation::ShuttersControl::shutters ->getDelayStart ), \&FHEM::Automation::ShuttersControl::SetCmdFn, \%h ); FHEM::Automation::ShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' . $FHEM::Automation::ShuttersControl::shutters->getShuttersDev . ' - versetztes fahren' ); } elsif ($offSetStart < 1 || $FHEM::Automation::ShuttersControl::shutters->getNoDelay ) { FHEM::Automation::ShuttersControl::SetCmdFn( \%h ); FHEM::Automation::ShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' . $FHEM::Automation::ShuttersControl::shutters->getShuttersDev . ' - NICHT versetztes fahren' ); } FHEM::Automation::ShuttersControl::ASC_Debug( 'FnSetDriveCmd: ' . $FHEM::Automation::ShuttersControl::shutters->getShuttersDev . ' - NoDelay: ' . ( $FHEM::Automation::ShuttersControl::shutters->getNoDelay ? 'JA' : 'NEIN' ) ); $FHEM::Automation::ShuttersControl::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 => $FHEM::Automation::ShuttersControl::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 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 setRainUnprotectionDelayObj { my $self = shift; my $value = shift; $self->{ $self->{shuttersDev} }->{RainProtection}->{UNPROTECTIONDELAYOBJVAL} = $value if ( defined($value) ); return; } sub setExternalTriggerStatus { my $self = shift; my $value = shift; $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} = $value if ( defined($value) ); return; } sub getExternalTriggerStatus { my $self = shift; return ( ( defined( $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} ) and $self->{ $self->{shuttersDev} }->{ASC_ExternalTrigger}->{event} ) ? 1 : 0 ); } sub getHomemode { my $self = shift; my $homemode = $FHEM::Automation::ShuttersControl::shutters->getRoommatesStatus; $homemode = $FHEM::Automation::ShuttersControl::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::Automation::ShuttersControl::Helper::_IsDay( $self->{shuttersDev} ); } sub getAntiFreezeStatus { use POSIX qw(strftime); my $self = shift; my $daytime = strftime( "%P", localtime() ); $daytime = ( defined($daytime) && $daytime ? $daytime : ( strftime( "%H", localtime() ) < 12 ? 'am' : 'pm' ) ); my $outTemp = $FHEM::Automation::ShuttersControl::ascDev->getOutTemp; # $outTemp = $FHEM::Automation::ShuttersControl::shutters->getOutTemp if ( $FHEM::Automation::ShuttersControl::shutters->getOutTemp != -100 ); sollte raus das der Sensor im Rollo auch ein Innentemperatursensor sein kann. if ( $FHEM::Automation::ShuttersControl::shutters->getAntiFreeze ne 'off' && $outTemp <= $FHEM::Automation::ShuttersControl::ascDev->getFreezeTemp ) { if ( $FHEM::Automation::ShuttersControl::shutters->getAntiFreeze eq 'soft' ) { return 1; } elsif ( $FHEM::Automation::ShuttersControl::shutters->getAntiFreeze eq $daytime ) { return 2; } elsif ( $FHEM::Automation::ShuttersControl::shutters->getAntiFreeze eq 'hard' ) { return 3; } } else { return 0; } } sub getShuttersPosCmdValueNegate { my $self = shift; return ( $FHEM::Automation::ShuttersControl::shutters->getOpenPos < $FHEM::Automation::ShuttersControl::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 ( $FHEM::Automation::ShuttersControl::shutters ->getShuttersPosCmdValueNegate ? $FHEM::Automation::ShuttersControl::shutters->getStatus > $posValue : $FHEM::Automation::ShuttersControl::shutters->getStatus < $posValue ); } sub getPosSetCmd { my $self = shift; return ( defined( $self->{ $self->{shuttersDev} }{posSetCmd} ) ? $self->{ $self->{shuttersDev} }{posSetCmd} : $FHEM::Automation::ShuttersControl::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 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 getRainUnprotectionDelayObj { my $self = shift; return ( ( defined( $self->{ $self->{shuttersDev} }->{RainProtection} ) && defined( $self->{ $self->{shuttersDev} }->{RainProtection} ->{UNPROTECTIONDELAYOBJVAL} ) ) ? $self->{ $self->{shuttersDev} }->{RainProtection} ->{UNPROTECTIONDELAYOBJVAL} : 'none' ); } 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( ",", $FHEM::Automation::ShuttersControl::shutters->getRoommates ) ) { $FHEM::Automation::ShuttersControl::shutters->setRoommate($ro); my $currentPrio = $statePrio{ $FHEM::Automation::ShuttersControl::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( ",", $FHEM::Automation::ShuttersControl::shutters->getRoommates ) ) { $FHEM::Automation::ShuttersControl::shutters->setRoommate($ro); my $currentPrio = $statePrio{ $FHEM::Automation::ShuttersControl::shutters ->getRoommateLastStatus }; $minPrio = $currentPrio if ( $minPrio > $currentPrio ); } my %revStatePrio = reverse %statePrio; return $revStatePrio{$minPrio}; } sub getOutTemp { my $self = shift; return ::ReadingsVal( $FHEM::Automation::ShuttersControl::shutters->_getTempSensor, $FHEM::Automation::ShuttersControl::shutters->getTempSensorReading, -100 ); } sub getIdleDetection { my $self = shift; return ::ReadingsVal( $self->{shuttersDev}, $FHEM::Automation::ShuttersControl::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 # Es wird durch das return die ShadingWaitingTime nicht mehr beachtet, Bugmeldung von Bernd Griemsmann # return # if ( defined($value) # && exists( $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} ) # && $self->{ $self->{shuttersDev} }{ShadingStatus}{VAL} eq $value ); $FHEM::Automation::ShuttersControl::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 setShadingLastPos { my $self = shift; my $value = shift; $self->{ $self->{shuttersDev} }{ShadingLastPos}{VAL} = $value if ( defined($value) ); return; } sub setShadingBetweenTheTimeSuspend { # Werte für value = 0, 1 my $self = shift; my $value = shift; $self->{ $self->{shuttersDev} }{ShadingBetweenTheTimeSuspend}{VAL} = $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} } ) > $FHEM::Automation::ShuttersControl::shutters ->getMaxBrightnessAverageArrayObjects ); return; } sub getBrightnessAverage { use FHEM::Automation::ShuttersControl::Helper qw (AverageBrightness); my $self = shift; return 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 getShadingBetweenTheTimeSuspend { # Werte für value = 0, 1 my $self = shift; return ( defined( $self->{ $self->{shuttersDev} }{ShadingBetweenTheTimeSuspend} ) && defined( $self->{ $self->{shuttersDev} }{ShadingBetweenTheTimeSuspend}{VAL} ) ? $self->{ $self->{shuttersDev} }{ShadingBetweenTheTimeSuspend}{VAL} : 0 ); } 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 ( ( $FHEM::Automation::ShuttersControl::shutters->getShadingMode ne 'off' && $FHEM::Automation::ShuttersControl::shutters ->getShadingLastStatus eq 'out' ) ? 1 : 0 ); } 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 ); } sub getShadingLastPos { my $self = shift; return ( defined( $self->{ $self->{shuttersDev} }{ShadingLastPos} ) && defined( $self->{ $self->{shuttersDev} }{ShadingLastPos}{VAL} ) ? $self->{ $self->{shuttersDev} }{ShadingLastPos}{VAL} : $FHEM::Automation::ShuttersControl::shutters->getShadingPos ); } ### Ende Beschattung 1;