Hallo,
ich habe einmal etwas im Netz gesucht, und bin bei c't auf diesen Artikel (https://www.heise.de/ct/ausgabe/2015-10-Internet-Printing-Protocol-Fehlersuche-Statusabfrage-drucken-ohne-Treiber-2600094.html) 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...
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.
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;
}
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;
}
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.