73_AutoShuttersControl

Begonnen von CoolTux, 25 März 2020, 10:40:56

Vorheriges Thema - Nächstes Thema

CoolTux

Bei meinem Glück habe ich Dich bestimmt wieder nicht korrekt verstanden  ;D
Aber meinst Du sowas wie


my ( $value3, $value4 );
( $value3, $value4 ) = split( ':', $values[1] )
      if ( defined( $values[1] ) );


Oder meinst Du eine separate Befüllung von $value3 und $value4?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

rudolfkoenig

Ich meinte es so, wie Du es in dem Code-Tag gezeigt hast.

RichardCZ

Prinzipiell ist ein

my $variable = 1 if ($bedingung);

zu vermeiden. Böse hinterhältige Sache. Wird "my" ausgeführt wenn Bedingung nicht zutrifft?

Meist will man vermutlich

my $variable;

$variable = 1 if ($bedingung);


Relativ elegant in einer zeile geht es mit einem Ternary:

my $variable = $bedingung ? 1 : undef;

Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

CoolTux

Ich danke Euch beiden. Werde es entsprechend an passen.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

#19
return
      if ( !exists( $hash->{helper} )
        or !defined( $hash->{helper}->{shuttersList} )
        or ref( $hash->{helper}->{shuttersList} ) ne 'ARRAY'
        or scalar( @{ $hash->{helper}->{shuttersList} } ) == 0
        or !defined( $shutters->getSunriseUnixTime )
        or !defined( $shutters->getSunsetUnixTime ) );


Mixed high and low-precedence booleans at line 3337, column 12.  See page 70 of PBP.  (Severity: 4)


Ich bilde mir ein zu verstehen was er da anmeckert. Leider weiß ich nicht wie ich es besser schreiben sollte  :-[

Jemand eine Idee?


Hat sich erledigt. Ich habe es gefunden. Lesen bildet. Lach
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

RichardCZ

Zitat von: CoolTux am 28 März 2020, 14:51:34
Mixed high and low-precedence booleans at line 3337, column 12.  See page 70 of PBP.  (Severity: 4)


Ich bilde mir ein zu verstehen was er da anmeckert. Leider weiß ich nicht wie ich es besser schreiben sollte  :-[

Jemand eine Idee?

or => ||
and => &&
not => !

die ausgeschriebenen logischen Operatoren haben so einen niedrigen Vorrang, dass sogar der Komma-Operator höher steht.

Deswegen kann man bedenkenlos ein

open my $FH, '>', $file or die  'blah';

machen. Ganz krass ist, dass diese Formen sogar eine niedrigere Priorität als "=" haben.

my $x = shift || 'default';

macht was man denkt,

my $x = shift or 'default';

ist eigentlich

(my $x = shift) || 'default'

Urgs.

https://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity

Die perlcritic Fehlermeldung mosert an, dass man mischt. In diesem Fall "!" und "or". Das kann ziemlich in die Hose gehen. Hier mal andersrum:

if ( not defined $x || y < 5)

selbst wenn man es gut meint:

if ( not (defined $x) || (y < 5) )

ist es halt dennoch gleichbedeutend mit

if ( not (defined $x || y < 5) )

Ergo: ersetze or durch ||

oder ! durch "not"

Ich empfehle ersteres (generell sollte man ! || && in logischen Termen verwenden. Die ausgeschriebene Form nur zur Programmflusskontrolle (siehe open or die).
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

CoolTux

if ( grep /^userAttrList:.rolled.out$/, @{$events} ) {

Das würde ich gerne sauberer machen.
Hierzu hatte ich in meinen jugendlichen Leichtsinn folgendes draus gemacht
Da @{$events} ja ein multiliner ist dachte ich an

if ( @{$events} =~ m{\AuserAttrList:.rolled.out\z}xms )

Aber er kommt mit @{$events} nicht klar. Wie wäre hier der saubere Weg?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

RichardCZ

#22
Zitat von: CoolTux am 28 März 2020, 15:12:23
if ( grep /^userAttrList:.rolled.out$/, @{$events} ) {

Das würde ich gerne sauberer machen.
Hierzu hatte ich in meinen jugendlichen Leichtsinn folgendes draus gemacht

Es geht um

        if ( grep /^userAttrList:.rolled.out$/, @{$events} ) {
            unless ( scalar( @{ $hash->{helper}{shuttersList} } ) == 0 ) {
                WriteReadingsShuttersList($hash);
                UserAttributs_Readings_ForShutters( $hash, 'add' );
                InternalTimer( gettimeofday() + 3,
                    'FHEM::AutoShuttersControl::RenewSunRiseSetShuttersTimer',
                    $hash );
                InternalTimer( gettimeofday() + 5,
                    'FHEM::AutoShuttersControl::AutoSearchTwilightDev', $hash );
            }
        }
        elsif ( grep /^partyMode:.off$/, @{$events} ) {
            EventProcessingPartyMode($hash);
        }
        elsif ( grep /^sunriseTimeWeHoliday:.(on|off)$/, @{$events} ) {
            RenewSunRiseSetShuttersTimer($hash);
        }


nehme ich an? Da würde ich in meinem jugendlichen Leichtsinn das hier daraus machen:

    my $found_event = {    # container to memoize specific found events
        rolledout => 0,
        partyoff  => 0,
        sunrise   => 0,
    };

    # iterate the event list just ONCE
    for my $event (@{$events}) {
        $found_event{rolledout}++ if ($event =~ m{^userAttrList:.rolled.out$}xms);
        $found_event{partyoff}++  if ($event =~ m{^partyMode:.off$}xms);
        $found_event{sunrise}++   if ($event =~ m{^sunriseTimeWeHoliday:.(on|off)$}xms);
    }

    # handle found events according to their priority
    if ($found_event{rolledout} && @{$hash->{helper}{shuttersList}}) {
        WriteReadingsShuttersList($hash);
        UserAttributs_Readings_ForShutters($hash, 'add');
        InternalTimer( gettimeofday() + 3,
                       'FHEM::AutoShuttersControl::RenewSunRiseSetShuttersTimer',
                       $hash );
        InternalTimer( gettimeofday() + 5,
                       'FHEM::AutoShuttersControl::AutoSearchTwilightDev', $hash );
    }
    elsif ($found_event{partyoff}) {
        EventProcessingPartyMode($hash);
    }
    elsif ($found_event{sunrise}) {
        RenewSunRiseSetShuttersTimer($hash);
    }


Aber nur so aus der Hüfte geschossen. grep in den Ifs knüppelt jedes Mal die liste durch "matche gegen die ganze Liste ... nix gefunden: matche nochmal was anderes gegen die selbe ganze Liste ..."

Ist ungetestet, kann also der ein oder andere Bug drin sein. Ein wenig Bauchweh habe ich mit den Punkten in den Regexen. Meintest Du \s ?

besonders stolz bin ich ja auf

unless ( scalar( @{ $hash->{helper}{shuttersList} } ) == 0
->
@{ $hash->{helper}{shuttersList} }
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

CoolTux

Danke das funktioniert ja bestens. Kleiner Fehler in Deinem Code nur damit andere die hier lesen nicht in ein Problem rennen

my $found_event = {    # container to memoize specific found events
        rolledout => 0,
        partyoff  => 0,
        sunrise   => 0,
    };

    # iterate the event list just ONCE
    for my $event (@{$events}) {
        $found_event{rolledout}++ if ($event =~ m{^userAttrList:.rolled.out$}xms);
        $found_event{partyoff}++  if ($event =~ m{^partyMode:.off$}xms);
        $found_event{sunrise}++   if ($event =~ m{^sunriseTimeWeHoliday:.(on|off)$}xms);
    }



my $found_event = {    # container to memoize specific found events
        rolledout => 0,
        partyoff  => 0,
        sunrise   => 0,
    };

    # iterate the event list just ONCE
    for my $event (@{$events}) {
        $found_event->{rolledout}++ if ($event =~ m{^userAttrList:.rolled.out$}xms);
        $found_event->{partyoff}++  if ($event =~ m{^partyMode:.off$}xms);
        $found_event->{sunrise}++   if ($event =~ m{^sunriseTimeWeHoliday:.(on|off)$}xms);
    }


$found_event ist kein Hash sondern eine Hash Referenz.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

RichardCZ

            if (
                !(
                    CheckIfShuttersWindowRecOpen($shuttersDev) == 2
                    && $shutters->getShuttersPlace eq 'terrace'
                )
              )


Ich habe vor einiger Zeit (anderswo hier im Forum) den Begriff "De Morgan Transformation" in den Raum geschmissen. Das blieb ohne Reaktion, also reagiere ich nochmal.  ;)

Zum Beispiel:

!(A && B) = !A || !B

für den obigen Code würde das bedeuten:


            if (CheckIfShuttersWindowRecOpen($shuttersDev) != 2
                    || $shutters->getShuttersPlace ne 'terrace')


Ob man das nun macht oder nicht, ist häufig Geschmacksfrage, bzw. wie intuitiv man den booleschen Ausdruck haben möchte.

An einigen Stellen (die erwähnt das PBP auch) ist die Kenntnis dieser Transformationen beim Übergang unless(x) -> if(!x)
aber durchaus hilfreich.

Man stelle sich sowas vor wie unless ($x ne 'foo') - das kann man noch einfach als die doppelte Negation erkennen => if ($x eq 'foo')

aber schon ein

unless ( !$x && $z ne 'bar')

... da windet man dann die ganze Zeit sein Hirn drum und in Wirklichkeit ist das

if ($x || $z eq 'bar')

Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

CoolTux

#25
Aber das würde die Bedingung falsch machen.

Es muss ja heißen

Wenn das Fenster 2 ist UND der Fensterplatz eine Terrasse

Im Umkehrschluss also z.B.

Ist das Fenster 2 aber der Fensterplatz keine Terasse mache es trotzdem
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

RichardCZ

Zitat von: CoolTux am 11 April 2020, 15:01:02
Aber das würde die Bedingung falsch machen.

Es muss ja heißen

Wenn das Fenster 2 ist UND der Fensterplatz eine Terrasse

Nö.  :)
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

CoolTux

Zitat von: RichardCZ am 11 April 2020, 15:04:50
Nö.  :)

Das würde also dennoch auch gehen

Ist das Fenster 2 aber der Fensterplatz keine Terasse mache es trotzdem
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

Zitat von: CoolTux am 11 April 2020, 15:05:56
Das würde also dennoch auch gehen

Ist das Fenster 2 aber der Fensterplatz keine Terasse mache es trotzdem

if (CheckIfShuttersWindowRecOpen($shuttersDev) != 2
                    || $shutters->getShuttersPlace ne 'terrace')


Ich weiß nicht. Das würde doch bei sowohl als auch die Bedingung erfüllen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

RichardCZ

Ich habe ein

Falls nicht gilt: Fenster ist 2 UND Fensterplatz ist Terasse

zu einem:

Falls: Fenster nicht 2 ODER Fensterplatz ist nicht Terasse


gemacht. Und ohne nachzuprüfen behaupte ich, das ist dasselbe.

Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.