[gelöst] Drucker-Tintenstand mit Cups/IPP auslesen

Begonnen von caldir65, 21 Oktober 2021, 18:04:26

Vorheriges Thema - Nächstes Thema

caldir65

Hallo,
ich habe einmal etwas im Netz gesucht, und bin bei c't auf diesen Artikel gestoßen, in dessen Nachgang ein paar interessante Hilfstools zum Auslesen eines Druckers, insbesondere des Verbrauchsmaterials wie Tinte gestoßen.

Jetzt würde ich diese Ausgabe des Scriptes
desktop:~/tmp$ ipptool -tv ipp://192.168.1.121/ marker.ipp
"marker.ipp":
    Get-Printer-Attributes:
        attributes-charset (charset) = utf-8
        attributes-natural-language (naturalLanguage) = en
        printer-uri (uri) = ipp://192.168.1.121:631/
        requested-attributes (1setOf keyword) = marker-names,marker-levels
    marker                                                               [PASS]
        RECEIVED: 221 bytes in response
        status-code = successful-ok (successful-ok)
        attributes-charset (charset) = utf-8
        attributes-natural-language (naturalLanguage) = en
        marker-names (1setOf nameWithoutLanguage) = Photo Black ink,Cyan ink,Magenta ink,Yellow ink,Black ink
        marker-levels (1setOf integer) = 26,14,7,16,89
gerne so umsetzen, daß ich dabei vernünftige Readings bekomme, die ich ggf. auch z.B. in einer UI weiter verwerten kann. Es soll dabei dann nur die Bezeichnung der Patrone (also z.B. "Photo Black ink") sowie der Füllgrad (hier im Bsp. 26) für alle Patronen ausgegeben werden. Leider bin ich des Programmierens nicht wirklich mächtig, würde mich über Tips und Unterstützung daher sehr freuen.

Gruß, Christoph

---
Nachtrag zur Lösung:
Stand heute (27.10.2021) habe ich vom Redakteurs des c't-Artikels, Herrn Dusan Zivandinovic, die Freigabe erhalten, die Datei entsprechend zu teilen ich habe sie somit einmal mit angehängt.
Die Datei Marker.IPP ist aus dem c't-Artikel und ein Zusatzangebot der c't zum Download. Sie bestimmt im Prinzip, was genau mittels dem Aufruf des ipptools abgefragt bzw. geliefert werden soll - in diesem Fall halt beschränkt auf den Tinten- oder Tonerstand (dürfte mit vielen Druckern funktionieren, die von Cups unterstützt werden).
In meinem Fall mußte ich diese Datei nur etwas anpassen, da die Zeilenumbrüche nicht korrekt waren.


Ich habe jetzt ein Script gebastelt, welches einmal mittels ipptool eine Datei füttert, und im Anschluß mittels Konsolenbefehl direkt die Readings über die entsprechende Funktion aktualisiert. Das Ganze wird stündlich per cron ausgeführt...

Alte Techniker-Regel: "kaum macht man es richtig, funktioniert es auch"
------
Dell Wyse5070 ThinClient 16GBRam, 64GB SSD, Lubuntu 22.04LTS, fhem (aktuell), debmatic, Homematic-Devs, ConBee II und deConz, viele Shellys, Rademacher, NextCloud-Anbindung, FullyKioskBrowser+FUIP uvm.

betateilchen

1. Schritt: Die Ausgabe in ein Textfile umleiten und diese Textdatei mit FileRead() in FHEM einlesen.

2. Schritt: Aus allen Zeilen, die ein "=" enthalten, kann man problemlos readings erzeugen, deren Namen man vor dem "=" ermittelt (z.B. attributes-charset) und den Wert aus dem Teil nach dem "=" verwendet (im Beispiel utf-8)

3. Schritt: aus dem Wert von "marker-levels" die entsprechenden Füllstände der einzelnen Farbwerte erzeugen.

Die Textfileerzeugung aus Schritt 1 kann man per Cronjob z.B. einmal pro Tag auf Betriebssystemebene erledigen. Geht grundsätzlich auch innerhalb von FHEM, aber ich bin kein Freund davon, regelmäßige Programmaufrufe auf Betriebssystemebene aus FHEM zu erledigen. Das macht cron einfach besser und stressfreier.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Ich habe nun


  • Deine Beispieldaten in eine Textdatei /tmp/ippdata.txt gekippt
  • einen dummy "ipp_dummy" angelegt
  • in meine 99_myUtils.pm die Funktion "ipp_fill" angelegt
  • die Funktion einmal manuell in der FHEM Befehlszeile aufgerufen

Danach habe ich im dummy "ipp_dumm" folgende readings:


READINGS:
     2021-10-21 19:41:00   attributes-charset utf-8
     2021-10-21 19:41:01   attributes-natural-language en
     2021-10-21 19:41:01   marker-levels   26,14,7,16,89
     2021-10-21 19:41:01   marker-names    Photo Black ink,Cyan ink,Magenta ink,Yellow ink,Black ink
     2021-10-21 19:41:00   printer-uri     ipp://192.168.1.121:631/
     2021-10-21 19:41:00   requested-attributes marker-names,marker-levels
     2021-10-21 19:41:00   status-code     successful-ok (successful-ok)



sub ipp_fill {
   my $filename = '/tmp/ippdata.txt';
   my ($err,@content) = FileRead({ FileName => $filename, ForceType => 'file' });
   return $err if $err;
   
   foreach my $line ( @content ){
      next if $line !~ /=/;
      $line =~ s/^\s+|\s+$//g;
      my ($readingName,$value) = split (/=/,$line);
      ($readingName,undef) = split (/\(/,$readingName);
      $readingName =~ s/^\s+|\s+$//g;
      $readingName = makeReadingName($readingName);
      $value =~ s/^\s+|\s+$//g;
      fhem("setreading ipp_dummy $readingName $value");
   }
   return;
}


-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Auch das Umwandeln in einzelne Füllstände ist nicht weiter problematisch:


   READINGS:
     2021-10-21 20:05:47   Black           89
     2021-10-21 20:05:46   Cyan            14
     2021-10-21 20:05:46   Magenta         7
     2021-10-21 20:05:46   Photo_Black     26
     2021-10-21 20:05:47   Yellow          16
     2021-10-21 20:05:45   attributes-charset utf-8
     2021-10-21 20:05:46   attributes-natural-language en
     2021-10-21 20:05:46   marker-levels   26,14,7,16,89
     2021-10-21 20:05:46   marker-names    Photo Black ink,Cyan ink,Magenta ink,Yellow ink,Black ink
     2021-10-21 20:05:45   printer-uri     ipp://192.168.1.121:631/
     2021-10-21 20:05:45   requested-attributes marker-names,marker-levels
     2021-10-21 20:05:45   status-code     successful-ok (successful-ok)



sub ipp_fill {
   my $filename = '/tmp/ippdata.txt';
   my ($err,@content) = FileRead({ FileName => $filename, ForceType => 'file' });
   return $err if $err;
   
   foreach my $line ( @content ){
      next if $line !~ /=/;
      $line =~ s/^\s+|\s+$//g;
      my ($readingName,$value) = split (/=/,$line);
      ($readingName,undef) = split (/\(/,$readingName);
      $readingName =~ s/^\s+|\s+$//g;
      $readingName = makeReadingName($readingName);
      $value =~ s/^\s+|\s+$//g;
      fhem("setreading ipp_dummy $readingName $value");
   }
   my @colors = split(/,/,ReadingsVal('ipp_dummy','marker-names',''));
   my @levels = split(/,/,ReadingsVal('ipp_dummy','marker-levels',''));
   for (my $i = 0; $i <= $#colors; $i++) {
      my $colorName = $colors[$i];
      $colorName =~ s/.ink//i;
      $colorName = makeReadingName($colorName);
      fhem("setreading ipp_dummy $colorName $levels[$i]");
   }
   return;
}
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

caldir65

#4
Moin,

super, danke für die ausführliche Antwort, ich werde mich damit mal auseinandersetzen, sobald ich Zeit habe.

Gruß, Christoph

-------

Nochmals vielen Dank, funktioniert wie gewünscht.
Alte Techniker-Regel: "kaum macht man es richtig, funktioniert es auch"
------
Dell Wyse5070 ThinClient 16GBRam, 64GB SSD, Lubuntu 22.04LTS, fhem (aktuell), debmatic, Homematic-Devs, ConBee II und deConz, viele Shellys, Rademacher, NextCloud-Anbindung, FullyKioskBrowser+FUIP uvm.