mod-AutoShuttersControl/73_AutoShuttersControl.pm

3143 lines
116 KiB
Perl
Raw Normal View History

2018-08-15 10:27:53 +02:00
###############################################################################
#
2018-08-15 10:27:53 +02:00
# Developed with Kate
#
# (c) 2018 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)
2018-09-03 22:19:25 +02:00
# - Beta-User for many tests and ideas
2018-08-15 10:27:53 +02:00
#
#
# 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
2018-08-15 10:27:53 +02:00
# 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$
#
###############################################################################
2018-09-24 15:29:39 +02:00
### Notizen
2018-09-28 08:57:25 +02:00
# - Feststellen ob ein Rolladen fährt oder nicht
2018-09-04 11:42:47 +02:00
2018-08-15 10:27:53 +02:00
package main;
use strict;
use warnings;
2018-11-02 05:52:27 +01:00
my $version = "0.1.88";
2018-08-15 10:27:53 +02:00
sub AutoShuttersControl_Initialize($) {
my ($hash) = @_;
2018-08-29 14:58:10 +02:00
## 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} = "AutoShuttersControl::Set";
$hash->{GetFn} = "AutoShuttersControl::Get";
$hash->{DefFn} = "AutoShuttersControl::Define";
$hash->{NotifyFn} = "AutoShuttersControl::Notify";
$hash->{UndefFn} = "AutoShuttersControl::Undef";
$hash->{AttrFn} = "AutoShuttersControl::Attr";
$hash->{AttrList} =
"disable:0,1 "
. "disabledForIntervals "
. "ASC_guestPresence:on,off "
. "ASC_temperatureSensor "
. "ASC_temperatureReading "
. "ASC_brightnessMinVal "
. "ASC_brightnessMaxVal "
. "ASC_autoShuttersControlMorning:on,off "
. "ASC_autoShuttersControlEvening:on,off "
. "ASC_autoShuttersControl_Shading:on,off "
. "ASC_autoShuttersControlComfort:on,off "
. "ASC_sunPosDevice "
. "ASC_sunPosReading "
. "ASC_sunElevationDevice "
. "ASC_sunElevationReading "
. "ASC_residentsDevice "
. "ASC_residentsDeviceReading "
. "ASC_rainSensorDevice "
. "ASC_rainSensorReading "
. "ASC_rainSensorShuttersClosedPos:0,10,20,30,40,50,60,70,80,90,100 "
. "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_antifreezeTemp:-5,-4,-3,-2,-1,0,1,2,3,4,5 "
. "ASC_timeUpHolidayDevice "
. "ASC_shuttersDriveOffset "
. $readingFnAttributes;
$hash->{NotifyOrderPrefix} = "51-"; # Order Nummer für NotifyFn
2018-08-15 10:27:53 +02:00
2018-08-29 14:58:10 +02:00
## Ist nur damit sich bei einem reload auch die Versionsnummer erneuert.
foreach my $d ( sort keys %{ $modules{AutoShuttersControl}{defptr} } ) {
2018-08-15 10:27:53 +02:00
my $hash = $modules{AutoShuttersControl}{defptr}{$d};
$hash->{VERSION} = $version;
2018-08-15 10:27:53 +02:00
}
}
2018-10-15 14:51:04 +02:00
## unserer packagename
2018-08-15 10:27:53 +02:00
package AutoShuttersControl;
use strict;
use warnings;
use POSIX;
use GPUtils qw(:all)
; # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt
use Data::Dumper; #only for Debugging
use Date::Parse;
2018-08-15 10:27:53 +02:00
my $missingModul = "";
2018-09-30 21:05:30 +02:00
eval "use JSON qw(decode_json encode_json);1" or $missingModul .= "JSON ";
2018-08-15 10:27:53 +02:00
2018-08-29 14:58:10 +02:00
## Import der FHEM Funktionen
2018-08-15 10:27:53 +02:00
BEGIN {
GP_Import(
qw(devspec2array
readingsSingleUpdate
readingsBulkUpdate
readingsBulkUpdateIfChanged
readingsBeginUpdate
readingsEndUpdate
defs
modules
Log3
CommandAttr
attr
CommandDeleteAttr
CommandDeleteReading
CommandSet
AttrVal
ReadingsVal
Value
IsDisabled
deviceEvents
init_done
addToDevAttrList
addToAttrList
delFromDevAttrList
delFromAttrList
gettimeofday
sunset_abs
sunrise_abs
InternalTimer
RemoveInternalTimer
computeAlignTime
ReplaceEventMap)
);
}
2018-08-15 10:27:53 +02:00
2018-08-29 14:58:10 +02:00
## Die Attributsliste welche an die Rolläden verteilt wird. Zusammen mit Default Werten
my %userAttrList = (
'ASC_Mode_Up:absent,always,off,home' => 'always',
'ASC_Mode_Down:absent,always,off,home' => 'always',
'ASC_Up:time,astro,brightness' => 'astro',
'ASC_Down:time,astro,brightness' => 'astro',
'ASC_AutoAstroModeMorning:REAL,CIVIL,NAUTIC,ASTRONOMIC,HORIZON' => 'none',
'ASC_AutoAstroModeMorningHorizon:-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9'
=> 'none',
'ASC_AutoAstroModeEvening:REAL,CIVIL,NAUTIC,ASTRONOMIC,HORIZON' => 'none',
'ASC_AutoAstroModeEveningHorizon:-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9'
=> 'none',
'ASC_Open_Pos:0,10,20,30,40,50,60,70,80,90,100' => [ '', 0, 100 ],
'ASC_Closed_Pos:0,10,20,30,40,50,60,70,80,90,100' => [ '', 100, 0 ],
'ASC_Pos_Cmd' => [ '', 'position', 'pct' ],
'ASC_Direction' => 178,
'ASC_Time_Up_Early' => '04:30',
'ASC_Time_Up_Late' => '09:00',
'ASC_Time_Up_WE_Holiday' => '08:30',
'ASC_Time_Down_Early' => '15:30',
'ASC_Time_Down_Late' => '22:30',
'ASC_Rand_Minutes' => 20,
'ASC_WindowRec' => 'none',
'ASC_Ventilate_Window_Open:on,off' => 'on',
'ASC_lock-out:soft,hard' => 'soft',
'ASC_lock-outCmd:inhibit,blocked' => 'none',
'ASC_Shading_Pos:10,20,30,40,50,60,70,80,90,100' => 30,
'ASC_Shading:on,off,delayed,present,absent' => 'off',
'ASC_Shading_Pos_after_Shading:-1,0,10,20,30,40,50,60,70,80,90,100' => -1,
'ASC_Shading_Angle_Left:0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90'
=> 85,
'ASC_Shading_Angle_Right:0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90'
=> 85,
'ASC_Shading_Brightness_Sensor' => 'none',
'ASC_Shading_Brightness_Reading' => 'brightness',
'ASC_Shading_StateChange_Sunny' => '6000',
'ASC_Shading_StateChange_Cloudy' => '4000',
'ASC_Shading_WaitingPeriod' => 20,
'ASC_Shading_Min_Elevation' => 'none',
'ASC_Shading_Min_OutsideTemperature' => 18,
'ASC_Shading_BlockingTime_After_Manual' => 20,
'ASC_Shading_BlockingTime_Twilight' => 45,
'ASC_Shading_Fast_Open:on,off' => 'none',
'ASC_Shading_Fast_Close:on,off' => 'none',
'ASC_Drive_Offset' => -1,
'ASC_WindowRec_subType:twostate,threestate' => 'twostate',
'ASC_ShuttersPlace:window,terrace' => 'window',
'ASC_Ventilate_Pos:10,20,30,40,50,60,70,80,90,100' => [ '', 70, 30 ],
'ASC_Pos_after_ComfortOpen:0,10,20,30,40,50,60,70,80,90,100' =>
[ '', 20, 80 ],
'ASC_GuestRoom:on,off' => 'none',
'ASC_Antifreeze:off,on' => 'off',
'ASC_Partymode:on,off' => 'off',
'ASC_Roommate_Device' => 'none',
'ASC_Roommate_Reading' => 'state',
'ASC_Self_Defense_Exclude:on,off' => 'off',
2018-10-16 10:30:10 +02:00
'ASC_BrightnessMinVal' => -1,
'ASC_BrightnessMaxVal' => -1,
);
my $shutters = new ASC_Shutters();
my $ascDev = new ASC_Dev();
2018-10-10 10:43:42 +02:00
sub Define($$) {
my ( $hash, $def ) = @_;
my @a = split( "[ \t][ \t]*", $def );
2018-08-15 10:27:53 +02:00
return "only one AutoShuttersControl instance allowed"
if ( devspec2array('TYPE=AutoShuttersControl') > 1 )
; # es wird geprüft ob bereits eine Instanz unseres Modules existiert,wenn ja wird abgebrochen
return "too few parameters: define <name> ShuttersControl" if ( @a != 2 );
return
"Cannot define ShuttersControl device. Perl modul ${missingModul}is missing."
if ($missingModul)
; # Abbruch wenn benötigte Hilfsmodule nicht vorhanden sind / vorerst unwichtig
my $name = $a[0];
$hash->{VERSION} = $version;
$hash->{MID} = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
; # eine Ein Eindeutige ID für interne FHEM Belange / nicht weiter wichtig
$hash->{NOTIFYDEV} = "global,"
. $name; # Liste aller Devices auf deren Events gehört werden sollen
$ascDev->setName($name);
2018-08-15 10:27:53 +02:00
readingsSingleUpdate(
$hash,
"state",
"please set attribut 'ACS' with value 1 or 2 to all your auto controlled shutters and then do 'set DEVICENAME scanForShutters",
1
);
CommandAttr( undef, $name . ' room ASC' )
if ( AttrVal( $name, 'room', 'none' ) eq 'none' );
CommandAttr( undef, $name . ' icon fts_shutter_automatic' )
if ( AttrVal( $name, 'icon', 'none' ) eq 'none' );
CommandAttr( undef, $name . ' ASC_autoAstroModeEvening REAL' )
if ( $ascDev->getAutoAstroModeEvening eq 'none' );
CommandAttr( undef, $name . ' ASC_autoAstroModeMorning REAL' )
if ( $ascDev->getAutoAstroModeMorning eq 'none' );
CommandAttr( undef, $name . ' ASC_autoShuttersControlMorning on' )
if ( $ascDev->getAutoShuttersControlMorning eq 'none' );
CommandAttr( undef, $name . ' ASC_autoShuttersControlEvening on' )
if ( $ascDev->getAutoShuttersControlEvening eq 'none' );
CommandAttr( undef, $name . ' ASC_temperatureReading temperature' )
if ( $ascDev->getTempReading eq 'none' );
CommandAttr( undef, $name . ' ASC_antifreezeTemp 3' )
if ( $ascDev->getAntifreezeTemp eq 'none' );
2018-08-15 10:27:53 +02:00
addToAttrList('ASC:0,1,2');
2018-08-15 10:27:53 +02:00
Log3( $name, 3, "AutoShuttersControl ($name) - defined" );
2018-08-15 10:27:53 +02:00
$modules{AutoShuttersControl}{defptr}{ $hash->{MID} } = $hash;
2018-08-15 10:27:53 +02:00
return undef;
}
sub Undef($$) {
my ( $hash, $arg ) = @_;
2018-08-15 10:27:53 +02:00
my $name = $hash->{NAME};
UserAttributs_Readings_ForShutters( $hash, 'del' )
; # es sollen alle Attribute und Readings in den Rolläden Devices gelöscht werden welche vom Modul angelegt wurden
delFromAttrList('ASC:0,1,2');
delete( $modules{AutoShuttersControl}{defptr}{ $hash->{MID} } );
Log3( $name, 3, "AutoShuttersControl ($name) - delete device $name" );
2018-08-15 10:27:53 +02:00
return undef;
}
sub Attr(@) {
my ( $cmd, $name, $attrName, $attrVal ) = @_;
my $hash = $defs{$name};
2018-08-15 10:27:53 +02:00
if ( $attrName eq "disable" ) {
if ( $cmd eq "set" and $attrVal eq "1" ) {
Log3( $name, 3, "AutoShuttersControl ($name) - disabled" );
}
elsif ( $cmd eq "del" ) {
Log3( $name, 3, "AutoShuttersControl ($name) - enabled" );
2018-08-15 10:27:53 +02:00
}
}
elsif ( $attrName eq "disabledForIntervals" ) {
if ( $cmd eq "set" ) {
return
"check disabledForIntervals Syntax HH:MM-HH:MM or 'HH:MM-HH:MM HH:MM-HH:MM ...'"
unless ( $attrVal =~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/ );
Log3( $name, 3,
"AutoShuttersControl ($name) - disabledForIntervals" );
#readingsSingleUpdate ($hash,"state","disabled",1);
2018-08-15 10:27:53 +02:00
}
elsif ( $cmd eq "del" ) {
Log3( $name, 3, "AutoShuttersControl ($name) - enabled" );
#readingsSingleUpdate ($hash,"state","active",1);
2018-08-15 10:27:53 +02:00
}
}
return undef;
}
sub Notify($$) {
my ( $hash, $dev ) = @_;
2018-08-15 10:27:53 +02:00
my $name = $hash->{NAME};
2018-10-10 10:43:42 +02:00
$ascDev->setName($name);
return if ( IsDisabled($name) );
2018-09-03 22:19:25 +02:00
2018-08-15 10:27:53 +02:00
my $devname = $dev->{NAME};
my $devtype = $dev->{TYPE};
my $events = deviceEvents( $dev, 1 );
return if ( !$events );
Log3( $name, 5,
"AutoShuttersControl ($name) - Devname: "
. $devname
. " Name: "
. $name
. " Notify: "
. Dumper $events); # mit Dumper
if (
(
grep /^DEFINED.$name$/,
@{$events} and $devname eq 'global' and $init_done
)
or (
grep /^INITIALIZED$/,
@{$events} or grep /^REREADCFG$/,
@{$events} or grep /^MODIFIED.$name$/,
@{$events}
)
2018-08-15 10:27:53 +02:00
and $devname eq 'global'
)
{
readingsSingleUpdate( $hash, 'partyMode', 'off', 0 )
if ( $ascDev->getPartyModeStatus eq 'none' );
readingsSingleUpdate( $hash, 'lockOut', 'off', 0 )
if ( $ascDev->getLockOut eq 'none' );
readingsSingleUpdate( $hash, 'sunriseTimeWeHoliday', 'off', 0 )
if ( $ascDev->getSunriseTimeWeHoliday eq 'none' );
readingsSingleUpdate( $hash, 'selfDefense', 'off', 0 )
if ( $ascDev->getSelfDefense eq 'none' );
CommandDeleteReading( undef, $name . ' selfDefence' )
if ( ReadingsVal( $name, 'selfDefence', 'none' ) ne 'none' )
; # temporär kann später entfernt werden.
# Ist der Event ein globaler und passt zum Rest der Abfrage oben wird nach neuen Rolläden Devices gescannt und eine Liste im Rolladenmodul sortiert nach Raum generiert
ShuttersDeviceScan($hash)
unless ( ReadingsVal( $name, 'userAttrList', 'none' ) eq 'none' );
}
return
unless ( ref( $hash->{helper}{shuttersList} ) eq 'ARRAY'
and scalar( @{ $hash->{helper}{shuttersList} } ) > 0 );
my $posReading = $shutters->getPosCmd;
if ( $devname eq $name ) {
if ( grep /^userAttrList:.rolled.out$/, @{$events} ) {
unless ( scalar( @{ $hash->{helper}{shuttersList} } ) == 0 ) {
2018-09-04 11:42:47 +02:00
WriteReadingsShuttersList($hash);
UserAttributs_Readings_ForShutters( $hash, 'add' );
InternalTimer( gettimeofday() + 3,
'AutoShuttersControl::RenewSunRiseSetShuttersTimer',
$hash );
2018-09-04 11:42:47 +02:00
}
}
elsif ( grep /^partyMode:.off$/, @{$events} ) {
2018-09-04 11:42:47 +02:00
PartyModeEventProcessing($hash);
}
elsif ( grep /^sunriseTimeWeHoliday:.(on|off)$/, @{$events} ) {
2018-09-18 09:35:45 +02:00
RenewSunRiseSetShuttersTimer($hash);
2018-09-04 11:42:47 +02:00
}
}
elsif ( $devname eq "global" )
{ # Kommt ein globales Event und beinhaltet folgende Syntax wird die Funktion zur Verarbeitung aufgerufen
if (
grep
/^(ATTR|DELETEATTR)\s(.*ASC_Roommate_Device|.*ASC_WindowRec|.*ASC_residentsDevice|.*ASC_rainSensorDevice|.*ASC_Shading_Brightness_Sensor)(\s.*|$)/,
@{$events}
)
{
GeneralEventProcessing( $hash, undef, join( ' ', @{$events} ) );
}
elsif (
grep
/^(ATTR|DELETEATTR)\s(.*ASC_Time_Up_WE_Holiday|.*ASC_Up|.*ASC_Down|.*ASC_AutoAstroModeMorning|.*ASC_AutoAstroModeMorningHorizon|.*ASC_AutoAstroModeEvening|.*ASC_AutoAstroModeEveningHorizon|.*ASC_Time_Up_Early|.*ASC_Time_Up_Late|.*ASC_Time_Down_Early|.*ASC_Time_Down_Late|.*ASC_Offset_Minutes_Morning|.*ASC_Offset_Minutes_Evening)(\s.*|$)/,
@{$events}
)
{
GeneralEventProcessing( $hash, undef, join( ' ', @{$events} ) );
2018-08-16 10:37:09 +02:00
}
2018-08-15 10:27:53 +02:00
}
elsif ( grep /^($posReading):\s\d+$/, @{$events} ) {
ShuttersEventProcessing( $hash, $devname, join( ' ', @{$events} ) );
}
else {
GeneralEventProcessing( $hash, $devname, join( ' ', @{$events} ) )
; # bei allen anderen Events wird die entsprechende Funktion zur Verarbeitung aufgerufen
}
2018-08-15 10:27:53 +02:00
return;
}
sub GeneralEventProcessing($$$) {
my ( $hash, $devname, $events ) = @_;
my $name = $hash->{NAME};
2018-08-16 10:37:09 +02:00
if ( defined($devname) and ($devname) )
{ # es wird lediglich der Devicename der Funktion mitgegeben wenn es sich nicht um global handelt daher hier die Unterschiedung
while ( my ( $device, $deviceAttr ) =
each %{ $hash->{monitoredDevs}{$devname} } )
{
WindowRecEventProcessing( $hash, $device, $events )
if ( $deviceAttr eq 'ASC_WindowRec' )
; # ist es ein Fensterdevice wird die Funktion gestartet
RoommateEventProcessing( $hash, $device, $events )
if ( $deviceAttr eq 'ASC_Roommate_Device' )
; # ist es ein Bewohner Device wird diese Funktion gestartet
ResidentsEventProcessing( $hash, $device, $events )
if ( $deviceAttr eq 'ASC_residentsDevice' );
RainEventProcessing( $hash, $device, $events )
if ( $deviceAttr eq 'ASC_rainSensorDevice' );
$shutters->setShuttersDev($device)
if ( $deviceAttr eq 'ASC_Shading_Brightness_Sensor' );
BrightnessEventProcessing( $hash, $device, $events )
if (
$deviceAttr eq 'ASC_Shading_Brightness_Sensor'
and ( $shutters->getDownMode eq 'brightness'
or $shutters->getUpMode eq 'brightness' )
);
}
}
else { # alles was kein Devicenamen mit übergeben hat landet hier
if ( $events =~
m#^ATTR\s(.*)\s(ASC_Roommate_Device|ASC_WindowRec|ASC_residentsDevice|ASC_rainSensorDevice|ASC_Shading_Brightness_Sensor)\s(.*)$#
)
{ # wurde den Attributen unserer Rolläden ein Wert zugewiesen ?
AddNotifyDev( $hash, $3, $1, $2 );
Log3( $name, 4,
"AutoShuttersControl ($name) - EventProcessing: ATTR" );
}
elsif ( $events =~
m#^DELETEATTR\s(.*)\s(ASC_Roommate_Device|ASC_WindowRec|ASC_residentsDevice|ASC_rainSensorDevice|ASC_Shading_Brightness_Sensor)$#
)
{ # wurde das Attribut unserer Rolläden gelöscht ?
Log3( $name, 4,
"AutoShuttersControl ($name) - EventProcessing: DELETEATTR" );
DeleteNotifyDev( $hash, $1, $2 );
}
elsif ( $events =~
m#^ATTR\s(.*)\s(ASC_Time_Up_WE_Holiday|ASC_Up|ASC_Down|ASC_AutoAstroModeMorning|ASC_AutoAstroModeMorningHorizon|ASC_AutoAstroModeEvening|ASC_AutoAstroModeEveningHorizon|ASC_Time_Up_Early|ASC_Time_Up_Late|ASC_Time_Down_Early|ASC_Time_Down_Late|ASC_Offset_Minutes_Morning|ASC_Offset_Minutes_Evening)\s(.*)$#
)
{
CreateSunRiseSetShuttersTimer( $hash, $1 )
if (
$2 ne 'ASC_Time_Up_WE_Holiday'
or ( $2 eq 'ASC_Time_Up_WE_Holiday'
and $ascDev->getSunriseTimeWeHoliday eq 'on' )
);
}
2018-08-16 10:37:09 +02:00
}
}
2018-08-15 10:27:53 +02:00
sub Set($$@) {
my ( $hash, $name, @aa ) = @_;
my ( $cmd, @args ) = @aa;
if ( lc $cmd eq 'renewsetsunrisesunsettimer' ) {
return "usage: $cmd" if ( @args != 0 );
2018-08-29 14:58:10 +02:00
RenewSunRiseSetShuttersTimer($hash);
}
elsif ( lc $cmd eq 'scanforshutters' ) {
return "usage: $cmd" if ( @args != 0 );
2018-09-03 22:19:25 +02:00
ShuttersDeviceScan($hash);
}
elsif ( lc $cmd eq 'createnewnotifydev' ) {
return "usage: $cmd" if ( @args != 0 );
CreateNewNotifyDev($hash);
}
elsif ( lc $cmd eq 'partymode' ) {
return "usage: $cmd" if ( @args > 1 );
readingsSingleUpdate( $hash, $cmd, join( ' ', @args ), 1 );
}
elsif ( lc $cmd eq 'lockout' ) {
return "usage: $cmd" if ( @args > 1 );
readingsSingleUpdate( $hash, $cmd, join( ' ', @args ), 1 );
SetHardewareBlockForShutters( $hash, join( ' ', @args ) );
}
elsif ( lc $cmd eq 'sunrisetimeweholiday' ) {
return "usage: $cmd" if ( @args > 1 );
readingsSingleUpdate( $hash, $cmd, join( ' ', @args ), 1 );
}
elsif ( lc $cmd eq 'selfdefense' ) {
return "usage: $cmd" if ( @args > 1 );
readingsSingleUpdate( $hash, $cmd, join( ' ', @args ), 1 );
}
else {
2018-09-03 22:19:25 +02:00
my $list = "scanForShutters:noArg";
$list .=
" renewSetSunriseSunsetTimer:noArg partyMode:on,off lockOut:on,off sunriseTimeWeHoliday:on,off selfDefense:on,off"
if ( ReadingsVal( $name, 'userAttrList', 'none' ) eq 'rolled out' );
$list .= " createNewNotifyDev:noArg"
2018-10-28 18:12:40 +01:00
if ( ReadingsVal( $name, 'userAttrList', 'none' ) eq 'rolled out'
and AttrVal( $name, 'verbose', 3 ) > 3 );
return "Unknown argument $cmd,choose one of $list";
2018-08-15 10:27:53 +02:00
}
return undef;
}
2018-09-21 08:44:38 +02:00
sub Get($$@) {
my ( $hash, $name, @aa ) = @_;
2018-09-21 08:44:38 +02:00
my ( $cmd, @args ) = @aa;
2018-09-21 08:44:38 +02:00
if ( lc $cmd eq 'showshuttersinformations' ) {
return "usage: $cmd" if ( @args != 0 );
2018-09-21 08:44:38 +02:00
my $ret = GetShuttersInformation($hash);
return $ret;
}
elsif ( lc $cmd eq 'shownotifydevsinformations' ) {
return "usage: $cmd" if ( @args != 0 );
my $ret = GetMonitoredDevs($hash);
return $ret;
}
else {
2018-09-21 08:44:38 +02:00
my $list = "";
2018-10-28 18:12:40 +01:00
$list .= " showShuttersInformations:noArg"
if ( ReadingsVal( $name, 'userAttrList', 'none' ) eq 'rolled out' );
$list .= " showNotifyDevsInformations:noArg"
if ( ReadingsVal( $name, 'userAttrList', 'none' ) eq 'rolled out'
and AttrVal( $name, 'verbose', 3 ) > 3 );
2018-10-28 18:12:40 +01:00
return "Unknown argument $cmd,choose one of $list";
2018-09-21 08:44:38 +02:00
}
}
2018-08-15 10:27:53 +02:00
sub ShuttersDeviceScan($) {
my $hash = shift;
my $name = $hash->{NAME};
2018-10-10 10:43:42 +02:00
$ascDev->setName($name);
2018-09-13 10:38:35 +02:00
delete $hash->{helper}{shuttersList};
2018-08-15 10:27:53 +02:00
my @list;
@list = devspec2array('ASC=[1-2]');
CommandDeleteReading( undef, $name . ' .*_nextAstroTimeEvent' );
unless ( scalar(@list) > 0 ) {
2018-09-03 22:19:25 +02:00
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, 'userAttrList', 'none' );
readingsBulkUpdate( $hash, 'state', 'no shutters found' );
readingsEndUpdate( $hash, 1 );
2018-09-03 22:19:25 +02:00
return;
}
my $shuttersList = '';
foreach (@list) {
push( @{ $hash->{helper}{shuttersList} }, $_ )
; ## einem Hash wird ein Array zugewiesen welches die Liste der erkannten Rollos beinhaltet
delFromDevAttrList( $_, 'ASC_Up:time,astro' )
if (
AttrVal( $_, 'userattr', 'none' ) =~ /\sASC_Up:time,astro\sASC_/ )
; # temporär muss später gelöscht werden ab Version 0.1.80
delFromDevAttrList( $_, 'ASC_Down:time,astro' )
if (
AttrVal( $_, 'userattr', 'none' ) =~ /\sASC_Down:time,astro\sASC_/ )
; # temporär muss später gelöscht werden ab Version 0.1.80
delFromDevAttrList( $_, 'ASC_Mode_Up:absent,always,off' )
if ( AttrVal( $_, 'userattr', 'none' ) =~
/\sASC_Mode_Up:absent,always,off\sASC_/ )
; # temporär muss später gelöscht werden ab Version 0.1.81
delFromDevAttrList( $_, 'ASC_Mode_Down:absent,always,off' )
if ( AttrVal( $_, 'userattr', 'none' ) =~
/\sASC_Mode_Down:absent,always,off\sASC_/ )
; # temporär muss später gelöscht werden ab Version 0.1.81
delFromDevAttrList( $_, 'ASC_Self_Defence_Exclude:on,off' )
; # temporär muss später gelöscht werden ab Version 0.1.80
delFromDevAttrList( $_, 'ASC_Offset_Minutes_Morning' )
; # temporär muss später gelöscht werden ab Version 0.1.81
delFromDevAttrList( $_, 'ASC_Offset_Minutes_Evening' )
; # temporär muss später gelöscht werden ab Version 0.1.81
2018-10-17 09:50:11 +02:00
CommandDeleteReading( undef,
$_ . ' .AutoShuttersControl_InternalTimerFuncHash' )
; # temporär muss später gelöscht werden ab Version 0.1.81
CommandDeleteReading( undef,
$_ . ' .AutoShuttersControl_LastPosition' )
; # temporär muss später gelöscht werden ab Version 0.1.81
CommandDeleteReading( undef, $_ . ' .AutoShuttersControl_DelayCmd' )
; # temporär muss später gelöscht werden ab Version 0.1.82
$shuttersList = $shuttersList . ',' . $_;
$shutters->setShuttersDev($_);
$shutters->setLastManPos( $shutters->getStatus );
2018-10-28 18:12:40 +01:00
$shutters->setLastPos( $shutters->getStatus );
$shutters->setDelayCmd('none');
2018-08-15 10:27:53 +02:00
}
$hash->{NOTIFYDEV} = $hash->{NOTIFYDEV} . $shuttersList;
if ( $ascDev->getMonitoredDevs ne 'none' ) {
$hash->{monitoredDevs} =
eval { decode_json( $ascDev->getMonitoredDevs ) };
my $notifyDevString = $hash->{NOTIFYDEV};
while ( each %{ $hash->{monitoredDevs} } ) {
$notifyDevString .= ',' . $_;
2018-08-16 10:37:09 +02:00
}
$hash->{NOTIFYDEV} = $notifyDevString;
2018-08-16 10:37:09 +02:00
}
readingsSingleUpdate( $hash, 'userAttrList', 'rolled out', 1 );
2018-08-15 10:27:53 +02:00
}
2018-08-29 14:58:10 +02:00
## Die Funktion schreibt in das Moduldevice Readings welche Rolläden in welchen Räumen erfasst wurden.
2018-08-15 10:27:53 +02:00
sub WriteReadingsShuttersList($) {
my $hash = shift;
my $name = $hash->{NAME};
2018-08-15 10:27:53 +02:00
CommandDeleteReading( undef, $name . ' room_.*' );
2018-08-15 10:27:53 +02:00
readingsBeginUpdate($hash);
foreach ( @{ $hash->{helper}{shuttersList} } ) {
readingsBulkUpdate(
$hash,
'room_' . makeReadingName( AttrVal( $_, 'room', 'unsorted' ) ),
ReadingsVal(
$name,
'room_' . makeReadingName( AttrVal( $_, 'room', 'unsorted' ) ),
''
)
. ','
. $_
)
if (
ReadingsVal(
$name,
'room_' . makeReadingName( AttrVal( $_, 'room', 'unsorted' ) ),
'none'
) ne 'none'
);
readingsBulkUpdate( $hash,
'room_' . makeReadingName( AttrVal( $_, 'room', 'unsorted' ) ), $_ )
if (
ReadingsVal(
$name,
'room_' . makeReadingName( AttrVal( $_, 'room', 'unsorted' ) ),
'none'
) eq 'none'
);
2018-08-15 10:27:53 +02:00
}
readingsBulkUpdate( $hash, 'state', 'active' );
readingsEndUpdate( $hash, 0 );
2018-08-15 10:27:53 +02:00
}
sub UserAttributs_Readings_ForShutters($$) {
my ( $hash, $cmd ) = @_;
my $name = $hash->{NAME};
2018-08-15 10:27:53 +02:00
while ( my ( $attrib, $attribValue ) = each %{userAttrList} ) {
foreach ( @{ $hash->{helper}{shuttersList} } ) {
addToDevAttrList( $_, $attrib )
; ## fhem.pl bietet eine Funktion um ein userAttr Attribut zu befüllen. Wir schreiben also in den Attribut userAttr alle unsere Attribute rein. Pro Rolladen immer ein Attribut pro Durchlauf
2018-08-29 14:58:10 +02:00
## Danach werden die Attribute die im userAttr stehen gesetzt und mit default Werten befüllt
if ( $cmd eq 'add' ) {
if ( ref($attribValue) ne 'ARRAY' ) {
$attr{$_}{ ( split( ':', $attrib ) )[0] } = $attribValue
if (
not
defined( $attr{$_}{ ( split( ':', $attrib ) )[0] } ) );
}
else {
$attr{$_}{ ( split( ':', $attrib ) )[0] } =
$attribValue->[ AttrVal( $_, 'ASC', 2 ) ]
if (
not
defined( $attr{$_}{ ( split( ':', $attrib ) )[0] } ) );
2018-09-03 22:19:25 +02:00
}
## Oder das Attribut wird wieder gelöscht.
}
elsif ( $cmd eq 'del' ) {
2018-10-17 09:50:11 +02:00
$shutters->setShuttersDev($_);
RemoveInternalTimer( $shutters->getInTimerFuncHash );
CommandDeleteReading( undef,
$_ . ' .?(AutoShuttersControl|ASC)_.*' );
CommandDeleteAttr( undef, $_ . ' ASC' );
delFromDevAttrList( $_, $attrib );
2018-08-16 10:37:09 +02:00
}
2018-08-15 10:27:53 +02:00
}
}
}
2018-08-29 14:58:10 +02:00
## Fügt dem NOTIFYDEV Hash weitere Devices hinzu
sub AddNotifyDev($@) {
my ( $hash, $dev, $shuttersDev, $shuttersAttr ) = @_;
my $name = $hash->{NAME};
2018-08-16 10:37:09 +02:00
my $notifyDev = $hash->{NOTIFYDEV};
$notifyDev = "" if ( !$notifyDev );
my %hash;
2018-08-16 10:37:09 +02:00
%hash = map { ( $_ => 1 ) }
split( ",", "$notifyDev,$dev" );
2018-08-29 14:58:10 +02:00
$hash->{NOTIFYDEV} = join( ",", sort keys %hash );
my @devs = split( ',', $dev );
foreach (@devs) {
$hash->{monitoredDevs}{$_}{$shuttersDev} = $shuttersAttr;
2018-09-30 21:05:30 +02:00
}
readingsSingleUpdate( $hash, '.monitoredDevs',
eval { encode_json( $hash->{monitoredDevs} ) }, 0 );
2018-08-16 10:37:09 +02:00
}
2018-08-29 14:58:10 +02:00
## entfernt aus dem NOTIFYDEV Hash Devices welche als Wert in Attributen steckten
2018-09-30 21:05:30 +02:00
sub DeleteNotifyDev($@) {
my ( $hash, $shuttersDev, $shuttersAttr ) = @_;
my $name = $hash->{NAME};
2018-08-16 10:37:09 +02:00
my $notifyDevs =
ExtractNotifyDevFromEvent( $hash, $shuttersDev, $shuttersAttr );
foreach my $notifyDev ( keys( %{$notifyDevs} ) ) {
Log3( $name, 4,
"AutoShuttersControl ($name) - DeleteNotifyDev - NotifyDev: "
. $_ );
2018-09-30 21:05:30 +02:00
delete $hash->{monitoredDevs}{$notifyDev}{$shuttersDev};
if ( !keys %{ $hash->{monitoredDevs}{$notifyDev} } ) {
2018-09-30 21:05:30 +02:00
delete $hash->{monitoredDevs}{$notifyDev};
my $notifyDevString = $hash->{NOTIFYDEV};
$notifyDevString = "" if ( !$notifyDevString );
2018-09-30 21:05:30 +02:00
my %hash;
%hash = map { ( $_ => 1 ) }
grep { " $notifyDev " !~ m/ $_ / }
split( ",", "$notifyDevString,$notifyDev" );
2018-09-30 21:05:30 +02:00
$hash->{NOTIFYDEV} = join( ",", sort keys %hash );
2018-09-30 21:05:30 +02:00
}
}
readingsSingleUpdate( $hash, '.monitoredDevs',
eval { encode_json( $hash->{monitoredDevs} ) }, 0 );
}
2018-08-29 14:58:10 +02:00
## Sub zum steuern der Rolläden bei einem Fenster Event
sub WindowRecEventProcessing($@) {
my ( $hash, $shuttersDev, $events ) = @_;
my $name = $hash->{NAME};
2018-10-10 10:43:42 +02:00
$ascDev->setName($name);
2018-08-29 14:58:10 +02:00
if ( $events =~ m#state:\s(open|closed|tilted)# ) {
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
2018-10-16 10:30:10 +02:00
my $queryShuttersPosWinRecTilted = (
ShuttersPosCmdValueNegieren($shuttersDev)
? $shutters->getStatus > $shutters->getVentilatePos
2018-10-16 10:30:10 +02:00
: $shutters->getStatus < $shutters->getVentilatePos
);
if ( $shutters->getDelayCmd ne 'none' )
{ # Es wird geschaut ob wärend der Fenster offen Phase ein Fahrbefehl über das Modul kam,wenn ja wird dieser aus geführt
if ( $1 eq 'closed' ) {
ShuttersCommandSet( $hash, $shuttersDev,
$shutters->getClosedPos );
2018-08-29 14:58:10 +02:00
}
elsif (
(
$1 eq 'tilted'
or ( $1 eq 'open' and $shutters->getSubTyp eq 'twostate' )
)
and $shutters->getVentilateOpen eq 'on'
and $queryShuttersPosWinRecTilted
)
{
ShuttersCommandSet( $hash, $shuttersDev,
$shutters->getVentilatePos );
2018-08-29 14:58:10 +02:00
}
}
elsif ( $1 eq 'closed'
) # wenn nicht dann wird entsprechend dem Fensterkontakt Event der Rolladen geschlossen oder zum lüften geöffnet
{
ShuttersCommandSet( $hash, $shuttersDev, $shutters->getClosedPos )
if ( $shutters->getStatus == $shutters->getVentilatePos
or $shutters->getStatus == $shutters->getPosAfterComfortOpen );
}
elsif (
(
$1 eq 'tilted'
or ( $1 eq 'open' and $shutters->getSubTyp eq 'twostate' )
)
and $shutters->getVentilateOpen eq 'on'
and $queryShuttersPosWinRecTilted
)
{
ShuttersCommandSet( $hash, $shuttersDev,
$shutters->getVentilatePos );
}
elsif ( $1 eq 'open'
and $shutters->getSubTyp eq 'threestate'
and $ascDev->getAutoShuttersControlComfort eq 'on'
and $queryShuttersPosWinRecTilted )
{
ShuttersCommandSet( $hash, $shuttersDev,
$shutters->getPosAfterComfortOpen );
2018-08-29 14:58:10 +02:00
}
}
}
2018-08-29 14:58:10 +02:00
## Sub zum steuern der Rolladen bei einem Bewohner/Roommate Event
sub RoommateEventProcessing($@) {
my ( $hash, $shuttersDev, $events ) = @_;
my $name = $hash->{NAME};
2018-10-10 10:43:42 +02:00
$ascDev->setName($name);
$shutters->setShuttersDev($shuttersDev);
my $reading = $shutters->getRoommatesReading;
if ( $events =~ m#$reading:\s(absent|gotosleep|asleep|awoken|home)# ) {
Log3( $name, 4,
"AutoShuttersControl ($name) - RoommateEventProcessing: $shutters->getRoommatesReading"
);
Log3( $name, 4,
"AutoShuttersControl ($name) - RoommateEventProcessing: $shuttersDev und Events $events"
);
2018-10-30 19:10:50 +01:00
if (
2018-10-30 19:10:50 +01:00
( $1 eq 'home' or $1 eq 'awoken' )
and ( $shutters->getRoommatesStatus eq 'home'
or $shutters->getRoommatesStatus eq 'awoken' )
and $ascDev->getAutoShuttersControlMorning eq 'on'
and ( $shutters->getModeUp eq 'always'
or $shutters->getModeUp eq 'home' )
)
{
2018-10-30 19:10:50 +01:00
if (
(
$shutters->getRoommatesLastStatus eq 'asleep'
or $shutters->getRoommatesLastStatus eq 'awoken'
)
and IsDay( $hash, $shuttersDev )
)
{
$shutters->setLastDrive('roommate awoken');
2018-10-30 19:10:50 +01:00
ShuttersCommandSet( $hash, $shuttersDev,
$shutters->getOpenPos );
}
2018-10-30 19:10:50 +01:00
if (
(
$shutters->getRoommatesLastStatus eq 'absent'
or $shutters->getRoommatesLastStatus eq 'gone'
or $shutters->getRoommatesLastStatus eq 'home'
)
and $shutters->getModeUp eq 'home'
and $shutters->getRoommatesStatus eq 'home'
)
{
2018-10-30 15:26:04 +01:00
if ( not IsDay( $hash, $shuttersDev ) ) {
my $position;
if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0
or $shutters->getVentilateOpen eq 'off' )
{
$position = $shutters->getClosedPos;
}
else { $position = $shutters->getVentilatePos; }
$shutters->setLastDrive('roommate home');
ShuttersCommandSet( $hash, $shuttersDev, $position );
}
elsif ( IsDay( $hash, $shuttersDev )
2018-10-30 19:10:50 +01:00
and $shutters->getStatus == $shutters->getClosedPos )
{
2018-10-30 15:26:04 +01:00
$shutters->setLastDrive('roommate home');
2018-10-30 19:10:50 +01:00
ShuttersCommandSet( $hash, $shuttersDev,
$shutters->getOpenPos );
}
}
2018-10-30 19:10:50 +01:00
}
elsif (
(
$shutters->getModeDown eq 'always'
or $shutters->getModeUp eq 'home'
)
and ( $1 eq 'gotosleep' or $1 eq 'asleep' )
and $ascDev->getAutoShuttersControlEvening eq 'on'
)
{
2018-09-13 08:11:10 +02:00
my $position;
if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0
or $shutters->getVentilateOpen eq 'off' )
{
$position = $shutters->getClosedPos;
2018-09-13 08:11:10 +02:00
}
else { $position = $shutters->getVentilatePos; }
$shutters->setLastDrive('roommate asleep');
ShuttersCommandSet( $hash, $shuttersDev, $position );
2018-09-10 08:27:11 +02:00
}
2018-10-30 19:10:50 +01:00
elsif ( $shutters->getModeDown eq 'absent'
and $1 eq 'absent' )
{
$shutters->setLastDrive('roommate absent');
ShuttersCommandSet( $hash, $shuttersDev, $shutters->getClosedPos );
}
}
}
2018-10-09 18:05:55 +02:00
sub ResidentsEventProcessing($@) {
my ( $hash, $device, $events ) = @_;
2018-10-09 18:05:55 +02:00
my $name = $device;
2018-10-10 10:43:42 +02:00
$ascDev->setName($name);
my $reading = $ascDev->getResidentsReading;
if ( $events =~ m#$reading:\s(absent)# and $ascDev->getSelfDefense eq 'on' )
{
foreach my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
2018-10-30 15:26:04 +01:00
2018-10-30 19:10:50 +01:00
if (
CheckIfShuttersWindowRecOpen($shuttersDev) != 0
and $shutters->getSelfDefenseExclude eq 'off'
or ( $shutters->getUpMode eq 'absent'
and not IsDay( $hash, $shuttersDev ) )
)
2018-10-30 15:26:04 +01:00
{
$shutters->setLastDrive('selfeDefense active');
$shutters->setDriveCmd( $shutters->getClosedPos );
}
}
}
elsif ( $events =~ m#$reading:\s(gone)#
and $ascDev->getSelfDefense eq 'on' )
{
foreach my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
$shutters->setShuttersDev($shuttersDev);
2018-10-30 19:10:50 +01:00
2018-10-30 15:26:04 +01:00
if ( $shutters->getShuttersPlace eq 'terrace' ) {
$shutters->setLastDrive('selfeDefense terrace');
$shutters->setDriveCmd( $shutters->getClosedPos );
}
}
}
elsif (
2018-10-30 19:10:50 +01:00
$events =~ m#$reading:\s(home)#
and ( $ascDev->getResidentsLastStatus eq 'absent'
or $ascDev->getResidentsLastStatus eq 'gone' )
)
{
foreach my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
$shutters->setShuttersDev($shuttersDev);
2018-10-30 19:10:50 +01:00
if ( $shutters->getStatus != $shutters->getClosedPos
and not IsDay( $hash, $shuttersDev )
2018-10-30 19:10:50 +01:00
and $shutters->getRoommatesStatus eq 'none' )
{
$shutters->setLastDrive('residents home');
$shutters->setDriveCmd( $shutters->getClosedPos );
}
elsif ( $shutters->getStatus == $shutters->getClosedPos
and IsDay( $hash, $shuttersDev )
2018-10-30 19:10:50 +01:00
and $shutters->getRoommatesStatus eq 'none' )
{
$shutters->setLastDrive('residents home');
$shutters->setDriveCmd( $shutters->getOpenPos );
}
2018-10-30 19:10:50 +01:00
elsif (
$ascDev->getSelfDefense eq 'on'
and CheckIfShuttersWindowRecOpen($shuttersDev) != 0
and $shutters->getSelfDefenseExclude eq 'off'
or ( $ascDev->getResidentsLastStatus eq 'gone'
and $shutters->getShuttersPlace eq 'terrace' )
)
2018-10-30 19:10:50 +01:00
{
$shutters->setLastDrive('selfeDefense inactive');
$shutters->setDriveCmd( $shutters->getLastPos );
}
}
}
}
sub RainEventProcessing($@) {
my ( $hash, $device, $events ) = @_;
my $name = $device;
$ascDev->setName($name);
my $reading = $ascDev->getRainSensorReading;
2018-10-28 18:12:40 +01:00
my $val;
2018-10-28 18:12:40 +01:00
if ( $events =~ m#$reading:\s(\d+|rain|dry)# ) {
if ( $1 eq 'rain' ) { $val = 1000 }
elsif ( $1 eq 'dry' ) { $val = 0 }
else { $val = $1 }
foreach my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
$shutters->setShuttersDev($shuttersDev);
if ( $val > 100
and $shutters->getStatus !=
$ascDev->getRainSensorShuttersClosedPos )
{
$shutters->setLastDrive('rain protection');
$shutters->setLastPos;
$shutters->setDriveCmd(
$ascDev->getRainSensorShuttersClosedPos );
}
2018-10-28 18:12:40 +01:00
elsif ( $val == 0
and $shutters->getStatus ==
$ascDev->getRainSensorShuttersClosedPos )
{
$shutters->setLastDrive('rain un-protection');
2018-10-28 18:12:40 +01:00
$shutters->setDriveCmd( $shutters->getLastPos );
}
2018-10-09 18:05:55 +02:00
}
}
}
2018-10-12 06:32:01 +02:00
sub BrightnessEventProcessing($@) {
my ( $hash, $shuttersDev, $events ) = @_;
my $name = $hash->{NAME};
2018-10-12 06:32:01 +02:00
$ascDev->setName($name);
$shutters->setShuttersDev($shuttersDev);
return
unless (
int( gettimeofday() / 86400 ) !=
int( computeAlignTime( '24:00', $shutters->getTimeUpEarly ) / 86400 )
and int( gettimeofday() / 86400 ) ==
int( computeAlignTime( '24:00', $shutters->getTimeUpLate ) / 86400 )
or int( gettimeofday() / 86400 ) !=
int( computeAlignTime( '24:00', $shutters->getTimeDownEarly ) / 86400 )
and int( gettimeofday() / 86400 ) ==
int( computeAlignTime( '24:00', $shutters->getTimeDownLate ) / 86400 )
);
my $reading = $shutters->getShadingBrightnessReading;
if ( $events =~ m#$reading:\s(\d+)# ) {
2018-10-16 10:30:10 +02:00
my $brightnessMinVal;
if ( $shutters->getBrightnessMinVal > -1 ) {
$brightnessMinVal = $shutters->getBrightnessMinVal;
}
else {
$brightnessMinVal = $ascDev->getBrightnessMinVal;
}
if (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00', $shutters->getTimeUpEarly ) / 86400
)
and int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00', $shutters->getTimeUpLate ) / 86400
)
2018-10-16 10:30:10 +02:00
and $1 > $brightnessMinVal
2018-10-28 18:12:40 +01:00
and $shutters->getUpMode eq 'brightness'
)
{
Log3( $name, 4,
"AutoShuttersControl ($shuttersDev) - BrightnessEventProcessing: Steuerung für Morgens"
);
2018-10-28 18:12:40 +01:00
my $homemode = $shutters->getRoommatesStatus;
$homemode = $ascDev->getResidentsStatus
if ( $homemode eq 'none' );
$shutters->setLastDrive('minimum brightness threshold exceeded');
2018-10-28 18:12:40 +01:00
if ( $shutters->getModeUp eq $homemode
or $homemode eq 'none'
or $shutters->getModeUp eq 'always' )
{
ShuttersCommandSet( $hash, $shuttersDev, $shutters->getOpenPos )
if (
(
$shutters->getRoommatesStatus eq 'home'
or $shutters->getRoommatesStatus eq 'awoken'
or $shutters->getRoommatesStatus eq 'absent'
or $shutters->getRoommatesStatus eq 'gone'
or $shutters->getRoommatesStatus eq 'none'
)
and $ascDev->getSelfDefense eq 'off'
or ( $ascDev->getSelfDefense eq 'on'
and CheckIfShuttersWindowRecOpen($shuttersDev) == 0 )
);
}
}
elsif (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00', $shutters->getTimeDownEarly ) / 86400
)
and int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00', $shutters->getTimeDownLate ) / 86400
)
2018-10-16 10:30:10 +02:00
and $1 < $brightnessMinVal
2018-10-28 18:12:40 +01:00
and $shutters->getDownMode eq 'brightness'
)
{
Log3( $name, 4,
"AutoShuttersControl ($shuttersDev) - BrightnessEventProcessing: Steuerung für Abends"
);
2018-10-28 18:12:40 +01:00
my $posValue;
if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0
or $shutters->getVentilateOpen eq 'off' )
{
$posValue = $shutters->getClosedPos;
}
else { $posValue = $shutters->getVentilatePos; }
my $homemode = $shutters->getRoommatesStatus;
$homemode = $ascDev->getResidentsStatus
if ( $homemode eq 'none' );
$shutters->setLastDrive('minimum brightness threshold fell below');
2018-10-28 18:12:40 +01:00
ShuttersCommandSet( $hash, $shuttersDev, $shutters->getClosedPos )
if ( $shutters->getModeDown eq $homemode
or $homemode eq 'none'
or $shutters->getModeDown eq 'always' );
}
2018-10-12 06:32:01 +02:00
}
}
2018-09-04 11:42:47 +02:00
sub PartyModeEventProcessing($) {
my ($hash) = @_;
my $name = $hash->{NAME};
2018-09-04 11:42:47 +02:00
foreach my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2
and $shutters->getSubTyp eq 'threestate' )
{
Log3( $name, 4,
"AutoShuttersControl ($name) - PartyModeEventProcessing Fenster offen"
);
$shutters->setDelayCmd( $shutters->getClosedPos );
Log3( $name, 4,
"AutoShuttersControl ($name) - PartyModeEventProcessing - Spring in ShuttersCommandDelaySet"
);
}
else {
Log3( $name, 4,
"AutoShuttersControl ($name) - PartyModeEventProcessing Fenster nicht offen"
);
ShuttersCommandSet(
$hash,
$shuttersDev,
(
CheckIfShuttersWindowRecOpen($shuttersDev) == 0
? $shutters->getClosedPos
: $shutters->getVentilatePos
)
);
2018-09-04 11:42:47 +02:00
}
}
}
sub ShuttersEventProcessing($@) {
my ( $hash, $shuttersDev, $events ) = @_;
my $name = $hash->{NAME};
$ascDev->setName($name);
if ( $events =~ m#.*:\s(\d+)# ) {
$shutters->setShuttersDev($shuttersDev);
if ( ( int( gettimeofday() ) - $shutters->getLastPosTimestamp ) > 60 ) {
$shutters->setLastDrive('manual');
$shutters->setLastDriveReading;
$shutters->setLastManPos($1);
}
}
}
2018-08-29 14:58:10 +02:00
# Sub für das Zusammensetzen der Rolläden Steuerbefehle
2018-09-04 11:42:47 +02:00
sub ShuttersCommandSet($$$) {
my ( $hash, $shuttersDev, $posValue ) = @_;
my $name = $hash->{NAME};
2018-10-10 10:43:42 +02:00
$ascDev->setName($name);
2018-09-13 08:11:10 +02:00
$shutters->setShuttersDev($shuttersDev);
2018-10-30 19:10:50 +01:00
# readingsBeginUpdate($hash);
2018-09-13 08:11:10 +02:00
if (
( $shutters->getPartyMode eq 'on' and $ascDev->getPartyMode eq 'on' )
or ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2
and $shutters->getSubTyp eq 'threestate'
and $ascDev->getAutoShuttersControlComfort eq 'off'
and $shutters->getVentilateOpen eq 'on' )
or (
CheckIfShuttersWindowRecOpen($shuttersDev) == 2
and ( $shutters->getLockOut eq 'soft'
or $shutters->getLockOut eq 'hard' )
and $ascDev->getLockOut eq 'on'
)
or ( $shutters->getAntiFreeze eq 'on'
and $ascDev->getOutTemp <= $ascDev->getAntifreezeTemp )
)
{
$shutters->setDelayCmd($posValue);
$ascDev->setDelayCmdReading;
2018-09-04 11:42:47 +02:00
}
else {
$shutters->setDriveCmd($posValue);
$shutters->setDelayCmd('none')
if ( $shutters->getDelayCmd ne 'none' )
; # setzt den Wert auf none da der Rolladen nun gesteuert werden kann.
$ascDev->setLastPosReading;
}
2018-10-30 19:10:50 +01:00
# readingsEndUpdate( $hash, 1 );
}
2018-08-29 14:58:10 +02:00
## Sub welche die InternalTimer nach entsprechenden Sunset oder Sunrise zusammen stellt
sub CreateSunRiseSetShuttersTimer($$) {
my ( $hash, $shuttersDev ) = @_;
my $name = $hash->{NAME};
my $shuttersDevHash = $defs{$shuttersDev};
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
$ascDev->setName($name);
return if ( IsDisabled($name) );
2018-10-30 19:10:50 +01:00
my $shuttersSunriseUnixtime =
2018-11-02 05:52:27 +01:00
ShuttersSunrise( $hash, $shuttersDev, 'unix' ) + 1;
my $shuttersSunsetUnixtime = ShuttersSunset( $hash, $shuttersDev, 'unix' ) + 1;
2018-09-13 08:11:10 +02:00
2018-10-28 18:12:40 +01:00
$shutters->setSunriseUnixTime($shuttersSunriseUnixtime);
$shutters->setSunsetUnixTime($shuttersSunsetUnixtime);
## In jedem Rolladen werden die errechneten Zeiten hinterlegt,es sei denn das autoShuttersControlEvening/Morning auf off steht
2018-09-13 08:11:10 +02:00
readingsBeginUpdate($shuttersDevHash);
readingsBulkUpdate(
$shuttersDevHash,
'ASC_Time_DriveDown',
(
$ascDev->getAutoShuttersControlEvening eq 'on'
? strftime(
"%e.%m.%Y - %H:%M", localtime($shuttersSunsetUnixtime)
)
: 'AutoShuttersControl off'
),
1
);
readingsBulkUpdate(
$shuttersDevHash,
'ASC_Time_DriveUp',
(
$ascDev->getAutoShuttersControlMorning eq 'on'
? strftime( "%e.%m.%Y - %H:%M",
localtime($shuttersSunriseUnixtime) )
: 'AutoShuttersControl off'
),
1
);
readingsEndUpdate( $shuttersDevHash, 0 );
2018-09-13 08:11:10 +02:00
readingsBeginUpdate($hash);
readingsBulkUpdateIfChanged(
$hash,
$shuttersDev . '_nextAstroTimeEvent',
(
$shuttersSunriseUnixtime < $shuttersSunsetUnixtime
? strftime( "%e.%m.%Y - %H:%M",
localtime($shuttersSunriseUnixtime) )
: strftime(
"%e.%m.%Y - %H:%M", localtime($shuttersSunsetUnixtime)
)
)
);
readingsEndUpdate( $hash, 1 );
CommandDeleteReading( undef,
$name . ' ' . $shuttersDev . '_nextAstroEvent' )
if ( ReadingsVal( $name, $shuttersDev . '_nextAstroEvent', 'none' ) ne
'none' ); # temporär
CommandDeleteReading( undef,
$shuttersDev . ' AutoShuttersControl_Time_Sunrise' )
if (
ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_Sunrise', 'none' )
ne 'none' ); # temporär
CommandDeleteReading( undef,
$shuttersDev . ' AutoShuttersControl_Time_Sunset' )
if (
ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_Sunset', 'none' )
ne 'none' ); # temporär
CommandDeleteReading( undef,
$shuttersDev . ' AutoShuttersControl_Time_DriveDown' )
if (
ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_DriveDown',
'none' ) ne 'none'
); # temporär
CommandDeleteReading( undef,
$shuttersDev . ' AutoShuttersControl_Time_DriveUp' )
if (
ReadingsVal( $shuttersDev, 'AutoShuttersControl_Time_DriveUp', 'none' )
ne 'none' ); # temporär
RemoveInternalTimer( $shutters->getInTimerFuncHash )
2018-10-17 09:50:11 +02:00
if ( defined( $shutters->getInTimerFuncHash ) );
2018-09-13 08:11:10 +02:00
2018-08-29 14:58:10 +02:00
## kleine Hilfe für InternalTimer damit ich alle benötigten Variablen an die Funktion übergeben kann welche von Internal Timer aufgerufen wird.
my %funcHash = (
hash => $hash,
shuttersdevice => $shuttersDev,
sunsettime => $shuttersSunsetUnixtime,
sunrisetime => $shuttersSunriseUnixtime
);
## Ich brauche beim löschen des InternalTimer den Hash welchen ich mitgegeben habe,dieser muss gesichert werden
2018-10-17 09:50:11 +02:00
$shutters->setInTimerFuncHash( \%funcHash );
InternalTimer( $shuttersSunsetUnixtime,
'AutoShuttersControl::SunSetShuttersAfterTimerFn', \%funcHash )
if ( $ascDev->getAutoShuttersControlEvening eq 'on' );
InternalTimer( $shuttersSunriseUnixtime,
'AutoShuttersControl::SunRiseShuttersAfterTimerFn', \%funcHash )
if ( $ascDev->getAutoShuttersControlMorning eq 'on' );
}
2018-08-29 14:58:10 +02:00
## Funktion zum neu setzen der Timer und der Readings für Sunset/Rise
sub RenewSunRiseSetShuttersTimer($) {
my $hash = shift;
foreach ( @{ $hash->{helper}{shuttersList} } ) {
2018-10-17 09:50:11 +02:00
$shutters->setShuttersDev($_);
RemoveInternalTimer( $shutters->getInTimerFuncHash );
$shutters->setInTimerFuncHash(undef);
CreateSunRiseSetShuttersTimer( $hash, $_ );
2018-08-29 14:58:10 +02:00
}
}
## Funktion zum hardwareseitigen setzen des lock-out oder blocking beim Rolladen selbst
sub SetHardewareBlockForShutters($$) {
my ( $hash, $cmd ) = @_;
foreach ( @{ $hash->{helper}{shuttersList} } ) {
if ( AttrVal( $_, 'ASC_lock-out', 'soft' ) eq 'hard'
and AttrVal( $_, 'ASC_lock-outCmd', 'none' ) ne 'none' )
{
CommandSet( undef, $_ . ' inhibit ' . $cmd )
if ( AttrVal( $_, 'ASC_lock-outCmd', 'none' ) eq 'inhibit' );
CommandSet( undef,
$_ . ' ' . ( $cmd eq 'on' ? 'blocked' : 'unblocked' ) )
if ( AttrVal( $_, 'ASC_lock-outCmd', 'none' ) eq 'blocked' );
}
}
}
2018-08-29 14:58:10 +02:00
## Funktion welche beim Ablaufen des Timers für Sunset aufgerufen werden soll
sub SunSetShuttersAfterTimerFn($) {
my $funcHash = shift;
my $hash = $funcHash->{hash};
my $shuttersDev = $funcHash->{shuttersdevice};
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
2018-10-28 18:12:40 +01:00
$ascDev->setName( $hash->{NAME} );
2018-09-10 20:12:26 +02:00
my $posValue;
if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 0
or $shutters->getVentilateOpen eq 'off' )
{
$posValue = $shutters->getClosedPos;
2018-09-10 20:12:26 +02:00
}
else { $posValue = $shutters->getVentilatePos; }
2018-10-28 18:12:40 +01:00
my $homemode = $shutters->getRoommatesStatus;
$homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' );
2018-10-31 09:58:23 +01:00
if ( $shutters->getModeDown eq $homemode
or $homemode eq 'none'
or $shutters->getModeDown eq 'always' )
{
2018-10-30 19:10:50 +01:00
$shutters->setLastDrive('night close');
ShuttersCommandSet( $hash, $shuttersDev, $posValue );
}
2018-09-10 20:12:26 +02:00
CreateSunRiseSetShuttersTimer( $hash, $shuttersDev );
}
2018-08-29 14:58:10 +02:00
## Funktion welche beim Ablaufen des Timers für Sunrise aufgerufen werden soll
sub SunRiseShuttersAfterTimerFn($) {
my $funcHash = shift;
my $hash = $funcHash->{hash};
my $shuttersDev = $funcHash->{shuttersdevice};
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
$ascDev->setName( $hash->{NAME} );
2018-10-28 18:12:40 +01:00
my $homemode = $shutters->getRoommatesStatus;
$homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' );
if ( $shutters->getModeUp eq $homemode
or $homemode eq 'none'
or $shutters->getModeUp eq 'always' )
{
2018-10-30 19:10:50 +01:00
if (
2018-10-31 09:58:23 +01:00
(
$shutters->getRoommatesStatus eq 'home'
or $shutters->getRoommatesStatus eq 'awoken'
or $shutters->getRoommatesStatus eq 'absent'
or $shutters->getRoommatesStatus eq 'gone'
or $shutters->getRoommatesStatus eq 'none'
)
and $ascDev->getSelfDefense eq 'off'
or ( $ascDev->getSelfDefense eq 'on'
and CheckIfShuttersWindowRecOpen($shuttersDev) == 0 )
2018-10-30 19:10:50 +01:00
)
{
$shutters->setLastDrive('day open');
ShuttersCommandSet( $hash, $shuttersDev, $shutters->getOpenPos );
}
}
CreateSunRiseSetShuttersTimer( $hash, $shuttersDev );
}
sub CreateNewNotifyDev($) {
my $hash = shift;
my $name = $hash->{NAME};
$hash->{NOTIFYDEV} = "global," . $name;
delete $hash->{monitoredDevs};
2018-10-14 18:38:44 +02:00
CommandDeleteReading( undef, $name . ' .monitoredDevs' );
my $shuttersList = '';
foreach ( @{ $hash->{helper}{shuttersList} } ) {
AddNotifyDev( $hash, AttrVal( $_, 'ASC_Roommate_Device', 'none' ),
$_, 'ASC_Roommate_Device' )
if ( AttrVal( $_, 'ASC_Roommate_Device', 'none' ) ne 'none' );
AddNotifyDev( $hash, AttrVal( $_, 'ASC_WindowRec', 'none' ),
$_, 'ASC_WindowRec' )
if ( AttrVal( $_, 'ASC_WindowRec', 'none' ) ne 'none' );
AddNotifyDev( $hash,
AttrVal( $_, 'ASC_Shading_Brightness_Sensor', 'none' ),
$_, 'ASC_Shading_Brightness_Sensor' )
if (
AttrVal( $_, 'ASC_Shading_Brightness_Sensor', 'none' ) ne 'none' );
$shuttersList = $shuttersList . ',' . $_;
}
AddNotifyDev( $hash, AttrVal( $name, 'ASC_residentsDevice', 'none' ),
$name, 'ASC_residentsDevice' )
if ( AttrVal( $name, 'ASC_residentsDevice', 'none' ) ne 'none' );
AddNotifyDev( $hash, AttrVal( $name, 'ASC_rainSensorDevice', 'none' ),
$name, 'ASC_rainSensorDevice' )
if ( AttrVal( $name, 'ASC_rainSensorDevice', 'none' ) ne 'none' );
$hash->{NOTIFYDEV} = $hash->{NOTIFYDEV} . $shuttersList;
}
2018-09-21 08:44:38 +02:00
sub GetShuttersInformation($) {
2018-10-28 18:12:40 +01:00
my $hash = shift;
my $ret = '<html><table><tr><td>';
2018-09-21 08:44:38 +02:00
$ret .= '<table class="block wide">';
$ret .= '<tr class="even">';
2018-10-09 18:05:55 +02:00
$ret .= "<td><b>Shutters</b></td>";
2018-09-21 20:03:02 +02:00
$ret .= "<td> </td>";
$ret .= "<td><b>Next DriveUp</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>Next DriveDown</b></td>";
$ret .= "<td> </td>";
2018-10-28 18:12:40 +01:00
$ret .= "<td><b>ASC Up</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>ASC Down</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>ASC Mode Up</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>ASC Mode Down</b></td>";
$ret .= "<td> </td>";
2018-09-21 20:03:02 +02:00
$ret .= "<td><b>Partymode</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>Lock-Out</b></td>";
2018-10-28 18:12:40 +01:00
$ret .= "<td> </td>";
$ret .= "<td><b>Last Drive</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>Position</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>Last Position</b></td>";
2018-09-21 08:44:38 +02:00
$ret .= '</tr>';
2018-09-21 22:12:24 +02:00
2018-10-28 18:12:40 +01:00
my $linecount = 1;
foreach my $shutter ( @{ $hash->{helper}{shuttersList} } ) {
$shutters->setShuttersDev($shutter);
if ( $linecount % 2 == 0 ) { $ret .= '<tr class="even">'; }
else { $ret .= '<tr class="odd">'; }
$ret .= "<td>$shutter</td>";
$ret .= "<td> </td>";
$ret .= "<td>"
. strftime( "%e.%m.%Y - %H:%M:%S",
localtime( $shutters->getSunriseUnixTime ) )
. "</td>";
$ret .= "<td> </td>";
$ret .= "<td>"
. strftime( "%e.%m.%Y - %H:%M:%S",
localtime( $shutters->getSunsetUnixTime ) )
. "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getUpMode . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getDownMode . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getModeUp . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getModeDown . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getPartyMode . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getLockOut . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getLastDrive . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getStatus . "</td>";
$ret .= "<td> </td>";
$ret .= "<td>" . $shutters->getLastPos . "</td>";
$ret .= '</tr>';
$linecount++;
2018-09-21 08:44:38 +02:00
}
$ret .= '</table></td></tr>';
$ret .= '</table></html>';
return $ret;
}
sub GetMonitoredDevs($) {
my $hash = shift;
my $notifydevs = eval {
decode_json( ReadingsVal( $hash->{NAME}, '.monitoredDevs', 'none' ) );
};
my $ret = '<html><table><tr><td>';
$ret .= '<table class="block wide">';
$ret .= '<tr class="even">';
2018-10-09 18:05:55 +02:00
$ret .= "<td><b>Shutters/ASC-Device</b></td>";
$ret .= "<td> </td>";
2018-10-09 18:05:55 +02:00
$ret .= "<td><b>NOTIFYDEV</b></td>";
$ret .= "<td> </td>";
$ret .= "<td><b>Attribut</b></td>";
$ret .= "<td> </td>";
$ret .= '</tr>';
if ( ref($notifydevs) eq "HASH" ) {
my $linecount = 1;
foreach my $notifydev ( sort keys( %{$notifydevs} ) ) {
if ( ref( $notifydevs->{$notifydev} ) eq "HASH" ) {
foreach
my $shutters ( sort keys( %{ $notifydevs->{$notifydev} } ) )
{
if ( $linecount % 2 == 0 ) { $ret .= '<tr class="even">'; }
else { $ret .= '<tr class="odd">'; }
$ret .= "<td>$shutters</td>";
$ret .= "<td> </td>";
2018-10-09 18:05:55 +02:00
$ret .= "<td>$notifydev</td>";
$ret .= "<td> </td>";
$ret .= "<td>$notifydevs->{$notifydev}{$shutters}</td>";
$ret .= "<td> </td>";
$ret .= '</tr>';
$linecount++;
}
}
}
}
###### create Links
my $aHref;
# create define Link
# $aHref="<a href=\"".$::FW_httpheader->{host}."/fhem?cmd=set".$::FW_CSRF."\">Create new NOTIFYDEV structure</a>";
# $aHref="<a href=\"/fhem?cmd=set+\">Create new NOTIFYDEV structure</a>";
# $aHref="<a href=\"".$headerHost[0]."/fhem?cmd=define+".makeDeviceName($dataset->{station}{name})."+Aqicn+".$dataset->{uid}.$FW_CSRF."\">Create Station Device</a>";
# $ret .= '<tr class="odd"> </tr>';
# $ret .= '<tr class="even"> </tr>';
# $ret .= "<td> </td>";
# $ret .= "<td> </td>";
# $ret .= "<td> </td>";
# $ret .= "<td> </td>";
# $ret .= "<td>".$aHref."</td>";
$ret .= '</table></td></tr>';
$ret .= '</table></html>';
return $ret;
}
#################################
## my little helper
#################################
2018-08-29 14:58:10 +02:00
# Hilfsfunktion welche meinen ReadingString zum finden der getriggerten Devices und der Zurdnung was das Device überhaupt ist und zu welchen Rolladen es gehört aus liest und das Device extraiert
2018-09-30 21:05:30 +02:00
sub ExtractNotifyDevFromEvent($$$) {
my ( $hash, $shuttersDev, $shuttersAttr ) = @_;
2018-09-30 21:05:30 +02:00
my %notifyDevs;
while ( my $notifyDev = each %{ $hash->{monitoredDevs} } ) {
Log3( $hash->{NAME}, 4,
"AutoShuttersControl ($hash->{NAME}) - ExtractNotifyDevFromEvent - NotifyDev: "
. $notifyDev );
Log3( $hash->{NAME}, 5,
"AutoShuttersControl ($hash->{NAME}) - ExtractNotifyDevFromEvent - ShuttersDev: "
. $shuttersDev );
if ( defined( $hash->{monitoredDevs}{$notifyDev}{$shuttersDev} )
and $hash->{monitoredDevs}{$notifyDev}{$shuttersDev} eq
$shuttersAttr )
{
Log3( $hash->{NAME}, 4,
"AutoShuttersControl ($hash->{NAME}) - ExtractNotifyDevFromEvent - ShuttersDevHash: "
. $hash->{monitoredDevs}{$notifyDev}{$shuttersDev} );
Log3( $hash->{NAME}, 5,
"AutoShuttersControl ($hash->{NAME}) - ExtractNotifyDevFromEvent - return ShuttersDev: "
. $notifyDev );
2018-09-30 21:05:30 +02:00
$notifyDevs{$notifyDev} = $shuttersDev;
}
}
2018-09-30 21:05:30 +02:00
return \%notifyDevs;
2018-08-16 10:37:09 +02:00
}
## Ist Tag oder Nacht für den entsprechende Rolladen
sub IsDay($$) {
my ( $hash, $shuttersDev ) = @_;
my $name = $hash->{NAME};
return ( ShuttersSunrise( $hash, $shuttersDev, 'unix' ) >
ShuttersSunset( $hash, $shuttersDev, 'unix' ) ? 1 : 0 );
}
sub ShuttersSunrise($$$) {
my ( $hash, $shuttersDev, $tm ) =
@_; # Tm steht für Timemode und bedeutet Realzeit oder Unixzeit
my $name = $hash->{NAME};
2018-09-13 08:11:10 +02:00
my $autoAstroMode;
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
$ascDev->setName($name);
2018-09-18 09:35:45 +02:00
if ( $shutters->getAutoAstroModeMorning ne 'none' ) {
$autoAstroMode = $shutters->getAutoAstroModeMorning;
$autoAstroMode =
$autoAstroMode . '=' . $shutters->getAutoAstroModeMorningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
else {
$autoAstroMode = $ascDev->getAutoAstroModeMorning;
$autoAstroMode =
$autoAstroMode . '='
. AttrVal( $name, 'ASC_autoAstroModeMorningHorizon', 0 )
if ( $autoAstroMode eq 'HORIZON' );
}
my $oldFuncHash = $shutters->getInTimerFuncHash;
my $shuttersSunriseUnixtime;
if ( $tm eq 'unix' ) {
if ( $shutters->getUpMode eq 'astro' ) {
if ( ( IsWe() or IsWeTomorrow() )
and $ascDev->getSunriseTimeWeHoliday eq 'on' )
{
if ( not IsWeTomorrow() ) {
2018-10-31 09:58:23 +01:00
if (
IsWe()
and int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
2018-10-31 09:58:23 +01:00
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 1
);
}
elsif (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$shutters->getTimeUpEarly,
$shutters->getTimeUpLate
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 1
);
2018-09-24 15:29:39 +02:00
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$shutters->getTimeUpEarly,
$shutters->getTimeUpLate
)
) + 1
);
2018-09-24 15:29:39 +02:00
}
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 1
);
2018-09-24 15:29:39 +02:00
}
2018-09-18 09:35:45 +02:00
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$shutters->getTimeUpEarly,
$shutters->getTimeUpLate
)
) + 1
);
}
if ( defined($oldFuncHash)
and ref($oldFuncHash) eq 'HASH'
and ( IsWe() or IsWeTomorrow() )
and $ascDev->getSunriseTimeWeHoliday eq 'on' )
{
if ( not IsWeTomorrow() ) {
if (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$shutters->getTimeUpEarly,
$shutters->getTimeUpLate
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime =
( $shuttersSunriseUnixtime + 86400 )
if ( $shuttersSunriseUnixtime <
( $oldFuncHash->{sunrisetime} + 180 )
and $oldFuncHash->{sunrisetime} < gettimeofday() );
}
}
}
elsif ( defined($oldFuncHash) and ref($oldFuncHash) eq 'HASH' ) {
$shuttersSunriseUnixtime = ( $shuttersSunriseUnixtime + 86400 )
if ( $shuttersSunriseUnixtime <
( $oldFuncHash->{sunrisetime} + 180 )
and $oldFuncHash->{sunrisetime} < gettimeofday() );
}
}
elsif ( $shutters->getUpMode eq 'time' ) {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $shutters->getTimeUpEarly );
}
elsif ( $shutters->getUpMode eq 'brightness' ) {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $shutters->getTimeUpLate );
}
return $shuttersSunriseUnixtime;
}
elsif ( $tm eq 'real' ) {
return sunrise_abs( $autoAstroMode, 0, $shutters->getTimeUpEarly,
$shutters->getTimeUpLate )
if ( $shutters->getUpMode eq 'astro' );
return $shutters->getTimeUpEarly if ( $shutters->getUpMode eq 'time' );
}
}
sub ShuttersSunset($$$) {
my ( $hash, $shuttersDev, $tm ) =
@_; # Tm steht für Timemode und bedeutet Realzeit oder Unixzeit
my $name = $hash->{NAME};
2018-09-13 08:11:10 +02:00
my $autoAstroMode;
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
$ascDev->setName($name);
2018-09-18 09:35:45 +02:00
if ( $shutters->getAutoAstroModeEvening ne 'none' ) {
$autoAstroMode = $shutters->getAutoAstroModeEvening;
$autoAstroMode =
$autoAstroMode . '=' . $shutters->getAutoAstroModeEveningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
else {
$autoAstroMode = $ascDev->getAutoAstroModeEvening;
$autoAstroMode =
$autoAstroMode . '='
. AttrVal( $name, 'ASC_autoAstroModeEveningHorizon', 0 )
if ( $autoAstroMode eq 'HORIZON' );
}
my $oldFuncHash = $shutters->getInTimerFuncHash;
my $shuttersSunsetUnixtime;
if ( $tm eq 'unix' ) {
if ( $shutters->getDownMode eq 'astro' ) {
$shuttersSunsetUnixtime = (
computeAlignTime(
'24:00',
sunset_abs(
$autoAstroMode,
0,
$shutters->getTimeDownEarly,
$shutters->getTimeDownLate
)
) + 1
);
if ( defined($oldFuncHash) and ref($oldFuncHash) eq 'HASH' ) {
$shuttersSunsetUnixtime = ( $shuttersSunsetUnixtime + 86400 )
if ( $shuttersSunsetUnixtime <
( $oldFuncHash->{sunsettime} + 180 )
and $oldFuncHash->{sunsettime} < gettimeofday() );
}
}
elsif ( $shutters->getDownMode eq 'time' ) {
$shuttersSunsetUnixtime =
computeAlignTime( '24:00', $shutters->getTimeDownEarly );
}
elsif ( $shutters->getDownMode eq 'brightness' ) {
$shuttersSunsetUnixtime =
computeAlignTime( '24:00', $shutters->getTimeDownLate );
}
return $shuttersSunsetUnixtime;
}
elsif ( $tm eq 'real' ) {
return sunset_abs(
$autoAstroMode, 0,
$shutters->getTimeDownEarly,
$shutters->getTimeDownLate
) if ( $shutters->getDownMode eq 'astro' );
return $shutters->getTimeDownEarly
if ( $shutters->getDownMode eq 'time' );
}
}
2018-08-29 14:58:10 +02:00
## Kontrolliert ob das Fenster von einem bestimmten Rolladen offen ist
sub CheckIfShuttersWindowRecOpen($) {
my $shuttersDev = shift;
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
if ( $shutters->getWinStatus eq 'open' ) { return 2; }
elsif ( $shutters->getWinStatus eq 'tilted'
and $shutters->getSubTyp eq 'threestate' )
{
return 1;
}
elsif ( $shutters->getWinStatus eq 'closed' ) { return 0; }
}
sub ShuttersPosCmdValueNegieren($) {
my $shuttersDev = shift;
2018-10-10 10:43:42 +02:00
$shutters->setShuttersDev($shuttersDev);
return ( $shutters->getOpenPos < $shutters->getClosedPos ? 1 : 0 );
}
sub makeReadingName($) {
my ($name) = @_;
my %charHash = (
"ä" => "ae",
"Ä" => "Ae",
"ü" => "ue",
"Ü" => "Ue",
"ö" => "oe",
"Ö" => "Oe",
"ß" => "ss"
);
my $charHashkeys = join( "|", keys(%charHash) );
$name = "UNDEFINED" if ( !defined($name) );
return $name if ( $name =~ m/^\./ );
$name =~ s/($charHashkeys)/$charHash{$1}/gi;
$name =~ s/[^a-z0-9._\-\/]/_/gi;
return $name;
}
sub TimeMin2Sec($) {
my $min = shift;
my $sec;
$sec = $min * 60;
return $sec;
}
2018-09-18 09:35:45 +02:00
sub IsWe() {
my ( undef, undef, undef, undef, undef, undef, $wday, undef, undef ) =
localtime( gettimeofday() );
my $we = ( ( $wday == 0 || $wday == 6 ) ? 1 : 0 );
if ( !$we ) {
foreach my $h2we ( split( ",", AttrVal( "global", "holiday2we", "" ) ) )
{
my ( $a, $b ) =
ReplaceEventMap( $h2we, [ $h2we, Value($h2we) ], 0 );
$we = 1 if ( $b && $b ne "none" );
2018-09-18 09:35:45 +02:00
}
}
return $we;
2018-09-18 09:35:45 +02:00
}
sub IsWeTomorrow() {
my ( undef, undef, undef, undef, undef, undef, $wday, undef, undef ) =
localtime( gettimeofday() );
2018-10-16 10:30:10 +02:00
my $we = (
( ( ( $wday + 1 == 7 ? 0 : $wday + 1 ) ) == 0 || ( $wday + 1 ) == 6 )
? 1
2018-10-16 10:30:10 +02:00
: 0
);
if ( !$we ) {
foreach my $h2we ( split( ",", AttrVal( "global", "holiday2we", "" ) ) )
{
my ( $a, $b ) = ReplaceEventMap( $h2we,
[ $h2we, ReadingsVal( $h2we, "tomorrow", "none" ) ], 0 );
$we = 1 if ( $b && $b ne "none" );
2018-09-18 09:35:45 +02:00
}
}
return $we;
2018-09-18 09:35:45 +02:00
}
sub IsHoliday($) {
my $hash = shift;
my $name = $hash->{NAME};
2018-09-18 09:35:45 +02:00
return (
ReadingsVal( AttrVal( $name, 'ASC_timeUpHolidayDevice', 'none' ),
'state', 0 ) == 1 ? 1 : 0
);
2018-09-18 09:35:45 +02:00
}
sub SetCmdFn($) {
2018-10-30 19:10:50 +01:00
my $h = shift;
my $shuttersDev = $h->{shuttersDev};
my $posValue = $h->{posValue};
2018-10-30 19:10:50 +01:00
$shutters->setShuttersDev($shuttersDev);
$shutters->setLastPos( $shutters->getStatus );
CommandSet( undef,
$shuttersDev
. ':FILTER='
. $shutters->getPosCmd . '!='
. $posValue . ' '
. $shutters->getPosCmd . ' '
. $posValue );
$shutters->setLastDriveReading if ( $shutters->getLastPos != $posValue );
2018-10-30 19:10:50 +01:00
$shutters->setLastDrive(
ReadingsVal( $shuttersDev, 'ASC_ShuttersLastDrive', 'none' ) )
if ( $shutters->getLastPos == $posValue );
}
2018-10-28 18:12:40 +01:00
########## Begin der Klassendeklarierungen für OOP (Objektorientierte Programmierung) #########################
2018-10-10 10:43:42 +02:00
## 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);
2018-10-08 21:05:47 +02:00
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
defs
ReadingsVal
readingsSingleUpdate
gettimeofday
InternalTimer)
);
}
2018-10-08 21:05:47 +02:00
sub new {
my $class = shift;
my $self = {
shuttersDev => undef,
defaultarg => undef,
roommate => undef,
};
2018-10-08 21:05:47 +02:00
bless $self, $class;
return $self;
}
2018-10-10 10:43:42 +02:00
sub setShuttersDev {
my ( $self, $shuttersDev ) = @_;
2018-10-17 09:50:11 +02:00
$self->{shuttersDev} = $shuttersDev if ( defined($shuttersDev) );
2018-10-10 10:43:42 +02:00
return $self->{shuttersDev};
2018-10-08 21:05:47 +02:00
}
sub getShuttersDev {
my $self = shift;
return $self->{shuttersDev};
}
sub setDriveCmd {
my ( $self, $posValue ) = @_;
my $offSet = 0;
2018-10-30 19:10:50 +01:00
my %h = (
shuttersDev => $self->{shuttersDev},
posValue => $posValue,
);
$offSet = $shutters->getOffset if ( $shutters->getOffset > 0 );
$offSet = $ascDev->getShuttersOffset if ( $shutters->getOffset == -1 );
2018-10-30 19:10:50 +01:00
InternalTimer( gettimeofday() + int( rand($offSet) ),
'AutoShuttersControl::SetCmdFn', \%h )
if ( $offSet > 0 );
AutoShuttersControl::SetCmdFn( \%h ) if ( $offSet == 0 );
return 0;
}
2018-10-08 21:05:47 +02:00
2018-10-28 18:12:40 +01:00
sub setSunsetUnixTime {
my ( $self, $unixtime ) = @_;
$self->{ $self->{shuttersDev} }{sunsettime} = $unixtime;
return 0;
}
sub setSunriseUnixTime {
my ( $self, $unixtime ) = @_;
$self->{ $self->{shuttersDev} }{sunrisetime} = $unixtime;
return 0;
}
sub setDelayCmd {
my ( $self, $posValue ) = @_;
$self->{ $self->{shuttersDev} }{delayCmd} = $posValue;
return 0;
}
sub setLastDrive {
my ( $self, $lastDrive ) = @_;
$self->{ $self->{shuttersDev} }{lastDrive} = $lastDrive;
return 0;
}
sub setLastDriveReading {
my $self = shift;
my $shuttersDevHash = $defs{ $self->{shuttersDev} };
readingsSingleUpdate( $shuttersDevHash, 'ASC_ShuttersLastDrive',
$shutters->getLastDrive, 0 );
return 0;
}
sub setLastPos
{ # letzte ermittelte Position bevor die Position des Rolladen über ASC geändert wurde
my ( $self, $position ) = @_;
2018-10-17 09:50:11 +02:00
$self->{ $self->{shuttersDev} }{lastPos}{VAL} = $position
2018-10-17 09:50:11 +02:00
if ( defined($position) );
$self->{ $self->{shuttersDev} }{lastPos}{TIME} = int( gettimeofday() )
if ( defined( $self->{ $self->{shuttersDev} }{lastPos} ) );
return 0;
}
2018-10-08 21:05:47 +02:00
sub setLastManPos
{ # letzte ermittelte Position bevor die Position des Rolladen manuell (nicht über ASC) geändert wurde
my ( $self, $position ) = @_;
$self->{ $self->{shuttersDev} }{lastManPos}{VAL} = $position
if ( defined($position) );
$self->{ $self->{shuttersDev} }{lastManPos}{TIME} = int( gettimeofday() )
if ( defined( $self->{ $self->{shuttersDev} }{lastManPos} ) );
return 0;
}
sub setDefault {
my ( $self, $defaultarg ) = @_;
2018-10-17 09:50:11 +02:00
$self->{defaultarg} = $defaultarg if ( defined($defaultarg) );
2018-10-10 10:43:42 +02:00
return $self->{defaultarg};
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub setRoommate {
my ( $self, $roommate ) = @_;
2018-10-17 09:50:11 +02:00
$self->{roommate} = $roommate if ( defined($roommate) );
2018-10-10 10:43:42 +02:00
return $self->{roommate};
2018-10-08 21:05:47 +02:00
}
2018-10-17 09:50:11 +02:00
sub setInTimerFuncHash {
my ( $self, $inTimerFuncHash ) = @_;
$self->{ $self->{shuttersDev} }{inTimerFuncHash} = $inTimerFuncHash
if ( defined($inTimerFuncHash) );
return 0;
}
sub getLastDrive {
my $self = shift;
2018-10-28 18:12:40 +01:00
$self->{ $self->{shuttersDev} }{lastDrive} =
ReadingsVal( $self->{shuttersDev}, 'ASC_ShuttersLastDrive', 'none' )
if ( not 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;
2018-10-17 09:50:11 +02:00
return $self->{ $self->{shuttersDev} }{lastPos}{VAL}
if ( defined( $self->{ $self->{shuttersDev} }{lastPos} )
and defined( $self->{ $self->{shuttersDev} }{lastPos}{VAL} ) );
}
sub getLastPosTimestamp {
my $self = shift;
2018-10-17 09:50:11 +02:00
return $self->{ $self->{shuttersDev} }{lastPos}{TIME}
if ( defined( $self->{ $self->{shuttersDev} } )
and defined( $self->{ $self->{shuttersDev} }{lastPos} )
and defined( $self->{ $self->{shuttersDev} }{lastPos}{TIME} ) );
}
sub getLastManPos
{ # letzte ermittelte Position bevor die Position des Rolladen manuell (nicht über ASC) geändert wurde
my $self = shift;
return $self->{ $self->{shuttersDev} }{lastManPos}{VAL}
if ( defined( $self->{ $self->{shuttersDev} }{lastManPos} )
and defined( $self->{ $self->{shuttersDev} }{lastManPos}{VAL} ) );
}
sub getLastManPosTimestamp {
my $self = shift;
return $self->{ $self->{shuttersDev} }{lastManPos}{TIME}
if ( defined( $self->{ $self->{shuttersDev} } )
and defined( $self->{ $self->{shuttersDev} }{lastManPos} )
and defined( $self->{ $self->{shuttersDev} }{lastManPos}{TIME} ) );
}
2018-10-17 09:50:11 +02:00
sub getInTimerFuncHash {
my $self = shift;
2018-10-17 09:50:11 +02:00
return $self->{ $self->{shuttersDev} }{inTimerFuncHash};
}
2018-10-08 21:05:47 +02:00
2018-10-28 18:12:40 +01:00
sub getSunsetUnixTime {
my $self = shift;
return $self->{ $self->{shuttersDev} }{sunsettime};
}
sub getSunriseUnixTime {
my $self = shift;
return $self->{ $self->{shuttersDev} }{sunrisetime};
}
sub getRoommatesStatus {
my $self = shift;
my $loop = 0;
2018-10-01 08:43:59 +02:00
my @roState;
my %statePrio = (
'asleep' => 1,
'gotosleep' => 2,
'awoken' => 3,
'home' => 4,
'absent' => 5,
'gone' => 6,
'none' => 7
);
my $minPrio = 10;
foreach my $ro ( split( ",", $shutters->getRoommates ) ) {
2018-10-10 10:43:42 +02:00
$shutters->setRoommate($ro);
my $currentPrio = $statePrio{ $shutters->getRoommateStatus };
$minPrio = $currentPrio if ( $minPrio > $currentPrio );
2018-10-01 08:43:59 +02:00
}
2018-10-17 09:50:11 +02:00
my %revStatePrio = reverse %statePrio;
2018-10-10 10:43:42 +02:00
return $revStatePrio{$minPrio};
2018-10-01 08:43:59 +02:00
}
2018-10-10 10:43:42 +02:00
sub getRoommatesLastStatus {
my $self = shift;
my $loop = 0;
2018-10-01 08:43:59 +02:00
my @roState;
my %statePrio = (
'asleep' => 1,
'gotosleep' => 2,
'awoken' => 3,
'home' => 4,
'absent' => 5,
'gone' => 6,
'none' => 7
);
my $minPrio = 10;
foreach my $ro ( split( ",", $shutters->getRoommates ) ) {
2018-10-10 10:43:42 +02:00
$shutters->setRoommate($ro);
my $currentPrio = $statePrio{ $shutters->getRoommateLastStatus };
$minPrio = $currentPrio if ( $minPrio > $currentPrio );
2018-10-01 08:43:59 +02:00
}
my %revStatePrio = reverse %statePrio;
2018-10-10 10:43:42 +02:00
return $revStatePrio{$minPrio};
2018-10-08 21:05:47 +02:00
}
2018-10-09 18:05:55 +02:00
## Subklasse Attr von ASC_Shutters##
package ASC_Shutters::Attr;
2018-10-08 21:05:47 +02:00
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
AttrVal)
);
}
2018-10-08 21:05:47 +02:00
sub getShuttersPlace {
my $self = shift;
return AttrVal( $self->{shuttersDev}, 'ASC_ShuttersPlace', 'window' );
}
sub getSelfDefenseExclude {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Self_Defense_Exclude', 'off' );
}
2018-10-08 21:05:47 +02:00
2018-10-12 06:32:01 +02:00
sub getShadingBrightnessSensor {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Brightness_Sensor',
$default );
2018-10-08 21:05:47 +02:00
}
2018-10-12 06:32:01 +02:00
sub getShadingBrightnessReading {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-12 06:32:01 +02:00
2018-10-17 09:50:11 +02:00
$default = 'brightness' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Brightness_Reading',
$default );
2018-10-12 06:32:01 +02:00
}
2018-10-08 21:05:47 +02:00
sub getOffset {
my $self = shift;
return AttrVal( $self->{shuttersDev}, 'ASC_Drive_Offset', 0 );
}
2018-10-10 10:43:42 +02:00
sub getPosCmd {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Pos_Cmd', 'pct' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getOpenPos {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Open_Pos', 0 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getVentilatePos {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Ventilate_Pos', 80 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getClosedPos {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Closed_Pos', 100 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getVentilateOpen {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Ventilate_Window_Open', 'off' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getPosAfterComfortOpen {
my $self = shift;
return AttrVal( $self->{shuttersDev}, 'ASC_Pos_after_ComfortOpen', 50 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getPartyMode {
my $self = shift;
return AttrVal( $self->{shuttersDev}, 'ASC_Partymode', 'off' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getRoommates {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_Roommate_Device', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getRoommatesReading {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'state' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_Roommate_Reading', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getModeUp {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Mode_Up', 'off' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getModeDown {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Mode_Down', 'off' );
2018-10-01 08:43:59 +02:00
}
2018-10-10 10:43:42 +02:00
sub getLockOut {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_lock-out', 'soft' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAntiFreeze {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Antifreeze', 'off' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeMorning {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeMorning',
$default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeEvening {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeEvening',
$default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeMorningHorizon {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeMorningHorizon',
0 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeEveningHorizon {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_AutoAstroModeEveningHorizon',
0 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getUpMode {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Up', 'astro' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getDownMode {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Down', 'astro' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getTimeUpEarly {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_Early', '04:30:00' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getTimeUpLate {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_Late', '09:00:00' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getTimeDownEarly {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Time_Down_Early', '15:30:00' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getTimeDownLate {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Time_Down_Late', '22:00:00' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getTimeUpWeHoliday {
my $self = shift;
2018-10-08 21:05:47 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_Time_Up_WE_Holiday',
'04:00:00' );
2018-10-08 21:05:47 +02:00
}
2018-10-16 10:30:10 +02:00
sub getBrightnessMinVal {
my $self = shift;
2018-10-16 10:30:10 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_BrightnessMinVal', -1 );
2018-10-16 10:30:10 +02:00
}
sub getBrightnessMaxVal {
my $self = shift;
2018-10-16 10:30:10 +02:00
return AttrVal( $self->{shuttersDev}, 'ASC_BrightnessMaxVal', -1 );
2018-10-16 10:30:10 +02:00
}
2018-10-09 18:05:55 +02:00
## Subklasse Readings von ASC_Shutters ##
package ASC_Shutters::Readings;
2018-10-08 21:05:47 +02:00
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
ReadingsVal)
);
}
2018-10-08 21:05:47 +02:00
2018-10-12 06:32:01 +02:00
sub getBrightness {
my $self = shift;
2018-10-10 10:43:42 +02:00
return ReadingsVal( $shutters->getShadingBrightnessSensor,
$shutters->getShadingBrightnessReading, 0 );
2018-10-12 06:32:01 +02:00
}
2018-10-10 10:43:42 +02:00
sub getStatus {
my $self = shift;
2018-10-10 10:43:42 +02:00
return ReadingsVal( $self->{shuttersDev}, $shutters->getPosCmd, 0 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getDelayCmd {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
return $self->{ $self->{shuttersDev} }{delayCmd};
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
## Klasse Fenster (Window) und die Subklassen Attr und Readings ##
package ASC_Window;
our @ISA = qw(ASC_Window::Attr ASC_Window::Readings);
2018-10-10 10:43:42 +02:00
## Subklasse Attr von Klasse ASC_Window ##
package ASC_Window::Attr;
2018-10-08 21:05:47 +02:00
2018-10-10 10:43:42 +02:00
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
AttrVal)
);
}
2018-10-10 10:43:42 +02:00
sub getSubTyp {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-10 10:43:42 +02:00
2018-10-17 09:50:11 +02:00
$default = 'twostate' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_WindowRec_subType', $default );
2018-10-10 10:43:42 +02:00
}
sub getWinDev {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-10 10:43:42 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $self->{shuttersDev}, 'ASC_WindowRec', $default );
2018-10-10 10:43:42 +02:00
}
## Subklasse Readings von Klasse ASC_Window ##
package ASC_Window::Readings;
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
ReadingsVal)
);
}
2018-10-10 10:43:42 +02:00
sub getWinStatus {
my $self = shift;
my $default = $self->{defaultarg};
2018-10-10 10:43:42 +02:00
2018-10-17 09:50:11 +02:00
$default = 'closed' if ( not defined($default) );
return ReadingsVal( $shutters->getWinDev, 'state', $default );
2018-10-08 21:05:47 +02:00
}
## Klasse ASC_Roommate ##
package ASC_Roommate;
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
ReadingsVal)
);
}
2018-10-08 21:05:47 +02:00
2018-10-10 10:43:42 +02:00
sub getRoommateStatus {
my $self = shift;
my $roommate = $self->{roommate};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-28 18:12:40 +01:00
$default = 'none' if ( not defined($default) );
return ReadingsVal( $roommate, $shutters->getRoommatesReading, $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getRoommateLastStatus {
my $self = shift;
my $roommate = $self->{roommate};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-28 18:12:40 +01:00
$default = 'none' if ( not defined($default) );
return ReadingsVal( $roommate, 'lastState', $default );
2018-10-08 21:05:47 +02:00
}
## Klasse ASC_Dev plus Subklassen ASC_Attr_Dev und ASC_Readings_Dev##
package ASC_Dev;
our @ISA = qw(ASC_Dev::Readings ASC_Dev::Attr);
2018-10-08 21:05:47 +02:00
use strict;
use warnings;
sub new {
my $class = shift;
my $self = { name => undef, };
2018-10-08 21:05:47 +02:00
bless $self, $class;
return $self;
}
2018-10-10 10:43:42 +02:00
sub setName {
my ( $self, $name ) = @_;
2018-10-17 09:50:11 +02:00
$self->{name} = $name if ( defined($name) );
2018-10-10 10:43:42 +02:00
return $self->{name};
}
sub setDefault {
my ( $self, $defaultarg ) = @_;
2018-10-17 09:50:11 +02:00
$self->{defaultarg} = $defaultarg if ( defined($defaultarg) );
2018-10-10 10:43:42 +02:00
return $self->{defaultarg};
}
2018-10-09 18:05:55 +02:00
## Subklasse Readings ##
package ASC_Dev::Readings;
2018-10-08 21:05:47 +02:00
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
readingsSingleUpdate
ReadingsVal
defs)
);
}
2018-10-08 21:05:47 +02:00
sub setDelayCmdReading {
my $self = shift;
my $name = $self->{name};
my $hash = $defs{$name};
readingsSingleUpdate( $hash,
$shutters->getShuttersDev . '_lastDelayPosValue',
$shutters->getDelayCmd, 1 );
return 0;
}
sub setLastPosReading {
my $self = shift;
my $name = $self->{name};
my $hash = $defs{$name};
readingsSingleUpdate( $hash, $shutters->getShuttersDev . '_lastPosValue',
$shutters->getLastPos, 1 );
return 0;
}
2018-10-10 10:43:42 +02:00
sub getPartyModeStatus {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return ReadingsVal( $name, 'partyMode', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getLockOut {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return ReadingsVal( $name, 'lockOut', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getSunriseTimeWeHoliday {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return ReadingsVal( $name, 'sunriseTimeWeHoliday', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getMonitoredDevs {
my $self = shift;
my $name = $self->{name};
2018-10-08 21:05:47 +02:00
$self->{monitoredDevs} = ReadingsVal( $name, '.monitoredDevs', 'none' );
2018-10-08 21:05:47 +02:00
return $self->{monitoredDevs};
}
2018-10-10 10:43:42 +02:00
sub getOutTemp {
my $self = shift;
my $name = $self->{name};
2018-10-08 21:05:47 +02:00
return ReadingsVal( $ascDev->getTempSensor, $ascDev->getTempReading, 100 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getResidentsStatus {
my $self = shift;
my $name = $self->{name};
2018-10-09 18:05:55 +02:00
return ReadingsVal( $ascDev->getResidentsDev, $ascDev->getResidentsReading,
2018-10-28 18:12:40 +01:00
'none' );
2018-10-09 18:05:55 +02:00
}
sub getResidentsLastStatus {
my $self = shift;
my $name = $self->{name};
2018-10-09 18:05:55 +02:00
2018-10-28 18:12:40 +01:00
return ReadingsVal( $ascDev->getResidentsDev, 'lastState', 'none' );
2018-10-09 18:05:55 +02:00
}
sub getSelfDefense {
my $self = shift;
my $name = $self->{name};
return ReadingsVal( $name, 'selfDefense', 'none' );
}
2018-10-08 21:05:47 +02:00
2018-10-09 18:05:55 +02:00
## Subklasse Attr ##
package ASC_Dev::Attr;
2018-10-08 21:05:47 +02:00
use strict;
use warnings;
use GPUtils qw(:all);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
AttrVal)
);
}
2018-10-08 21:05:47 +02:00
sub getShuttersOffset {
2018-10-30 19:10:50 +01:00
my $self = shift;
my $name = $self->{name};
return AttrVal( $name, 'ASC_shuttersDriveOffset', 0 );
}
2018-10-12 06:32:01 +02:00
sub getBrightnessMinVal {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-12 06:32:01 +02:00
2018-10-17 09:50:11 +02:00
$default = 8000 if ( not defined($default) );
return AttrVal( $name, 'ASC_brightnessMinVal', $default );
2018-10-12 06:32:01 +02:00
}
sub getBrightnessMaxVal {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 20000 if ( not defined($default) );
return AttrVal( $name, 'ASC_brightnessMaxVal', $default );
2018-10-12 06:32:01 +02:00
}
2018-10-08 21:05:47 +02:00
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeEvening {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_autoAstroModeEvening', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeEveningHorizon {
my $self = shift;
my $name = $self->{name};
2018-10-08 21:05:47 +02:00
return AttrVal( $name, 'ASC_autoAstroModeEveningHorizon', 0 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeMorning {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_autoAstroModeMorning', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoAstroModeMorningHorizon {
my $self = shift;
my $name = $self->{name};
2018-10-08 21:05:47 +02:00
return AttrVal( $name, 'ASC_autoAstroModeMorningHorizon', 0 );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoShuttersControlMorning {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_autoShuttersControlMorning', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoShuttersControlEvening {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_autoShuttersControlEvening', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAutoShuttersControlComfort {
my $self = shift;
my $name = $self->{name};
2018-10-08 21:05:47 +02:00
return AttrVal( $name, 'ASC_autoShuttersControlComfort', 'off' );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getAntifreezeTemp {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_antifreezeTemp', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getTempSensor {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_temperatureSensor', $default );
2018-10-08 21:05:47 +02:00
}
2018-10-10 10:43:42 +02:00
sub getTempReading {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-08 21:05:47 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_temperatureReading', $default );
2018-10-08 21:05:47 +02:00
}
2018-08-15 10:27:53 +02:00
2018-10-10 10:43:42 +02:00
sub getResidentsDev {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-09 18:05:55 +02:00
2018-10-17 09:50:11 +02:00
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_residentsDevice', $default );
2018-10-09 18:05:55 +02:00
}
2018-10-10 10:43:42 +02:00
sub getResidentsReading {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
2018-10-09 18:05:55 +02:00
2018-10-17 09:50:11 +02:00
$default = 'state' if ( not defined($default) );
return AttrVal( $name, 'ASC_residentsDeviceReading', $default );
2018-10-09 18:05:55 +02:00
}
sub getRainSensor {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
$default = 'none' if ( not defined($default) );
return AttrVal( $name, 'ASC_rainSensorDevice', $default );
}
sub getRainSensorReading {
my $self = shift;
my $name = $self->{name};
my $default = $self->{defaultarg};
$default = 'state' if ( not defined($default) );
return AttrVal( $name, 'ASC_rainSensorReading', $default );
}
sub getRainSensorShuttersClosedPos {
my $self = shift;
my $name = $self->{name};
return AttrVal( $name, 'ASC_rainSensorShuttersClosedPos', 50 );
}
2018-08-15 10:27:53 +02:00
1;
=pod
=item device
=item summary Modul
=item summary_DE Modul zur Automatischen Rolladensteuerung auf Basis bestimmter Ereignisse
=begin html
<a name="AutoShuttersControl"></a>
<h3>Automated Shutter Control - ASC</h3>
2018-08-15 10:27:53 +02:00
<ul>
<u><b>AutoShuttersControl (shurt: ASC) is designed for automation of shutter levels based on individual presets and timers. Timers can use sunrise and sunset events,reaction on opening or closing of correspondant window contacts is possible.</b></u>
<br>
This module generates a virtual device. If your shutters are represented in FHEM as devices,just put them under controll of this module. Then you get further options to let ASC controll them. Set the provided attributes and ASC will e.g. open your shutter after sunrise when resident is awoken. Or let it go to a predifined position for ventilation when window is tilted.
<br><br>
<a name="AutoShuttersControlDefine"></a>
<b>Define</b>
<ul><br>
<code>define &lt;name&gt; AutoShuttersControl</code>
<br><br>
Example:
<ul><br>
<code>define Rolladensteuerung AutoShuttersControl</code><br>
</ul>
<br>
This creates a AutoShuttersControl Device named Rolladensteuerung.<br>
After this first step,start adding shutter devices by assigning the new attribute "AutoShuttersControl" using "1" or "2" as value.<br>
Use "1" if your shutter is open at lower position (typically: 0 = open,100 = closed) and shutter command "position" is used. Right choice for ROLLO devices.
"2" means opposite,so open is 100 and closed corresponds to 0; command for going to a specific position is "pct". Use "2" especially for HomeMatic devices.<br>
Next use the "scanForShutters" setter to get your shutter(s) controlled by ASC and start configuring your shutter devices by setting the ASC attributes to your needs.
</ul>
<br><br>
<a name="AutoShuttersControlReadings"></a>
<b>Readings</b>
<ul>
Module Device
<ul>
<li>..._nextAstroTimeEvent - Execution time of the next Astro Event,sunrise,sunset or fixed time per shutter</li>
<li>..._lastPosValue - last sent positioning command per shutter</li>
<li>..._lastDelayPosValue - last positioning command per shutter not yet sent,waiting for event dependent execution.</li>
<li>partyMode - on/off; activates a global party mode,all shutters with ASC_Partymode attribute set to "on" will not get any command from ASC until part is set to "off" again. Then the last intermediate positioning command will be executed,e.g. based on window opening or resident state.</li>
2018-09-28 08:57:25 +02:00
<li>lockOut - on/off f&uuml;r das aktivieren des Aussperrschutzes gem&auml;&szlig; dem entsprechenden Attribut ASC_lock-out im jeweiligen Rolladen. (siehe Beschreibung bei den Attributen f&uuml;r die Rolladendevices)</li>
<li>room_... - List of all shutter devices under ASC control per room</li>
<li>state - State of the ASC device (active,enabled or disabled)</li>
<li>userAttrList - Indicates if all UserAttributes are rolled out to shutter devices.</li>
</ul><br>
Shutter Devices
<ul>
2018-09-28 08:57:25 +02:00
<li>ASC_Time_DriveUp - Shutter's individual sunrise time</li>
<li>ASC_Time_DriveDown - Shutter's individual sunset time</li>
</ul>
</ul>
<br><br>
<a name="AutoShuttersControlSet"></a>
<b>Set</b>
<ul>
<li>partyMode - on/off activates global party mode. See Reading partyMode</li>
2018-09-18 09:35:45 +02:00
<li>lockOut - on/off aktiviert den globalen Aussperrschutz. Siehe Reading partyMode</li>
<li>renewSetSunriseSunsetTimer - renews individual times and internal timers for all shutters under ASC control.</li>
<li>scanForShutters - add all FHEM devices to ASC control; looks up for devices with attribute "AutoShuttersControl" set to 1 or 2.</li>
<li></li>
</ul>
<br><br>
<a name="AutoShuttersControlGet"></a>
<b>Get</b>
<ul>
<li></li>
</ul>
<br><br>
<a name="AutoShuttersControlAttributes"></a>
<b>Attributes</b>
<ul>
Modul Device
<ul>
<li>ASC_antifreezeTemp - Temperature limit. Below this temperature,ASC will not issue positioning commands to prevent damages from frozen shutters. Last positioning command will be stored for later execution.</li>
<li>ASC_autoAstroModeEvening - can be set to REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_autoAstroModeEveningHorizon - Highth above horizon. Use this in combination with attribute ASC_autoAstroModeEvening set to HORIZON</li>
<li>ASC_autoAstroModeMorning - can be set to REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_autoAstroModeMorningHorizon - similar to ASC_autoAstroModeEvening</li>
<li>ASC_autoShuttersControlComfort - on/off. Switch to on to react on open or tilted events. Needs further info in shutter attributes about WindowRec,WindowRecType and ASC_Pos_after_ComfortOpen (last sets target position).</li>
2018-09-28 08:57:25 +02:00
<li>ASC_autoShuttersControlEvening - on/off; Switch to on to close this shutter in the evening</li>
<li>ASC_autoShuttersControlMorning - on/off; similar to ASC_autoShuttersControlEvening for opening.</li>
<li>ASC_temperatureReading - Reading name for outside temperature</li>
<li>ASC_temperatureSensor - Device name for outside temperature</li>
</ul><br>
Individual Shutter Devices
<ul>
<li>AutoShuttersControl - 0/1/2. Use "1" if your shutter is open at lower position (typically: 0 = open,100 = closed) and shutter command "position" is used. Right choice for ROLLO devices.
"2" means opposite,so open is 100 and closed corresponds to 0; command for going to a specific position is "pct". Use "2" especially for HomeMatic devices.</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Antifreeze - on/off; Set to on to prevent ASC commands under the set temperature limit</li>
<li>ASC_AutoAstroModeEvening - can be set to REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_AutoAstroModeEveningHorizon - Highth above horizon. Use this in combination with attribute ASC_autoAstroModeEvening set to HORIZON</li>
<li>ASC_AutoAstroModeMorning - can be set to REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_AutoAstroModeMorningHorizon - similar to ASC_autoAstroModeEvening</li>
<li>ASC_Closed_Pos - in 10 steps from 0 to 100,defaults will be set dependent on AutoShuttersControl attribute value.</li>
<li>ASC_Down - astro/time. "Astro" uses sunrise logic to calculate sunset time,"time" uses ASC_Time_Down_Early attibute's value.</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Mode_Down - always/absent/off. Additional conditions for close commands based on roommate state. Please note: If there's no roommate and attribute set to "absent" no closing command will be issued.</li>
<li>ASC_Mode_Up - always/absent/off. Like ASC_Mode_Down for opening commands.</li>
<li>ASC_Offset_Minutes_Evening - </li>
<li>ASC_Offset_Minutes_Morning - </li>
<li>ASC_Open_Pos - in 10 steps from 0 to 100,defaults will be set dependent on AutoShuttersControl attribute value.</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Partymode - on/off. See correspondant Attribute for ASC Module.</li>
<li>ASC_Pos_Cmd - set command for setting the shutter to a decent level; must correspond to the reading name for the actual position of the shutter</li>
<li>ASC_Pos_after_ComfortOpen - in 10 steps from 0 to 100,defaults will be set dependent on AutoShuttersControl attribute value.</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Roommate_Reading - Reading name of the roommate device's status info.</li>
2018-10-01 09:15:21 +02:00
<li>ASC_Roommate_Device - Name of comma seperated roommate device/s to be used to controll all shutters in the same room as the roommate.</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Time_Down_Early - Early limit for closing timer calculation using sunset</li>
<li>ASC_Time_Down_Late - Latest limit for closing timer calculation using sunset</li>
<li>ASC_Time_Up_Early - Like ...Time_Down... for opening</li>
<li>ASC_Time_Up_Late - Like ...Time_Down... for opening</li>
<li>ASC_Time_Up_WE_Holiday - Sunrise fr&uuml;hste Zeit zum hochfahren am Wochenende und/oder Urlaub</li>
2018-10-09 18:05:55 +02:00
<li>ASC_Time_Up_HolidayDevice - Device zur Urlaubserkennung/muss 0 oder 1 im Reading state beinhalten.</li>
<li>ASC_Up - astro/time "Astro" will use sunrise calculation for opening times,"time" uses ASC_Time_Up_Early value.</li>
<li>ASC_Ventilate_Pos - in 10 steps from 0 to 100,defaults will be set dependent on AutoShuttersControl attribute value.</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Ventilate_Window_Open - Level to be set for ventilation in case of opening or tilted event (only if current shutter position is below this level</li>
<li>ASC_WindowRec - Name of the window contact corresponding to the shutter</li>
<li>ASC_WindowRec_subType - Type of the used window contact: twostate (only sends open and closed) or threestate (sends also tilted)</li>
<li>ASC_lock-out - soft/hard stellt entsprechend den Aussperrschutz ein. Bei global aktiven Aussperrschutz (set ASC-Device lockOut soft) und einem Fensterkontakt open bleibt dann der Rolladen oben. Dies gilt nur bei Steuerbefehle über das ASC Modul. Stellt man global auf hard,wird bei entsprechender M&ouml;glichkeit versucht den Rolladen Hardwareseitig zu blockieren. Dann ist auch ein fahren &uuml;ber die Taster nicht mehr m&ouml;glich.</li>
2018-09-28 08:57:25 +02:00
<li>ASC_lock-outCmd - inhibit/blocked set Befehl für das Rolladen-Device zum Hardware sperren. Zum gesetzt werden wenn man "ASC_lock-out" auf hard setzt</li>
</ul>
</ul>
2018-08-15 10:27:53 +02:00
</ul>
=end html
=begin html_DE
<a name="AutoShuttersControl"></a>
2018-09-05 20:48:15 +02:00
<h3>Automatische Rolladensteuerung - ASC</h3>
2018-08-15 10:27:53 +02:00
<ul>
<u><b>AutoShuttersControl oder kurz ASC,steuert automatisch Deine Rolladen nach bestimmten Vorgaben. Zum Beispiel Sonnenaufgang und Sonnenuntergang oder je nach Fenstervent</b></u>
2018-08-15 10:27:53 +02:00
<br>
Dieses Modul soll alle vom Modul &uuml;berwachten Roll&auml;den entsprechend der Konfiguration &uuml;ber die Attribute im Rolladen Device steuern. Es wird bei entsprechender Konfiguration zum Beispiel die Roll&auml;den hochfahren wenn ein Bewohner erwacht ist und draussen bereits die Sonne aufgegangen ist. Auch ist es m&ouml;glich das bei ankippen eines Fensters der geschlossene Rolladen in eine L&uuml;ftungsposition f&auml;hrt.
<br><br>
<a name="AutoShuttersControlDefine"></a>
<b>Define</b>
<ul><br>
<code>define &lt;name&gt; AutoShuttersControl</code>
<br><br>
Example:
<ul><br>
<code>define Rolladensteuerung AutoShuttersControl</code><br>
</ul>
<br>
Der Befehl erstellt ein AutoShuttersControl Device mit Namen Rolladen.<br>
Nachdem das Device angelegt wurde,m&uuml;ssen in allen Roll&auml;den Devices welche gesterut werden sollen das Attribut AutoShuttersControl mit Wert 1 oder 2 gesetzt werden.<br>
Dabei bedeutet 1 = "Inverse oder Rollo Bsp.: Rollo Oben 0,Rollo Unten 100 und der Befehl zum Prozentualen fahren ist position",2 = "Homematic Style Bsp.: Rollo Oben 100,Rollo Unten 0 und der Befehl zum Prozentualen fahren ist pct.<br>
Habt Ihr das Attribut gesetzt,k&ouml;nnt Ihr den automatischen Scan nach den Devices anstossen.
</ul>
<br><br>
<a name="AutoShuttersControlReadings"></a>
<b>Readings</b>
<ul>
Im Modul Device
<ul>
<li>..._nextAstroTimeEvent - Uhrzeit des n&auml;chsten Astro Events,Sonnenauf,Sonnenuntergang oder feste Zeit pro Rollonamen</li>
<li>..._lastPosValue - letzter abgesetzter Fahrbefehl pro Rollanamen</li>
<li>..._lastDelayPosValue - letzter abgesetzter Fahrbefehl welcher beim n&auml;chsten zul&auml;ssigen Event ausgef&uuml;hrt wird.</li>
<li>partyMode - on/off aktiviert den globalen Partymodus,alle Roll&auml;den welche das Attribut ASC_Partymode bei sich auf on gestellt haben werden nicht mehr gesteuert. Der letzte Schaltbefehle welcher durch ein Fensterevent oder Bewohnerstatus an die Roll&auml;den gesendet wurde,wird beim off setzen durch set ASC-Device partyMode off ausgef&uuml;hrt</li>
2018-09-28 08:57:25 +02:00
<li>lockOut - on/off f&uuml;r das aktivieren des Aussperrschutzes gem&auml;&szlig; dem entsprechenden Attribut ASC_lock-out im jeweiligen Rolladen. (siehe Beschreibung bei den Attributen f&uuml;r die Rolladendevices)</li>
<li>room_... - Auflistung aller Roll&auml;den welche in den jeweiligen R&auml;men gefunden wurde,Bsp.: room_Schlafzimmer,Terrasse</li>
<li>state - Status des Devices active,enabled,disabled</li>
2018-09-28 08:57:25 +02:00
<li>sunriseTimeWeHoliday - on/off wird das Rolladen Device Attribut Attributes ASC_Time_Up_WE_Holiday Beachtet oder nicht</li>
<li>userAttrList - Status der UserAttribute welche an die Roll&auml;den gesendet werden</li>
</ul><br>
In den Roll&auml;den Devices
<ul>
2018-09-28 08:57:25 +02:00
<li>ASC_Time_DriveUp - Sonnenaufgangszei f&uuml;r das Rollo</li>
<li>ASC_Time_DriveDown - Sonnenuntergangszeit f&uuml;r das Rollo</li>
<li>ASC_ShuttersLastDrive - Grund des letzten fahrens vom Rolladen</li>
</ul>
</ul>
<br><br>
<a name="AutoShuttersControlSet"></a>
<b>Set</b>
<ul>
<li>partyMode - on/off aktiviert den globalen Partymodus. Siehe Reading partyMode</li>
<li>lockOut - on/off aktiviert den globalen Aussperrschutz. Siehe Reading partyMode</li>
<li>renewSetSunriseSunsetTimer - erneuert bei allen Roll&auml;den die Zeiten f&uuml;r Sunset und Sunrise und setzt die internen Timer neu.</li>
<li>scanForShutters - sucht alle FHEM Devices mit dem Attribut "AutoShuttersControl" 1/2</li>
2018-09-28 08:57:25 +02:00
<li>sunriseTimeWeHoliday - on/off aktiviert/deaktiviert die Beachtung des Rolladen Device Attributes ASC_Time_Up_WE_Holiday</li>
<li>createNewNotifyDev - Legt die interne Struktur f&uuml;r NOTIFYDEV neu an - Attribut verbose muss gr&ouml;$szlig;er 3 sein.</li>
<li>selfDefense - on/off,aktiviert/deaktiviert den Selbstschutz,wenn das Residents Device absent meldet und selfDefense aktiv ist und ein Fenster im Haus steht noch offen,wird an diesem Fenster das Rollo runter gefahren</li>
</ul>
<br><br>
<a name="AutoShuttersControlGet"></a>
<b>Get</b>
<ul>
<li>showShuttersInformations - zeigt eine &Uuml;bersicht der Autofahrzeiten</li>
<li>showNotifyDevsInformations - zeigt eine &Uuml;bersicht der abgelegten NOTIFYDEV Struktur. Diehnt zur Kontrolle</li>
</ul>
<br><br>
<a name="AutoShuttersControlAttributes"></a>
<b>Attributes</b>
<ul>
Im Modul Device
<ul>
2018-09-28 08:57:25 +02:00
<li>ASC_antifreezeTemp - Temperatur ab welcher der Frostschutz greifen soll und das Rollo nicht mehr f&auml;hrt. Der letzte Fahrbefehl wird gespeichert.</li>
<li>ASC_autoAstroModeEvening - aktuell REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_autoAstroModeEveningHorizon - H&ouml;he &uuml;ber Horizont wenn beim Attribut ASC_autoAstroModeEvening HORIZON ausgew&auml;hlt</li>
<li>ASC_autoAstroModeMorning - aktuell REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_autoAstroModeMorningHorizon - H&ouml;he &uuml;ber Horizont wenn beim Attribut ASC_autoAstroModeMorning HORIZON ausgew&auml;hlt</li>
<li>ASC_autoShuttersControlComfort - on/off schaltet die Komfortfunktion an. Bedeutet das ein Rolladen mit einem threestate Sensor am Fenster beim &ouml;ffnen in eine weit offen Position f&auml;hrt. Die Offenposition wird beim Rolladen &uuml;ber das Attribut ASC_Pos_after_ComfortOpen eingestellt.</li>
<li>ASC_autoShuttersControlEvening - on/off,ob Abends die Roll&auml;den automatisch nach Zeit gesteuert werden sollen</li>
<li>ASC_autoShuttersControlMorning - on/off,ob Morgens die Roll&auml;den automatisch nach Zeit gesteuert werden sollen</li>
2018-09-28 08:57:25 +02:00
<li>ASC_temperatureReading - Reading f&uuml;r die Aussentemperatur</li>
<li>ASC_temperatureSensor - Device f&uuml;r die Aussentemperatur</li>
2018-10-09 18:05:55 +02:00
<li>ASC_timeUpHolidayDevice - Device zur Urlaubserkennung oder Sonstiges / muss 0 oder 1 im Reading state beinhalten.</li>
<li>ASC_residentsDevice - Devicenamen vom Residents Device der obersten Ebene</li>
<li>ASC_residentsDeviceReading - Status Reading vom Residents Device der obersten Ebene</li>
<li>ASC_brightnessMinVal - minimaler Lichtwert ab welchen Schaltbedingungen gepr&uuml;ft werden sollen</li>
<li>ASC_brightnessMaxVal - maximaler Lichtwert ab welchen Schaltbedingungen gepr&uuml;ft werden sollen</li>
<li>ASC_rainSensorDevice - Device welches bei Regen getriggert werden soll</li>
<li>ASC_rainSensorReading - das ensprechende Reading zum Regendevice</li>
<li>ASC_rainSensorShuttersClosedPos - Position n welche der Rolladen fahren soll wenn es Regnet</li>
<li>ASC_shuttersDriveOffset - maximale zuf&auml;llige Verz&ouml;gerung in Sekunden bei der Berechnung der Fahrzeiten, 0 bedeutet sofort</li>
</ul><br>
In den Roll&auml;den Devices
<ul>
<li>AutoShuttersControl - 0/1/2 1 = "Inverse oder Rollo Bsp.: Rollo Oben 0,Rollo Unten 100 und der Befehl zum Prozentualen fahren ist position",2 = "Homematic Style Bsp.: Rollo Oben 100,Rollo Unten 0 und der Befehl zum Prozentualen fahren ist pct</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Antifreeze - on/off Frostschutz an oder aus</li>
<li>ASC_AutoAstroModeEvening - aktuell REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_AutoAstroModeEveningHorizon - H&ouml;he &uuml;ber Horizont wenn beim Attribut ASC_autoAstroModeEvening HORIZON ausgew&auml;hlt</li>
<li>ASC_AutoAstroModeMorning - aktuell REAL,CIVIL,NAUTIC,ASTRONOMIC</li>
2018-09-28 08:57:25 +02:00
<li>ASC_AutoAstroModeMorningHorizon - H&ouml;he &uuml;ber Horizont wenn beim Attribut ASC_autoAstroModeMorning HORIZON ausgew&auml;hlt</li>
<li>ASC_Closed_Pos - in 10 Schritten von 0 bis 100,default Vorgabe ist abh&auml;ngig vom Attribut AutoShuttersControl</li>
<li>ASC_Down - astro/time/brightness bei Astro wird Sonnenuntergang berechnet,bei time wird der Wert aus ASC_Time_Down_Early als Fahrzeit verwendet und bei brightness muss ASC_Time_Down_Early und ASC_Time_Down_Late korrekt gesetzt werden. Der Timer l&auml;uft dann nach ASC_Time_Down_Late Zeit,es wird aber in der Zeit zwischen ASC_Time_Down_Early und ASC_Time_Down_Late geschaut ob die als Attribut im Moduldevice hinterlegte ASC_brightnessMinVal erreicht wurde,wenn ja wird der Rolladen runter gefahren</li>
2018-10-28 18:12:40 +01:00
<li>ASC_Mode_Down - always/home/absent/off wann darf die Automatik steuern. immer,niemals,bei abwesenheit des Roommate (ist kein Roommate und absent eingestellt wird gar nicht gesteuert)</li>
<li>ASC_Mode_Up - always/home/absent/off wann darf die Automatik steuern. immer,niemals,bei abwesenheit des Roommate (ist kein Roommate und absent eingestellt wird gar nicht gesteuert)</li>
<li>ASC_Drive_Offset - maximale zuf&auml;llige Verz&ouml;gerung in Sekunden bei der Berechnung der Fahrzeiten, 0 bedeutet sofort, -1 bedeutet das das gleichwertige Attribut aus dem ASC Device ausgewertet werden soll.</li>
<li>ASC_Open_Pos - in 10 Schritten von 0 bis 100,default Vorgabe ist abh&auml;ngig vom Attribut AutoShuttersControl</li>
<li>ASC_Partymode - on/off schaltet den Partymodus an oder aus,Wird dann am ASC Device set ASC-DEVICE partyMode on geschalten,werden alle Fahrbefehle an den Roll&auml;den welche das Attribut auf on haben zwischen gespeichert und sp&auml;ter erst ausgef&uuml;hrt</li>
<li>ASC_Pos_Cmd - der set Befehl um den Rolladen in Prozent Angaben zu fahren,muss der selbe sein wie das Reading welches die Position des Rolladen in Prozent an gibt</li>
<li>ASC_Pos_after_ComfortOpen - in 10 Schritten von 0 bis 100,default Vorgabe ist abh&auml;ngig vom Attribut AutoShuttersControl</li>
2018-09-28 08:57:25 +02:00
<li>ASC_Roommate_Reading - das Reading zum Roommate Device welches den Status wieder gibt</li>
2018-10-28 18:12:40 +01:00
<li>ASC_Roommate_Device - mit Komma getrennte Namen des/der Roommate Device/s welche den/die Bewohner des Raumes vom Rolladen wieder gibt. Es macht nur Sinn in Schlaf- oder Kinderzimmern</li>
<li>ASC_Time_Down_Early - Sunset fr&uuml;hste Zeit zum runter fahren</li>
<li>ASC_Time_Down_Late - Sunset sp&auml;teste Zeit zum runter fahren</li>
<li>ASC_Time_Up_Early - Sunrise fr&uuml;hste Zeit zum hoch fahren</li>
<li>ASC_Time_Up_Late - Sunrise sp&auml;teste Zeit zum hoch fahren</li>
<li>ASC_Time_Up_WE_Holiday - Sunrise fr&uuml;hste Zeit zum hochfahren am Wochenende und/oder Urlaub (we2holiday wird beachtet),Achtung sollte nicht gr&ouml;&szlig;er sein wie ASC_Time_Up_Late sonst wird ASC_Time_Up_Late verwendet</li>
<li>ASC_Up - astro/time/brightness bei Astro wird Sonnenaufgang berechnet,bei time wird der Wert aus ASC_Time_Up_Early als Fahrzeit verwendet und bei brightness muss ASC_Time_Up_Early und ASC_Time_Up_Late korrekt gesetzt werden. Der Timer l&auml;uft dann nach ASC_Time_Up_Late Zeit,es wird aber in der Zeit zwischen ASC_Time_Up_Early und ASC_Time_Up_Late geschaut ob die als Attribut im Moduldevice hinterlegte ASC_brightnessMinVal erreicht wurde,wenn ja wird der Rolladen runter gefahren</li>
<li>ASC_Ventilate_Pos - in 10 Schritten von 0 bis 100,default Vorgabe ist abh&auml;ngig vom Attribut AutoShuttersControl</li>
<li>ASC_Ventilate_Window_Open - auf l&uuml;ften,wenn das Fenster gekippt/ge&ouml;ffnet wird und aktuelle Position unterhalb der L&uuml;ften-Position ist</li>
2018-09-28 08:57:25 +02:00
<li>ASC_WindowRec - Name des Fensterkontaktes an welchen Fenster der Rolladen angebracht ist</li>
<li>ASC_WindowRec_subType - Typ des verwendeten Fensterkontakts: twostate (optisch oder magnetisch) oder threestate (Drehgriffkontakt)</li>
<li>ASC_lock-out - soft/hard stellt entsprechend den Aussperrschutz ein. Bei global aktiven Aussperrschutz (set ASC-Device lockOut soft) und einem Fensterkontakt open bleibt dann der Rolladen oben. Dies gilt nur bei Steuerbefehle über das ASC Modul. Stellt man global auf hard,wird bei entsprechender M&ouml;glichkeit versucht den Rolladen Hardwareseitig zu blockieren. Dann ist auch ein fahren &uuml;ber die Taster nicht mehr m&ouml;glich.</li>
<li>ASC_lock-outCmd - inhibit/blocked set Befehl f&uuml;r das Rolladen-Device zum Hardware sperren. Zum gesetzt werden wenn man "ASC_lock-out" auf hard setzt</li>
<li>ASC_Self_Defense_Exclude - on/off bei on Wert wird dieser Rolladen bei aktiven Self Defense und offenen Fenster nicht runter gefahren wenn Residents absent ist.</li>
<li>ASC_Shading_Brightness_Sensor - Sensor Device welches f&uuml;r die Lichtwerte verwendet wird. ACHTUNG! Findet auch Verwendung bei ASC_Down - brightness</li>
2018-10-16 14:55:01 +02:00
<li>ASC_BrightnessMinVal - minimaler Lichtwert ab welchen Schaltbedingungen gepr&uuml;ft werden sollen / wird der Wert von -1 nicht ge&auml;ndert, so wird automatisch der Wert aus dem Moduldevice genommen</li>
<li>ASC_BrightnessMaxVal - maximaler Lichtwert ab welchen Schaltbedingungen gepr&uuml;ft werden sollen / wird der Wert von -1 nicht ge&auml;ndert, so wird automatisch der Wert aus dem Moduldevice genommen</li>
<li>ASC_ShuttersPlace - window/terrace, wenn dieses Attribut auf terrace gesetzt ist und das Residence Device in den Status "done" geht und SelfDefence aktiv ist wird das Rollo geschlossen</li>
</ul>
</ul>
2018-08-15 10:27:53 +02:00
</ul>
=end html_DE
=cut