[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

Finde gut, dass es auf GitHub steht.

Zum "GetDeviceData": wie gesagt macht das was du möchtest bereits das Script in Post 5-7 (oder so).
Außerdem kann man dem PDF mit der Loewe API aus Post 2 sowohl jeweils ein Beispiel zum Request für jeden Befehl, als auch der Antwort für jeden Befehl entnehmen.

Ich würde daher vorschlagen, dort mal nachzusehen.

@viegener: Programmierung einer Aufzeichnung ist möglich. Dafür brauchst du aber die Startzeit nach UTC, die Länge der Sendung, sowie den Sender. Die Schwierigkeit beim Sender ist, dass man nicht sagen kann nimm ZDF auf. Vielmehr hat ja der TV Senderlisten (min. eine). In der trägt jeder Sender eine ID (Mediathek ID), über diese kann der Sender dann referenziert werden.
Um das zu erreichen was du, glaube ich, willst, müsste man daher erstmal die Senderliste auslesen und abspeichern in FHEM. Dann in FHEM quasi beim Auswählen von "ZDF" dem TV die jeweilige ID aus der Senderliste schicken.
Ein Vorgehen zum Parsen der Senderliste habe ich bereits.

Grüße

Gesendet von meinem LG-D855 mit Tapatalk


der.einstein

Hier der Auszug aus der API für GetDeviceData:


Retrieving Device Information 
This call allows the client to retrieve additional information from the TV regarding its configuration. 
GetDeviceData can be used for discovery. The value of element ClientId can be left empty, there is no
need to call RequestAccess first.
<ltv:GetDeviceData>
  <ltv:fcid>8138942</ltv:fcid>
  <ltv:ClientId>LRemoteClient-0-1314017969</ltv:ClientId>
</ltv:GetDeviceData>
might yield the following response:
<ltv:GetDeviceDataResponse>
  <ltv:fcid>8138942</ltv:fcid>
  <ltv:ClientId>LRemoteClient-0-1314017969</ltv:ClientId>
  <ltv:Chassis>SL150</ltv:Chassis>
  <ltv:SW-Version>PV7.2.1</ltv:SW-Version>
  <ltv:MAC-Address>00:0a:0b:0c:0d:0e</ltv:MAC-Address>
  <ltv:MAC-Address-LAN>34:f6:2d:ff:ff:ff</ltv:MAC-Address-LAN>
  <ltv:MAC-Address-WLAN/>
  <ltv:Location>Germany</ltv:Location>
  <ltv:NetworkHostName>hl1</ltv:NetworkHostName>
  <ltv:StreamingServerName>Remote TV</ltv:StreamingServerName>
  <ltv:OwnVolumeId>DLN1://2fd9d370-1dd2-11b2-822f-00098219b9bb</ltv:OwnVolumeId>
</ltv:GetDeviceDataResponse>
Some elements of the response might not be supported by older chassis.
For SL220, from PV1.9.1 on also the MAC address is returned as above to support i.e. wake on
(w)lan functionality. In addition to the MAC-Address of the currently active network device, MAC-
Address-LAN and MAC-Address-WLAN are returned. MAC-Address-WLAN may be empty, when
there is no wireless hardware installed.     
Location returns the location of the device, which is set at initial installation. 
If there is some kind of error while collecting the device data, the response will contain empty strings
for some or all values:
<ltv:GetDeviceDataResponse>
  <ltv:fcid>8138942</ltv:fcid>
  <ltv:ClientId>LRemoteClient-0-1314017969</ltv:ClientId>
  <ltv:Chassis/>
  <ltv:SW-Version/>
  <ltv:MAC-Address/>
  <ltv:MAC-Address-LAN/>
  <ltv:MAC-Address-WLAN/>
  <ltv:Location/>
  <ltv:NetworkHostName/>
  <ltv:StreamingServerName/>
  <ltv:OwnVolumeId/>
</ltv:GetDeviceDataResponse>

der.einstein

Und hier der Auszug aus der API für das Setzen eines Timers:


Programming Timers
External applications may program record timers on the tv set:
<ltv:ProgramTimer>
  <ltv:fcid>8138436</ltv:fcid>
  <ltv:ClientId>LRemoteClient-0-1314017969</ltv:ClientId>
  <ltv:Device>PVR</ltv:Device>
  <ltv:RecordingType>default</ltv:RecordingType>
  <ltv:Locator>
dvb://localhost/#?chlview=default&amp;progNum=2&amp;gcn=7&amp;onid=1&amp;tsid=1011&amp;sid=11110
  </ltv:Locator>
  <ltv:Timer starttime="1315494000" duration="3600" repeatDays="0"/>
</ltv:ProgramTimer>
"Device" specifies the device to record on. Currently only "PVR", referring to the local DR+
recorder, is supported.
"RecordingType" will allow specifying different recording type i.e. for series recording etc. Currently
only "default" is supported.
"Locator" is the usual locator format which must refer to a channel.
"Timer" then contains the timing information for the recording. The starttime should be given in
seconds since epoch UTC, the duration in seconds. "repeatDays" is a bitmask specifying which days
to repeat the recording on: 

Sun Mon Tue Wed Thu Fri Sat
0x01 0x02 0x04 0x08 0x10 0x20 0x40
If the value for "repeatDays" is prefixed with "0x", it will be treated as a hexadecimal value.
Otherwise, a decimal value is assumed.

The above message yields a simple response message:
<ltv:ProgramTimerResponse>
  <ltv:fcid>8138436</ltv:fcid>
  <ltv:ClientId>LRemoteClient-0-1314017969</ltv:ClientId>
  <ltv:Result>0</ltv:Result>
</ltv:ProgramTimerResponse>
As usual a result of "0" denotes success where a negative value is an error code. Note that since
recording requests may be delayed an arbitrary time due to necessary user interaction in terms of
conflict, "0" does not mean that the timer has necessarily been correctly programmed. It only means
that the tv has accepted and processed the request.


Gesendet von meinem LG-D855 mit Tapatalk


viegener

Habe gerade das erste mal getestet, leider komme ich nicht sehr weit, beim define kommt folgende Fehlermeldung:

2017.09.10 21:40:57 3: LoeweTV loewe: defined LoeweTV device
STARTING SENDREQUEST: GetDeviceData
2017.09.10 21:41:03 1: PERL WARNING: Use of uninitialized value in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 433.
2017.09.10 21:41:03 1: PERL WARNING: Use of uninitialized value in concatenation (.) or string at ./FHEM/82_LoeweTV.pm line 458.
Can't locate object method "Headers" via package "HTTP::Headers" at /usr/share/perl5/HTTP/Message.pm line 649.


Da hänge ich jetzt erstmal
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

der.einstein

Ja, das ist wegen den paar Änderungen, die man bei CoolTuc Version machen muss.
Ich werde morgen gern ein Diff Patch machen.

Gesendet von meinem LG-D855 mit Tapatalk


CoolTux

Danke für das Testen. Ich schaue es mir morgen früh einmal in Ruhe an.
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

#66
So, hier mal die Zeilen, die ich geändert habe, damit dein (CooLTux) Script (Achtung: Aus Post Nr. 38 https://forum.fhem.de/index.php?action=post;quote=682281;topic=70266.30;last_msg=683900) bei mir läuft:

50c50
<                         "status:Accepted,Pending,Denied,undef " .
---
>                         "status:accepted,Pending,Denied,undef " .
116c116
<     my ($action,$RCkey);
---
>
118c118
<     if( lc $cmd eq 'setactionfield' ) { $action = $arg;$RCkey = $params[0];
---
>     if( lc $cmd eq 'setactionfield' ) {
120c120
<     } elsif( lc $cmd eq 'setvolume' ) { $action = "SetVolume";$RCkey = $params[0];
---
>     } elsif( lc $cmd eq 'setvolume' ) {
122c122
<     } elsif( lc $cmd eq 'setmute' ) { $action = "SetMute"; $RCkey = $params[0];
---
>     } elsif( lc $cmd eq 'setmute' ) {
167c167
<     if ($hash->{status} eq "Accepted")        {&LoeweTV_sendRequest($hash,$action,$RCkey);}
---
>     if ($hash->{status} eq "accepted")        {&LoeweTV_sendRequest($hash,$action,$RCkey);}
223,224c223,224
<         &LoeweTV_checkAccess($hash,$hash->{CLIENTID},$hash->{FCID});
<         &LoeweTV_sendRequest($hash,"InjectRCKey",22);
---
>         LoeweTV_checkAccess($hash,$hash->{CLIENTID},$hash->{FCID});
>         LoeweTV_sendRequest($hash,"InjectRCKey",22);
237c237
<     while ((ReadingsVal($name,'state','denied') ne "Accepted") and ($n<=3)) {
---
>     while ((ReadingsVal($name,'state','denied') ne "accepted") and ($n<=3)) {

CoolTux

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

Also ich habe mir den Patch angeschaut. Basierend auf dem aktuellen Stand des Modules hilft der Patch nicht weiter.
Sicherlich kommt das ein oder andere später zum tragen aber nicht bei der ersten Kontaktaufnahme die ich erstmal aktiv ablaufen habe. Mehr macht ein Define aktuell nicht.

Ich hoffe viegener kann sich das mal genauer anschauen. Oder der.einstein nimmt noch mal aus dem Git die aktuelle Version.
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

Ich bin dafür entweder nach dem setzen und parsen des $twig ein weiteres "$actions{$action}2]->();" einzufügen (man beachte die 2), oder das Setzen/Parsen des $twig zusammen mit einer weiteren anonymen Subroutine mit in den %actions hash aufzunehmen.

Dann hätte man die Möglichkeit geschaffen, abhängig vom Funktionsaufruf vor und nach dem Absetzen der Request eigenen Code abzuarbeiten.

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.

Grüße

Gesendet von meinem LG-D855 mit Tapatalk


der.einstein

Zitat von: CoolTux am 11 September 2017, 12:47:18
Also ich habe mir den Patch angeschaut. Basierend auf dem aktuellen Stand des Modules hilft der Patch nicht weiter.
Sicherlich kommt das ein oder andere später zum tragen aber nicht bei der ersten Kontaktaufnahme die ich erstmal aktiv ablaufen habe. Mehr macht ein Define aktuell nicht.

Ich hoffe viegener kann sich das mal genauer anschauen. Oder der.einstein nimmt noch mal aus dem Git die aktuelle Version.
Ja, hatte das befürchtet [emoji14]
Ich machs heut Abend nochmal mit der GitHub Version

Wir Krieg ich die aktuellen GitHub Version am schnellsten in FHEM? (ich verwende Ubuntu 16.04)

Wieso hast du dem Skript die "82_" vorangestellt? Macht das einen Unterschied?

Grüße

Gesendet von meinem LG-D855 mit Tapatalk


CoolTux

Hier bekommst immer die aktuellste Developer Version
https://github.com/LeonGaultier/fhem-LoeweTV/archive/devel.zip


Die 82 ist eine Zuordnung die lediglich den Zusammenhang zu Multimedia Module in FHEM darstellen soll. Hat keinen Nutzen bezüglich dem Einbinden an sich sondern ist eine FHEM Developerinterne Sache. Man versucht gleiche Module unter einer Nummer zu bekommen. Weather Module zum Beispiel und halt Multimedia. Für Multimedia gibt es einen extra Guide bezüglich Readings und States. Hier lohnt sich mal ein Blick rein.
https://wiki.fhem.de/wiki/DevelopmentGuidelinesAV


Installieren entweder kopieren der Datei mittels scp(ssh) oder ich kopiere aus dem Entwicklereditor den Code und füge ihn in die Moduldatei über vim direkt ein.
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

So, hiermit komme ich ein wenig weiter:

package main;

use strict;
use warnings;
use Data::Dumper::Simple;
use XML::Twig;

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.23";


# 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 < 3 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->{VERSION}    = $version;
    $hash->{INTERVAL}   = 15;
    $hash->{CLIENTID} = "?";
    $hash->{status} = undef;

    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 );
    }
   
    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_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' ) { $action = "SetActionField";$RCkey = $arg;

    } elsif( lc $cmd eq 'setvolume' ) { $action = "SetVolume";$RCkey = $arg;
   
    } elsif( lc $cmd eq 'setmute' ) { $action = "SetMute";$RCkey = $arg;
   
    } elsif( lc $cmd eq 'connect' ) { $action = "RequestAccess";$RCkey = "0";
   
    } elsif( lc $cmd eq 'wakeup' ) {
   
        LoeweTV_WakeUp_Udp($hash,$hash->{HOST},$hash->{TVMAC});
        return;
   
    } elsif( lc $cmd eq 'remotecontrol' ) { $action = "InjectRCKey";$RCkey = $arg;
   
   
    } 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)      = 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: $hash->{status}   \n";
   
   
    return($hash->{status});
   
   
    }

sub LoeweTV_SendRequest($$$) {

    my($hash, $action, $RCkey)  = @_;
    print "action: $action     RCkey: $RCkey \n";
    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 {readingsSingleUpdate($name,'state',"$_->text_only('m:AccessStatus'",1);},}
                                    ],
                                   
        "InjectRCKey"           =>  [sub {$content='<InputEventSequence>
                                        <RCKeyEvent alphabet="l2700" value="'.$RCkey.'" mode="press"/>
                                        <RCKeyEvent alphabet="l2700" value="'.$RCkey.'" mode="release"/>
                                        </InputEventSequence>'},{"ltv:InjectRCKey" => sub {$hash->{lastchunk} = $_->text_only();}},],
                                       
        "GetDeviceData"         =>  [sub {$content='';},{"m:MAC-Address" => sub {$hash->{TVMAC} = $_->text("m:MAC-Address");}}],
           
        "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->{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   \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>\n";
   
    my $action_xml1 = "<ltv:$action>\n";
   
    my $header2 = "<ltv:fcid>".$hash->{FCID}."</ltv:fcid>
            <ltv:ClientId>".$hash->{CLIENTID}."</ltv:ClientId>\n";

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



    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;
   
   
    # 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);
   
   
    $noob = $response->content;
    #print "RESPONSE WAS: $response->content \n";
    print Dumper $response;
    $twig2 = XML::Twig->new(twig_handlers => $handlers,keep_encoding => 1)->parse($noob);
   
   
    LoeweTV_ResponseProcessing($hash,$response);
}
   
   
sub LoeweTV_ResponseProcessing($$) {
   
    my ($hash,$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($hash->{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

CoolTux

Sehr schön. Und wie weit genau.
Kommst Du bis zum ResponseProcessing? Wie sehen dann die Ausgaben aus?


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

Ich habe jetzt einige Anpassungen übernommen. Bewusst aber nicht alle weil ich noch nicht so weit bin.
use XML::Twig; gab es bereits als eval Verpackung

Ansonsten habe ich erstmal Änderungen gemacht die lediglich den ersten Kontakt betreffen sollten. Also für ein GetDeviceData nötig sein sollten.
Kann bitte einmal jemand die Version testen und mir wenn es denn klappt ein Logauszug geben. Sollte ja was drin stehen im Log
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