new module files, change rain and wind code

for multisensor
	geändert:       ShuttersControl.pm
	geändert:       ShuttersControl/Dev/Attr.pm
	neue Datei:     ShuttersControl/Helper.pm
	geändert:       ShuttersControl/Shading.pm
	geändert:       ShuttersControl/Shutters.pm
This commit is contained in:
Marko Oldenburg 2020-07-08 20:46:21 +02:00
parent 269288c24a
commit f8800e910b
6 changed files with 1060 additions and 943 deletions

@ -1,11 +1,11 @@
UPD 2020-07-07_14:49:19 97041 FHEM/73_AutoShuttersControl.pm
UPD 2020-07-08_11:34:15 177894 lib/FHEM/Automation/ShuttersControl.pm
UPD 2020-07-08_20:43:22 144312 lib/FHEM/Automation/ShuttersControl.pm
UPD 2020-06-22_09:41:40 2657 lib/FHEM/Automation/ShuttersControl/Dev.pm
UPD 2020-07-07_14:49:19 2496 lib/FHEM/Automation/ShuttersControl/Roommate.pm
UPD 2020-07-07_14:49:19 30710 lib/FHEM/Automation/ShuttersControl/Shutters.pm
UPD 2020-07-07_14:49:19 17908 lib/FHEM/Automation/ShuttersControl/Shading.pm
UPD 2020-07-08_14:55:44 30718 lib/FHEM/Automation/ShuttersControl/Shutters.pm
UPD 2020-07-08_19:33:26 21666 lib/FHEM/Automation/ShuttersControl/Shading.pm
UPD 2020-06-22_09:41:40 2175 lib/FHEM/Automation/ShuttersControl/Window.pm
UPD 2020-07-08_10:45:35 11567 lib/FHEM/Automation/ShuttersControl/Dev/Attr.pm
UPD 2020-07-08_20:16:15 11566 lib/FHEM/Automation/ShuttersControl/Dev/Attr.pm
UPD 2020-07-03_11:29:10 7251 lib/FHEM/Automation/ShuttersControl/Dev/Readings.pm
UPD 2020-07-03_11:29:10 52390 lib/FHEM/Automation/ShuttersControl/Shutters/Attr.pm
UPD 2020-06-22_09:41:40 2903 lib/FHEM/Automation/ShuttersControl/Shutters/Readings.pm

@ -75,11 +75,9 @@ use Date::Parse;
use FHEM::Automation::ShuttersControl::Shutters;
use FHEM::Automation::ShuttersControl::Dev;
use FHEM::Automation::ShuttersControl::Shading;
require Exporter;
our @ISA = qw(Exporter);
our @Export = qw($shutters $ascDev %userAttrList);
use FHEM::Automation::ShuttersControl::Shading qw (:ALL);
use FHEM::Automation::ShuttersControl::Helper qw (:ALL);
# try to use JSON::MaybeXS wrapper
# for chance of better performance + open code
@ -184,10 +182,6 @@ BEGIN {
delFromDevAttrList
delFromAttrList
gettimeofday
sunset
sunset_abs
sunrise
sunrise_abs
InternalTimer
RemoveInternalTimer
computeAlignTime
@ -534,8 +528,8 @@ sub EventProcessingGeneral {
if ( defined($devname) && ($devname) )
{ # es wird lediglich der Devicename der Funktion mitgegeben wenn es sich nicht um global handelt daher hier die Unterscheidung
my $windReading = $ascDev->getWindSensorReading;
my $rainReading = $ascDev->getRainSensorReading;
my $windReading = $ascDev->getWindSensorReading // 'none';
my $rainReading = $ascDev->getRainSensorReading // 'none';
while ( my ( $device, $deviceAttr ) =
each %{ $hash->{monitoredDevs}{$devname} } )
@ -691,7 +685,7 @@ sub Set {
elsif ( lc $cmd eq 'controlshading' ) {
return "usage: $cmd" if ( scalar( @{$aArg} ) > 1 );
my $response = _CheckASC_ConditionsForShadingFn($hash);
my $response = CheckASC_ConditionsForShadingFn($hash);
readingsSingleUpdate(
$hash, $cmd,
(
@ -1778,7 +1772,7 @@ sub EventProcessingRain {
my ( $hash, $device, $events ) = @_;
my $name = $device;
my $reading = $ascDev->getRainSensorReading;
my $reading = $ascDev->getRainSensorReading // 'none';
if ( $events =~ m{$reading:\s(\d+(\.\d+)?|rain|dry)}xms ) {
my $val;
@ -1842,7 +1836,7 @@ sub EventProcessingWind {
my $name = $hash->{NAME};
$shutters->setShuttersDev($shuttersDev);
my $reading = $ascDev->getWindSensorReading;
my $reading = $ascDev->getWindSensorReading // 'none';
if ( $events =~ m{$reading:\s(\d+(\.\d+)?)}xms ) {
for my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
$shutters->setShuttersDev($shuttersDev);
@ -3442,839 +3436,10 @@ sub GetMonitoredDevs {
## my little helper
#################################
sub PositionValueWindowRec {
my $shuttersDev = shift;
my $posValue = shift;
if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 1
&& $shutters->getVentilateOpen eq 'on' )
{
$posValue = $shutters->getVentilatePos;
}
elsif (CheckIfShuttersWindowRecOpen($shuttersDev) == 2
&& $shutters->getSubTyp eq 'threestate'
&& $ascDev->getAutoShuttersControlComfort eq 'on' )
{
$posValue = $shutters->getComfortOpenPos;
}
elsif (
CheckIfShuttersWindowRecOpen($shuttersDev) == 2
&& ( $shutters->getSubTyp eq 'threestate'
|| $shutters->getSubTyp eq 'twostate' )
&& $shutters->getVentilateOpen eq 'on'
)
{
$posValue = $shutters->getVentilatePos;
}
if ( $shutters->getQueryShuttersPos($posValue) ) {
$posValue = $shutters->getStatus;
}
return $posValue;
}
sub AutoSearchTwilightDev {
my $hash = shift;
my $name = $hash->{NAME};
if ( devspec2array('TYPE=(Astro|Twilight)') > 0 ) {
CommandAttr( undef,
$name
. ' ASC_twilightDevice '
. ( devspec2array('TYPE=(Astro|Twilight)') )[0] )
if ( AttrVal( $name, 'ASC_twilightDevice', 'none' ) eq 'none' );
}
return;
}
sub GetAttrValues {
my ( $dev, $attribut, $default ) = @_;
my @values = split( ' ',
AttrVal( $dev, $attribut, ( defined($default) ? $default : 'none' ) ) );
my ( $value1, $value2 ) = split( ':', $values[0] );
my ( $value3, $value4, $value5, $value6, $value7, $value8 );
( $value3, $value4 ) = split( ':', $values[1] )
if ( defined( $values[1] ) );
( $value5, $value6 ) = split( ':', $values[2] )
if ( defined( $values[2] ) );
( $value7, $value8 ) = split( ':', $values[3] )
if ( defined( $values[3] ) );
return (
$value1,
defined($value2) ? $value2 : 'none',
defined($value3) ? $value3 : 'none',
defined($value4) ? $value4 : 'none',
defined($value5) ? $value5 : 'none',
defined($value6) ? $value6 : 'none',
defined($value7) ? $value7 : 'none',
defined($value8) ? $value8 : 'none'
);
}
# Hilfsfunktion welche meinen ReadingString zum finden der getriggerten Devices und der Zurdnung was das Device überhaupt ist und zu welchen Rolladen es gehört aus liest und das Device extraiert
sub ExtractNotifyDevFromEvent {
my ( $hash, $shuttersDev, $shuttersAttr ) = @_;
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} )
&& $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 );
$notifyDevs{$notifyDev} = $shuttersDev;
}
}
return \%notifyDevs;
}
## Ist Tag oder Nacht für den entsprechende Rolladen
sub _IsDay {
my $shuttersDev = shift;
$shutters->setShuttersDev($shuttersDev);
my $brightnessMinVal = (
$shutters->getBrightnessMinVal > -1
? $shutters->getBrightnessMinVal
: $ascDev->getBrightnessMinVal
);
my $brightnessMaxVal = (
$shutters->getBrightnessMaxVal > -1
? $shutters->getBrightnessMaxVal
: $ascDev->getBrightnessMaxVal
);
my $isday = ( ShuttersSunrise( $shuttersDev, 'unix' ) >
ShuttersSunset( $shuttersDev, 'unix' ) ? 1 : 0 );
my $respIsDay = $isday;
ASC_Debug( 'FnIsDay: ' . $shuttersDev . ' Allgemein: ' . $respIsDay );
if (
(
(
(
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00', $shutters->getTimeUpEarly )
/ 86400
)
&& !IsWe()
)
|| (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday ) / 86400
)
&& IsWe()
&& $ascDev->getSunriseTimeWeHoliday eq 'on'
&& $shutters->getTimeUpWeHoliday ne '01:25'
)
)
&& int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00', $shutters->getTimeUpLate ) / 86400
)
)
|| (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00', $shutters->getTimeDownEarly ) /
86400
)
&& int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00', $shutters->getTimeDownLate ) / 86400
)
)
)
{
##### Nach Sonnenuntergang / Abends
$respIsDay = (
(
(
$shutters->getBrightness > $brightnessMinVal
&& $isday
&& !$shutters->getSunset
)
|| !$shutters->getSunset
) ? 1 : 0
) if ( $shutters->getDown eq 'brightness' );
ASC_Debug( 'FnIsDay: '
. $shuttersDev
. ' getDownBrightness: '
. $respIsDay
. ' Brightness: '
. $shutters->getBrightness
. ' BrightnessMin: '
. $brightnessMinVal
. ' Sunset: '
. $shutters->getSunset );
##### Nach Sonnenauf / Morgens
$respIsDay = (
(
(
$shutters->getBrightness > $brightnessMaxVal
&& !$isday
&& $shutters->getSunrise
)
|| $respIsDay
|| $shutters->getSunrise
) ? 1 : 0
) if ( $shutters->getUp eq 'brightness' );
ASC_Debug( 'FnIsDay: '
. $shuttersDev
. ' getUpBrightness: '
. $respIsDay
. ' Brightness: '
. $shutters->getBrightness
. ' BrightnessMax: '
. $brightnessMaxVal
. ' Sunrise: '
. $shutters->getSunrise );
}
return $respIsDay;
}
sub ShuttersSunrise {
my $shuttersDev = shift;
my $tm = shift; # Tm steht für Timemode und bedeutet Realzeit oder Unixzeit
my $autoAstroMode;
$shutters->setShuttersDev($shuttersDev);
if ( $shutters->getAutoAstroModeMorning ne 'none' ) {
$autoAstroMode = $shutters->getAutoAstroModeMorning;
$autoAstroMode =
$autoAstroMode . '=' . $shutters->getAutoAstroModeMorningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
else {
$autoAstroMode = $ascDev->getAutoAstroModeMorning;
$autoAstroMode =
$autoAstroMode . '=' . $ascDev->getAutoAstroModeMorningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
my $oldFuncHash = $shutters->getInTimerFuncHash;
my $shuttersSunriseUnixtime =
computeAlignTime( '24:00', sunrise( 'REAL', 0, '4:30', '8:30' ) );
if ( $tm eq 'unix' ) {
if ( $shutters->getUp eq 'astro' ) {
if ( ( IsWe() || IsWe('tomorrow') )
&& $ascDev->getSunriseTimeWeHoliday eq 'on'
&& $shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
if (
IsWe()
&& int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$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
);
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$shutters->getTimeUpEarly,
$shutters->getTimeUpLate
)
) + 1
);
}
}
else {
if (
IsWe()
&& (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 1
) / 86400
)
|| int( gettimeofday() / 86400 ) != int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$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->getTimeUpEarly,
$shutters->getTimeUpLate
)
) + 1
);
}
else {
if (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 86401
);
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$shutters->getTimeUpWeHoliday
)
) + 1
);
}
}
}
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$shutters->getTimeUpEarly,
$shutters->getTimeUpLate
)
) + 1
);
}
if ( defined($oldFuncHash)
&& ref($oldFuncHash) eq 'HASH'
&& ( IsWe() || IsWe('tomorrow') )
&& $ascDev->getSunriseTimeWeHoliday eq 'on'
&& $shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
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 )
&& $oldFuncHash->{sunrisetime} < gettimeofday() );
}
}
}
elsif ( defined($oldFuncHash) && ref($oldFuncHash) eq 'HASH' ) {
$shuttersSunriseUnixtime = ( $shuttersSunriseUnixtime + 86400 )
if ( $shuttersSunriseUnixtime <
( $oldFuncHash->{sunrisetime} + 180 )
&& $oldFuncHash->{sunrisetime} < gettimeofday() );
}
}
elsif ( $shutters->getUp eq 'time' ) {
if ( ( IsWe() || IsWe('tomorrow') )
&& $ascDev->getSunriseTimeWeHoliday eq 'on'
&& $shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
if (
int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$shutters->getTimeUpEarly ) / 86400
)
&& $shutters->getSunrise
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $shutters->getTimeUpEarly )
+ 86400;
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpEarly );
}
}
else {
if (
IsWe()
&& int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$shutters->getTimeUpEarly ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpEarly );
}
elsif (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday ) + 86400;
}
}
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $shutters->getTimeUpEarly );
}
}
elsif ( $shutters->getUp eq 'brightness' ) {
if ( ( IsWe() || IsWe('tomorrow') )
&& $ascDev->getSunriseTimeWeHoliday eq 'on'
&& $shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
if (
IsWe()
&& int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $shutters->getTimeUpWeHoliday
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $shutters->getTimeUpLate
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $shutters->getTimeUpLate );
}
}
else {
if (
IsWe()
&& (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $shutters->getTimeUpWeHoliday
)
) / 86400
)
|| int( gettimeofday() / 86400 ) != int(
(
computeAlignTime(
'24:00', $shutters->getTimeUpWeHoliday
)
) / 86400
)
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $shutters->getTimeUpLate
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $shutters->getTimeUpLate );
}
else {
if (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $shutters->getTimeUpWeHoliday
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$shutters->getTimeUpWeHoliday );
}
}
}
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $shutters->getTimeUpLate );
}
}
return $shuttersSunriseUnixtime;
}
elsif ( $tm eq 'real' ) {
return sunrise_abs( $autoAstroMode, 0, $shutters->getTimeUpEarly,
$shutters->getTimeUpLate )
if ( $shutters->getUp eq 'astro' );
return $shutters->getTimeUpEarly if ( $shutters->getUp eq 'time' );
}
return;
}
sub IsAfterShuttersTimeBlocking {
my $shuttersDev = shift;
$shutters->setShuttersDev($shuttersDev);
if (
( int( gettimeofday() ) - $shutters->getLastManPosTimestamp ) <
$shutters->getBlockingTimeAfterManual
|| ( !$shutters->getIsDay
&& defined( $shutters->getSunriseUnixTime )
&& $shutters->getSunriseUnixTime - ( int( gettimeofday() ) ) <
$shutters->getBlockingTimeBeforDayOpen )
|| ( $shutters->getIsDay
&& defined( $shutters->getSunriseUnixTime )
&& $shutters->getSunsetUnixTime - ( int( gettimeofday() ) ) <
$shutters->getBlockingTimeBeforNightClose )
)
{
return 0;
}
else { return 1 }
}
sub IsAfterShuttersManualBlocking {
my $shuttersDev = shift;
$shutters->setShuttersDev($shuttersDev);
if ( $ascDev->getBlockAscDrivesAfterManual
&& $shutters->getStatus != $shutters->getOpenPos
&& $shutters->getStatus != $shutters->getClosedPos
&& $shutters->getStatus != $shutters->getWindPos
&& $shutters->getStatus != $shutters->getShadingPos
&& $shutters->getStatus != $shutters->getComfortOpenPos
&& $shutters->getStatus != $shutters->getVentilatePos
&& $shutters->getStatus != $shutters->getAntiFreezePos
&& $shutters->getLastDrive eq 'manual' )
{
return 0;
}
elsif ( ( int( gettimeofday() ) - $shutters->getLastManPosTimestamp ) <
$shutters->getBlockingTimeAfterManual )
{
return 0;
}
else { return 1 }
}
sub ShuttersSunset {
my $shuttersDev = shift;
my $tm = shift; # Tm steht für Timemode und bedeutet Realzeit oder Unixzeit
my $autoAstroMode;
$shutters->setShuttersDev($shuttersDev);
if ( $shutters->getAutoAstroModeEvening ne 'none' ) {
$autoAstroMode = $shutters->getAutoAstroModeEvening;
$autoAstroMode =
$autoAstroMode . '=' . $shutters->getAutoAstroModeEveningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
else {
$autoAstroMode = $ascDev->getAutoAstroModeEvening;
$autoAstroMode =
$autoAstroMode . '=' . $ascDev->getAutoAstroModeEveningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
my $oldFuncHash = $shutters->getInTimerFuncHash;
my $shuttersSunsetUnixtime =
computeAlignTime( '24:00', sunset( 'REAL', 0, '15:30', '21:30' ) );
if ( $tm eq 'unix' ) {
if ( $shutters->getDown eq 'astro' ) {
$shuttersSunsetUnixtime = (
computeAlignTime(
'24:00',
sunset_abs(
$autoAstroMode,
0,
$shutters->getTimeDownEarly,
$shutters->getTimeDownLate
)
) + 1
);
if ( defined($oldFuncHash) && ref($oldFuncHash) eq 'HASH' ) {
$shuttersSunsetUnixtime += 86400
if ( $shuttersSunsetUnixtime <
( $oldFuncHash->{sunsettime} + 180 )
&& $oldFuncHash->{sunsettime} < gettimeofday() );
}
}
elsif ( $shutters->getDown eq 'time' ) {
$shuttersSunsetUnixtime =
computeAlignTime( '24:00', $shutters->getTimeDownEarly );
}
elsif ( $shutters->getDown 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->getDown eq 'astro' );
return $shutters->getTimeDownEarly
if ( $shutters->getDown eq 'time' );
}
return;
}
## Kontrolliert ob das Fenster von einem bestimmten Rolladen offen ist
sub CheckIfShuttersWindowRecOpen {
my $shuttersDev = shift;
$shutters->setShuttersDev($shuttersDev);
if ( $shutters->getWinStatus =~
m{[Oo]pen|false}xms ) # CK: covers: open|opened
{
return 2;
}
elsif ($shutters->getWinStatus =~ m{tilt}xms
&& $shutters->getSubTyp eq 'threestate' ) # CK: covers: tilt|tilted
{
return 1;
}
elsif ( $shutters->getWinStatus =~ m{[Cc]lose|true}xms ) {
return 0;
} # CK: covers: close|closed
}
sub makeReadingName {
my ($rname) = shift;
my %charHash = (
chr(0xe4) => "ae", # ä
chr(0xc4) => "Ae", # Ä
chr(0xfc) => "ue", # ü
chr(0xdc) => "Ue", # Ü
chr(0xf6) => "oe", # ö
chr(0xd6) => "Oe", # Ö
chr(0xdf) => "ss" # ß
);
my $charHashkeys = join( "", keys(%charHash) );
return $rname if ( $rname =~ m{^\./}xms );
$rname =~ s/([$charHashkeys])/$charHash{$1}/xgi;
$rname =~ s/[^a-z0-9._\-\/]/_/xgi;
return $rname;
}
sub TimeMin2Sec {
my $min = shift;
my $sec;
$sec = $min * 60;
return $sec;
}
sub IsWe {
return main::IsWe( shift, shift );
}
sub _DetermineSlatCmd {
my $value = shift;
@ -4647,100 +3812,6 @@ sub DevStateIcon {
return;
}
sub _CheckASC_ConditionsForShadingFn {
my $hash = shift;
my $error;
$error .=
' no valid data from the ASC temperature sensor, is ASC_tempSensor attribut set?'
if ( $ascDev->getOutTemp == -100 );
$error .= ' no twilight device found'
if ( $ascDev->_getTwilightDevice eq 'none' );
my $count = 1;
for my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
InternalTimer(
gettimeofday() + $count,
'FHEM::Automation::ShuttersControl::_CheckShuttersConditionsForShadingFn',
$shuttersDev
);
$count++;
}
return (
defined($error)
? $error
: 'none'
);
}
sub _CheckShuttersConditionsForShadingFn {
my $shuttersDev = shift;
$shutters->setShuttersDev($shuttersDev);
my $shuttersDevHash = $defs{$shuttersDev};
my $message = '';
my $errorMessage;
my $warnMessage;
my $infoMessage;
$infoMessage .= (
$shutters->getShadingMode ne 'off'
&& $ascDev->getAutoShuttersControlShading eq 'on'
&& $shutters->getOutTemp == -100
? ' shading active, global temp sensor is set, but shutters temperature sensor is not set'
: ''
);
$warnMessage .= (
$shutters->getShadingMode eq 'off'
&& $ascDev->getAutoShuttersControlShading eq 'on'
? ' global shading active but ASC_Shading_Mode attribut is not set or off'
: ''
);
$errorMessage .= (
$shutters->getShadingMode ne 'off'
&& $ascDev->getAutoShuttersControlShading ne 'on'
&& $ascDev->getAutoShuttersControlShading ne 'off'
? ' ASC_Shading_Mode attribut is set but global shading has errors, look at ASC device '
. '<a href="'
. '/fhem?detail='
. ReadingsVal( $shuttersDev, 'associatedWith', 'ASC device' )
. $::FW_CSRF . '">'
. ReadingsVal( $shuttersDev, 'associatedWith', 'ASC device' )
. '</a>'
: ''
);
$errorMessage .= (
$shutters->getBrightness == -1 && $shutters->getShadingMode ne 'off'
? ' no brightness sensor found, please set ASC_BrightnessSensor attribut'
: ''
);
$message .= ' ERROR: ' . $errorMessage
if ( defined($errorMessage)
&& $errorMessage ne '' );
$message .= ' WARN: ' . $warnMessage
if ( defined($warnMessage)
&& $warnMessage ne ''
&& $errorMessage eq '' );
$message .= ' INFO: ' . $infoMessage
if ( defined($infoMessage)
&& $infoMessage ne ''
&& $errorMessage eq '' );
readingsBeginUpdate($shuttersDevHash);
readingsBulkUpdateIfChanged( $shuttersDevHash, 'ASC_ShadingMessage',
'<html>' . $message . ' </html>' );
readingsEndUpdate( $shuttersDevHash, 1 );
}
sub RemoveShuttersTimer {
my $hash = shift;

@ -264,7 +264,7 @@ sub _getRainSensor {
return $device if ( $device eq 'none' );
$self->{ASC_rainSensor}->{device} = $device;
$self->{ASC_rainSensor}->{reading} =
( $reading ne 'none' ? $reading : 'state' );
( $reading ne 'none' ? $reading : 'rain' );
$self->{ASC_rainSensor}->{triggermax} = (
( $max ne 'none'
&& $max =~ m{\A(-?\d+(\.\d+)?)\z}xms )

@ -0,0 +1,935 @@
###############################################################################
#
# Developed with Kate
#
# (c) 2018-2020 Copyright: Marko Oldenburg (fhemsupport@cooltux.net)
# All rights reserved
#
# Special thanks goes to:
# - Bernd (Cluni) this module is based on the logic of his script "Rollladensteuerung für HM/ROLLO inkl. Abschattung und Komfortfunktionen in Perl" (https://forum.fhem.de/index.php/topic,73964.0.html)
# - Beta-User for many tests, many suggestions and good discussions
# - pc1246 write english commandref
# - FunkOdyssey commandref style
# - sledge fix many typo in commandref
# - many User that use with modul and report bugs
# - Christoph (christoph.kaiser.in) Patch that expand RegEx for Window Events
# - Julian (Loredo) expand Residents Events for new Residents functions
# - Christoph (Christoph Morrison) for fix Commandref, many suggestions and good discussions
#
#
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License,or
# any later version.
#
# The GNU General Public License can be found at
# http://www.gnu.org/copyleft/gpl.html.
# A copy is found in the textfile GPL.txt and important notices to the license
# from the author is found in LICENSE.txt distributed with these scripts.
#
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# $Id$
#
###############################################################################
## unserer packagename
package FHEM::Automation::ShuttersControl::Helper;
use strict;
use warnings;
use POSIX qw(strftime);
use utf8;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
PositionValueWindowRec
AutoSearchTwilightDev
GetAttrValues
CheckIfShuttersWindowRecOpen
ExtractNotifyDevFromEvent
ShuttersSunrise
ShuttersSunset
makeReadingName
IsWe
IsAfterShuttersTimeBlocking
IsAfterShuttersManualBlocking
);
our %EXPORT_TAGS = (
ALL => [
qw(
PositionValueWindowRec
AutoSearchTwilightDev
GetAttrValues
CheckIfShuttersWindowRecOpen
ExtractNotifyDevFromEvent
ShuttersSunrise
ShuttersSunset
makeReadingName
IsWe
IsAfterShuttersTimeBlocking
IsAfterShuttersManualBlocking
)
],
);
use GPUtils qw(GP_Import);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
devspec2array
CommandAttr
AttrVal
Log3
computeAlignTime
gettimeofday
sunset
sunset_abs
sunrise
sunrise_abs
)
);
}
sub PositionValueWindowRec {
my $shuttersDev = shift;
my $posValue = shift;
if ( CheckIfShuttersWindowRecOpen($shuttersDev) == 1
&& $FHEM::Automation::ShuttersControl::shutters->getVentilateOpen eq 'on' )
{
$posValue = $FHEM::Automation::ShuttersControl::shutters->getVentilatePos;
}
elsif (CheckIfShuttersWindowRecOpen($shuttersDev) == 2
&& $FHEM::Automation::ShuttersControl::shutters->getSubTyp eq 'threestate'
&& $FHEM::Automation::ShuttersControl::ascDev->getAutoShuttersControlComfort eq 'on' )
{
$posValue = $FHEM::Automation::ShuttersControl::shutters->getComfortOpenPos;
}
elsif (
CheckIfShuttersWindowRecOpen($shuttersDev) == 2
&& ( $FHEM::Automation::ShuttersControl::shutters->getSubTyp eq 'threestate'
|| $FHEM::Automation::ShuttersControl::shutters->getSubTyp eq 'twostate' )
&& $FHEM::Automation::ShuttersControl::shutters->getVentilateOpen eq 'on'
)
{
$posValue = $FHEM::Automation::ShuttersControl::shutters->getVentilatePos;
}
if ( $FHEM::Automation::ShuttersControl::shutters->getQueryShuttersPos($posValue) ) {
$posValue = $FHEM::Automation::ShuttersControl::shutters->getStatus;
}
return $posValue;
}
sub AutoSearchTwilightDev {
my $hash = shift;
my $name = $hash->{NAME};
if ( devspec2array('TYPE=(Astro|Twilight)') > 0 ) {
CommandAttr( undef,
$name
. ' ASC_twilightDevice '
. ( devspec2array('TYPE=(Astro|Twilight)') )[0] )
if ( AttrVal( $name, 'ASC_twilightDevice', 'none' ) eq 'none' );
}
return;
}
sub GetAttrValues {
my $dev = shift;
my $attribut = shift;
my $default = shift;
my @values = split( ' ',
AttrVal( $dev, $attribut, ( defined($default) ? $default : 'none' ) ) );
my ( $value1, $value2 ) = split( ':', $values[0] );
my ( $value3, $value4, $value5, $value6, $value7, $value8 );
( $value3, $value4 ) = split( ':', $values[1] )
if ( defined( $values[1] ) );
( $value5, $value6 ) = split( ':', $values[2] )
if ( defined( $values[2] ) );
( $value7, $value8 ) = split( ':', $values[3] )
if ( defined( $values[3] ) );
return (
$value1,
defined($value2) ? $value2 : 'none',
defined($value3) ? $value3 : 'none',
defined($value4) ? $value4 : 'none',
defined($value5) ? $value5 : 'none',
defined($value6) ? $value6 : 'none',
defined($value7) ? $value7 : 'none',
defined($value8) ? $value8 : 'none'
);
}
## Kontrolliert ob das Fenster von einem bestimmten Rolladen offen ist
sub CheckIfShuttersWindowRecOpen {
my $shuttersDev = shift;
$FHEM::Automation::ShuttersControl::shutters->setShuttersDev($shuttersDev);
if ( $FHEM::Automation::ShuttersControl::shutters->getWinStatus =~
m{[Oo]pen|false}xms ) # CK: covers: open|opened
{
return 2;
}
elsif ($FHEM::Automation::ShuttersControl::shutters->getWinStatus =~ m{tilt}xms
&& $FHEM::Automation::ShuttersControl::shutters->getSubTyp eq 'threestate' ) # CK: covers: tilt|tilted
{
return 1;
}
elsif ( $FHEM::Automation::ShuttersControl::shutters->getWinStatus =~ m{[Cc]lose|true}xms ) {
return 0;
} # CK: covers: close|closed
}
sub ExtractNotifyDevFromEvent {
my $hash = shift;
my $shuttersDev = shift;
my $shuttersAttr = shift;
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} )
&& $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 );
$notifyDevs{$notifyDev} = $shuttersDev;
}
}
return \%notifyDevs;
}
## Ist Tag oder Nacht für den entsprechende Rolladen
sub _IsDay {
my $shuttersDev = shift;
$FHEM::Automation::ShuttersControl::shutters->setShuttersDev($shuttersDev);
my $brightnessMinVal = (
$FHEM::Automation::ShuttersControl::shutters->getBrightnessMinVal > -1
? $FHEM::Automation::ShuttersControl::shutters->getBrightnessMinVal
: $FHEM::Automation::ShuttersControl::ascDev->getBrightnessMinVal
);
my $brightnessMaxVal = (
$FHEM::Automation::ShuttersControl::shutters->getBrightnessMaxVal > -1
? $FHEM::Automation::ShuttersControl::shutters->getBrightnessMaxVal
: $FHEM::Automation::ShuttersControl::ascDev->getBrightnessMaxVal
);
my $isday = ( ShuttersSunrise( $shuttersDev, 'unix' ) >
ShuttersSunset( $shuttersDev, 'unix' ) ? 1 : 0 );
my $respIsDay = $isday;
FHEM::Automation::ShuttersControl::ASC_Debug( 'FnIsDay: ' . $shuttersDev . ' Allgemein: ' . $respIsDay );
if (
(
(
(
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly ) /
86400
)
&& !IsWe()
)
|| (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ) /
86400
)
&& IsWe()
&& $FHEM::Automation::ShuttersControl::ascDev->getSunriseTimeWeHoliday eq 'on'
&& $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ne '01:25'
)
)
&& int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpLate ) /
86400
)
)
|| (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeDownEarly ) /
86400
)
&& int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeDownLate ) /
86400
)
)
)
{
##### Nach Sonnenuntergang / Abends
$respIsDay = (
(
(
$FHEM::Automation::ShuttersControl::shutters->getBrightness > $brightnessMinVal
&& $isday
&& !$FHEM::Automation::ShuttersControl::shutters->getSunset
)
|| !$FHEM::Automation::ShuttersControl::shutters->getSunset
) ? 1 : 0
) if ( $FHEM::Automation::ShuttersControl::shutters->getDown eq 'brightness' );
FHEM::Automation::ShuttersControl::ASC_Debug( 'FnIsDay: '
. $shuttersDev
. ' getDownBrightness: '
. $respIsDay
. ' Brightness: '
. $FHEM::Automation::ShuttersControl::shutters->getBrightness
. ' BrightnessMin: '
. $brightnessMinVal
. ' Sunset: '
. $FHEM::Automation::ShuttersControl::shutters->getSunset );
##### Nach Sonnenauf / Morgens
$respIsDay = (
(
(
$FHEM::Automation::ShuttersControl::shutters->getBrightness > $brightnessMaxVal
&& !$isday
&& $FHEM::Automation::ShuttersControl::shutters->getSunrise
)
|| $respIsDay
|| $FHEM::Automation::ShuttersControl::shutters->getSunrise
) ? 1 : 0
) if ( $FHEM::Automation::ShuttersControl::shutters->getUp eq 'brightness' );
FHEM::Automation::ShuttersControl::ASC_Debug( 'FnIsDay: '
. $shuttersDev
. ' getUpBrightness: '
. $respIsDay
. ' Brightness: '
. $FHEM::Automation::ShuttersControl::shutters->getBrightness
. ' BrightnessMax: '
. $brightnessMaxVal
. ' Sunrise: '
. $FHEM::Automation::ShuttersControl::shutters->getSunrise );
}
return $respIsDay;
}
sub ShuttersSunrise {
my $shuttersDev = shift;
my $tm = shift; # Tm steht für Timemode und bedeutet Realzeit oder Unixzeit
my $autoAstroMode;
$FHEM::Automation::ShuttersControl::shutters->setShuttersDev($shuttersDev);
if ( $FHEM::Automation::ShuttersControl::shutters->getAutoAstroModeMorning ne 'none' ) {
$autoAstroMode = $FHEM::Automation::ShuttersControl::shutters->getAutoAstroModeMorning;
$autoAstroMode =
$autoAstroMode . '=' . $FHEM::Automation::ShuttersControl::shutters->getAutoAstroModeMorningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
else {
$autoAstroMode = $FHEM::Automation::ShuttersControl::ascDev->getAutoAstroModeMorning;
$autoAstroMode =
$autoAstroMode . '=' . $FHEM::Automation::ShuttersControl::ascDev->getAutoAstroModeMorningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
my $oldFuncHash = $FHEM::Automation::ShuttersControl::shutters->getInTimerFuncHash;
my $shuttersSunriseUnixtime =
computeAlignTime( '24:00', sunrise( 'REAL', 0, '4:30', '8:30' ) );
if ( $tm eq 'unix' ) {
if ( $FHEM::Automation::ShuttersControl::shutters->getUp eq 'astro' ) {
if ( ( IsWe() || IsWe('tomorrow') )
&& $FHEM::Automation::ShuttersControl::ascDev->getSunriseTimeWeHoliday eq 'on'
&& $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
if (
IsWe()
&& int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
);
}
elsif (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
);
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) + 1
);
}
}
else {
if (
IsWe()
&& (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
) / 86400
)
|| int( gettimeofday() / 86400 ) != int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
) / 86400
)
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
);
}
elsif (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) + 1
);
}
else {
if (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 86401
);
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) + 1
);
}
}
}
}
else {
$shuttersSunriseUnixtime = (
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) + 1
);
}
if ( defined($oldFuncHash)
&& ref($oldFuncHash) eq 'HASH'
&& ( IsWe() || IsWe('tomorrow') )
&& $FHEM::Automation::ShuttersControl::ascDev->getSunriseTimeWeHoliday eq 'on'
&& $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
if (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00',
sunrise_abs(
$autoAstroMode,
0,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) + 1
) / 86400
)
)
{
$shuttersSunriseUnixtime =
( $shuttersSunriseUnixtime + 86400 )
if ( $shuttersSunriseUnixtime <
( $oldFuncHash->{sunrisetime} + 180 )
&& $oldFuncHash->{sunrisetime} < gettimeofday() );
}
}
}
elsif ( defined($oldFuncHash) && ref($oldFuncHash) eq 'HASH' ) {
$shuttersSunriseUnixtime = ( $shuttersSunriseUnixtime + 86400 )
if ( $shuttersSunriseUnixtime <
( $oldFuncHash->{sunrisetime} + 180 )
&& $oldFuncHash->{sunrisetime} < gettimeofday() );
}
}
elsif ( $FHEM::Automation::ShuttersControl::shutters->getUp eq 'time' ) {
if ( ( IsWe() || IsWe('tomorrow') )
&& $FHEM::Automation::ShuttersControl::ascDev->getSunriseTimeWeHoliday eq 'on'
&& $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
if (
int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly ) / 86400
)
&& $FHEM::Automation::ShuttersControl::shutters->getSunrise
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly )
+ 86400;
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly );
}
}
else {
if (
IsWe()
&& int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly );
}
elsif (
int( gettimeofday() / 86400 ) != int(
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ) + 86400;
}
}
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly );
}
}
elsif ( $FHEM::Automation::ShuttersControl::shutters->getUp eq 'brightness' ) {
if ( ( IsWe() || IsWe('tomorrow') )
&& $FHEM::Automation::ShuttersControl::ascDev->getSunriseTimeWeHoliday eq 'on'
&& $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday ne '01:25' )
{
if ( !IsWe('tomorrow') ) {
if (
IsWe()
&& int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpLate );
}
}
else {
if (
IsWe()
&& (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) / 86400
)
|| int( gettimeofday() / 86400 ) != int(
(
computeAlignTime(
'24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) / 86400
)
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
elsif (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpLate
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpLate );
}
else {
if (
int( gettimeofday() / 86400 ) == int(
(
computeAlignTime(
'24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday
)
) / 86400
)
)
{
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00',
$FHEM::Automation::ShuttersControl::shutters->getTimeUpWeHoliday );
}
}
}
}
else {
$shuttersSunriseUnixtime =
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeUpLate );
}
}
return $shuttersSunriseUnixtime;
}
elsif ( $tm eq 'real' ) {
return sunrise_abs( $autoAstroMode, 0, $FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeUpLate )
if ( $FHEM::Automation::ShuttersControl::shutters->getUp eq 'astro' );
return $FHEM::Automation::ShuttersControl::shutters->getTimeUpEarly if ( $FHEM::Automation::ShuttersControl::shutters->getUp eq 'time' );
}
return;
}
sub ShuttersSunset {
my $shuttersDev = shift;
my $tm = shift; # Tm steht für Timemode und bedeutet Realzeit oder Unixzeit
my $autoAstroMode;
$FHEM::Automation::ShuttersControl::shutters->setShuttersDev($shuttersDev);
if ( $FHEM::Automation::ShuttersControl::shutters->getAutoAstroModeEvening ne 'none' ) {
$autoAstroMode = $FHEM::Automation::ShuttersControl::shutters->getAutoAstroModeEvening;
$autoAstroMode =
$autoAstroMode . '=' . $FHEM::Automation::ShuttersControl::shutters->getAutoAstroModeEveningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
else {
$autoAstroMode = $FHEM::Automation::ShuttersControl::ascDev->getAutoAstroModeEvening;
$autoAstroMode =
$autoAstroMode . '=' . $FHEM::Automation::ShuttersControl::ascDev->getAutoAstroModeEveningHorizon
if ( $autoAstroMode eq 'HORIZON' );
}
my $oldFuncHash = $FHEM::Automation::ShuttersControl::shutters->getInTimerFuncHash;
my $shuttersSunsetUnixtime =
computeAlignTime( '24:00', sunset( 'REAL', 0, '15:30', '21:30' ) );
if ( $tm eq 'unix' ) {
if ( $FHEM::Automation::ShuttersControl::shutters->getDown eq 'astro' ) {
$shuttersSunsetUnixtime = (
computeAlignTime(
'24:00',
sunset_abs(
$autoAstroMode,
0,
$FHEM::Automation::ShuttersControl::shutters->getTimeDownEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeDownLate
)
) + 1
);
if ( defined($oldFuncHash) && ref($oldFuncHash) eq 'HASH' ) {
$shuttersSunsetUnixtime += 86400
if ( $shuttersSunsetUnixtime <
( $oldFuncHash->{sunsettime} + 180 )
&& $oldFuncHash->{sunsettime} < gettimeofday() );
}
}
elsif ( $FHEM::Automation::ShuttersControl::shutters->getDown eq 'time' ) {
$shuttersSunsetUnixtime =
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeDownEarly );
}
elsif ( $FHEM::Automation::ShuttersControl::shutters->getDown eq 'brightness' ) {
$shuttersSunsetUnixtime =
computeAlignTime( '24:00', $FHEM::Automation::ShuttersControl::shutters->getTimeDownLate );
}
return $shuttersSunsetUnixtime;
}
elsif ( $tm eq 'real' ) {
return sunset_abs(
$autoAstroMode, 0,
$FHEM::Automation::ShuttersControl::shutters->getTimeDownEarly,
$FHEM::Automation::ShuttersControl::shutters->getTimeDownLate
) if ( $FHEM::Automation::ShuttersControl::shutters->getDown eq 'astro' );
return $FHEM::Automation::ShuttersControl::shutters->getTimeDownEarly
if ( $FHEM::Automation::ShuttersControl::shutters->getDown eq 'time' );
}
return;
}
sub IsAfterShuttersTimeBlocking {
my $shuttersDev = shift;
$FHEM::Automation::ShuttersControl::shutters->setShuttersDev($shuttersDev);
if (
( int( gettimeofday() ) - $FHEM::Automation::ShuttersControl::shutters->getLastManPosTimestamp ) <
$FHEM::Automation::ShuttersControl::shutters->getBlockingTimeAfterManual
|| ( !$FHEM::Automation::ShuttersControl::shutters->getIsDay
&& defined( $FHEM::Automation::ShuttersControl::shutters->getSunriseUnixTime )
&& $FHEM::Automation::ShuttersControl::shutters->getSunriseUnixTime - ( int( gettimeofday() ) ) <
$FHEM::Automation::ShuttersControl::shutters->getBlockingTimeBeforDayOpen )
|| ( $FHEM::Automation::ShuttersControl::shutters->getIsDay
&& defined( $FHEM::Automation::ShuttersControl::shutters->getSunriseUnixTime )
&& $FHEM::Automation::ShuttersControl::shutters->getSunsetUnixTime - ( int( gettimeofday() ) ) <
$FHEM::Automation::ShuttersControl::shutters->getBlockingTimeBeforNightClose )
)
{
return 0;
}
else { return 1 }
}
sub IsAfterShuttersManualBlocking {
my $shuttersDev = shift;
$FHEM::Automation::ShuttersControl::shutters->setShuttersDev($shuttersDev);
if ( $FHEM::Automation::ShuttersControl::ascDev->getBlockAscDrivesAfterManual
&& $FHEM::Automation::ShuttersControl::shutters->getStatus != $FHEM::Automation::ShuttersControl::shutters->getOpenPos
&& $FHEM::Automation::ShuttersControl::shutters->getStatus != $FHEM::Automation::ShuttersControl::shutters->getClosedPos
&& $FHEM::Automation::ShuttersControl::shutters->getStatus != $FHEM::Automation::ShuttersControl::shutters->getWindPos
&& $FHEM::Automation::ShuttersControl::shutters->getStatus != $FHEM::Automation::ShuttersControl::shutters->getShadingPos
&& $FHEM::Automation::ShuttersControl::shutters->getStatus != $FHEM::Automation::ShuttersControl::shutters->getComfortOpenPos
&& $FHEM::Automation::ShuttersControl::shutters->getStatus != $FHEM::Automation::ShuttersControl::shutters->getVentilatePos
&& $FHEM::Automation::ShuttersControl::shutters->getStatus != $FHEM::Automation::ShuttersControl::shutters->getAntiFreezePos
&& $FHEM::Automation::ShuttersControl::shutters->getLastDrive eq 'manual' )
{
return 0;
}
elsif ( ( int( gettimeofday() ) - $FHEM::Automation::ShuttersControl::shutters->getLastManPosTimestamp ) <
$FHEM::Automation::ShuttersControl::shutters->getBlockingTimeAfterManual )
{
return 0;
}
else { return 1 }
}
sub makeReadingName {
my ($rname) = shift;
my %charHash = (
chr(0xe4) => "ae", # ä
chr(0xc4) => "Ae", # Ä
chr(0xfc) => "ue", # ü
chr(0xdc) => "Ue", # Ü
chr(0xf6) => "oe", # ö
chr(0xd6) => "Oe", # Ö
chr(0xdf) => "ss" # ß
);
my $charHashkeys = join( "", keys(%charHash) );
return $rname if ( $rname =~ m{^\./}xms );
$rname =~ s/([$charHashkeys])/$charHash{$1}/xgi;
$rname =~ s/[^a-z0-9._\-\/]/_/xgi;
return $rname;
}
sub IsWe {
return main::IsWe( shift, shift );
}
1;

@ -45,22 +45,133 @@ use warnings;
use POSIX qw(strftime);
use utf8;
use GPUtils qw(GP_Import);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
CheckASC_ConditionsForShadingFn
ShadingProcessing
ShadingProcessingDriveCommand
);
our %EXPORT_TAGS = (
ALL => [
qw(
CheckASC_ConditionsForShadingFn
ShadingProcessing
ShadingProcessingDriveCommand
)
],
);
use GPUtils qw(GP_Import);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
Log3
gettimeofday
InternalTimer
readingsBeginUpdate
readingsBulkUpdate
readingsBulkUpdateIfChanged
readingsEndUpdate
defs
)
);
}
sub CheckASC_ConditionsForShadingFn {
my $hash = shift;
my $error;
$error .=
' no valid data from the ASC temperature sensor, is ASC_tempSensor attribut set?'
if ( $FHEM::Automation::ShuttersControl::ascDev->getOutTemp == -100 );
$error .= ' no twilight device found'
if ( $FHEM::Automation::ShuttersControl::ascDev->_getTwilightDevice eq 'none' );
my $count = 1;
for my $shuttersDev ( @{ $hash->{helper}{shuttersList} } ) {
InternalTimer(
gettimeofday() + $count,
'FHEM::Automation::ShuttersControl::Shading::_CheckShuttersConditionsForShadingFn',
$shuttersDev
);
$count++;
}
return (
defined($error)
? $error
: 'none'
);
}
sub _CheckShuttersConditionsForShadingFn {
my $shuttersDev = shift;
$FHEM::Automation::ShuttersControl::shutters->setShuttersDev($shuttersDev);
my $shuttersDevHash = $defs{$shuttersDev};
my $message = '';
my $errorMessage;
my $warnMessage;
my $infoMessage;
$infoMessage .= (
$FHEM::Automation::ShuttersControl::shutters->getShadingMode ne 'off'
&& $FHEM::Automation::ShuttersControl::ascDev->getAutoShuttersControlShading eq 'on'
&& $FHEM::Automation::ShuttersControl::shutters->getOutTemp == -100
? ' shading active, global temp sensor is set, but shutters temperature sensor is not set'
: ''
);
$warnMessage .= (
$FHEM::Automation::ShuttersControl::shutters->getShadingMode eq 'off'
&& $FHEM::Automation::ShuttersControl::ascDev->getAutoShuttersControlShading eq 'on'
? ' global shading active but ASC_Shading_Mode attribut is not set or off'
: ''
);
$errorMessage .= (
$FHEM::Automation::ShuttersControl::shutters->getShadingMode ne 'off'
&& $FHEM::Automation::ShuttersControl::ascDev->getAutoShuttersControlShading ne 'on'
&& $FHEM::Automation::ShuttersControl::ascDev->getAutoShuttersControlShading ne 'off'
? ' ASC_Shading_Mode attribut is set but global shading has errors, look at ASC device '
. '<a href="'
. '/fhem?detail='
. ReadingsVal( $shuttersDev, 'associatedWith', 'ASC device' )
. $::FW_CSRF . '">'
. ReadingsVal( $shuttersDev, 'associatedWith', 'ASC device' )
. '</a>'
: ''
);
$errorMessage .= (
$FHEM::Automation::ShuttersControl::shutters->getBrightness == -1 && $FHEM::Automation::ShuttersControl::shutters->getShadingMode ne 'off'
? ' no brightness sensor found, please set ASC_BrightnessSensor attribut'
: ''
);
$message .= ' ERROR: ' . $errorMessage
if ( defined($errorMessage)
&& $errorMessage ne '' );
$message .= ' WARN: ' . $warnMessage
if ( defined($warnMessage)
&& $warnMessage ne ''
&& $errorMessage eq '' );
$message .= ' INFO: ' . $infoMessage
if ( defined($infoMessage)
&& $infoMessage ne ''
&& $errorMessage eq '' );
readingsBeginUpdate($shuttersDevHash);
readingsBulkUpdateIfChanged( $shuttersDevHash, 'ASC_ShadingMessage',
'<html>' . $message . ' </html>' );
readingsEndUpdate( $shuttersDevHash, 1 );
}
sub ShadingProcessing {
### angleMinus ist $FHEM::Automation::ShuttersControl::shutters->getShadingAzimuthLeft

@ -552,7 +552,7 @@ sub getAttrUpdateChanges {
sub getIsDay {
my $self = shift;
return FHEM::Automation::ShuttersControl::_IsDay( $self->{shuttersDev} );
return FHEM::Automation::ShuttersControl::Helper::_IsDay( $self->{shuttersDev} );
}
sub getAntiFreezeStatus {