Hallo,
wie genau bekomme ich das was mir get Unifi voucher ...
zurückgibt (eine 10 stellige Zahl, mehr nicht ) in eine Textdatei ?
So klappts nicht:
FileWrite({ FileName=>"/opt/fhem/Gastzugang.txt", ForceType=>"file", NoNL => 0},fhem("get Unifi voucher 7d2x"))
War der Meinung es ginge im einfachsten Fall sowas :
FileWrite({ FileName=>"/opt/fhem/Gastzugang.txt", ForceType=>"file", NoNL => 0},'Test')
Klappt aber auch nicht .
Gruß
Thomas
-rw-r--r-- 1 fhem dialout 5 Jul 14 17:22 Gastzugang.txt
Zitat von: TomLee am 14 Juli 2020, 16:36:13
War der Meinung es ginge im einfachsten Fall sowas :
FileWrite({ FileName=>"/opt/fhem/Gastzugang.txt", ForceType=>"file", NoNL => 0},'Test')
Klappt aber auch nicht .
Und was steht in der Datei "Gastzugang.txt" denn drin? Die ist doch immerhin 5 Byte groß.
Bei mir klappt das Beispiel problemlos und in der Datei steht "Test" drin.
Das Beispiel mit der get-Rückgabe habe ich gerade mit einem Calendar-device (get oc_test vevents) getestet, das funktioniert auch einwandfrei.
{FileWrite({ FileName=>"/opt/fhem/Gastzugang.txt", ForceType=>"file", NoNL => 0},CommandGet(undef,'oc_test vevents'))}
liefert als Ergebnis
/opt/fhem# cat Gastzugang.txt
1: VEVENT @24 [known]
CREATED: 20190224T120417Z
DTEND: 20190224T150000
DTSTAMP: 20190224T120424Z
DTSTART: 20190224T140000
SEQUENCE: 0
SUMMARY: TestEreignis
TRANSP: OPAQUE
UID: 64BD5B49-06FC-44F3-9AF0-6958D84C3DFF
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR: AUTOMATIC
>>> Events:
>>> Skipped events:
2: VEVENT @35 [known]
CREATED: 20190224T090600Z
DTEND: 20190224T114500
DTSTAMP: 20190224T090605Z
DTSTART: 20190224T104500
SEQUENCE: 0
SUMMARY: Neues Ereignis
TRANSP: OPAQUE
UID: ACF19889-2E7A-4DA2-A343-7F0E1D9FB51E
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR: AUTOMATIC
>>> Events:
>>> Skipped events:
Alles gut, hab gerade gemerkt das mein Terminal am Rechner mir keinen Inhalt der Dateien anzeigte auf dem Rechner auf dem ich per SSH eingeloggt war, warum auch immer, einmal ausgeloggt und wieder ein und jetzt seh ich auch was passiert, sry.
Trotzdem Danke für die Rückmeldung.
Nächte Frage die mir etwas unklar ist:
Ich will die Datei auf Knopfdruck ausdrucken.
Habs ehrlich gesagt noch nicht ausprobiert aber ich denke ich brauch doch eine minimale Pause zwischen dem schreiben und anschließendem drucken Befehl und ich bin nicht im FHEM-Befehl.
Wie häng ich jetzt den drucken-Befehl (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.txt"))
an Filewrite an mit sleep ohne das das System steht, oder brauch ich keine Pause ?
$NAME eq "FB_433_2_TasteD" && $EVENT eq "on" ? (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.pdf")) : FileWrite({ FileName=>"/opt/fhem/Gastzugang.txt", ForceType=>"file", NoNL => 0},fhem("get Unifi voucher 7d2x"));
edit:
und wenn evtl. jemand einen Tipp hat wie man den Wert in der Datei zentriert ausgedruckt bekommt nehm ich den auch mit :)
man lpr bringt mich nicht weiter.
Warum willst Du überhaupt eine Datei erzeugen und gibst den Text nicht direkt auf den Drucker aus?
Zentriert drucken ist eher eine Frage von Postscript oder ähnlicher Druckersprache, die Dein Drucker beherrscht. Das ist nicht zwingend eine Option von lpr selbst.
ZitatWarum willst Du überhaupt eine Datei erzeugen ...
Schlicht, weil ich nur den Filewrite-Weg kenne, von
dir, bin halt mal kein IT-Mensch.
Vorausgesetzt die Frage zielt darauf ab ich könnte das einfacher umsetzen wär ich für weitere Hinweise wie "Text nicht direkt auf dem Drucker ausgeben" dankbar, weil die paar Schlagworte werden mich in Verbindung mit "FHEM" vermutlich nicht weiterbringen.
Postscript behalte ich im Hinterkopf und warte auf den Heureka-Effekt, beschäftigen werde ich mich nicht mit, aber Danke das ich jetzt eine Verbindung habe.
Naja, Du hast doch lpr auch selbst gefunden, was grundsätzlich völlig unabhängig von FileWrite() oder FHEM ist. Und lpr braucht nicht zwingend eine Datei als Eingabe, sondern kann auch direkt Daten entgegennehmen. Deshalb war meine Frage, warum Du eine Datei erzeugen willst - brauchst Du diese Datei denn für irgendwas anderes als zum Ausdrucken?
Meine Vermutung ist, dass Du das, was Du da tun willst, vielleicht auf Betriebssystemebene viel einfacher lesen könntest. Also das Erzeugen des voucher und den Ausdruck auf dem Drucker. Dafür könnte man ggf. ein Shell Skript erstellen, das beide Schritte abarbeitet. Dann müsstest Du aus FHEM heraus nur noch dieses Skript aufrufen und bräuchtest Dir keine Gedanken über Wartezeiten, blockierendes FHEM usw. machen.
Wie gesagt - das ist nur eine Vermutung. Aber ich denke, ich habe verstanden, was Du eigentlich tun willst und ich glaube nicht, dass die Aufgabenstellung ausschließlich über FHEM lösbar ist. Meines Erachtens lohnt es sich immer, auch über den Tellerrand zu schauen und ggf. alternative Lösungswege zu bewerten.
Deshalb war meine Frage, warum Du eine Datei erzeugen willst - brauchst Du diese Datei denn für irgendwas anderes als jetzt zum Ausdrucken?
Danke für den Stupser, berechtigte Frage, nee brauch eigentlich keine Datei nur drucken, fertig.
Weiter gehts mit einer Perl-Grundlagen Frage :P
Wie übergebe ich jetzt die Variable, wie ist die richtige Syntax ?
my $voucher = fhem('get Unifi voucher 7d2x');
(system("lpr -P HL-2035 -o media=Custom.95x138mm <<< $voucher"))
(system("lpr -P HL-2035 -o media=Custom.95x138mm <<< '$voucher'"))
(system("lpr -P HL-2035 -o media=Custom.95x138mm <<< ('$voucher')"))
Klappt alles nicht, wenn ich die myUtils speichern will.
(system("lpr -P HL-2035 -o media=Custom.95x138mm <<< ".$voucher))
DANKE
versteh ich auch sofort, noch nicht ausprobiert, aber weiß mittlerweile das es klappt.
Neues Problem und ich frag besser gleich.
Die Variable ist nicht bekannt, weil sie in dem System-Aufruf ist ?
syntax error at ./FHEM/99_myUtils_Remotes.pm line 86, near ") $NAME " Global symbol "$voucher" requires explicit package name (did you forget to declare "my $voucher"?) at ./FHEM/99_myUtils_Remotes.pm line 87.
sub my433RemoteCodesHandlerKueche {
my $NAME = shift;
my $EVENT = shift // return;
my $voucher = fhem('get Unifi voucher 7d2x')
$NAME eq "FB_433_2_TasteA" && $EVENT eq "on" ? fhem("set MQTT2_EG_Flur_Kueche_Tuer on") : fhem("set EG_Echo_Kueche notifications_delete ".(sprintf('fw@'. ReadingsVal('EG_Echo_Kueche','timer_id',0))));
$NAME eq "FB_433_2_TasteD" && $EVENT eq "on" ? (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.pdf")) : (system("lpr -P HL-2035 -o media=Custom.95x138mm <<< ".$voucher));
}
Wo genau muss ich die Variable my $voucher = fhem('get Unifi voucher 7d2x')
definieren, das ist mir jetzt völlig unklar, doch nicht im System-Aufruf ?
Ich würde sagen, es fehlt ein Semikolon nach "my $voucher = ..."
::)
Jetzt gibts aber immer noch keinen Druckauftrag.
Im Log steht:
2020.07.15 12:29:12 3: sduino IT: FB_433_2_TasteD on->off
2020.07.15 12:29:12 3: get Unifi voucher 7d2x : 9561737429
sh: 1: Syntax error: redirection unexpected
2020.07.15 12:29:12 3: not_FB_433_2_TasteX return value: -1
Alles korrekt bis auf das sh: 1: Syntax error: redirection unexpected
Zum Vergleich der andere System-Aufruf:
2020.07.15 12:28:41 3: sduino IT: FB_433_2_TasteD on->on
2020.07.15 12:28:41 3: get Unifi voucher 7d2x : 4790518579
2020.07.15 12:28:41 3: not_FB_433_2_TasteX return value: -1
die -1 ist normal, bekommt man auch über die Befehlszeile zurück.
$NAME eq "FB_433_2_TasteD" && $EVENT eq "on" ? (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.pdf")) : (system("lpr -P HL-2035 -o media=Custom.95x138mm <<< ".$voucher));
'<<<' ist ein bash Feature.
Perl nutzt aber /bin/sh (shell) und nicht bash (Bourne again shell)
Workaround: "bash -c ..." damit sh bash aufruft.
Wie ist das genau gemeint ?
<<< durch bash -c ersetzen ?
(system("lpr -P HL-2035 -o media=Custom.95x138mm bash -c 'Test' "))
ergibt im Log
2020.07.15 16:34:40 3: sduino IT_set: FB_433_2_TasteD off
2020.07.15 16:34:40 3: get Unifi voucher 7d2x : 9561737429
lpr: Fehler - Zugriff auf »bash« nicht möglich - Datei oder Verzeichnis nicht gefunden
2020.07.15 16:34:40 3: not_FB_433_2_TasteX return value: -1
lpr: Fehler - Zugriff auf »bash« nicht möglich - Datei oder Verzeichnis nicht gefunden
Im Terminal das gleiche
pi@FHEMSERVER:~ $ lpr -P HL-2035 -o media=Custom.95x138mm bash -c 'Test'
lpr: Fehler - Zugriff auf »bash« nicht möglich - Datei oder Verzeichnis nicht gefunden
lpr -P HL-2035 -o media=Custom.95x138mm <<< "Test"
Macht was es soll.
Mach zuerst /bin/sh
Dann bist Du im (nicht bash) Shell.
Jeztz macht vermutlich
lpr -P HL-2035 -o media=Custom.95x138mm <<< "Test"
nicht mehr was er soll.
Aus dem Shell musst Du dann explizit bash aufrufen und zum bash -c Parameter dein "bash script" als Parameter geben. Etwas wie:
bash -c 'lpr -P HL-2035 -o media=Custom.95x138mm <<< "Test"'
Zitatnicht mehr was er soll.
Ja dann klappts, aber wie mach ich das in der myUtils, kann doch nicht einfach ein bash -c vor die " im System-Aufruf schreiben.
$NAME eq "FB_433_2_TasteD" && $EVENT eq "on" ? (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.pdf")) : (system("lpr -P HL-2035 -o media=Custom.95x138mm <<< ".$voucher));
Und was mich noch stört ist das jetzt auch ein get gemacht wird wenn irgendeine Taste betätigt wird .
Kann man das auch noch umgehen ?
Nur ein get wenn TasteD off betätigt wird .
Dachte das liegt an der kurzen Variante von if, darum hab ich es auch mal so versucht, dann aber festgestellt das es bei jeder Taste gemacht wird:
return (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.pdf")) if $NAME eq "FB_433_2_TasteD" && $EVENT eq "on";
return (system(bash -c "lpr -P HL-2035 -o media=Custom.95x138mm bash -c 'Test' ")) if $NAME eq "FB_433_2_TasteD" && $EVENT eq "off";
Zitat von: TomLee am 15 Juli 2020, 18:05:11
kann doch nicht einfach ein bash -c vor die " im System-Aufruf schreiben.
Doch schon und das ist wahrscheinlich das einfachste.
system('/bin/bash -c "'. "blabla <<<" .$voucher.'"')
Es gibt 2 Alternativen:
- bash spezifische Features nicht benutzen (davon '<<<'). Man kann z.B. statt dessen
echo "Test" | lpr -P HL-2035 -o media=Custom.95x138mm
benutzen, wenn lpr das Piping akzeptiert
- backquotes benutzen statt system(). Wird aber mit einer Variable nicht einfach.
Oder man geht ja über eine Datei.
Oder wie betateilchen gesagt hat: über ein bash Skript auf System Ebene, das von fhem aufgerufen wird.
bei lpr würde ich immer mit piping arbeiten.
Danke.
Die einfache Variante klappt jetzt, bin ich vorerst zufrieden mit.
Was die Alternativen angeht, ist wohl einleuchtend das ich davon erstmal die Finger lasse.
Für nen Tipp mit dem get bei jeder Taste wär ich noch dankbar.
Und, aber da komm ich auch selbst drauf, vlt. gleich nen Tip dazu wie ich in dem Vergleich
$NAME eq "FB_433_2_TasteA && ..."
auch $NAME verwende und bspw. ein A anhänge.
Denke so in die Richtung aber noch nicht ausprobiert.
$NAME eq "$NAME".A &&
oder gleich mit einem Smartmatch ?
rein von der Logik her möchte ich behaupten, dass der Vergleich
$NAME eq "$NAME".A
niemals "wahr" ergeben kann.
Ja, Denkfehler. Ist gestrichen.
Das mit dem get ist wohl die Definition im notify ? reagiert immer bei jeder Taste.
Ich verstehs noch nicht, wird dann immer die Variable "abgerufen" ? gibts doch nicht ?
my $voucher = fhem('get Unifi voucher 7d2x');
FB_433_2_Taste.*:.* {my433RemoteCodesHandlerKueche ($NAME,$EVENT)}
Die Funktion wird von deinem notify bei jeder Taste aufgerufen.
Das "get" ist nicht in irgendeinem "if" sondern einfach so am Anfang der Routine, ohne Bedingung.
Dann wird es ja jedes mal gemacht, das ist klar.
Wenn Du es nur bei TasteD und "off" willst, dann musst Du es unter der if ($NAME eq "FB_433_2_TasteD" && $EVENT eq "off") Bedingung unterordnen.
Zitat von: TomLee am 15 Juli 2020, 20:56:49
Das mit dem get ist wohl die Definition im notify ? reagiert immer bei jeder Taste.
Ich verstehs noch nicht, wird dann immer die Variable "abgerufen" ? gibts doch nicht ?
Jetzt sind wir aber endgültig im Urschleim des logischen Denkens angekommen *kopfschüttel*
Bitte lies dringend die Dokumentation zu notify,
help notify
damit Du vielleicht doch noch irgendwann verstehst, was Du da eigentlich tust.
Mit bloßem Code-abschreiben und Copy&Paste kommst Du nicht dauerhaft weiter.
ZitatMit bloßem Code-abschreiben und Copy&Paste kommst Du nicht dauerhaft
Ich bin Ich, was auch immer du in den falschen Hals bekommen hast, gebs kund.
Mit 100% Sicherheit basiert die zitierte Aussage nicht auf copy&paste, einfach nur Unwissenheit, aber ich kann deine Gedanken nachvollziehen, während meiner letzten Posts ging mir genau das durch den Kopf, man könnte mir das vorwerfen.
Welch Wunder du hast es gemacht.
ZitatJetzt sind wir aber endgültig im Urschleim des logischen Denkens angekommen *kopfschüttel*
Mich fuchst es was dich genau zu dieser Aussage gebracht hat !?
$EVENT beinhaltet in dem Fall nicht das komplette Ereignis sondern nur on/off.
Man könnte auch EVTPART0 nehmen, ja, das hab ich mir zuvor angeschaut, aber für $EVENT entschieden. Nix copy&paste !
Was das notify angeht wüsst' ich aktuell nicht was ich mir eventuell noch anschauen soll das ich irgendwann verstehe was ich da tu.
Zu der letzten Frage bezüglich der Variable, die aber nicht das notify betrifft sondern mMn. Perl-Grundlagen, war mir
offensichtlich einfach nicht klar auf welcher Ebene man die Variable deklariert. Schlimm ?
Ich hab gefragt, hab ne Antwort bekommen, verstanden was ich zu tun habe und umgesetzt, fragen wird man doch noch dürfen wenn was unklar ist.
Zitat von: TomLee am 16 Juli 2020, 11:15:58
Was das notify angeht wüsst' ich aktuell nicht was ich mir eventuell noch anschauen soll das ich irgendwann verstehe was ich da tu.
Beispielsweise, wie man ein notify so definiert, dass es auch wirklich das tut, was Du eigentlich willst. Insbesondere geht es um den regex-Teil des notify.
Zitat von: TomLee am 16 Juli 2020, 11:15:58
Mich fuchst es was dich genau zu dieser Aussage gebracht hat !?
Naja, Du definierst zuerst ein notify
FB_433_2_Taste.*:.* {my433RemoteCodesHandlerKueche ($NAME,$EVENT)}
dessen regex zwingend
auf jeden event eines device reagiert. Und dann wunderst Du Dich darüber...
Zitat von: TomLee am 15 Juli 2020, 20:56:49
im notify ? reagiert immer bei jeder Taste.
Ich verstehs noch nicht, wird dann immer die Variable "abgerufen" ? gibts doch nicht ?
... dass genau das passiert: das notify reagiert
auf jeden event.
Für ich ist das ein klares Zeichen dafür, dass bezüglich des Verständnis von notify (und events in FHEM im Allgemeinen) noch Lernbedarf besteht. Deshalb der Verweis auf das notify.
Zitat von: TomLee am 16 Juli 2020, 11:15:58
Ich hab gefragt, hab ne Antwort bekommen
ja, Fragen ist halt immer einfacher und bequemer als Nachdenken (am besten VOR dem Nachfragen).
Zitat von: TomLee am 16 Juli 2020, 11:15:58
Mich fuchst es was dich genau zu dieser Aussage gebracht hat !?
Die regex eines notify gehören für mich zum FHEM-Urschleim. Und sie beruhen auf nichts anderem als Logik.
Möchte es mal so sagen... ich bin bestimmt der Letzte, der jemanden nicht weiterhelfen würde, wenn man wirklich mal nicht weiterkommt. Aber als "Gegenleistung" des Fragestellers erwarte ich dafür auch ein bisschen Mitarbeit und Engagement des Fragestellers bezüglich des Verstehens des vorgeschlagenen Lösungsweges.
Meistens poste ich ganz bewusst keine Lösung, die man per copy&paste einfach übernehmen kann, sondern versuche Hinweise auf einen möglichen Lösungsweg zu geben und in die richtige Richtung zu stupsen (siehe meine Hinweise zu LPR und der Textdatei, wo Dir das sogar doch noch aufgefallen war).
Bei Dir vermisse ich (als Helfender) aber ein bisschen diese Mitarbeit, es kommt einfach eine (meist simple) Frage nach der anderen und es erscheint mir sehr wahrscheinlich, dass Du ein paar der Fragen hättest
vermeiden selbst beantworten können, wenn Du Dir ein bisschen Mühe gegeben hätte (z.B. die Übergabe von Werten in einem Shell Skript). Ja, das kostet Zeit, aber sich die Mühe zu machen lohnt sich immer.
Übrigens: auch das Beantworten Deiner Fragen kostet Zeit. Das stört mich aber nicht, solange ich als Helfender erkenne, dass der Fragesteller sich mit den Antworten auseinandersetzt und daraus lernen möchte. Wenn ich das aber nicht erkenne, fuchst
mich das.
Zitat von: TomLee am 15 Juli 2020, 22:42:27
Ich bin Ich,
Ja, offensichtlich.
Nix für ungut, ich habe nix in den falschen Hals bekommen.
Was das notify angeht:
Ich hab letzte Woche, nach rd. 5 Jahren FHEM (angefangen mit null Programmierkentnissen), das erste mal ein notify ausgelagert, ja ich bin am experimentieren was wie geht, richtig erkannt.
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.
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.
ZitatMöchte es mal so sagen...
Ich verstehe sehr gut was du rüberbringen möchtest, ich denke nicht anders und deine Hinweise weiß ich immer zu schätzen.
Ja. ich gebe zu ich habs mir hier ausnahmsweise einfacher gemacht und schneller gefragt wie eigentlich üblich.
Hey, /bin/bash -c und Shell/Bash-Script, ich bin kein Programmierer, eine Hürde mit dem auslagern des notify geschafft und das mit weniger Kenntnis wie Perl-Grundlagen und schon wird von einem verlangt ein Script zu schreiben womit ich mich noch nie mit beschäftigt habe, klar fuchst mich das jetzt auch deswegen mach ich mich aber nicht verrückt und beschäftige mich damit zu gegebener Zeit auch wenns nochmal fünf Jahre dauern sollte bis dieser Tag kommt.
Ja, Ich bin Ich und ich mach weiter mit ganz einfachen Verständnisfragen im Anfängerbereich:
Was mich beschäftigt welche Variante von if ich jetzt im myUtils Code weiter verwenden soll, kann/darf ich mischen.
Weil die kurze Variante mit ? : ist mir am liebsten, soll aber eher für oneliner in FHEMWEB genutzt werden und bekomm ich keine Variable reingebastelt, auch in die return if Variante nicht.
Also besser auf die oneliner-Variante in einer myUtils ganz verzichten ?
Soll ich hier am Beispiel statt
return (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.pdf")) if $NAME eq "FB_433_2_TasteD" && $EVENT eq "on";
das besser in einem else Zweig von
if ($NAME eq "FB_433_2_TasteD" && $EVENT eq "off")
{my $voucher = fhem('get Unifi voucher 7d2x');
(system('/bin/bash -c "'. "lpr -P HL-2035 -o media=Custom.95x138mm <<<" .$voucher.'"'));
unterbringen?
Spricht was dagegen wenn keine Variable benötigt wird statt if () {} else {} wieder return if zu verwenden also wieder zu mischen ?
sub my433RemoteCodesHandlerKueche {
my $NAME = shift;
my $EVENT = shift // return;
$NAME eq "FB_433_2_TasteA" && $EVENT eq "on" ? fhem("set MQTT2_EG_Flur_Kueche_Tuer on") : fhem("set EG_Echo_Kueche notifications_delete ".(sprintf('fw@'. ReadingsVal('EG_Echo_Kueche','timer_id',0))));
return (system("lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/Gastzugang.pdf")) if $NAME eq "FB_433_2_TasteD" && $EVENT eq "on";
if ($NAME eq "FB_433_2_TasteD" && $EVENT eq "off")
{my $voucher = fhem('get Unifi voucher 7d2x');
(system('/bin/bash -c "'. "lpr -P HL-2035 -o media=Custom.95x138mm <<<" .$voucher.'"'));
}
}
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....).
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.
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.
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'
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 ?
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.
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;
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
Und was mach ich dann ?
Einen String übergeben in eine Variable und dann im Script erst ein Array draus machen ?
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 ?
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
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
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")}');
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;
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?
ZitatWas liefert denn der fhem-Aufruf als Ergebnis in die variable?
xxxxxxxxxxx,xxxxxxxxxxx,xxxxxxxxxxxx
ZitatWieso brauchst Du ein array, wenn Du davon nur einen einzigen Wert verwendest?
Ich werde (so der Plan, ausser du schlägst einen anderen Weg vor) beim ersten Tastendruck (https://forum.fhem.de/index.php/topic,113183.msg1074962.html#msg1074962) die voucher.ps (in ähnlicher Form, mit ${arr[0]}) und beim zweiten Tastendruck die erweiterte voucherx.ps (DIN A6 obere Hälfte mittig der erste voucher ${arr[0]},untere Hälfte mittig der zweite voucher ${arr[1]}, die ich aber noch nicht gezeigt habe/gar nicht existiert, aber später) ausdrucken.
Der Plan ist bisher, das mit den Tastendrücken sogar mit
Each und sleep in Verbindung mit
delete($defs{FB_433_2_TasteC}{EACH_INDEX}) umzusetzen, alles ohne Fragezeichen.
Und ? Gehe davon aus du hast überall mitgelesen, immer noch der Meinung: von hinten durch die Brust ins Auge... ?