[Q] Hilfe gesucht: Loewe Connect ID DR+ Smart-TV mit FHEM steuern

Begonnen von der.einstein, 08 April 2017, 15:40:50

Vorheriges Thema - Nächstes Thema

der.einstein

#75
Hallo CoolTux,
also in Zeile 339 "LoeweTV_SendRequest($hash,"RequestAccess",0);" fehlt definitiv ein ";"  8)

Dann brauchen wir meiner Meinung nach beides: eine Variable für "status" (wo immer die dann gespeichert ist) und das Reading "state".

Außerdem sollten wir ein Define des TV mit NUR der IP zulassen, wenn wir die TVMAC über "GetDeviceData" bekommen wollen.

Hier der Output, den ich jetzt hatte ab "Define":

2017.09.12 20:22:34 3: LoeweTV LoeweTV: defined LoeweTV device
STARTING SENDREQUEST: GetDeviceData   
2017.09.12 20:22:39 2: Sub LoeweTV_PresenceRun (LoeweTV) - Response: HTTP::Response=HASH(0x40efbb8)->error_as_HTML
2017.09.12 20:22:39 2: Sub LoeweTV_PresenceRun (LoeweTV) - Response: HTTP::Response=HASH(0x40efbb8)->content


Also: Leider führt er den Code an der Stelle nicht aus, sondern macht ein "print" der $response. Hier müssen wir vermutlich mit "." Concatenation arbeiten? Kann mich aber auch irren  8)

Schade, dass du die anderen Funktionen wieder rausgeschmissen hast  ::) Aber da kommen wir schon noch hin  ;D

Mir ist außerdem Aufgefallen über Debugging mit "Data::Dumper::Simple", dass FHEM zwar die richtige $request absetzt und die richtige $response erhält, aber das Parsen nicht hinhaut. Daher habe ich mal des XML::Twig nochmal obenhin gestellt. Eventuell ist es auch ein Problem mit dem Scoping der Variablen? Aber da bin ich noch Anfänger und hab da erstmal keine Lösung gefunden.  :-\

@CoolTux: Kannst du mir auch bitte mal schreiben, wie bei dir jetzt die logische Abfolge der Funktionen ist bei unterschiedlichen Vorgängen? Danke.

Grüße!

CoolTux

Zitat
Außerdem sollten wir ein Define des TV mit NUR der IP zulassen, wenn wir die TVMAC über "GetDeviceData" bekommen wollen.

Wie genau meinst Du das? Man kann doch das Modul ohne Probleme anlegen wenn man nur die IP ein gibt. Bei mir meckert er zu mindest nicht


Zitat
@CoolTux: Kannst du mir auch bitte mal schreiben, wie bei dir jetzt die logische Abfolge der Funktionen ist bei unterschiedlichen Vorgängen? Danke.
Meinst jetzt bei mir im speziellen oder allgemein wie es im Modul werden soll? Denk dran ich habe keon Loewe TV ich mache das alles im Blindflug und so wirklich komme ich aktuell auch nicht weiter.
Aber vielleicht mal eine Beschreibung wie die ersten Schritte aussehen sollen.
Also define einer Modulinstanz durch Angabe der IP, dabei sollte der Fernsehr erreichbar sein und antworten (reicht es hier aus das er auf standby ist oder muss er richtig an sein), dann wird ein getdevicedata gemacht und wir fischen die MAC Adresse des TV aus der Antwort. Dann wird die DEF über $hash->{DEF} neu geschrieben, diesmal mit IP MAC. Das machen wir deswegen damit wie beim nächsten mal wenn FHEM neugestartet wird nicht wieder den Fernsehr an haben müssen um an die MAC zu kommen sondern dann haben wir die MAC fertig in der Konfig im define. Wenn wir das haben machen wir uns Gedanken um die weiteren Dinge. Immer Schritt für Schritt. Es sei denn Du hast eine bessere/schnellere funktionierende Lösung.
Wie schön erwähnt ist das schreiben eines einfachen Perl Scriptes was plump Schaltbefehle senden soll und das entwickeln eines FHEM Modules wo es um Kommunikationsaufbau und Interaktionsprozesse geht komplett unterschiedlich.


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

der.einstein

Sorry, es klappt mit nur der IP beim Anlegen/Define.

Der TV reagiert im Standby nicht auf Ping und nicht auf SOAP-Requests, AUSSER er wurde mit Wake-On-MAN aufgeweckt, dann kann ich am der Stelle InjectRCKey 22 senden, und er fährt richtig,hoch und zeigt das zuletzt gesehene Programm an.
D. h. er sollte richtig an sein beim Define.

Bzgl. der Readings hab ich noch ne Frage. Wenn es ums Anlegen eines Wertes/Textes geht, den ich zwar für das Funktionieren des Module brauche und zwischen den einzelnen Funktionen übergeben muss, und wenn dieser uninteressant für externe Module ist, und er nicht nach einem Neustart sofort verfügbar sein soll, dann kann der Wert doch in der $hash->{werr}? Oder sollte er dann in den $hash->{HELPER}?

Grüße

Gesendet von meinem LG-D855 mit Tapatalk


viegener

OK, habe die neue Version aus github geladen und das Semikolon ergänzt (und dann auch noch Data::Dumper::Simple installiert  ;)

Gute Nachricht - es geht etwas weiter / Schlechte Nachricht Es gibt immer noch reichlich logs und einen Crash:


2017.09.12 22:26:06 3: LoeweTV loewe: defined LoeweTV device
STARTING SENDREQUEST: GetDeviceData
2017.09.12 22:26:12 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x3cea318)->error_as_HTML
2017.09.12 22:26:12 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x3cea318)->content
2017.09.12 22:26:12 1: PERL WARNING: Use of uninitialized value in string eq at ./FHEM/82_LoeweTV.pm line 509.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 426.
STARTING SENDREQUEST:
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 434.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 439.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in hash element at ./FHEM/82_LoeweTV.pm line 447.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 453.
Unknown action:
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $content in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 457.
2017.09.12 22:26:23 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x489be70)->error_as_HTML
2017.09.12 22:26:23 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x489be70)->content
STARTING SENDREQUEST:
Unknown action:
2017.09.12 22:26:34 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x457ea58)->error_as_HTML
2017.09.12 22:26:34 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x457ea58)->content
2017.09.12 22:26:47 1: PERL WARNING: Use of uninitialized value in subroutine entry at ./FHEM/82_LoeweTV.pm line 318.
Bad arg length for Socket::pack_sockaddr_in, length is 0, should be 4 at /usr/lib/perl5/Socket.pm line 809.


Nach dem Define habe ich noch set mut und WakeUp etc ausprobiert

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

CoolTux

Zitat von: viegener am 12 September 2017, 22:36:56
OK, habe die neue Version aus github geladen und das Semikolon ergänzt (und dann auch noch Data::Dumper::Simple installiert  ;)

Gute Nachricht - es geht etwas weiter / Schlechte Nachricht Es gibt immer noch reichlich logs und einen Crash:


2017.09.12 22:26:06 3: LoeweTV loewe: defined LoeweTV device
STARTING SENDREQUEST: GetDeviceData
2017.09.12 22:26:12 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x3cea318)->error_as_HTML
2017.09.12 22:26:12 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x3cea318)->content
2017.09.12 22:26:12 1: PERL WARNING: Use of uninitialized value in string eq at ./FHEM/82_LoeweTV.pm line 509.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 426.
STARTING SENDREQUEST:
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 434.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 439.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in hash element at ./FHEM/82_LoeweTV.pm line 447.
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $action in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 453.
Unknown action:
2017.09.12 22:26:23 1: PERL WARNING: Use of uninitialized value $content in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 457.
2017.09.12 22:26:23 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x489be70)->error_as_HTML
2017.09.12 22:26:23 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x489be70)->content
STARTING SENDREQUEST:
Unknown action:
2017.09.12 22:26:34 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x457ea58)->error_as_HTML
2017.09.12 22:26:34 2: Sub LoeweTV_PresenceRun (loewe) - Response: HTTP::Response=HASH(0x457ea58)->content
2017.09.12 22:26:47 1: PERL WARNING: Use of uninitialized value in subroutine entry at ./FHEM/82_LoeweTV.pm line 318.
Bad arg length for Socket::pack_sockaddr_in, length is 0, should be 4 at /usr/lib/perl5/Socket.pm line 809.


Nach dem Define habe ich noch set mut und WakeUp etc ausprobiert

Bitte noch keine Set Befehle. So weit sind wir noch lange nicht. Wir sind erst beim define und beim erhalten der ersten Informationen nach einer ersten Kontaktaufnahme.
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: der.einstein am 12 September 2017, 22:25:43
Sorry, es klappt mit nur der IP beim Anlegen/Define.

Der TV reagiert im Standby nicht auf Ping und nicht auf SOAP-Requests, AUSSER er wurde mit Wake-On-MAN aufgeweckt, dann kann ich am der Stelle InjectRCKey 22 senden, und er fährt richtig,hoch und zeigt das zuletzt gesehene Programm an.
D. h. er sollte richtig an sein beim Define.

Bzgl. der Readings hab ich noch ne Frage. Wenn es ums Anlegen eines Wertes/Textes geht, den ich zwar für das Funktionieren des Module brauche und zwischen den einzelnen Funktionen übergeben muss, und wenn dieser uninteressant für externe Module ist, und er nicht nach einem Neustart sofort verfügbar sein soll, dann kann der Wert doch in der $hash->{werr}? Oder sollte er dann in den $hash->{HELPER}?

Grüße

Gesendet von meinem LG-D855 mit Tapatalk
Wenn Du einen Wert hast den Du ständig zum abgleichen benötigst, und zwar nicht nur bei einer Ausführung sondern permanent dann legst Du ihn entweder sichtbar als Internal ab das wäre dann $hash->{INTERNALNAME}. Oder aber unter $hash->{helper}{Name} also in helper. Ins Internal lohnt sich nur wenn es etwas ist was auch mal so von Interesse ist. An sonsten helper.
Sowas wie du ab fragen willst, also so eine Art Zwischenstatus macht man am besten in den helper.
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

viegener

Ich hab mal ein bisschen weitergeschaut:

- Ich denke es wäre hilfreich Requestmessage und Response zu Dumpen (per Dumper-Aufruf)
- Im Request fehlt soweit ich das erkennen kann ein "<?xml version='1.0' encoding='UTF-8'?>"
- In meinen Versuchen habe ich noch einen SOAPAction - Header im http-header gesehen (weiss aber nicht ob der zwingend ist (im API ist er so nicht beschrieben)

Ich konnte aber bisher keinen erfolgreichen "GetDeviceData" Request sehen -
@der.einstein: klappt das bei Dir ?


Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

der.einstein

#82
So Jungs, einen ersten Erfolg haben wir: der GetDeviceData Call funktioniert und extrahiert erfolgreich die TVMAC!
Ich hab jetzt allerdings einen RequestAccess Call vorgeschalten. Dieser extrahiert erfolgreich eine ClientId

@viegener: habe das Dumping nun so hinbekommen, dass es sinnvollen output im Log geben sollte

Hier der Code, nach meinen Modifizierungen:

package main;

use strict;
use warnings;

use Data::Dumper::Simple;    # Kann später entfernt werden, nur zum Debuggen


my $missingModul = "";
eval "use LWP::UserAgent;1" or $missingModul .= "LWP::UserAgent ";
eval "use HTTP::Request::Common;1" or $missingModul .= "HTTP::Request::Common ";
eval "use XML::Twig;1" or $missingModul .= "XML::Twig ";

use Blocking;


my $version = "0.0.26";


# Declare functions
sub LoeweTV_Define($$);
sub LoeweTV_Undef($$);
sub LoeweTV_Initialize($);
sub LoeweTV_Get($@);
sub LoeweTV_Set($@);
sub LoeweTV_WakeUp_Udp($@);
sub LoeweTV_CheckAccess($$$);
sub LoeweTV_SendRequest($$$);
sub LoeweTV_ResponseProcessing($$$);
sub LoeweTV_WriteReadings($$);
sub LoeweTV_Presence($);
sub LoeweTV_PresenceRun($);
sub LoeweTV_PresenceDone($);
sub LoeweTV_PresenceAborted($);




sub LoeweTV_Initialize($) {
    my ($hash) = @_;
   
    #$hash->{GetFn}      = "LoeweTV_Get";
    $hash->{SetFn}      = "LoeweTV_Set";
    $hash->{DefFn}      = "LoeweTV_Define";
    $hash->{UndefFn}    = "LoeweTV_Undef";

    $hash->{AttrList}   =  "fhemMAC " .
                        "interval " .
                        #"ip " .
                        #"tvmac " .
                        #"action " .
                        #"RCkey " .
                        #"clientid " .
                        #"fcid " .
                        "status:Accepted,Pending,Denied,undef " .
                        #"connectsuccess:true,false " .
                        #"pingresult:down,up " .
                        #"lastersponse " .
                        #"lastchunk " .
                        #"volstate " .
                        #"mutstate:0,1 " .
                        #"curlocator " .
                        #"curevent " .
                        #"nextevent " .
                        $readingFnAttributes;
                         
    foreach my $d(sort keys %{$modules{LoeweTV}{defptr}}) {
   
        my $hash = $modules{LoeweTV}{defptr}{$d};
        $hash->{VERSION}      = $version;
    }
}

sub LoeweTV_Define($$) {

    my ( $hash, $def )  = @_;
   
    my @a               = split( "[ \t][ \t]*", $def );


    return "too few parameters: define <NAME> LoeweTV <HOST> <MAC-TV>" if( @a < 2 or @a > 4 );
    return "Cannot define Loewe device. Perl modul ${missingModul}is missing." if ( $missingModul );

   
   
   
    my $name            = $hash->{NAME};
    my $host            = $a[2];
   
    $hash->{HOST}       = $host;
    $hash->{FCID}       = 1234;
    $hash->{TVMAC}      = $a[3] if(defined($a[3]));
    $hash->{TVMAC} = undef if(!defined($a[3]));
    $hash->{VERSION}    = $version;
    $hash->{INTERVAL}   = 15;
    $hash->{CLIENTID}   = "?";
    $hash->{status} = "Denied";
    $hash->{lastresponse} = "";
    $hash->{lastchunk} = "";
    $hash->{lastrequest} = "";
    $hash->{Chassis} = "";
    $hash->{SW_Version} = "";

    Log3 $name, 3, "LoeweTV $name: defined LoeweTV device";
   
    $modules{LoeweTV}{defptr}{HOST} = $hash;
    readingsSingleUpdate($hash,'state','initialized',1);
   
    LoeweTV_Presence($hash);
   
   
    if( $init_done ) {
        LoeweTV_Presence($hash);
        InternalTimer( gettimeofday()+5, "LoeweTV_FirstRun", $hash, 0 );
    } else {
        InternalTimer( gettimeofday()+15, "LoeweTV_Presence", $hash, 0 );
        InternalTimer( gettimeofday()+20, "LoeweTV_FirstRun", $hash, 0 );
    }

    #if(ReadingsVal($name,'presence','absent') eq 'present') {
    #}

    return undef;
}

sub LoeweTV_Undef($$) {

    my ( $hash, $arg ) = @_;


    #RemoveInternalTimer($hash);
    delete $modules{LoeweTV}{defptr}{HOST} if( defined($modules{LoeweTV}{defptr}{HOST}) );

    return undef;
}

sub LoeweTV_Attr(@) {

    my ( $cmd, $name, $attrName, $attrVal ) = @_;
    my $hash = $defs{$name};
   
    my $orig = $attrVal;

   
    if( $attrName eq "disable" ) {
        if( $cmd eq "set" and $attrVal eq "1" ) {
            readingsSingleUpdate ( $hash, "state", "disabled", 1 );
            $hash->{PARTIAL} = '';
            Log3 $name, 3, "LoeweTV ($name) - disabled";
        }

        elsif( $cmd eq "del" ) {
            readingsSingleUpdate ( $hash, "state", "active", 1 );
            Log3 $name, 3, "LoeweTV ($name) - enabled";
        }
    }
   
    elsif( $attrName eq "disabledForIntervals" ) {
        if( $cmd eq "set" ) {
            Log3 $name, 3, "LoeweTV ($name) - enable disabledForIntervals";
            readingsSingleUpdate ( $hash, "state", "Unknown", 1 );
        }

        elsif( $cmd eq "del" ) {
            readingsSingleUpdate ( $hash, "state", "active", 1 );
            Log3 $name, 3, "LoeweTV ($name) - delete disabledForIntervals";
        }
    }
   
    elsif( $attrName eq "interval" ) {
        if( $cmd eq "set" ) {
            $hash->{INTERVAL}   = $attrVal;
            RemoveInternalTimer($hash);
            Log3 $name, 3, "LoeweTV ($name) - set interval: $attrVal";
            LoeweTV_InternalTimerGetDeviceData($hash);
        }

        elsif( $cmd eq "del" ) {
            $hash->{INTERVAL}   = 15;
            RemoveInternalTimer($hash);
            Log3 $name, 3, "LoeweTV ($name) - delete User interval and set default: 300";
            LoeweTV_InternalTimerGetDeviceData($hash);
        }
    }

    return undef;
}

sub LoeweTV_FirstRun($) {

    my $hash        = shift;
    my $name        = $hash->{NAME};
   
    if(ReadingsVal($name,'presence','absent') eq 'present') {
        LoeweTV_CheckAccess($hash,$hash->{CLIENTID},$hash->{FCID});
        LoeweTV_SendRequest($hash,'GetDeviceData',0);
    } else {
        readingsSingleUpdate($hash,'state','off',1);
    }
   
    InternalTimer( gettimeofday()+10, "LoeweTV_TimerStatusRequest", $hash, 1 );
}

sub LoeweTV_Set($@) {
   
    my ($hash, $name, $cmd, @args) = @_;
    my ($arg, @params) = @args;
   
    my ($action,$RCkey);

   
    if( lc $cmd eq 'setactionfield' ) {

    } elsif( lc $cmd eq 'setvolume' ) {
   
    } elsif( lc $cmd eq 'setmute' ) {
   
    } elsif( lc $cmd eq 'connect' ) { LoeweTV_SendRequest($hash, "RequestAccess", 0)
   
    } elsif( lc $cmd eq 'wakeup' ) {
   
        LoeweTV_WakeUp_Udp($hash,$hash->{HOST},$hash->{TVMAC});
        return;
   
    } elsif( lc $cmd eq '' ) {
   
   
    } elsif( lc $cmd eq '' ) {
   
   
    } else {
   
        my $list    = 'SetActionField SetVolume:slider,0,1,100 SetMute:on,off connect:noArg WakeUp:noArg';
       
        return "Unknown argument $cmd, choose one of $list";
    }
   
   
#     $hash->{helper}{RCkey} = "" if( not defined $hash->{helper}{RCkey} );
#     
#     $hash->{helper}{fcid} = "1234" if( not defined $hash->{helper}{fcid} );
#     
#     LoeweTV_hostUp($hash);
#
#     
#     if (! defined $hash->{CLIENTID}){$hash->{CLIENTID} = "?"};
#     
#     LoeweTV_CheckAccess($hash,$hash->{CLIENTID},$hash->{FCID});
#     
#     if ($hash->{status} eq "accepted") {LoeweTV_SendRequest($hash,$action,$RCkey);}
   
   
   
    LoeweTV_SendRequest($hash,$action,$RCkey) if(ReadingsVal($name,'presence','absent') eq 'present');
   
   
    Log3 $name, 5, "LoeweTV $name: called function LoeweTV_Set()";
    return undef;
}

sub LoeweTV_TimerStatusRequest($) {

### Hier kommen dann die Sachen rein welche alle x Sekunden ausfegührt werden um Infos zu erhalten
### presence zum Beispiel





}

# method to wake via lan, taken from Net::Wake package
sub LoeweTV_WakeUp_Udp($@) {

    my ($hash,$mac_addr,$host,$port) = @_;
    my $name  = $hash->{NAME};

    # use the discard service if $port not passed in
    if (!defined $port || $port !~ /^\d+$/ ) { $port = 9 }

    my $sock = new IO::Socket::INET(Proto=>'udp') or die "socket : $!";
    if(!$sock) {
        Log3 $name, 3, "LoeweTV ($name) - Can't create WOL socket";
        return 1;
    }
 
    my $ip_addr   = inet_aton($host);
    my $sock_addr = sockaddr_in($port, $ip_addr);
    $mac_addr     =~ s/://g;
    my $packet    = pack('C6H*', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, $mac_addr x 16);

    setsockopt($sock, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt : $!";
    send($sock, $packet, 0, $sock_addr) or die "send : $!";
    close ($sock);

    return 1;
}

sub LoeweTV_CheckAccess($$$) {

    my ( $hash, $clientid, $fcid ) = @_;
    #my ($hash)      = shift;
    my $name        = $hash->{NAME};
    my $n           = 1;
   
   
    while (($hash->{status} ne "Accepted") and ($n<=3)) {
   
        $n=$n+1;
        LoeweTV_SendRequest($hash,"RequestAccess",0);
    };

print "run CHECKACCESS: ".ReadingsVal($name,'state','denied')."   \n";
   
   
    return(ReadingsVal($name,'state','denied'));
   
   
    }

sub LoeweTV_SendRequest($$$) {

    my($hash, $action, $RCkey)  = @_;
   
    my $name                    = $hash->{NAME};

    my ($message, $response, $request, $userAgent, $noob, $twig2, $content, $handlers);
    our $result ="";
    my %actions = (
        "RequestAccess"         =>  [sub {$content='<ltv:DeviceType>Apple iPad</ltv:DeviceType>
                                        <ltv:DeviceName>FHEM</ltv:DeviceName>
                                        <ltv:DeviceUUID>'.$hash->{TVMAC}.'</ltv:DeviceUUID>
                                        <ltv:RequesterName>Assist Media App</ltv:RequesterName>'},
                                        {'m:ClientId' => sub {$hash->{CLIENTID} = $_->text_only('m:ClientId')},
                                        'm:AccessStatus' => sub {$hash->{status} = $_->text_only('m:AccessStatus');},}
                                    ],
                                   
        "InjectRCKey"           =>  [sub {$content='<InputEventSequence>
                                        <RCKeyEvent alphabet="l2700" value="'.$RCkey.'" mode="press"/>
                                        <RCKeyEvent alphabet="l2700" value="'.$RCkey.'" mode="release"/>
                                        </InputEventSequence>'},{"ltv:InjectRCKey" => sub {$hash->{helper}{lastchunk} = $_->text_only();}},],
                                       
        "GetDeviceData"         =>  [sub {$content='';},{"m:MAC-Address" => sub {$hash->{TVMAC} = $_->text("m:MAC-Address");},"m:Chassis" => sub {$hash->{Chassis} = $_->text("m:Chassis");},"m:SW-Version" => sub {$hash->{SW_Version} = $_->text("m:SW-Version");}}],
           
        "GetChannelList"        =>  [sub {$content="<ltv:ChannelListView>".$RCkey."</ltv:ChannelListView>
                                        <ltv:QueryParameters>
                                        <ltv:Range startIndex='".$ARGV[4]."' maxItems='9999'/>
                                        <ltv:OrderField field='userChannelNumber' type='ascending'/>
                                        </ltv:QueryParameters>";$result="m:GetChannelListResponse"}
                                    ],
                                       
        "GetListOfChannelLists" =>  [sub {$content="<ltv:QueryParameters>
                                        <ltv:Range startIndex='".$RCkey."' maxItems='9999'/>
                                        <ltv:OrderField field='userChannelNumber' type='ascending'/>
                                        </ltv:QueryParameters>";$result="m:ResultItemChannelLists"}
                                    ],
                                       
        "GetMediaItem"          =>  [sub {$content='<MediaItemReference mediaItemUuid="'.$RCkey.'"/>';$result="m:ShortInfo"}],
           
        "GetMediaEvent"         =>  [sub {$content='<MediaEventReference mediaEventUuid="'.$RCkey.'"/>';$result="m:ShortInfo"}],
           
        "GetChannelInfo"        =>  [sub {$content=""}],
           
        "GetCurrentPlayback"    =>  [sub {$content='';},
                                        {"m:Locator" => sub {$hash->{helper}{lastchunk} = $_->text_only();},}
                                    ],
                                       
        "GetCurrentEvent"       =>  [sub {$content="<ltv:Player>0</ltv:Player>";},
                                        {"m:Name" => sub {$hash->{curevent}[0] = $_->text("m:Name");},
                                        "m:ExtendedInfo" => sub {$hash->{curevent}[1] = $_->text("m:ExtendenInfo");},
                                        "m:Locator" => sub {$hash->{curlocator} = $_->text_only("m:Locator");}},
                                    ],
                                       
        "GetNextEvent"          => [sub {$content="<ltv:Player>0</ltv:Player>";$result="m:GetNextEventResponse"}],
           
        "SetActionField"        => [sub {$content="<ltv:InputText>".$RCkey."</ltv:InputText>";$result="m:Result"}],
           
        "SetVolume"             => [sub {$content="<Value>".$RCkey."</Value>";$result="m:Value"}],
           
        "GetVolume"             => [sub {$content="";$result="m:Value"}],
           
        "SetMute"               => [sub {$content="<Value>".$RCkey."</Value>";$result="m:Value"}],
           
        "GetMute"               => [sub {$content="";$result="m:Value"}],
           
        "GetDRPlusArchive"      => [sub {$content="<ltv:QueryParameters>
                                        <ltv:Range startIndex='".$RCkey."' maxItems='1000'/>
                                        <ltv:OrderField field='userChannelNumber' type='ascending'/>
                                        </ltv:QueryParameters>";$result="ltv:ResultItemDRPlusFragment"}
                                    ],
    );

   
    print "STARTING SENDREQUEST: $action with $RCkey   \n";
   
    #$action = "GetDeviceData" if( ! defined($action));
   
    my $header = "<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ltv='urn:loewe.de:RemoteTV:Tablet'><env:Body>";
   
    my $action_xml1 = "<ltv:$action>";
   
    my $header2 = "<ltv:fcid>".$hash->{FCID}."</ltv:fcid><ltv:ClientId>".$hash->{CLIENTID}."</ltv:ClientId>";

    my $action_xml2 = "</ltv:$action>";
   
    my $footer = "</env:Body></env:Envelope>";
   
   



    if ($actions{$action}[0]) {
   
        $actions{$action}[0]->();
        $handlers=$actions{$action}[1];
   
    } else {
        print "Unknown action: $action\n";
    };

    # Aufbau der Messages
    $message = $header.$action_xml1.$header2.$content.$action_xml2.$footer;
    print Dumper $message;
   
    # Aufbau der HTTP Verbindung
    $request = HTTP::Request->new(POST => 'http://'.$hash->{HOST}.':905/loewe_tablet_0001');
   
    # Aufbau des Agents
    $userAgent = LWP::UserAgent->new(agent => 'Assist Media/23 CFNetwork/808 Darwin/16.0.0');
   
    # Aufbau des Headers
    $request->header('Accept' => '*/*');
    $request->header('Accept-Encoding' => 'gzip, deflate');
    $request->header('Accept-Language' => 'de-de');
    $request->header('Connection' => 'keep-alive');
   
    $request->header('SOAPAction' => $action);
   
    # !!!
    $request->content_type("application/soap+xml; charset=utf-8");
   
    # ???
    $request->content($message);
    $response = $userAgent->request($request);
   
    $hash->{lastrequest} = $request->content;
   
    $noob = $response->content;
    #print Dumper $response;
    print "\n";
    print Dumper $noob;
    $twig2 = XML::Twig->new(twig_handlers => $handlers,keep_encoding => 1)->parse($noob);
   
   
    LoeweTV_ResponseProcessing($hash,$action,$response);
}
   
   
sub LoeweTV_ResponseProcessing($$$) {
   
    my ($hash,$action,$response)        = @_;
   
    my $name                    = $hash->{NAME};
   
    Log3 $name, 2, "Sub LoeweTV_PresenceRun ($name) - Response: $response->error_as_HTML";
    Log3 $name, 2, "Sub LoeweTV_PresenceRun ($name) - Response: $response->content";
   
    if($response->code == 200) {
        $hash->{connectsuccess} = "true";
        $hash->{lastresponse} = $response->content;
   
    } else {
        $hash->{connectsuccess} = "false";
        $hash->{lastresponse} = $response->error_as_HTML;
    }
   
    if($action eq "RequestAccess"){
        return($hash->{status})
    }else{
        return($hash->{status})
    };
}

sub LoeweTV_WriteReadings($$) {




}

############ Presence Erkennung Begin #################
sub LoeweTV_Presence($) {

    my $hash    = shift;   
    my $name    = $hash->{NAME};
   
   
    $hash->{helper}{RUNNING_PID} = BlockingCall("LoeweTV_PresenceRun", $name.'|'.$hash->{HOST}, "LoeweTV_PresenceDone", 5, "LoeweTV_PresenceAborted", $hash) unless(exists($hash->{helper}{RUNNING_PID}) );
}

sub LoeweTV_PresenceRun($) {

    my $string          = shift;
    my ($name, $host)   = split("\\|", $string);
   
    my $tmp;
    my $response;

   
    $tmp = qx(ping -c 3 -w 2 $host 2>&1);

    if(defined($tmp) and $tmp ne "") {
   
        chomp $tmp;
        Log3 $name, 5, "LoeweTV ($name) - ping command returned with output:\n$tmp";
        $response = "$name|".(($tmp =~ /\d+ [Bb]ytes (from|von)/ and not $tmp =~ /[Uu]nreachable/) ? "present" : "absent");
   
    } else {
   
        $response = "$name|Could not execute ping command";
    }
   
    Log3 $name, 4, "Sub LoeweTV_PresenceRun ($name) - Sub finish, Call LoeweTV_PresenceDone";
    return $response;
}

sub LoeweTV_PresenceDone($) {

    my ($string)            = @_;
   
    my ($name,$response)    = split("\\|",$string);
    my $hash                = $defs{$name};
   
   
    delete($hash->{helper}{RUNNING_PID});
   
    Log3 $name, 4, "Sub LoeweTV_PresenceDone ($name) - Der Helper ist disabled. Daher wird hier abgebrochen" if($hash->{helper}{DISABLED});
    return if($hash->{helper}{DISABLED});
   
    readingsSingleUpdate($hash,'presence',$response,1);
   
    Log3 $name, 4, "Sub LoeweTV_PresenceDone ($name) - Abschluss!";
}

sub LoeweTV_PresenceAborted($) {

    my ($hash)  = @_;
    my $name    = $hash->{NAME};

   
    delete($hash->{helper}{RUNNING_PID});
    readingsSingleUpdate($hash,'presence','timedout', 1);
   
    Log3 $name, 4, "Sub LoeweTV_PresenceAborted ($name) - The BlockingCall Process terminated unexpectedly. Timedout!";
}

####### Presence Erkennung Ende ############








1;


=pod
=item device
=item summary control for Loewe TV devices via network connection
=item summary_DE Steuerung von Loewe TV Ger&auml;ten &uuml;ber das Netzwerk
=begin html

<a name="LoeweTV"></a>
<h3>LoeweTV</h3>

=end html

=begin html_DE

<a name="LoeweTV"></a>
<h3>LoeweTV</h3>

=end html_DE

=cut


Und hier der Eintrag in FHEM:

CFGFN
   
CLIENTID
   
LRemoteClient-1-1505330745
Chassis
   
SL220
DEF    
192.168.0.2
FCID
   
1234
HOST
   
192.168.0.2
INTERVAL
   
15
NAME
   
LoeweTV
NR
   
87
STATE
   
initialized
SW_Version
   
2.4.55.0
TVMAC
   
00:09:82:19:ab:58
TYPE
   
LoeweTV
VERSION
   
0.0.26
connectsuccess
   
true
lastchunk
   
lastrequest
   
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ltv='urn:loewe.de:RemoteTV:Tablet'><env:Body><ltv:GetDeviceData><ltv:fcid>1234</ltv:fcid><ltv:ClientId>LRemoteClient-1-1505330745</ltv:ClientId></ltv:GetDeviceData></env:Body></env:Envelope>
lastresponse
   
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <m:GetDeviceDataResponse xmlns:m="urn:loewe.de:RemoteTV:Tablet"> <m:fcid>1234</m:fcid><m:ClientId>LRemoteClient-1-1505330745</m:ClientId><m:Chassis>SL220</m:Chassis><m:SW-Version>2.4.55.0</m:SW-Version><m:MAC-Address>00:09:82:19:ab:58</m:MAC-Address><m:MAC-Address-LAN>00:09:82:19:ab:58</m:MAC-Address-LAN><m:MAC-Address-WLAN>f8:35:dd:97:9b:5a</m:MAC-Address-WLAN><m:Location>Germany</m:Location></m:GetDeviceDataResponse> </SOAP-ENV:Body></SOAP-ENV:Envelope>
status
   
Accepted

viegener

@der.einstein: Ja - hab mir Deine Änderungen angeschaut - das Problem ist, dass GetDeviceData wohl entgegen der API-Beschreibung wohl nur mit Client-ID geht (auch leer habe ich probiert)

@Cooltux: Das mit der SoapAction war ja bereits drin, das hatte ich wohl übersehen

@CoolTux: Ich habe meine Änderungen mal als pull request in Dein git repository gestellt

In der Version funktioniert GetDeviceData und CheckAccess bei mir grundsätzlich
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

CoolTux

Zitat von: viegener am 13 September 2017, 22:53:25
@der.einstein: Ja - hab mir Deine Änderungen angeschaut - das Problem ist, dass GetDeviceData wohl entgegen der API-Beschreibung wohl nur mit Client-ID geht (auch leer habe ich probiert)

@Cooltux: Das mit der SoapAction war ja bereits drin, das hatte ich wohl übersehen

@CoolTux: Ich habe meine Änderungen mal als pull request in Dein git repository gestellt

In der Version funktioniert GetDeviceData und CheckAccess bei mir grundsätzlich

Guten Morgen,

Vielen Dank, ich habe es so übernommen.

@der.einstein
Ich habe immer noch Schwierigkeiten das ganze Konstrukt zu verstehen. Aber ich habe da eine Befürchtung, helft mir mal beide bitte.

"GetDeviceData"         =>  [sub {$content='';},{"m:MAC-Address" => sub {$hash->{TVMAC} = $_->text("m:MAC-Address");},"m:Chassis" => sub {$hash->{Chassis} = $_->text("m:Chassis");},"m:SW-Version" => sub {$hash->{SW_Version} = $_->text("m:SW-Version");}}],


Verstehe ich das richtig? Diese Zeile dient nicht nur zum erstellen einer Anfrage zum Fernsehr hin, sondern ist in Verbindung mit dieser anonymen Subroutine gleich noch die Auswertung? Wenn ja würde dieser Satz von Dir dann auch für mich Sinn ergeben
Zitat
In dem Teil für "GetCurrentEvent" siehst du, wie mehrere Infos aus dem Response extrahiert werden können: Titel, Inhalt, Locator. Diese kann man an der Stelle in jede beliebige Perl-Datenstruktur schieben -> Frage ist, wo du sie haben möchtest.
In meinen Augen wäre das seltsam und unflexible. Wüsste jetzt nicht wie ich da das schreiben der Readings und/oder das neusetzen der DEF unterbringen sollte.


Zitat
Und hier der Eintrag in FHEM:

CFGFN
   
CLIENTID
   
LRemoteClient-1-1505330745
Chassis
   
SL220
DEF   
192.168.0.2
FCID
   
1234
HOST
   
192.168.0.2
INTERVAL
   
15
NAME
   
LoeweTV
NR
   
87
STATE
   
initialized
SW_Version
   
2.4.55.0
TVMAC
   
00:09:82:19:ab:58
TYPE
   
LoeweTV
VERSION
   
0.0.26
connectsuccess
   
true
lastchunk
   
lastrequest


Hier gehören einige Angaben in Readings.
Zitat
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <m:GetDeviceDataResponse xmlns:m="urn:loewe.de:RemoteTV:Tablet"> <m:fcid>1234</m:fcid><m:ClientId>LRemoteClient-1-1505330745</m:ClientId><m:Chassis>SL220</m:Chassis><m:SW-Version>2.4.55.0</m:SW-Version><m:MAC-Address>00:09:82:19:ab:58</m:MAC-Address><m:MAC-Address-LAN>00:09:82:19:ab:58</m:MAC-Address-LAN><m:MAC-Address-WLAN>f8:35:dd:97:9b:5a</m:MAC-Address-WLAN><m:Location>Germany</m:Location></m:GetDeviceDataResponse> </SOAP-ENV:Body></SOAP-ENV:Envelope>

In die Internals kommen aus diesen Informationen lediglich die MAC welche ausserdem mittels $hash->{DEF} noch zusätzlich mit in die DEF kommt sowie die ClientId. Alle anderen Infos müssen in Readings geschrieben werden.
Noch eine Frage zu der MAC, ich sehe hier zwei, einmal WLan und einmal LAN. Ist es egal welche man nimmt? sicherlich nicht. Wie erkennt man ob der Fernsehr über LAN oder WLAN mit FHEM verbunden ist so das wir automatisch die richtige eintragen können?
Wenn man das nicht kann, schlage ich vor beide MAC's erstmal in Readings zu schreiben und dann über die get Funktion ein Auswahlmenü mit den MAC Adressen und der Anbindungsform an zu bieten wo der User dann Anklicken muß wie er eigebunden ist. Danach erst wird $hash->{MAC} gesetzt und $hash->{DEF} neu geschrieben.

Was sagt Ihr dazu?



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

viegener

Über das Konstrukt im SendRequest bin ich auch gestolpert. Ja es dient zum Erstellen der Anfrage und Analysieren der Antwort. Kommt sehr elegant daher, finde ich aber persönlich schwer zu warten (es kommen manchmal die berühmten fehlermeldungen mit eval at line 5 - wo ist bitte zeile 5 in dem Konstrukt  ;) ). Und ich stimme zu - für die Handhabung von Readings etc ist das jetzt nicht optimal.

Den Vorschlga mit den MACs finde ich gut - aus meiner Sicht würde ich die MAC sogar aus der DEF heraushalten, denn diese ist ja vom Device zu ermitteln und MAC-Addressen sind nicht das was jeder eintippen will.

Ich denke was man berücktichtigen sollte, ist dass für die meisten Aufrufe eine gültige ClientID erforderlich ist. Diese ist aber nur begrenzt haltbar, deshalb habe ich in einem anderen Modul eine Art queuing eingerichtet. Wenn ein Request mit der Fehlermeldung client id nicht gültig zurückkommt wird einfach ein requestAccess gequeued und dann derselbe aufruf auch in die Queue geschrieben.

Wenn ich das richtig verstehe sind die jetzigen Aufrufe zum Fernseher blocking? Wenn ja dann müsste das vermutlich geändert werden, da ie Queue ist verrmutlich auch notwendig, weil die Aufrufe zum Teil Zeit benötigen und bei Fehlern auch in Timeouts laufen könnten. Dann wäre auch ein Queuing erforderlich, damit immer nur ein Request zum Fernseher geht, selbst wenn jeman den nächsten Request schon absetzt.

Das Queuing ist auch ganz simpel:

- Die Parameter eines Requests werden in der Queue abgelegt - z.B. als Hash oder Array
- Wenn ein Request abgesetzt wird, wird ein Status intern im Modul gesetzt - working
- Sollte ein neuer Request kommen wird dieser einfach in die Queue gestellt - fertig
- Am ende des Requests wird der interne Status einfach wieder auf - idle gesetzt
- Im Fehlerfall lässt sich dann auch ein retry abhandeln

Wie gesagt die Behandlung sollte sowieso non-blocking / asynchron werden
Vorraussetzung ist allerdings, dass man alles was später zur Behandlung der Antwort braucht auch in der Queue im Parameterhash steht

Ich kann da gerne auch beitragen, allerdings wäre wohl eine Umstellung auf httpUtils Vorraussetzung


Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

der.einstein

#86
Zitat von: CoolTux am 14 September 2017, 06:54:13
Guten Morgen,

Vielen Dank, ich habe es so übernommen.

@der.einstein
Ich habe immer noch Schwierigkeiten das ganze Konstrukt zu verstehen. Aber ich habe da eine Befürchtung, helft mir mal beide bitte.

"GetDeviceData"         =>  [sub {$content='';},{"m:MAC-Address" => sub {$hash->{TVMAC} = $_->text("m:MAC-Address");},"m:Chassis" => sub {$hash->{Chassis} = $_->text("m:Chassis");},"m:SW-Version" => sub {$hash->{SW_Version} = $_->text("m:SW-Version");}}],


Verstehe ich das richtig? Diese Zeile dient nicht nur zum erstellen einer Anfrage zum Fernsehr hin, sondern ist in Verbindung mit dieser anonymen Subroutine gleich noch die Auswertung? Wenn ja würde dieser Satz von Dir dann auch für mich Sinn ergebenIn meinen Augen wäre das seltsam und unflexible. Wüsste jetzt nicht wie ich da das schreiben der Readings und/oder das neusetzen der DEF unterbringen sollte.



Hier gehören einige Angaben in Readings.
In die Internals kommen aus diesen Informationen lediglich die MAC welche ausserdem mittels $hash->{DEF} noch zusätzlich mit in die DEF kommt sowie die ClientId. Alle anderen Infos müssen in Readings geschrieben werden.
Noch eine Frage zu der MAC, ich sehe hier zwei, einmal WLan und einmal LAN. Ist es egal welche man nimmt? sicherlich nicht. Wie erkennt man ob der Fernsehr über LAN oder WLAN mit FHEM verbunden ist so das wir automatisch die richtige eintragen können?
Wenn man das nicht kann, schlage ich vor beide MAC's erstmal in Readings zu schreiben und dann über die get Funktion ein Auswahlmenü mit den MAC Adressen und der Anbindungsform an zu bieten wo der User dann Anklicken muß wie er eigebunden ist. Danach erst wird $hash->{MAC} gesetzt und $hash->{DEF} neu geschrieben.

Was sagt Ihr dazu?



Grüße
Das hatte ich ja versucht dir zu sagen: Request zusammenbauen und Konstruktion des Parsers werden im Hash %actions definiert. Der Vorteil daraus ist, es gibt nur die eine Stelle im Modul, an der ich da was ändern müsste. Der Nachteil ist,  dass es eventuell erstmal ungewöhnlich ist, aber meiner Meinung nach nutzt es Perl sehr gut aus. Daraus erklärt sich auch mein weiterer Vorschlag von weiter oben: für jede definierte Request nicht nur Code angeben der vor dem Request auszuführen ist, sondern auch danach, also "$actions{$action}[2]". Schreiben von Readings und Ändern der DEF sollten damit kein Problem sein.
Ich habe die Art und Weise, wie das geschrieben ist, von den Beispielen zu XML::Twig entlehnt.

Zu dem Problem mit den MACs des TV habe ich es so verstanden dass in dem XML-Feld, dass wir jetzt abfragen, die aktuell relevante Addresse steht. Bei mir ist der TV über LAN im Netz, daher steht dort diese. Wäre er über WLAN im Netz, stünde in dem Feld die andere Addresse. Also sollte es ausreichen, das 1 Feld abzufragen?

@viegener: über HttpUtils könnten wir maximal die Requests absetzen, aber die Responses müssen mit einem speziell für XML gedachten Paket bearbeitet werden, da sollten wir nicht das Rad neu erfinden.
Das mit dem Queuing finde ich interessant. Bei mir hatte bisher aber ausgereicht, vor dem Absetzen eines Request einfach den AccessStatus abzufragen und ggf. die aktuelle ClientId zu verlängern/bestätigen. Ich kann mir aber vorstellen, dass man mit Queuing komplexere Situationen handeln kann.

Gesendet von meinem LG-D855 mit Tapatalk

CoolTux

Zitat von: viegener am 14 September 2017, 10:55:01
Über das Konstrukt im SendRequest bin ich auch gestolpert. Ja es dient zum Erstellen der Anfrage und Analysieren der Antwort. Kommt sehr elegant daher, finde ich aber persönlich schwer zu warten (es kommen manchmal die berühmten fehlermeldungen mit eval at line 5 - wo ist bitte zeile 5 in dem Konstrukt  ;) ). Und ich stimme zu - für die Handhabung von Readings etc ist das jetzt nicht optimal.
Mag elegant sein für unsere Anforderungen ist es aber verkehrt/kacke. Kenne mich leider damit auch nicht so aus.
Das werden wir sicherlich Ändern müssen.

Zitat
Den Vorschlga mit den MACs finde ich gut - aus meiner Sicht würde ich die MAC sogar aus der DEF heraushalten, denn diese ist ja vom Device zu ermitteln und MAC-Addressen sind nicht das was jeder eintippen will.
Kleines Verständnis Problem glaube. Keiner soll hier ne MAC eintippen. Das aller erste Define welches vom User kommt wird lediglich die Host IP beinhalten als Option
define myTV LoeweTV 192.168.1.1
Sobald der define Befehl ausgeführt wurde wird ein der getDeviceData Befehl ausgeführt und somit die MAC ausgelesen. Nun kommt es drauf an, wäre es nur eine MAC hätte ich in der Auswertung einfach die DEF über den Hash neu geschrieben damit in der Konfig beim define nun die MAC mit dran steht. Würde also in der Konfig dann drin stehen
define myTV LoeweTV 192.168.1.1 00:09:82:19:ab:58
somit kann man dann das bei späteren FHEM Starts ausklammern und muß nicht neu ermitteln. Nur so eine Idee.
Noch logischer kommt es ja daher wenn wir darauf achten müssen welche MAC benutzt wird. So muß man die MAC nur einmal ermitteln lässt sich die mittels FHEM get Befehl anzeigen und klickt dann einfach auf den Link mit der richtigen MAC. Der Link führt entweder den $hash->{DEF} aus oder eben ein defmod oder so.


Zitat
Ich denke was man berücktichtigen sollte, ist dass für die meisten Aufrufe eine gültige ClientID erforderlich ist. Diese ist aber nur begrenzt haltbar, deshalb habe ich in einem anderen Modul eine Art queuing eingerichtet. Wenn ein Request mit der Fehlermeldung client id nicht gültig zurückkommt wird einfach ein requestAccess gequeued und dann derselbe aufruf auch in die Queue geschrieben.
Finde ich eine sehr gute Lösung und sollten wir im Hinterkopf behalten

Zitat
Wenn ich das richtig verstehe sind die jetzigen Aufrufe zum Fernseher blocking? Wenn ja dann müsste das vermutlich geändert werden, da ie Queue ist verrmutlich auch notwendig, weil die Aufrufe zum Teil Zeit benötigen und bei Fehlern auch in Timeouts laufen könnten. Dann wäre auch ein Queuing erforderlich, damit immer nur ein Request zum Fernseher geht, selbst wenn jeman den nächsten Request schon absetzt.

Das Queuing ist auch ganz simpel:

- Die Parameter eines Requests werden in der Queue abgelegt - z.B. als Hash oder Array
- Wenn ein Request abgesetzt wird, wird ein Status intern im Modul gesetzt - working
- Sollte ein neuer Request kommen wird dieser einfach in die Queue gestellt - fertig
- Am ende des Requests wird der interne Status einfach wieder auf - idle gesetzt
- Im Fehlerfall lässt sich dann auch ein retry abhandeln

Wie gesagt die Behandlung sollte sowieso non-blocking / asynchron werden
Vorraussetzung ist allerdings, dass man alles was später zur Behandlung der Antwort braucht auch in der Queue im Parameterhash steht

Ich kann da gerne auch beitragen, allerdings wäre wohl eine Umstellung auf httpUtils Vorraussetzung

Das wird auf jeden Fall noch geändert. Ich wollte erstmal schauen was an kommt und wie man das verarbeiten kann. Mir ging es um das verstehen so das ich das ganze dann auf httputils umbauen kann. Aber noch habe ich einen Knoten im Gehirn.


@der.einstein
Der Request beinhaltete

<m:MAC-Address>00:09:82:19:ab:58</m:MAC-Address><m:MAC-Address-LAN>00:09:82:19:ab:58</m:MAC-Address-LAN><m:MAC-Address-WLAN>f8:35:dd:97:9b:5a</m:MAC-Address-WLAN>

Also sollte die tatsächlich relevante MAC in <m:MAC-Address>00:09:82:19:ab:58</m:MAC-Address> stehen, korrekt?

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

viegener

ZitatAlso sollte die tatsächlich relevante MAC in <m:MAC-Address>00:09:82:19:ab:58</m:MAC-Address> stehen, korrekt?

Ja das passt --> Diese Mac ist Loewe Opta zugeordnet / die andere gehört wohl dem Hersteller des WLAN-Moduls (Gemtek)
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

viegener

Vielleicht sollten wir uns abstimmen was die nunfolgenden Änderungen angeht, damit wir uns nicht gegenseitig ins Handwerk greifen.

Was den Komplex des Requestprocessings angeht gibt es vermutlich eine Abhängigkeit - erst httputils / dann queuing?

Ich kann vermutlich zu beidem beitragen, vielleicht muss man das sogar in einem Rutsch machen, da für den Callback bei httputil ja sowieso eine Parameterübergabe im Hash erforderlich wäre.

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können