(erledigt) Ausgabe eines get in Textdatei schreiben

Begonnen von TomLee, 14 Juli 2020, 16:36:13

Vorheriges Thema - Nächstes Thema

Beta-User

Zitat von: TomLee am 16 Juli 2020, 16:14:50
Was mich beschäftigt welche Variante von if ich jetzt im myUtils Code weiter verwenden soll, kann/darf ich mischen.
Man _kann_ das im Prinzip beliebig mischen.

Zu einem großen Teil ist es m.E. eine Frage der Lesbarkeit und des Wiederfindens.

Vielleicht nochmal zu dem hier:
Zitat von: Beta-User am 12 Juli 2020, 08:47:45
Ich finde es übersichtlich, wenn der Code an sich "nichts" bzw. möglichst wenig über die Geräte weiß, und man am Aufruf/der cfg zumindest grob erkennen kann, was passieren soll. Dementsprechend enthält nur die etwas spezielle Geschichte mit den Deckenlichtern in meinem Code überhaupt irgendeinen Device-Namen; der kommt in der Regel aus dem Aufruf im notify...
Dinge, die sich auf konkrete Devices beziehen, _finde_ ich persönlich in der Konfiguration am besten aufgehoben, da mache ich ein "configdb search" nach dem Schlüsselbegriff und sollte dann direkt schon alles beieinanderhaben, was irgendwie von Relevanz ist. Zusätzlich noch myUtils-Code mit grep&Co zu durchsuchen, ist hingegen m.E. nicht so prickelnd. (In einer Kopie der cfg mit einem ordentlichen Editor zu suchen, ist da schon deutlich umständlicher, aber auch da geht es noch...)

Tendenziell würde ich auch völlig unterschiedliche Dinge (Voucher drucken oder Licht anschalten) nicht unbedingt in dieselbe Sub packen. Das erstere wäre vielleicht wirklich eine Sache für ein "onliner-notify" (mit passendem sehr eingeschränktem Trigger), das andere ist generalisierter Code, bei dem du beim Aufruf der sub evtl. besser den Namen des zu schaltenden Lichts mitgibst (s.o.) und - über vielleicht über weitere Parameter (oder key-value-Paare) - die Info mit übergibst, ob irgendeine Benachrichtigung stattfinden soll, ein Timer gelöscht... Das wären dann optionale Argumente, die man dann entweder mit "defaults" versehen kann oder eben über weitere if-Bedingungen nur dann berücksichtigt, wenn sie gesetzt sind (=> Erfahrungs-/Übungsfrage).
Vermutlich würde ich das "Deckenlichter-Ding" heute auch so schreiben, dass ich schlicht die 4 beteiligten Geräte als Parameter übergebe...




Zurück zu deiner eigentlichen Frage:
Generell würde ich diesen "Einheitscode" wenn, dann aber anders strukturieren, also z.B. die Tasten je in einem eigenen if-Zweig nacheinander durchgehen und dann ggf. weiter mit on/off-Unterscheidungen arbeiten usw. Dann ist er viel schneller zu durchsuchen, weil das Auge direkt die notwendigen Ankerstellen findet (daher würde ich auch für Anweisungen terniäre Operationen eher zurückhaltend einsetzen; das ist eher was für interne Werteermittlungen und kann dann auch zu sehr übersichtlichen Schreibweisen führen, wenn man das ganze untereinander schreibt).

Letztendlich geht es immer darum: Wie findest du dich am besten in dem eigenen Code zurecht?
(und wie geht es ggf. jemandem anderen = dir selbst in 5 Jahren (oder auch nur 5 Wochen...)?)

Wenn es dir jetzt wie "Kraut und Rüben" vorkommt, blickst du ziemlich sicher in einem Jahr nicht mehr durch (oder es kostet dich lange, das zu finden, was du eigentlich suchst, die Logik erschließt sich nicht, usw., usf....).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

betateilchen

Zitat von: TomLee am 16 Juli 2020, 16:14:50
Was das notify angeht:

Was den regex angeht hab ich den bewusst so gewählt, mein Gedanke war ein notify für alle Tasten zu verwenden, statt mehrere.
Ja richtig erkannt,  ich habe noch kein Verständnis welcher Weg einzuschlagen ist, für jede Taste eines oder nur eins was ich bevorzugen würde.

Wenn ich nur ein notify möchte muss das (bei entsprechender Namenwahl) logischerweise auf jedes event reagieren.

Du hast es immer noch nicht verstanden. Ein Event, das du im regex eines notify verwenden willst, besteht grundsätzlich aus zwei Teilen - aus dem Namen des devices UND aus dem ausgelösten event.
Was Du tun möchtest: Du möchtest auf bestimmte events möglichst vieler devices mit einem notify reagieren. Das ist grundsätzlich eine der einfachsten Aufgaben in FHEM.

Zitat von: TomLee am 16 Juli 2020, 16:14:50
Wenn ich nur ein notify möchte muss das (bei entsprechender Namenwahl) logischerweise auf jedes event reagieren.

Genau diese Aussage ist falsch und die Ursache Deiner ursprünglichen Schwierigkeiten. Das notify muss nicht auf jedes EVENT reagieren, sondern auf eine Reihe von devices. Den event, auf den reagiert werden soll, kannst Du sehr genau spezifizieren.

Zitat von: TomLee am 16 Juli 2020, 16:14:50
Mit dem Verständnis das man die Variable nur in der richtigen Ebene deklarieren muss, frag ich mich jetzt auch was denn dagegen spricht den regex so zu verwenden, es klappt doch so, nix wird mehr unnötig ausgeführt.

passender Vergleich: Du hast die Kopfschmerzen durch eine Kopfschmerztablette verdrängt. Aber nicht die Ursache der Kopfschmerzen gesucht, geschweige denn beseitigt.

Und die Variablendeklaration hat überhaupt nichts mit der gewählten regex zu tun. Aber das wäre ein anderes Thema.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Zitat von: betateilchen am 16 Juli 2020, 17:56:20
Das notify muss nicht auf jedes EVENT reagieren, sondern auf eine Reihe von devices. Den event, auf den reagiert werden soll, kannst Du sehr genau spezifizieren.

Hier ein Beispiel für eine regex, die in meiner FHEM Installation zu finden ist und genau die gestellte Anforderung erfüllt und völlig unterschiedliche Kombinationen aus device und event enthält/berücksichtigt:

(st_fl_PIR_Motion.*|.*motion:.*|.*Diesel.*|.*lumi.*|.*measured.*|.*desired.*|.*actuator.*|.*valve.*|.*level.*|.*temperature.*|.*humidity.*|.*pressure.*|RM_.*|out_Regen.*|gds.*|gtag.*|owo.*|mqtt.*)

Wie Du siehst, kommt es auch darauf...

Zitat von: TomLee am 16 Juli 2020, 16:14:50
Wenn ich nur ein notify möchte muss das (bei entsprechender Namenwahl) logischerweise auf jedes event reagieren.

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

TomLee

#33
Zitat
Zentriert drucken ist eher eine Frage von Postscript oder ähnlicher Druckersprache, die Dein Drucker beherrscht. Das ist nicht zwingend eine Option von lpr selbst.

Ja vorab, hab mich nicht viel mit beschäftigt, den Code gedruckt aus Wikipedia, fertig.
Kann man man den Code (mit der Variablen drin) auch direkt dem Drucker übergeben oder geht das nur mit einer .ps Datei ?
Probiert hab ich es, klappt nicht, aber eventuell gibts ja einen Weg ?

lpr -P HL-2035 -o media=Custom.95x138mm <<< '%! /Courier findfont 20 scalefont setfont 70 330 moveto (Hallo Welt!) show showpage'

TomLee

#34
Ok, es ist ganz einfach so ein Script zu erstellen, Ich bin halt Ich und brauch zwei Tage länger um das zu verinnerlichen.

#!/bin/bash

voucher=$(perl fhem.pl 7072 "get Unifi voucher 7d2x");
lpr -P HL-2035 -o media=Custom.95x138mm <<< $voucher


Es klappt so, korrekt umgesetzt ?
Um eine Pause muss man sich so keine Gedanken mehr machen, auch wenn man größere Daten zuvor abrufen wollte oder fehlt da noch was ?

Das mit dem Postscript war ja von dir nicht auf das Script bezogen, habs als Erläuterung verstanden.
Ich stell mir jetzt die Frage wie ich den Voucher in eine Postscript Datei bekomme ?
Ich weiß zwar noch nicht genau wie weil ich den Befehl noch nicht kenne ( nur Vermutung echo ?) aber eine Vorstellung hätte ich es umzusetzen.
Ist es auch hier wieder so einfach, aus dem Script immer wieder den Code (sind ja nur ein paar Zeilen) mit der Variablen drin in die Datei zu schreiben ?

TomLee

#35
Mit der großen Unterstützung und den vielen Hinweisen hab ich es jetzt gepackt den voucher zentriert oben auf einer DIN A6 Seite auszudrucken.

#!/bin/bash

voucher=$(perl fhem.pl 7072 "get Unifi voucher 7d2x");
sed -i 's/^\/Courier.*$/\/Courier findfont 20 scalefont setfont 70 330 moveto ('"$voucher"') show showpage/' /opt/fhem/voucher.ps;
lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/voucher.ps;


Hier noch der Inhalt der voucher.ps zum Verständnis.
Wenn ich alles in die erste Zeile des %! schreibe wird nichts gedruckt (da darf wohl nur %! stehen), deshalb schreibe ich alles in eine Zeile in der zweiten Zeile.

%!
/Courier findfont 20 scalefont setfont 70 330 moveto (1234567890) show showpage


Die Möglichkeiten mit Postscript sind ja jetzt grenzenlos, danke für den Hinweis.

TomLee

Kann mir wer sagen wie ich ein "Perl-Array" korrekt an ein "Bashscript-Array" übergebe, das ich mit ${array[1]} auf die Elemente zugreifen kann ?

Zitat#!/bin/bash
array=(perl fhem.pl 7072 "{my @ar = (fhem("get Unifi voucherList 7d2x") =~ m,code.=.([0-9]{10}),g); )}");
sed -i 's/^\/Courier.*$/\/Courier findfont 20 scalefont setfont 70 330 moveto ('"${array[1]}"') show showpage/' /opt/fhem/voucherx.ps;
#lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/voucher.ps;

betateilchen

Zitat von: TomLee am 28 Juli 2020, 11:55:08
Kann mir wer sagen wie ich ein "Perl-Array" korrekt an ein "Bashscript-Array" übergebe,

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

TomLee

Und was mach ich dann ?

Einen String übergeben in eine Variable und dann im Script erst ein Array draus machen ?

TomLee

#39
Kann ich mit Telnet kein Perl verwenden ?

Dann ist der Satz aus dem Wiki nicht ganz richtig

ZitatÜber Telnet kann man alles eingeben, was man auch über die Weboberfläche eingeben kann

Muss ich zuvor den String bspw. in ein Reading schreiben, das ich mit einem FHEM-Befehl darauf zugreifen kann ?

betateilchen

Zitat von: TomLee am 28 Juli 2020, 13:54:56
Kann ich mit Telnet kein Perl verwenden ?

Doch, und FHEM wird den Perl Code auch korrekt ausführen.

Zitat von: TomLee am 28 Juli 2020, 13:54:56
Dann ist der Satz aus dem Wiki nicht ganz richtig

Doch, denn da steht nur was von "eingeben", über den von FHEM zu erwartenden Rückgabewert steht nix geschrieben.

Zitat von: TomLee am 28 Juli 2020, 12:21:00
Einen String übergeben in eine Variable und dann im Script erst ein Array draus machen ?

Jepp. https://de.wikipedia.org/wiki/Serialisierung
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

ZitatDoch, und FHEM wird den Perl Code auch korrekt ausführen.

Komm nicht auf die Syntax, nichts klappt:

voucher=$(perl fhem.pl 7072 "{ReadingsVal("Unifi","voucher","unknown")}");
voucher=$(perl fhem.pl 7072 {ReadingsVal("Unifi","voucher","unknown")});
voucher=$(perl fhem.pl 7072 ReadingsVal("Unifi","voucher","unknown"));


Ein
{ReadingsVal("Unifi","voucher","unknown")}

aus der Befehlszeile macht was es soll gibt mir das userReadings zurück:
attr Unifi userReadings voucher {my @ar = (fhem("get Unifi voucherList 7d2x") =~ m,code.=.([0-9]{10}),g);;;;my $ar = join(',',@ar)}

(Ich weiß kein Trigger, weiß nicht welches Reading nehmen :P)




Was auch merkwürdig ist aber nur zu Testzwecken:
voucher=$(perl fhem.pl 7072 "get Unifi voucher 7d2x");


gibt mir korrekt wie oben schon den einen voucher zurück.

Mit
voucher=$(perl fhem.pl 7072 "get Unifi voucherList 7d2x");


klappts nicht.

Ist der String zu lang oder warum geht das nicht ?

==================================================================
code = xxxxxxxxxx
duration = 10080
note = 7d2x
quota = 2
status = VALID_MULTI
status_expires = 0
used = 0
delivered_at = Tue Jul 28 14:41:45 2020
==================================================================
code = xxxxxxxxxx
duration = 10080
note = 7d2x
quota = 2
status = VALID_MULTI
status_expires = 0
used = 0
delivered_at = Tue Jul 28 14:44:08 2020
==================================================================
code = xxxxxxxxxxx
duration = 10080
end_time = 1595864960
note = 7d2x
quota = 2
start_time = 1595260160
status = EXPIRED
status_expires = -76967
used = 1
delivered_at = Tue Jul 28 14:14:31 2020
==================================================================
Count: 3


TomLee

OK, OK. Es sind die Hochkommas und Semikola.

So klappts:

voucher=$(perl fhem.pl 7072 "{ReadingsVal('Unifi','voucher','unknown')}");
voucher=$(perl fhem.pl 7072 '{ReadingsVal("Unifi","voucher","unknown")}');

TomLee

Irgendwer ist mir irgendwann noch dankbar das ich noch festhalte wie man den String dann in ein Array bekommt:

#!/bin/bash

voucher=$(perl fhem.pl 7072 "{ReadingsVal('Unifi','voucher','unknown')}");
IFS=',' arr=($voucher)
sed -i 's/^\/Courier.*$/\/Courier findfont 20 scalefont setfont 70 330 moveto ('"${arr[2]}"') show showpage/' /opt/fhem/voucherx.ps;
lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/voucher.ps;

betateilchen

ich vermute, dass Du auch hier wieder von hinten durch die Brust ins Auge...

Was liefert denn der fhem-Aufruf als Ergebnis in die variable?
Wieso brauchst Du ein array, wenn Du davon nur einen einzigen Wert verwendest?

Und warum heißt die Datei einmal voucherx.ps und dann voucher.ps?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!