[Gelöst] Warum greift die regex nicht

Begonnen von ripper, 09 Mai 2017, 21:09:23

Vorheriges Thema - Nächstes Thema

ripper

Hallo,

ich habe mir mit einem RaspiZero und MPD einen Internetradio "gebastelt" der über HDMI an meinem Denon Verstärker hängt. Den Denon kann ich mit dem inoffiziellen Modul genügend Informationen entlocken um das ganze über FHEM steuern zu können. Jetzt hab ich mir in ein 99_myUtils File eine Steuerung zusammengeschustert um Musikstreams starten und stoppen zu können, je nach zustand des Verstärkers, bzw. auch den Verstärker ein und umzuschalten.

Ich habe jetzt noch eine Abfrage mit der ich schon einige Abende kämpfe. Ziel soll es sein, MPD zu stoppen, wenn am Denon der Eingangskanal gewechselt wird.
Das Event das der Denon erzeugt schaut dann z.B. so aus:
input: Mediaplayer
Was ich will ist eine Abfrage die immer Wahr ist wenn
$event eq "input alles außer Mediaplayer
Nachdem ich jetzt angefangen habe mich hierfür in regex einzulesen habe ich folgendes:
elsif (($event eq "input: /[^M]*/") and ($mpdStat eq "play")){fhem("set raspiMusic stop");
laut regex101.com sollte /[^M]*/ auf alles passen was kein "M" enthält.

Kann mir jemand einen Tipp geben ob ich hier komplett auf dem Holzweg bin oder warum dass ganze nicht funktioniert?

Vielen Dank schon mal.
Flo


Vollständigkeitshalber hab ich hier noch die ganze sub (es sind noch einige Hilfslogausgaben enthalten):
sub mpdDenonSteuerung($$){
my ($geraet, $event) = @_;
my $denonStat = ReadingsVal('denon','state',''); #on/off/disconnected
my $denonInput = ReadingsVal('denon','input',''); #input: Mediaplayer/
my $mpdStat = ReadingsVal('raspiMusic','state',''); #play/stop

if ($geraet eq "denon"){
#RaspiMusic stop wenn denon ausgeschalten wird
    if (($event eq "presence: absent") and ($mpdStat eq "play")){fhem("set raspiMusic stop");
{Log 3, "[denonZweig] $event, $mpdStat, erster if"};
    }
elsif (($event eq "disconnected") and ($mpdStat eq "play")){fhem("set raspiMusic stop");
{Log 3, "[denonZweig] $event, $mpdStat, erster elsif"};
}
#RaspiMusic stop wenn denon umgeschalten wird   
elsif (($event eq "input: Mediaplayer") and ($mpdStat eq "stop")){fhem ("set raspiMusic playlist rockantenne");
{Log 3, "[denonZweig] $event, $mpdStat, zweiter elsif"};
}
    elsif (($event eq "input: /[^M]*/") and ($mpdStat eq "play")){fhem("set raspiMusic stop");
{Log 3, "[denonZweig] $event, $mpdStat, driter elsif"};
    }
}
elsif ($geraet eq "raspiMusic"){
#denon anschalten und eingang auswählen wenn RaspiMusic play geschalten wird
    if (($event eq "play") and (($denonStat eq "off") or ($denonStat eq "disconnected"))) {system("/opt/fhem/skripte/denon_einUndUmschalten.sh &");
{Log 3, "[raspiMusicZweig] $event, $denonStat, erster if"};
    }
#denon eingang wählen wenn er bereits laeuft und RaspiMusic play geschalten wird
    elsif (($event eq "play") and ($denonInput ne "Mediaplayer")) {system("/opt/fhem/skripte/denon_eingangMediaplayer.sh &");
{Log 3, "[raspiMusicZweig] $event, $denonStat, $denonInput, erster elsif"};
}
#denon ausschalten wenn RaspiMusic gestoppt wird
    elsif (($event eq "stop") and ($denonInput eq "Mediaplayer") and (ReadingsVal('denon','presence','') eq "present")) {system("/opt/fhem/skripte/denon_ausschalten.sh &");
{Log 3, "[raspiMusicZweig] $event, $denonStat, $denonInput, zweiter elsif"};
}
}
}


Das ganze wird mit diesem Notify aufgerufen:
defmod n_denonRaspiMusicSteuerung notify denon:input:.*|denon:presence:.*|raspiMusic:play|raspiMusic:stop {mpdDenonSteuerung("$NAME","$EVENT")}

DeeSPe

Regex Vergleiche gehen mit =~ oder !~ und nicht mit eq oder ne.
Wenn nur bei Mediaplayer nicht, warum dann nicht "$event ne 'Mediaplayer'"?
Ganz ohne Regex.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

ripper

Wieder was gelernt. Vielen Dank dafür. Leider klappt das nicht.

Um den Denon nicht unnötig mit Strom versorgen zu müssen ist er so eingestellt dass, das Netzwerk im Standby abgeschalten wird. Der Befehl zum einschalten kommt über HDMI-CEC. Jetzt läuft der Verstärker schon aber bis FHEM das mitbekommt vergeht je nach Timing noch ca. eine Minute. Stört mich nicht, bis auf in diesem Fall. Mit $event ne 'Mediaplayer' schaltet alles wieder ab. Da zuerst diese Bedingung wahr wird, dann der MPD ein stop event generiert und dann das letzte elsif wahr wird.

Ich test morgen nochmal mit der regex weiter.

Gruß
Flo

DeeSPe

Musste Deinen Code erst mal ein Wenig für mich "entwirren".
Da waren einige () und {} zu viel drin!

Vielleicht so?
sub mpdDenonSteuerung($$)
{
    my ($geraet, $event) = @_;
    my $denonStat = ReadingsVal('denon','state','');     #on/off/disconnected
    my $denonInput = ReadingsVal('denon','input','');    #input: Mediaplayer/
    my $mpdStat = ReadingsVal('raspiMusic','state','');  #play/stop

    if ($geraet eq "denon")
    {
        #RaspiMusic stop wenn denon ausgeschalten wird
        if (($event eq "presence: absent") and ($mpdStat eq "play")
        {
            fhem("set raspiMusic stop");
            Log 3, "[denonZweig] $event, $mpdStat, erster if";
        }
        elsif ($event eq "disconnected" && $mpdStat eq "play")
        {
            fhem("set raspiMusic stop");
            Log 3, "[denonZweig] $event, $mpdStat, erster elsif"};
        }
        #RaspiMusic stop wenn denon umgeschalten wird   
        elsif ($event eq "input: Mediaplayer" && $mpdStat eq "stop")
        {
            fhem ("set raspiMusic playlist rockantenne");
            Log 3, "[denonZweig] $event, $mpdStat, zweiter elsif";
        }
        elsif ($event ne "input: Mediaplayer" && $mpdStat eq "play")
        {
            fhem("set raspiMusic stop");
            Log 3, "[denonZweig] $event, $mpdStat, driter elsif";
        }   
    }
    elsif ($geraet eq "raspiMusic")
    {
        #denon anschalten und eingang auswählen wenn RaspiMusic play geschalten wird
        if (($event eq "play" && $denonStat eq "off") || ($denonStat eq "disconnected"))
        {
            system("/opt/fhem/skripte/denon_einUndUmschalten.sh &");
            Log 3, "[raspiMusicZweig] $event, $denonStat, erster if";
        }
        #denon eingang wählen wenn er bereits laeuft und RaspiMusic play geschalten wird
        elsif ($event eq "play" && $denonInput ne "Mediaplayer")
        {
            system("/opt/fhem/skripte/denon_eingangMediaplayer.sh &");
            Log 3, "[raspiMusicZweig] $event, $denonStat, $denonInput, erster elsif";
        }
        #denon ausschalten wenn RaspiMusic gestoppt wird
        elsif ($event eq "stop" && $denonInput eq "Mediaplayer" && ReadingsVal('denon','presence','') eq "present")
        {
            system("/opt/fhem/skripte/denon_ausschalten.sh &");
            Log 3, "[raspiMusicZweig] $event, $denonStat, $denonInput, zweiter elsif";
        }
    }
}


Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

ripper

Wow...danke fürs aufzeigen wie sowas ausschauen kann. Bin auf diesem Gebiet noch absoluter Anfänger...aber den Code werd ich morgen als erstes entwirren.

Habs jetzt nur am  Handy Browser angeschaut. Aber wenn ichs richtig gesehen habe hast du "$event ne " input: Mediaplayer" geändert oder?
Wie in meinem vorherigen Post geschrieben klappt dass eben nicht, da FHEM ca. Eine Minute braucht bis es merkt dass der Denon läuft und weil ich zwei Readings Abfrage und "present" ne "input: Mediaplayer" ist schaltet erst der MPD ab und durch das "stop" event wird dann auch der Denon wieder abgeschalten.

Gruß
Flo

Gesendet von meinem Moto G 2014 mit Tapatalk


ripper

so nochmal ein bisschen probiert und es klappt :)
elsif ($event =~ /input\D\s[A-LN-Za-ln-z].*/ and $mpdStat eq "play")
{
fhem("set raspiMusic stop");
Log 3, "[denonZweig] $event, $mpdStat, zweiter elsif";
    }


@DeeSPe
Das den Code auch mal nach deiner Vorlage gestaltet, wirkt wirklich übersichtlicher - Danke nochmal dafür.

DeeSPe

Ich werfe mal noch einen dazu:
elsif ($event =~ /^input:\s[a-ln-z].*/i and $mpdStat eq "play")

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

ripper

ok...ich glaub ich habs verstanden.
Macht eine kürzere regex das "Programm" effektiver oder schneller, bzw. braucht weniger speicher...du weist schon was ich meine. Oder ist es "einfach nur" eine weitere Möglichkeit den gewünschten String auszufiltern?

Gruß
Flo

DeeSPe

Ist einfach nur kürzer und mit dem i hinten dran auch effizienter denke ich.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

ripper

Vielen Dank für deine Erklärung und deine Hilfe ;D

Jetzt läuft alles wie es soll

Gruß
Flo