[geändert]TV Programm automatisieren - Vorschlag mit der Bitte um Unterstützung

Begonnen von supernova1963, 16 November 2017, 22:32:59

Vorheriges Thema - Nächstes Thema

supernova1963

Hallo DarkT,

ich habe dein perl - script getestet. Es läuft einwandfrei. Das geniale suchen der img-URLs über die img-Tags beeindruckt mich als Perl Anfänger sehr.

Mein Problem jedoch ist, dass so zwar alle Logos lokal gespeichert wären, deren Name aber weder durchgängig mit dem Suchbegriff noch mit den vergebenen device Namen überein stimmen (z.B. ard.png, Suchbegriff "Das Erste", Sendername "Das_Erste"). 

Wäre es nicht auch möglich, dass man mit zwei Parameter: </Pfad/SollDateiName> <vollständige url des Images> gezielt nur 1 Logo abholt und in dem Vorgabepfad und mit dem Vorgabe-Dateiname speichert?

Es würde generell nur einmal für jeden Sender starten (z.B. im TVSender_notify mit der Abfrage ob die Datei existiert). Das hätte u.A. auch den Vorteil, dass bei neuen Logos nur die Datei gelöscht werden muss, damit bei der nächsten Änderung es neu geladen wird.

Danke für deinen tollen Beitrag,

Gernot

DarkT

Also wenn ich das richtig verstehe, dann würde es Dir genügen, wenn Du so was hast

Eingabe: ard.png -> Das_Erste
Ausgabe: Datei im Ordner ../images/Das_Erste.png

Du musst dann eine Mapping im Code hinterlegen. Das könnte man das wie folgt lösen:


# includes
# ---------------------------------
use File::Fetch;
use LWP::Simple;
use HTML::LinkExtor;
use Data::Dumper;
use Cwd qw();
$Data::Dumper::Indent=1;

# variable definitions
# ---------------------------------

# mapping array for desired filenames
my %filename_mapping = (
        'ard.png' => 'Das_Erste.png',
        'rtl.png' => 'RTL.png',
    );

# where to find all icons
my $url = "http://images.klack.de/fernsehprogramm/fernsehprogramm/-1/free.html";

# where should the icons be stored
my $folder = Cwd::cwd() . "/icons/";


# program
# ---------------------------------

#1 Load url with all images
my %images = ();
my $html = get($url)
  or die "could not get images \n";

# extract all links from url
my $parser = HTML::LinkExtor->new(undef, $url);
$parser->parse($html);
my @all_link_refs = $parser->links();

# for each link, check if is an icon
for my $link_ref ( @all_link_refs  ) {
  my ( $html_tag, $attr_name, $this_url ) = @$link_ref;
  if ( ($html_tag eq 'img') ) {
    my $image_name = (split("/", $this_url))[-1];
    $images{$image_name}++;

# if is icon -> download and rename to desired filename
    if ( $images{$image_name} == 1  ) {
        # print "Downloading $image_name -> $filename_mapping{$image_name} ...\n";
         my $ff = File::Fetch->new(uri => $this_url);
my $file = $ff->fetch(to => $folder) or die $ff->error;
rename $folder . $image_name, $folder . $filename_mapping{$image_name};
    }   
  }
}


Neu ist dann


  • my %filename_mapping
    Hier müsste dann - falls notwendig - ein mapping für jedes Icon eingetragen werden
  • $folder
    Hier kann der Ordner angegeben werden wohin die Icons geladen werden (zur Zeit <current working directory>/icons)
  • rename
    Diese Zeile nennt die Dateien wie gewünscht um

Hast Du Dir das so vorgestellt?

Anmerkung:
Eventuell kann man das ganze natürlich auch so löäsen, dass man für jedes Icon die komplette URL hinterlegt ... das ist dann noch etwas unabhängiger von der Seite "http://images.klack.de/fernsehprogramm/fernsehprogramm/-1/free.html" ... ich weiss nicht wie sehr sich diese Seite ändert.

supernova1963

Hallo DarkT,

deine Perl Kenntnisse hätte ich gerne. Sehr interessanter Lösungsansatz für den Download aller Logos.

Ich habe es mir etwas einfacher gemacht und warte bis das Reading (z.B. Das_Erste_Logo) im HTTPMOD Device die vollständige URL für das Senderlogo ermittelt hat. Dann lasse ich die Datei mit wget <Logo URL> -O <Pfad>/<Devicename>.png herunterladen. Dan habe ich zwar nur das eine Logo pro TVSender Device, aber mehr benötigt man ja auch nicht.

Ich kämpfe noch mit der Umsetzung von Ronny's Vorschlag zur Optimerung der Aktualisierungszyklen. Wenn ich das am Wochenende geschafft habe, werde ich eine neue Version ins git stellen.

Danke, ich habe viel gelernt,

Gernot

DarkT

War mein erstes Perl Skript - bin allerdings beruflich mit Entwicklung verbunden.
Da ist dann irgendwie eine Sprache wie die andere ;)

Vielen Dank für deine Mühen

supernova1963

Hallo zusammen,

Ich habe eben ein Zwischenrelease hochgeladen:

https://github.com/supernova1963/TVSender/releases/tag/0.2.3

Noch nicht geschafft habe ich:

  • UmschaltTimer (Vorschlag von Ronny)
  • Optimierung der Seitenabrufe (Ronny) oder MasterDevice (CoolTux)
  • DetailLink mit asynchOutput (dev0) (

Hilfe benötige ich zu folgenden Thema um die Seitenabrufe zu optimieren:

Ermittlung der nächsten Uhrzeit von den folgenden Sendungen und deren Umwandlung in einen TimeStamp für "InternalTimer($timestamp, $functionName, $arg);".
Da man nicht auf den Device Hash des TV_Program_NEXT zugreifen soll, suche ich nach einer geeigneten Vorgehensweise zur Ermittlung der ReadingsNamen für ReadingsVal(...).

Alternativ bzw. ergänzend würde voraussichtlich das Master Device, wenn es läuft und die notwendigen Anpassungen durchgeführt sind, einiges vereinfachen.

Danke,

Gernot


supernova1963

Sorry, ich verzweifle an dem asyncOutput.

Ich möchte das Ergebnis der Befehle als URL Link aufrufen:

./fhem?cmd=get%20Das_Erste%20AktuelleSendung
./fhem?cmd=get%20Das_Erste%20NaechsteSendung
./fhem?cmd=get%20Das_Erste%20PrimeTimeSendung
./fhem?cmd=get%20Das_Erste%20PrimeTimeSendungfolgend

Dafür sind folgende gets definiert:
sub TVSender_Get($@) {
  my ($hash, $name, $cmd, @args) = @_;
  my ($arg, @params) = @args;
  my $list = '';
  my $table = '';

  if ($cmd eq 'AktuelleSendung') {
    $table = '<html><table width=650px >'
      .'<tr><td style="text-align: center;;background-color: #e0e0e0;;color: black" colspan=3 >A  K  T  U  E  L  L</td></tr>'
      .'<tr><td style="vertical-align: top;;text-align: right;;font-size: larger;;width: 50px" >'.ReadingsVal($name,"TV_Program_NOW_Time","").'</td>'
      .'<td style="vertical-align: top;;text-align: left;;font-weight: bold;;font-size: larger;;width: 400px;;white-space: normal" ><a href="/fhem?cmd=set%20'.$name.'%20Switch2Channel%201" >'.ReadingsVal($name,"TV_Program_NOW_Title","").'</a><br /><div style="vertical-align: top;;text-align: left;;font-weight: initial;;font-size: smaller">'.ReadingsVal($name,"TV_Program_NOW_Description","").'</div></td>'
      .'<td style="vertical-align: top;;width: 200px" >'.ReadingsVal($name,"TV_Program_NOW_Image","").'</td></tr>'.'</table></html>';
    return $table;
  }
  elsif ($cmd eq 'NaechsteSendung') {
    $table = '<html><table width=650px >'
      .'<tr><td style="text-align: center;;background-color: #e0e0e0;;color: black" colspan=3 >A  N  S  C  H  L  I  E  S  S  E  N  D</td></tr>'
      .'<tr><td style="vertical-align: top;;text-align: right;;font-size: larger;;width: 50px" >'.ReadingsVal($name,"TV_Program_NEXT_Time","").'</td>'
      .'<td style="vertical-align: top;;text-align: left;;font-weight: bold;;font-size: larger;;width: 400px;;white-space: normal" ><a href="/fhem?cmd=set%20'.$name.'%20Switch2Channel%201" >'.ReadingsVal($name,"TV_Program_NEXT_Title","").'</a><br /><div style="vertical-align: top;;text-align: left;;font-weight: initial;;font-size: smaller">'.ReadingsVal($name,"TV_Program_NEXT_Description","").'</div></td>'
      .'<td style="vertical-align: top;;width: 200px" >'.ReadingsVal($name,"TV_Program_NEXT_Image","").'</td></tr>'.'</table></html>';
      return $table;
  }
  elsif ($cmd eq 'PrimeTimeSendung') {
    $table = '<html><table width=650px >'
      .'<tr><td style="text-align: center;;background-color: #e0e0e0;;color: black" colspan=3 >P  R  I  M  E    T  I  M  E</td></tr>'
      .'<tr><td style="vertical-align: top;;text-align: right;;font-size: larger;;width: 50px" >'.ReadingsVal($name,"TV_Program_PT_Time","").'</td>'
      .'<td style="vertical-align: top;;text-align: left;;font-weight: bold;;font-size: larger;;width: 400px;;white-space: normal" ><a href="/fhem?cmd=set%20'.$name.'%20Switch2Channel%201" >'.ReadingsVal($name,"TV_Program_PT_Title","").'</a><br /><div style="vertical-align: top;;text-align: left;;font-weight: initial;;font-size: smaller">'.ReadingsVal($name,"TV_Program_PT_Description","").'</div></td>'
      .'<td style="vertical-align: top;;width: 200px" >'.ReadingsVal($name,"TV_Program_PT_Image","").'</td></tr>'.'</table></html>';
      return $table;
   }
  elsif ($cmd eq 'PrimeTimeSendungfolgend') {
    $table = '<html><table width=650px >'
    .'<tr><td style="text-align: center;;background-color: #e0e0e0;;color: black" colspan=3 >D  A  N  A  C  H</td></tr>'
    .'<tr><td style="vertical-align: top;;text-align: right;;font-size: larger;;width: 50px" >'.ReadingsVal($name,"TV_Program_PTNEXT_Time","").'</td>'
    .'<td style="vertical-align: top;;text-align: left;;font-weight: bold;;font-size: larger;;width: 400px;;white-space: normal" ><a href="/fhem?cmd=set%20'.$name.'%20Switch2Channel%201" >'.ReadingsVal($name,"TV_Program_PTNEXT_Title","").'</a><br /><div style="vertical-align: top;;text-align: left;;font-weight: initial;;font-size: smaller">'.ReadingsVal($name,"TV_Program_PTNEXT_Description","").'</div></td>'
    .'<td style="vertical-align: top;;width: 200px" >'.ReadingsVal($name,"TV_Program_PTNEXT_Image","").'</td></tr>'.'</table></html>';
    return $table;
  }
  else {
    $list = ""
    ."AktuelleSendung:noArg"
    ." NaechsteSendung:noArg"
    ." PrimeTimeSendung:noArg"
    ." PrimeTimeSendungfolgend:noArg" ;

    return "Unknown argument $cmd, choose one of $list";
  }
}


Was muss ich nun tun, damit die URL-Links funktionieren?

Ich habe gelesen, dass die AsyncOutput Funktion im TVSender Modul initialisiert und existieren muss:
$hash->{AsyncOutputFn}  = 'TVSender_AsyncOutput';
...
sub TVSender_AsyncOutput ($)
{
my ( $client_hash, $text ) = @_;
        ...
return $error;
}


Meine Fragen:

Ich sehe nur einen Parameter der übergeben wird. Aufgelöst werden jedoch ($Client_hash, $text). Ist das korrekt?
Was muß ich in die sub TVSender_AsyncOutput ($) eintragen, damit das Ergebnis der gets ausgegeben wird?
Wie muss der URL-Link aussehen?

Vielen Dank für eure Hilfe,

Gernot


CoolTux

https://wiki.fhem.de/wiki/DevelopmentModuleAPI#asyncOutput

Da hast Du was missverstanden. Nicht Dein Modul muß die Fn bereitstellen sondern das Modul über das die Clientverbindung besteht. Also FHEMWEB oder telnet. Gehen ja im Moment nur die zwei. FTUI ginge zum Beispiel nicht.

Einfach in der Funktion in welcher Du das ganze dann zusammenbauen willst

if( $param->{cl} and $param->{cl}->{TYPE} eq 'FHEMWEB' ) {
       
        my $ret = '<html><table><tr><td>';
        $ret .= '<table class="block wide">';
        $ret .= '<tr class="even">';
        $ret .= "<td><b>City</b></td>";
        $ret .= "<td><b>Last Update Time</b></td>";
        $ret .= "<td><b>Latitude</b></td>";
        $ret .= "<td><b>Longitude</b></td>";
        $ret .= "<td></td>";
        $ret .= '</tr>';
.....


Das $param->{cl} musst Du natürlich mitgeben, also in meinem Beispiel. Also da wo Du den nicht blockierenden Datenabruf tätigst


$param->{cl} = $hash->{CL} if( ref($hash->{CL}) eq 'HASH' );
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

mkraus81

hi,

seit heute Mittag scheint es nicht mehr zu gehen... im Log steht

TV_Program_NEXT: Read response to update didn't match any Reading
2017.12.06 13:25:08 3: TV_Program_NEXT: Read response to update didn't match any Reading
2017.12.06 13:25:08 3: TV_Program_PT: Read response to update didn't match any Reading
2017.12.06 13:27:08 3: TV_Program_NOW: Read response to update didn't match any Reading
2017.12.06 13:27:08 3: TV_Program_NEXT: Read response to update didn't match any Reading
2017.12.06 13:29:08 3: TV_Program_PTNEXT: Read response to update didn't match any Reading
2017.12.06 13:31:08 3: TV_Program_NEXT: Read response to update didn't match any Reading

Mir fehlt da leider das Wissen ob den Fehler zu analysieren... Ich vermute, dass sich eventuell was an der Website geändert hat?

Invers

Muss wirklich an Klack liegen. Ich nutze das alte Modul und da geht auch nichts.
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2

supernova1963

Hallo ist bei mir das Gleiche,

Komme aber erst am Wochenende dazu die Regex zu überprüfen und ggf. anzupassen.
Sollte einer von euch die neuen Regex posten, erstelle morgens früh ein Update.

Danke,

Gernot

supernova1963

Hallo zusammen,

seit heute früh, funktioniert es bei mir ohne Änderungen wieder.
Wie sieht es bei euch aus?

Gernot

P.S. nur für Tester: Da mir das manuelle "set <TVSender> UpdateAll" zu aufwendig wurde (hab' zum Test mal mehr als 30 TVSender definiert!), aktualisiere ich, - nachdem ich das Modul verändert und neu geladen habe, jedes TVSender Device mit
set TYPE=TVSender UpdateAll
Funktioniert das bei Euch auch, oder bricht dann alles zusammen?
Bitte seid vorsichtig mit dem Test in einem Live-System, da damit für jeden Sender alle Einstellungen inkl. der Einstellungen für die HTTPMOD Devices für jedes TVSender Device aktualisiert werden.

CoolTux

Ich bin aktuell dabei die Umstellung zu schreiben auf ein Master Device welches dann die Daten via HttpUtils_NonblockingGet holt
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

mkraus81

ich habe eine Verbesserunswunsch...

kann man es irgendwie so machen, das bei UpdateAll das Switch Attribute nicht aktualisiert wird?
Denn ich habe keine Harmony sonder nutze das LGWebOS Modul

set LgTVWohnzimmer channel 1

und das jedesmal wieder manuell zu ändern ist irgendwie doof

oder irgendwie eine Funktion mit der man bei allen devices das Switch Attribute auf einmal ändern kann

CoolTux

@Gernot
Ich habe soeben eine erste Version mit Bridge Deviceunterstützung hochgeladen. Wenn man das erste mal ein Device definiert wird automatisch das Bridge Device angelegt und es beginnt ein fetch der Daten welcher entweder von Hand noch mal gemacht werden kann set update beim Bridge Device oder halt eben alle INTERVAL Sekunden. Default im Moment 300 und noch nicht änderbar.

Ich würde Dich bitten, Code den Du nicht verstehst nicht gleich zu löschen, sondern mich zu fragen was genau der Code macht.



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

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