Immer drei Codes vorhalten

Begonnen von TomLee, 25 Juni 2023, 13:10:57

Vorheriges Thema - Nächstes Thema

betateilchen

Zitat von: TomLee am 26 Juni 2023, 13:25:28Obs OK ist wenn ein neuer Code ergänzt wird, die alte Datei (der verbrauchte QR-Code) zu löschen und die verbleibenden zwei einfach zu überschreiben?

Das kannst Du machen, aber welchen Sinn hätte das? Die zwei neuen Dateien für die verbleibenden Codes würden sich doch nicht verändern.

In der Funktion bist Du ohnehin schon an einer Stelle, die nur durchlaufen wird, wenn es einen neuen Code gibt, dann reicht es völlig, einfach eine neue Datei für den neuen Code zu erzeugen.

Die Schleife, die Du da eingebaut hast, ist offensichtlich komplett überflüssig.

  return if ($oldSet eq $newSet);
  fhem("setreading du_reed codes $newSet");
  unlink "www/scripts/tmp/$checkVal.png";
  system("qrencode -o www/scripts/tmp/$newCode.png $newCode &");
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

#16
Stimmt  ::)

Ich kanns halt nicht lassen:

ZitatDu stehst Dir halt oft selbst im Weg und machst Dir unnötig das Leben schwer, weil Du in den allermeisten Fällen viel zu kompliziert denkst.

Danke

TomLee

Es gab schon irgendwie einen Grund, wenn man nicht einmal alle Dateien händisch anlegt, gibts immer nur eine .png.

TomLee

Für einen Vorschlag wie man es am besten löst irgendeine beliebige der drei Dateien auf Knopfdruck als Telegramnachricht zu senden wär ich dankbar.

Vom Zeitstempel der Erstellung abhängig machen geht mir durch den Kopf, bspw. die zuletzt erstellte, das Problem ist dann aber wenn es doch mal vorkommt das man einen zweiten QR-Code benötigt (das wird selten, bis gar nicht vorkommen, aber kann) und der zuerst angeforderte noch nicht verbraucht ist, dann ja immer der gleiche geschickt wird.

betateilchen

Du tust es schon wieder - wirres Denken.
Bitte formuliere die Anforderung einfach und eindeutig.

Zitat von: TomLee am 26 Juni 2023, 17:17:59irgendeine beliebige der drei Dateien

ist etwas völlig anderes als

Zitat von: TomLee am 26 Juni 2023, 17:17:59bspw. die zuletzt erstellte,
-----------------------
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: TomLee am 26 Juni 2023, 16:57:48Es gab schon irgendwie einen Grund, wenn man nicht einmal alle Dateien händisch anlegt, gibts immer nur eine .png.

Das ist völlig logisch.

Aber DAS ist auch wieder eine Anforderung, die nichts mit dem zu tun hat, was ursprünglich hier im Thread umgesetzt werden sollte.

Das erstmalige Anlegen der drei QR-Codes ist etwas komplett anderes als das Erzeugen eines neuen Codes nach dem Verbrauch eines existierenden.
-----------------------
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: TomLee am 26 Juni 2023, 17:17:59Für einen Vorschlag wie man es am besten löst irgendeine beliebige der drei Dateien auf Knopfdruck...

das Problem ist dann aber wenn es doch mal vorkommt das man einen zweiten QR-Code benötigt

Diese beiden Aufgaben in Kombination kannst Du z.B. so lösen:

defmod n_du_reed notify global:givemecode { Debug ((split(" ",ReadingsVal("du_reed","codes","0 0 0")))[Each("n_du_reed","0,1,2")]) }

Mit jedem Trigger "trigger global givemecode" (den Du natürlich anpassen kannst) wird einer der codes zurückgeliefert. Im Beispiel wird der code ins Log geschrieben, Du kannst ihn natürlich auch beliebig anders verwenden, z.B. um den Namen des qr-code-files zusammenzubauen und diese Datei dann verschicken zu können.

Auf "beliebige" und "nach Erstellungszeitpunkt" habe ich bewusst verzichtet. Die einzige sinnvolle Anforderung ist "nicht zweimal den gleichen Code hintereinander".
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

Vielen Dank für deine Hilfe.

TomLee

#23
Ich bekomm das so hin zu senden:

fhem("set tb_TelegramBot sendDocument www/scripts/tmp/".
((split(" ",ReadingsVal("MQTT2_dopen","codes","0 0 0")))[Each($SELF,"0,1,2")]).'.png')

Wenn ich ehrlich bin, ich verstehe die Syntax des Beispiel aber nicht, würd ich aber gerne.

Natürlich kenn ich split, ReadingsVal und Each, die Syntax, also warum  jede runde Klammer nötig/wichtig  ist und vorallem die Verwendung der eckigen, ist mir völlig unklar.

Wie ich die Rückgabe in eine Variable bekomme ist genauso unklar, bekomme ihn nur angehangen.

Wenns dir nicht zu doof und lästig ist, wär ich dankbar wenn du dazu ein paar Worte sagen könntest.

TomLee

Ah, das ist "Slice on the fly".

Die äusseren Klammern in deinem Beispiel braucht man aber nach jetzigem testen nicht, da muss ich gestern was falsch gemacht haben als ich das ohne die ausprobiert hatte.

TomLee

#25
Keine Ahnung was ich da gestern falsch gemacht hatte um den Rückgabewert in eine Variable zu bekommen, eigentlich nix anderes wie jetzt, wo es auf Anhieb ganz normal klappt:

{my $v=(split(' ',ReadingsVal('MQTT2_dopen','codes','0 0 0')))[Each('c_tb_push_qr','0,1,2')];; return $v;;}


Hier nochmal alles zusammengefasst wie ich vorhabe das in Zukunft zu nutzen:

sub dopen { #notify
my $checkVal  = shift // '0000';
my $dopenname = shift;
my $oldSet    = ReadingsVal($dopenname,'codes','0 0 0');
my @codes     = split(' ',$oldSet,3);
my $newCode   = sprintf('%04d',rand(9999));
@codes = map { $_ eq $checkVal ? $newCode : $_ } @codes;
my $newSet    = join(' ',@codes);
return if ($oldSet eq $newSet);
fhem("setreading $dopenname codes $newSet");
unlink "www/scripts/tmp/$checkVal.png";
system("qrencode -o www/scripts/tmp/$newCode.png $newCode &");
}

sub penopener { #notify
my $code     = shift // '0000';
my $dev      = shift;
my $devactor = shift;
my @codes    = split(' ',ReadingsVal($dev,'codes','0 0 0'));
fhem("set $devactor on") if ( grep( /^$code$/, @codes ) );
 }

sub pushqr { #cmdalias, IOS Shortcut
my $devpush  = shift;
my $devcodes = shift;
my $devindex = shift;
fhem("set $devpush sendDocument www/scripts/tmp/".(split(' ',ReadingsVal($devcodes,'codes','0 0 0')))[Each($devindex,'0,1,2')].'.png');
}

betateilchen

#26
Sorry, bin im Moment nicht zuhause und nur mit Tablet unterwegs, da macht Forum und antworten nicht so richtig Spaß.

Dein Konstrukt sieht ja soweit ganz brauchbar aus, bis auf das hier:

for (@codes) {
$code == $_ ? fhem("set $devactor on") : ''};

Das ist Käse.
Was ist die einfach formulierte Aufgabe? Du möchtest wissen, ob ein array einen bestimmten Wert enthält und (nur!) dann die Tür öffnen.
Es reicht also völlig, den Positiv-Fall zu beschreiben:

fhem("set $devactor on") if ( grep( /^$code$/, @codes ) );

-----------------------
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: TomLee am 28 Juni 2023, 12:39:23{my $v=(split(' ',ReadingsVal('MQTT2_dopen','codes','0 0 0')))[Each('c_tb_push_qr','0,1,2')];; return $v;;}

Warum der Umweg über eine Variable, wenn Du die Variable für nix anderes benutzt, als sie zurückzugeben? Das geht auch einfacher.

{ return (split(' ',ReadingsVal('MQTT2_dopen','codes','0 0 0')))[Each('c_tb_push_qr','0,1,2')] }
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

ZitatDas ist totaler Käse.

Verstehe dein Vorschlag zur Umsetzung als effizienter, über eine Schleife weniger effizient, aber nicht als totaler Käse.
Mit dem Hintergedanken das man es besser machen könnte hab ich das ja auch gepostet (darum gings bisher ja nicht) und gehofft das du (oder wer anders) da nochmal drüber schaut und evtl. Optimierungspotential sieht.



ZitatWarum der Umweg über eine Variable, wenn Du die Variable für nix anderes benutzt, als sie zurückzugeben?

Ich hatte die Syntax ja zuerst nicht verstanden und beim beschäftigen damit wollt ich die Rückgabe in einer Variablen haben, einfach nur zum Verständnis/lernen.
Wie man an meiner Zusammenfassung sieht hab ich den Umweg über eine Variable in dem cmdalias ja nicht verwendet, da unnötig.



Der Vollständigkeit wegen, hier steht der Sketch den ich verwende.



Ich bin Dir sehr dankbar für deine Hilfe.

TomLee

Mir kommt das eben erst (du hast ja sicher mitgelesen), ich bin nur am Tablet, bin am grillen und hab das nur nebenbei ausprobier (bis jetzt nicht weiter mit beschäftigt, aber es tut was es soll).

Spricht was gegen die Match-Variante:

sub penopener { #notify
my $code   = shift // '0000';
my $dev = shift;
my $devactor = shift;
#my @codes  = split(' ',ReadingsVal($dev,'codes','0 0 0'));
my $codes = ReadingsVal($dev,'codes','0 0 0');
#fhem("set $devactor on") if ( grep( /^$code$/, @codes ) );
fhem("set $devactor on") if $codes =~ $code;
 }