From 1a8cbfc1b89c13774bcea3e968ece9c983a48ae0 Mon Sep 17 00:00:00 2001 From: LeonGaultier Date: Tue, 11 Jun 2019 06:13:24 +0000 Subject: [PATCH] 73_AutoShuttersControl: add new attribut ASC_Shading_MinMax_Elevation, many bugfixes git-svn-id: https://svn.fhem.de/fhem/trunk@19594 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/73_AutoShuttersControl.pm | 238 +++++++++++++++++++++------- 2 files changed, 185 insertions(+), 55 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 70e403bec..d0120c7dd 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 73_AutoShuttersControl: add new attribut + ASC_Sgading_MinMax_Elevation, many bug fixes - bugfix: 88_HMCCU: Fixed noInitialUpdate bug - bugfix: 70_BOTVAC: set robotSounds filter - feature: 70_BOTVAC: add pollingMode diff --git a/fhem/FHEM/73_AutoShuttersControl.pm b/fhem/FHEM/73_AutoShuttersControl.pm index 70779ee3c..bd4b731aa 100644 --- a/fhem/FHEM/73_AutoShuttersControl.pm +++ b/fhem/FHEM/73_AutoShuttersControl.pm @@ -48,7 +48,7 @@ use strict; use warnings; use FHEM::Meta; -my $version = '0.6.16'; +my $version = '0.6.17'; sub AutoShuttersControl_Initialize($) { my ($hash) = @_; @@ -119,8 +119,79 @@ use GPUtils qw(:all) use Data::Dumper; #only for Debugging use Date::Parse; -my $missingModul = ''; -eval "use JSON qw(decode_json encode_json);1" or $missingModul .= 'JSON '; +# my $missingModul = ''; +# eval "use JSON qw(decode_json encode_json);1" or $missingModul .= 'JSON '; + +# try to use JSON::MaybeXS wrapper +# for chance of better performance + open code +eval { + require JSON::MaybeXS; + import JSON::MaybeXS qw( decode_json encode_json ); + 1; +}; + +if ($@) { + $@ = undef; + + # try to use JSON wrapper + # for chance of better performance + eval { + + # JSON preference order + local $ENV{PERL_JSON_BACKEND} = + 'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP' + unless ( defined( $ENV{PERL_JSON_BACKEND} ) ); + + require JSON; + import JSON qw( decode_json encode_json ); + 1; + }; + + if ($@) { + $@ = undef; + + # In rare cases, Cpanel::JSON::XS may + # be installed but JSON|JSON::MaybeXS not ... + eval { + require Cpanel::JSON::XS; + import Cpanel::JSON::XS qw(decode_json encode_json); + 1; + }; + + if ($@) { + $@ = undef; + + # In rare cases, JSON::XS may + # be installed but JSON not ... + eval { + require JSON::XS; + import JSON::XS qw(decode_json encode_json); + 1; + }; + + if ($@) { + $@ = undef; + + # Fallback to built-in JSON which SHOULD + # be available since 5.014 ... + eval { + require JSON::PP; + import JSON::PP qw(decode_json encode_json); + 1; + }; + + if ($@) { + $@ = undef; + + # Fallback to JSON::backportPP in really rare cases + require JSON::backportPP; + import JSON::backportPP qw(decode_json encode_json); + 1; + } + } + } + } +} ## Import der FHEM Funktionen BEGIN { @@ -196,7 +267,7 @@ my %userAttrList = ( 'ASC_Shading_Angle_Right' => '-', 'ASC_Shading_StateChange_Sunny' => '-', 'ASC_Shading_StateChange_Cloudy' => '-', - 'ASC_Shading_Min_Elevation' => '-', + 'ASC_Shading_MinMax_Elevation' => '-', 'ASC_Shading_Min_OutsideTemperature' => '-', 'ASC_Shading_WaitingPeriod' => '-', 'ASC_Drive_Offset' => '-', @@ -257,12 +328,13 @@ sub Define($$) { 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 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 + +# 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]; @@ -844,8 +916,6 @@ sub AddNotifyDev($@) { %hash = map { ( $_ => 1 ) } split( ',', "$notifyDev,$dev" ); - my $match - ; # CK: added local variable to save matched event type (open|opened|close|closed|tilt|tilted) $hash->{NOTIFYDEV} = join( ',', sort keys %hash ); my @devs = split( ',', $dev ); @@ -892,7 +962,7 @@ sub EventProcessingWindowRec($@) { my ( $hash, $shuttersDev, $events ) = @_; my $name = $hash->{NAME}; - if ( $events =~ m#.*state:.*(open(?>ed)?|closed?|tilt(?>ed)?)# + if ( $events =~ m#.*state:.*?([Oo]pen(?>ed)?|[Cc]losed?|tilt(?>ed)?)# and IsAfterShuttersManualBlocking($shuttersDev) ) { my $match = $1; @@ -912,9 +982,10 @@ sub EventProcessingWindowRec($@) { #### Hardware Lock der Rollläden $shutters->setHardLockOut('off') - if ( $match =~ /close/ and $shutters->getShuttersPlace eq 'terrace' ); + if ( $match =~ /[Cc]lose/ + and $shutters->getShuttersPlace eq 'terrace' ); $shutters->setHardLockOut('on') - if ( $match =~ /open/ + if ( $match =~ /[Oo]pen/ and $shutters->getShuttersPlace eq 'terrace' ); # my $queryShuttersPosWinRecTilted = ( @@ -939,7 +1010,7 @@ sub EventProcessingWindowRec($@) { ); if ( - $match =~ /close/ + $match =~ /[Cc]lose/ and IsAfterShuttersTimeBlocking($shuttersDev) and ( $shutters->getStatus == $shutters->getVentilatePos or $shutters->getStatus == $shutters->getComfortOpenPos @@ -991,7 +1062,7 @@ sub EventProcessingWindowRec($@) { elsif ( ( $match =~ /tilt/ - or ( $match =~ /open/ + or ( $match =~ /[Oo]pen/ and $shutters->getSubTyp eq 'twostate' ) ) and $shutters->getVentilateOpen eq 'on' @@ -1002,7 +1073,7 @@ sub EventProcessingWindowRec($@) { $shutters->setNoOffset(1); $shutters->setDriveCmd( $shutters->getVentilatePos ); } - elsif ( $match =~ /open/ + elsif ( $match =~ /[Oo]pen/ and $shutters->getSubTyp eq 'threestate' ) { my $posValue; @@ -1951,6 +2022,7 @@ sub ShadingProcessing($@) { if ( $azimuth < $winPosMin or $azimuth > $winPosMax or $elevation < $shutters->getShadingMinElevation + or $elevation > $shutters->getShadingMaxElevation or $brightness < $shutters->getShadingStateChangeCloudy or $outTemp < $shutters->getShadingMinOutsideTemperature ) { @@ -1986,6 +2058,7 @@ sub ShadingProcessing($@) { elsif ( $azimuth > $winPosMin and $azimuth < $winPosMax and $elevation > $shutters->getShadingMinElevation + and $elevation < $shutters->getShadingMaxElevation and $brightness > $shutters->getShadingStateChangeSunny and $outTemp > $shutters->getShadingMinOutsideTemperature ) { @@ -2036,14 +2109,14 @@ sub ShadingProcessingDriveCommand($$) { if ( $shutters->getShadingStatus eq 'in' and $getShadingPos != $getStatus ) { - my $queryShuttersShadingPos = ( - $shutters->getShuttersPosCmdValueNegate - ? $getStatus > $getShadingPos - : $getStatus < $getShadingPos - ); + # my $queryShuttersShadingPos = ( + # $shutters->getShuttersPosCmdValueNegate + # ? $getStatus > $getShadingPos + # : $getStatus < $getShadingPos + # ); if ( - not $queryShuttersShadingPos + not $shutters->getQueryShuttersPos( $shutters->getShadingPos ) and not( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 and $shutters->getShuttersPlace eq 'terrace' ) ) @@ -2233,7 +2306,7 @@ sub ShuttersCommandSet($$$) { ) or ( CheckIfShuttersWindowRecOpen($shuttersDev) == 2 and $shutters->getShuttersPlace eq 'terrace' - and not $shutters->getQueryShuttersPos($posValue) ) + and $shutters->getQueryShuttersPos($posValue) ) ) ) { @@ -2356,11 +2429,9 @@ sub CreateSunRiseSetShuttersTimer($$) { } InternalTimer( $shuttersSunsetUnixtime, - 'FHEM::AutoShuttersControl::SunSetShuttersAfterTimerFn', \%funcHash ) - if ( $ascDev->getAutoShuttersControlEvening eq 'on' ); + 'FHEM::AutoShuttersControl::SunSetShuttersAfterTimerFn', \%funcHash ); InternalTimer( $shuttersSunriseUnixtime, - 'FHEM::AutoShuttersControl::SunRiseShuttersAfterTimerFn', \%funcHash ) - if ( $ascDev->getAutoShuttersControlMorning eq 'on' ); + 'FHEM::AutoShuttersControl::SunRiseShuttersAfterTimerFn', \%funcHash ); $ascDev->setStateReading('created new drive timer'); } @@ -2394,7 +2465,12 @@ sub RenewSunRiseSetShuttersTimer($) { # ; # temporär muss später gelöscht werden ab Version 0.4.11beta9 # delFromDevAttrList( $_, 'ASC_BrightnessMaxVal' ) # ; # temporär muss später gelöscht werden ab Version 0.4.11beta9 + $attr{$_}{'ASC_Shading_MinMax_Elevation'} = + AttrVal( $_, 'ASC_Shading_Min_Elevation', 'none' ) + if ( AttrVal( $_, 'ASC_Shading_Min_Elevation', 'none' ) ne 'none' ); + delFromDevAttrList( $_, 'ASC_Shading_Min_Elevation' ) + ; # temporär muss später gelöscht werden ab Version 0.6.17 } } @@ -2480,13 +2556,14 @@ sub SunSetShuttersAfterTimerFn($) { $homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' ); if ( - ( + $ascDev->getAutoShuttersControlEvening eq 'on' + and IsAfterShuttersManualBlocking($shuttersDev) + and ( $shutters->getModeDown eq $homemode or ( $shutters->getModeDown eq 'absent' and $homemode eq 'gone' ) or $shutters->getModeDown eq 'always' ) - and IsAfterShuttersManualBlocking($shuttersDev) ) { # my $queryShuttersPosPrivacyDown = ( @@ -2526,12 +2603,16 @@ sub SunRiseShuttersAfterTimerFn($) { $homemode = $ascDev->getResidentsStatus if ( $homemode eq 'none' ); if ( - $shutters->getModeUp eq $homemode - or ( $shutters->getModeUp eq 'absent' - and $homemode eq 'gone' ) - or $shutters->getModeUp eq 'always' + $ascDev->getAutoShuttersControlMorning eq 'on' + and ( + $shutters->getModeUp eq $homemode + or ( $shutters->getModeUp eq 'absent' + and $homemode eq 'gone' ) + or $shutters->getModeUp eq 'always' + ) ) { + if ( ( $shutters->getRoommatesStatus eq 'home' @@ -2552,6 +2633,7 @@ sub SunRiseShuttersAfterTimerFn($) { ShuttersCommandSet( $hash, $shuttersDev, $shutters->getOpenPos ); } } + CreateSunRiseSetShuttersTimer( $hash, $shuttersDev ); } @@ -3365,7 +3447,7 @@ sub CheckIfShuttersWindowRecOpen($) { my $shuttersDev = shift; $shutters->setShuttersDev($shuttersDev); - if ( $shutters->getWinStatus =~ /open/ ) # CK: covers: open|opened + if ( $shutters->getWinStatus =~ /[Oo]pen/ ) # CK: covers: open|opened { return 2; } @@ -3374,7 +3456,7 @@ sub CheckIfShuttersWindowRecOpen($) { { return 1; } - elsif ( $shutters->getWinStatus =~ /close/ ) { + elsif ( $shutters->getWinStatus =~ /[Cc]lose/ ) { return 0; } # CK: covers: close|closed } @@ -4089,15 +4171,13 @@ sub _getBrightnessSensor { ### erwartetes Ergebnis # DEVICE:READING MAX:MIN - - return $device if ( $device eq 'none' ); $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device} = $device; $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{reading} = ( $reading ne 'none' ? $reading : 'brightness' ); $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermin} = - ( $min ne 'none' ? $min : '-1' ); + ( $min ne 'none' ? $min : -1 ); $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{triggermax} = - ( $max ne 'none' ? $max : '-1' ); + ( $max ne 'none' ? $max : -1 ); return $self->{ $self->{shuttersDev} }->{ASC_BrightnessSensor}->{device}; } @@ -4154,7 +4234,53 @@ sub getShadingMinOutsideTemperature { sub getShadingMinElevation { my $self = shift; - return AttrVal( $self->{shuttersDev}, 'ASC_Shading_Min_Elevation', 25.0 ); + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{minVal} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} + ) + and ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} ) < 2 + ); + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} = int( gettimeofday() ); + my ( $min, $max ) = + FHEM::AutoShuttersControl::GetAttrValues( $self->{shuttersDev}, + 'ASC_Shading_MinMax_Elevation', '25.0:100.0' ); + + ### erwartetes Ergebnis + # MIN:MAX + + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation}->{minVal} = + $min; + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation}->{maxVal} = + ( $max ne 'none' ? $max : 100 ); + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{minVal}; +} + +sub getShadingMaxElevation { + my $self = shift; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{maxVal} + if ( + exists( + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} + ) + and ( gettimeofday() - + $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{LASTGETTIME} ) < 2 + ); + $shutters->getShadingMinElevation; + + return $self->{ $self->{shuttersDev} }->{ASC_Shading_MinMax_Elevation} + ->{maxVal}; } sub getShadingStateChangeSunny { @@ -5157,7 +5283,8 @@ sub getblockAscDrivesAfterManual { =pod =item device =item summary Module for controlling shutters depending on various conditions -=item summary_DE Modul zur Automatischen Rolladensteuerung auf Basis bestimmter Ereignisse +=item summary_DE Modul zur automatischen Rolladensteuerung auf Basis bestimmter Ereignisse + =begin html @@ -5315,21 +5442,21 @@ sub getblockAscDrivesAfterManual { if the ASC_autoAstroModeMorning attribute is set to HORIZON. Defaults to 0. -
  • ASC_autoShuttersControlComfort - on/off - +
  • ASC_autoShuttersControlComfort - on|off - Controls the comfort functions: If a three state sensor, like the HmIP-SRH window handle sensor, is installed, ASC will open the window if the sensor signals open position. The ASC_ComfortOpen_Pos attribute has to be set for the shutter to on, defaults to off.
  • -
  • ASC_autoShuttersControlEvening - on/off - Enables the automatic control by ASC +
  • ASC_autoShuttersControlEvening - on|off - Enables the automatic control by ASC at the evenings.
  • -
  • ASC_autoShuttersControlMorning - on/off - Enables the automatic control by ASC +
  • ASC_autoShuttersControlMorning - on|off - Enables the automatic control by ASC at the mornings.
  • -
  • ASC_blockAscDrivesAfterManual - 0,1 - If set to 1, ASC will not +
  • ASC_blockAscDrivesAfterManual 0|1 - If set to 1, ASC will not automatically control a shutter if there was an manual control to the shutter. To be considered, the ASC_ShuttersLastDrive reading has to contain the value manual and the shutter is in an unknown (i.e. not otherwise configured in ASC) position. @@ -5411,7 +5538,7 @@ sub getblockAscDrivesAfterManual {

    At shutter devices, controlled by ASC:

      -
    • ASC - 0/1/2 +
    • ASC - 0|1|2
      • 0 - don't create attributes for ASC at the first scan and don't be controlled by ASC
      • @@ -5421,7 +5548,7 @@ sub getblockAscDrivesAfterManual { controlled by pct values.
    • -
    • ASC_Antifreeze - soft/am/pm/hard/off - Freeze protection. +
    • ASC_Antifreeze - soft|am|pm|hard|off - Freeze protection.
      • soft - see ASC_Antifreeze_Pos.
      • hard / am / pm - freeze protection will be active (everytime, @@ -5643,8 +5770,8 @@ sub getblockAscDrivesAfterManual { points. East is 90 °, South 180 °, West is 270 ° and North is 0 °. Defaults to South (180).
      • -
      • ASC_Shading_Min_Elevation - Shading starts as this point of sun elevation is - reached, depending also on other sensor values. Defaults to 25.0. +
      • ASC_Shading_MinMax_Elevation - Shading starts as min point of sun elevation is + reached and end as max point of sun elevation is reached, depending also on other sensor values. Defaults to 25.0:100.0.
      • ASC_Shading_Min_OutsideTemperature - Shading starts at this outdoor temperature, depending also on other sensor values. Defaults to 18.0. @@ -5978,10 +6105,10 @@ sub getblockAscDrivesAfterManual {
      • ASC_Pos_Reading - Name des Readings, welches die Position des Rollladen in Prozent an gibt; wird bei unbekannten Device Typen auch als set Befehl zum fahren verwendet
      • ASC_PrivacyDownTime_beforNightClose - wie viele Sekunden vor dem abendlichen schließen soll der Rollladen in die Sichtschutzposition fahren, -1 bedeutet das diese Funktion unbeachtet bleiben soll (default: -1)
      • ASC_PrivacyDown_Pos - Position den Rollladens für den Sichtschutz (default: 50)
      • -
      • ASC_WindProtection - on/off - soll der Rollladen beim Regenschutz beachtet werden. On=JA, off=NEIN.
      • +
      • ASC_WindProtection - on/off - soll der Rollladen beim Regenschutz beachtet werden. on=JA, off=NEIN.
      • ASC_Roommate_Device - mit Komma getrennte Namen des/der Roommate Device/s, welche den/die Bewohner des Raumes vom Rollladen wiedergibt. Es macht nur Sinn in Schlaf- oder Kinderzimmern (default: none)
      • ASC_Roommate_Reading - das Reading zum Roommate Device, welches den Status wieder gibt (default: state)
      • -
      • SC_Self_Defense_Exclude - on/off - bei on Wert wird dieser Rollladen bei aktiven Self Defense und offenen Fenster nicht runter gefahren, wenn Residents absent ist. (default: off)
      • +
      • ASC_Self_Defense_Exclude - on/off - bei on Wert wird dieser Rollladen bei aktiven Self Defense und offenen Fenster nicht runter gefahren, wenn Residents absent ist. (default: off)
        • Beschreibung der Beschattungsfunktion
          Damit die Beschattung Funktion hat, müssen folgende Anforderungen erfüllt sein. @@ -5991,7 +6118,7 @@ sub getblockAscDrivesAfterManual {
        • ASC_Shading_Angle_Left - Vorlaufwinkel im Bezug zum Fenster, ab wann abgeschattet wird. Beispiel: Fenster 180° - 85° ==> ab Sonnenpos. 95° wird abgeschattet (default: 75)
        • ASC_Shading_Angle_Right - Nachlaufwinkel im Bezug zum Fenster, bis wann abgeschattet wird. Beispiel: Fenster 180° + 85° ==> bis Sonnenpos. 265° wird abgeschattet (default: 75)
        • ASC_Shading_Direction - Position in Grad, auf der das Fenster liegt - genau Osten wäre 90, Süden 180 und Westen 270 (default: 180)
        • -
        • ASC_Shading_Min_Elevation - ab welcher Höhe des Sonnenstandes soll beschattet werden, immer in Abhängigkeit der anderen einbezogenen Sensorwerte (default: 25.0)
        • +
        • ASC_Shading_MinMax_Elevation - ab welcher min Höhe des Sonnenstandes soll beschattet und ab welcher max Höhe wieder beendet werden, immer in Abhängigkeit der anderen einbezogenen Sensorwerte (default: 25.0:100.0)
        • ASC_Shading_Min_OutsideTemperature - ab welcher Temperatur soll Beschattet werden, immer in Abhängigkeit der anderen einbezogenen Sensorwerte (default: 18)
        • ASC_Shading_Mode - absent,always,off,home / wann soll die Beschattung nur stattfinden. (default: off)
        • ASC_Shading_Pos - Position des Rollladens für die Beschattung
        • @@ -6099,7 +6226,8 @@ sub getblockAscDrivesAfterManual { "FHEM": 5.00918799, "perl": 5.016, "Meta": 0, - "JSON": 0 + "JSON": 0, + "Date::Parse": 0 }, "recommends": { },