Home of the Squeezebox™ & Transporter® network music players.
Results 1 to 10 of 10
  1. #1
    Senior Member
    Join Date
    Jan 2011
    Location
    Germany
    Posts
    226

    Übergabe von Argumenten an eine Funktion fir von Timer aufgerufen wird

    Hallo zusammen,

    ich würde gerne einer Funktion, die durch einen Timer aufgerufen wird, Argumente mitgeben.

    Reinschreiben würde ich denke ich mal folgendermaßen (angelehnt an AsyncHTTP):
    Code:
     Slim::Utils::Timers::setTimer(undef, time() + 1, \&_function, {
                                                                    name_argument_1 => $valueArgument_1,
                                                                    name_argument_2 => $valueArgument_2,
                                                            },
                                                        );
    Wie komme ich nur dann wieder an die Werte dran, wenn die eigentliche Funktion aufgerufen wird?
    Im Gegensatz zu asyncSimple hat ein Timer kein new und kein _params...
    Code:
    sub function {
                my $name_argument_1 = ...;
                my $name_argument_2 = ...;
    }
    Im Falle von asyncHTTP wäre es $asyncHTTP->params() aber wie mach ich das beim Timer?
    Aus dem Quellcode für die Timer in LMS werde ich ehrlich gesagt nicht ganz schlau...

    Kann mir jemand ein Beispiel im Code zeigen, wo sowas drin ist oder mir einfach so weiterhelfen?
    LMS-7.9@solaris. 2x Radio, 2x Duet, 1x Chromecast v1, ShairTunes, 1x Philips Hue System

  2. #2
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    19,702
    Code:
    sub function {
                my ($param1, $params) = @_;
                my $name_argument_1 = $params->{name_argument_1};
                my $name_argument_2 = $params->{name_argument_2};
    }
    $param1 wäre der Wert, den du als ersten Parameter an setTimer übergibst. In deinem Fall ist das undef. Häufig ist es z.B. $client, wenn es sich um etwas Geräte spezifisches handelt. Aber es steht dir frei, was du da verwendest. Wichtig ist einfach zu wissen, dass $param1 und die Referenz auf eine Funktion auch verwendet werden, wenn du über killTimer einen Timer wieder stoppen möchtest.

    $params ist die Liste von Werten, die du nach der Funktions-Referenz an setTimer übergibst.
    Michael

    http://www.herger.net/slim-plugins - MusicArtistInfo, MusicInfoSCR

  3. #3
    Senior Member
    Join Date
    Jan 2011
    Location
    Germany
    Posts
    226
    Danke.
    Ich werd's bei nächster Gelegeheit einbauen.
    LMS-7.9@solaris. 2x Radio, 2x Duet, 1x Chromecast v1, ShairTunes, 1x Philips Hue System

  4. #4
    Senior Member
    Join Date
    Jan 2011
    Location
    Germany
    Posts
    226
    Guten Abend,

    ich mal wieder.

    Ich habe die Zeilen entsprechend eingebaut, allerdings funktioniert jetzt eine Funktion nicht mehr...

    Folgende Funktion wird dem Timer übergeben (ja, rekursiv aufgerufen):
    Code:
    sub _sendConnectRequest {
        my ($self, $params) = @_;
        
        my $deviceUDN = $params->{'deviceUDN'};
        my $XMLConfig = $params->{'XMLConfig'};
        
        $log->error('deviceUDN: ' .Dumper($deviceUDN));
        $log->error('XMLConfig: ' .Dumper($XMLConfig->{'device'}));
        
        my $device = Plugins::HueBridge::Settings->findUDN( $deviceUDN, $XMLConfig->{'device'} );
            
        my $bridgeIpAddress = $device->{'ip_address'};
        
        my $uri = join('', 'http://', $bridgeIpAddress, '/api');
        my $contentType = "application/json";
        
        my $request = { 'devicetype' => 'squeeze2hue#lms' };
        my $requestBody = encode_json($request);
        
        $connectDisconnectStatus = 1;
        $connectProgress += 1;
        
        Slim::Utils::Timers::setTimer(undef, time() + 1, \&_sendConnectRequest, {
                                                                    deviceUDN => $deviceUDN,
                                                                    XMLConfig => $XMLConfig,
                                                            },
                                                        );
        
        my $asyncHTTP = Slim::Networking::SimpleAsyncHTTP->new(
            \&_sendConnectRequestOK,
            \&_sendConnectReqeustERROR,
            {
                deviceUDN => $deviceUDN,
                XMLConfig => $XMLConfig,
                error       => "Can't get response.",
            },
        );
    
        $asyncHTTP->_createHTTPRequest(POST => ($uri, 'Content-Type' => $contentType, $requestBody));
    }
    Ich erhalten dann folgende Fehlermeldung (Dumper Output schonmal dabei):
    Code:
    [17-05-17 20:36:13.0070] Slim::Utils::Timers::__ANON__ (273) Error: Timer Plugins::HueBridge::HueCom::_sendConnectRequest failed: 
    20:36:13.050  Got a reply for service D56CDCFEC956@SqueezeBox._raop._tcp.local.: Name now registered and active
    [17-05-17 20:36:53.0004] Plugins::HueBridge::HueCom::_sendConnectRequest (114) deviceUDN: $VAR1 = 'uuid:2f402f80-da50-11e1-9b23-0017882d3081';
    [17-05-17 20:36:53.0016] Plugins::HueBridge::HueCom::_sendConnectRequest (115) XMLConfig: $VAR1 = [
              {
                'ip_address' => '192.168.47.251',
                'user_valid' => '0',
                'user_name' => 'none',
                'udn' => 'uuid:2f402f80-da50-11e1-9b23-0017882d3081',
                'name' => 'Hue Bridge',
                'enabled' => '1',
                'mac' => '00:17:88:2d:30:81'
              },
              {
                'user_valid' => '0',
                'user_name' => 'none',
                'udn' => 'uuid:2',
                'mac' => '00:17:88:2d:30:81',
                'enabled' => '1',
                'name' => 'Hue Bridge 2',
                'ip_address' => '192.168.47.251'
              }
            ];
    [17-05-17 20:36:53.0024] Slim::Utils::Timers::__ANON__ (273) Error: Timer Plugins::HueBridge::HueCom::_sendConnectRequest failed: Can't use string ("uuid:2f402f80-da50-11e1-9b23-001"...) as an ARRAY ref while "strict refs" in use at /opt/lms-7.9.1/Plugins/HueBridge/Settings.pm line 249.
    Die erste Zeile des Outputs scheint ein anderer Fehler zu sein, so wie ich das interpretiere...
    Aber ich komme (wie immer) mit diesen Referenzen etc. nicht klar...

    In der Settings.pm in Zeile 249 hätten wir:
    Code:
    sub findUDN {
        my $udn = shift(@_);
        my $listpar = shift(@_);
        my @list = @{$listpar};       ### <-- Hier ist Zeile 249.
    
        while (@list) {
    
            my $p = pop @list;
            if ($p->{ 'udn' } eq $udn) { return $p; }
        }
    
        return undef;
    }
    Warum das nur jetzt nicht mehr klappt, verstehe ich nicht. Irgenndwie scheint durch den neuen Aufruf mit den params etwas schiefzugehen...

    Der originale Code ist übrigens hier:
    -> https://github.com/chincheta0815/LMS...HueCom.pm#L106
    -> https://github.com/chincheta0815/LMS...ttings.pm#L246

    Vielen Dank schonmal für die Hilfe.
    LMS-7.9@solaris. 2x Radio, 2x Duet, 1x Chromecast v1, ShairTunes, 1x Philips Hue System

  5. #5
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    19,702

    =?utf-8?q?=C3=9Cbergabe_von_Argumenten_an_eine_Fu?==?utf-8?q?nktion_fir_von_Timer_aufgerufen_wird?=

    > my $device = Plugins::HueBridge::Settings->findUDN( $deviceUDN, $XMLConfig->{'device'} );

    Wenn du die Methode einer Klasse über Klasse->methode() aufrufst, so ist
    der erste Parameter, der der Methode übergeben wird, eine Referenz zu
    ihrer Klasse. In deinem Code jedoch gehst du davon aus, dass der erste
    Wert eine UDN sei:

    > sub findUDN {
    > my $udn = shift(@_);


    Wenn du also die Klasse nicht brauchst, dann rufe sie nicht als Methode
    einer Klasse auf, sondern als einfache Funktion:

    my $device = Plugins::HueBridge::Settings::findUDN( $deviceUDN,
    $XMLConfig->{'device'} );

    Also nicht Klasse->methode(), sondern Klasse::methode().

    --

    Michael

  6. #6
    Senior Member
    Join Date
    Jan 2011
    Location
    Germany
    Posts
    226
    Quote Originally Posted by mherger View Post
    Wenn du also die Klasse nicht brauchst, dann rufe sie nicht als Methode
    einer Klasse auf, sondern als einfache Funktion:

    my $device = Plugins::HueBridge::Settings::findUDN( $deviceUDN,
    $XMLConfig->{'device'} );

    Also nicht Klasse->methode(), sondern Klasse::methode().
    Mal so ausgedrückt: Da ich nicht weiß, ob ich die Klasse brauche oder nicht, geht der Aufruf glaub ich auch direkt als Methode.
    Ich renne nur immer automatisch in die Syntax mit dem "->" da ich das irgendwie eingänglicher finde...

    Mal zum Verständnis:
    Wenn ich allerdings der Funktion noch ein "$self = shift" als erste Argumentüberahme reinschaschreibe würde es auch funktionieren?
    An anderen Stellen, klappt es nämlich mit dem Pfeil und da hab ich dann immer "$self = shift" o.ä. als erstes Argument, dass ich nicht übergebe...

    Gibt es vielleicht einen prinzipielle Vorteil, wenn ich die Klasse mitgebe?
    LMS-7.9@solaris. 2x Radio, 2x Duet, 1x Chromecast v1, ShairTunes, 1x Philips Hue System

  7. #7
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    19,702

    =?utf-8?q?=C3=9Cbergabe_von_Argumenten_an_eine_Fu?==?utf-8?q?nktion_fir_von_Timer_aufgerufen_wird?=

    > Wenn ich allerdings der Funktion noch ein "$self = shift" als erste
    > Argumentüberahme reinschaschreibe würde es auch funktionieren?


    Ja, das ginge auch. Nur musst du dann sicher stellen, dass das erste
    Argument _immer_ diese Referenz (oder undef) ist. Du kannst eine solche
    Methode dann z.B. nicht mehr einfach als Callback verwenden, da dieser
    die Klasse nicht mit berüchsichtigen würde.

    > Gibt es vielleicht einen prinzipielle Vorteil, wenn ich die Klasse
    > mitgebe?


    Wenn du die Vorteile der OO-Programmierung verwenden willst, natürlich.
    Z.B. stehen jedem Plugin, welches von Slim::Plugin::Base abgeleitet ist,
    geerbte Methoden zur Verfügung, die du sonst selber implementieren müsstest.

    --

    Michael

  8. #8
    Senior Member
    Join Date
    Jan 2011
    Location
    Germany
    Posts
    226
    Quote Originally Posted by mherger View Post
    Du kannst eine solche
    Methode dann z.B. nicht mehr einfach als Callback verwenden, da dieser
    die Klasse nicht mit berüchsichtigen würde.
    Dann könnte ich die Funktion nicht mehr an den Time geben, oder?
    (Ich hab noch keine für mich verständliche Definition von Callback gefunden...)

    Quote Originally Posted by mherger View Post
    Wenn du die Vorteile der OO-Programmierung verwenden willst, natürlich.
    Z.B. stehen jedem Plugin, welches von Slim::Plugin::Base abgeleitet ist,
    geerbte Methoden zur Verfügung, die du sonst selber implementieren müsstest.
    Will ich nicht bewusst machen, mache es aber denke ich teilweise schon unbewisst, da ich von "Codebeispielen" lebe ;o)
    Allerdings ist verstehen manchmal auch nicht schlecht...
    LMS-7.9@solaris. 2x Radio, 2x Duet, 1x Chromecast v1, ShairTunes, 1x Philips Hue System

  9. #9
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    19,702

    =?utf-8?q?=C3=9Cbergabe_von_Argumenten_an_eine_Fu?==?utf-8?q?nktion_fir_von_Timer_aufgerufen_wird?=

    > Dann könnte ich die Funktion nicht mehr an den Time geben, oder?

    Genau.

    --

    Michael

  10. #10
    Senior Member
    Join Date
    Jan 2011
    Location
    Germany
    Posts
    226
    Super! Hat geklappt.

    Besten Dank.
    LMS-7.9@solaris. 2x Radio, 2x Duet, 1x Chromecast v1, ShairTunes, 1x Philips Hue System

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •