Immer drei Codes vorhalten

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

Vorheriges Thema - Nächstes Thema

TomLee

Der Titel hat noch wenig mit meiner ersten Frage zu tun, wenn mir jemand bitte hilft, ergibt sich das aber noch im weiteren Verlauf.

Gegeben sind zum testen:

defmod du_reed dummy
attr du_reed setList on off

setstate du_reed on
setstate du_reed 2023-06-25 02:34:11 codes 1234 5678 9101
setstate du_reed 2023-06-25 12:50:21 state on

Und der dummy (wird erst später gebraucht):
defmod du_doorpen dummy

setstate du_doorpen 1234
setstate du_doorpen 2023-06-24 17:15:11 state 1234

Macht wenig Sinn die Elemente von einem Array in das andere zu stupsen, ist nur beispielhaft, es soll aber mein Unverständnis verdeutlichen.
Das hier funzt:

defmod not_du_reed notify du_reed:on {\
my @codes = split(' ',ReadingsVal('du_reed','codes',0));;\
my @a;;\
for (@codes){\
push (@a,$_) }\
return join q( ), @a;;\
}

Warum klappt das dann nicht genauso mit der Schleife wenn ich die Elemente des Array in einem Hash als Key haben möchte, @codes gibt doch genauso die Anzahl zurück ?
(Ich erwähns gleich, die Elemente als Key deswegen, weil später beim auslösen des notify das Schlüssel->Wert-Paar aus dem Hash gelöscht werden soll, das zu dem Wert in dem du_doorpen dummy passt)

defmod not_du_reed notify du_reed:on {\
my @codes = split(' ',ReadingsVal('du_reed','codes',0));;\
my %hcodes=();;\
my @a = keys(%hcodes);;\
\
for (@codes){\
$hcodes{"$codes[$_]"}=$_};;\
print Dumper \%hcodes;;\
}

Ergibt:
2023.06.25 12:50:21 1: PERL WARNING: Use of uninitialized value within @codes in string at (eval 3369) line 7.
2023.06.25 12:50:21 3: eval: my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $NAME=   $evalSpecials->{'%NAME'};my $SELF=   $evalSpecials->{'%SELF'};my $TYPE=   $evalSpecials->{'%TYPE'};{
my @codes = split(' ',ReadingsVal('du_reed','codes',0));
my %hcodes=();
my @a = keys(%hcodes);

for (@codes){
$hcodes{"$codes[$_]"}=$_};
print Dumper \%hcodes;
}
$VAR1 = {
          '' => 9101
        };
2023.06.25 12:50:21 3: not_du_reed return value: 1

Ich bekomms nur mit Hilfe des Bereichsoperator hin:

defmod not_du_reed notify du_reed:on {\
my @codes = split(' ',ReadingsVal('du_reed','codes',0));;\
my %hcodes=();;\
\
for (0..@codes-1){\
$hcodes{"$codes[$_]"}=$_};;\
print Dumper \%hcodes;;\
}

TomLee

ZitatMal wieder von hinten durch die Brust ins Auge?

Ich mein nicht das die Verwendung von Each mich hier weiter bringt. Du bist aber immer schon 5 Schritte voraus, wo ich gerade mal beim zweiten bin, vlt. dann nicht ganz auszuschliessen.

Wenn du_reed auslöst wird, soll das Schlüsselpaar das zu dem Wert in du_doorpen passt aus dem Hash gelöscht werden (Code verbraucht).

Das klappt auch, so:

defmod not_du_reed notify du_reed:on {\
my @codes = split(' ',ReadingsVal('du_reed','codes',0));;\
my %hcodes=();;\
\
for (1..@codes-1){\
$hcodes{"$codes[$_]"}=$_};;\
if (exists $hcodes{ReadingsVal('du_doorpen','state',0)}) {\
delete($hcodes{ReadingsVal('du_doorpen','state',0)});;\
};;\
print Dumper \%hcodes;;\
}

Aber dann komm ich nicht weiter, es soll der verbrauchte Code ersetzt werden durch einen neuen -> immer drei Codes vorgehalten werden:

du_reed:on {
my @codes = split(' ',ReadingsVal('du_reed','codes',0));
my %hcodes=();
my @a = keys(%hcodes);

for (1..@codes-1){
$hcodes{"$codes[$_]"}=$_};
if (exists $hcodes{ReadingsVal('du_doorpen','state',0)}) {
delete($hcodes{ReadingsVal('du_doorpen','state',0)});
push (@a,int(rand(9999)));
my $v = join q( ), @a;
fhem("setreading du_reed codes $v");
};
#print Dumper \%hcodes;
}

Warum wird alles was nach dem delete steht nicht ausgeführt ?

betateilchen

#2
Zitat von: TomLee am 25 Juni 2023, 14:20:05Ich mein nicht das die Verwendung von Each mich hier weiter bringt. Du bist aber immer schon 5 Schritte voraus, wo ich gerade mal beim zweiten bin, vlt. dann nicht ganz auszuschliessen.

Meinen Vorschlag mit Each() hatte ich wieder gelöscht, weil ich trotz mehrmaligem Lesen Deines Beitrags immer noch nicht verstanden hatte, was Du als Ergebnis haben möchtest, bzw. was die grundsätzliche Aufgabenstellung ist.

Beispielsweise verstehe ich das hier schon nicht:

my %hcodes=();
my @a = keys(%hcodes);

Was soll denn in @a landen, wenn in %hcodes überhaupt noch nichts drinsteht, weil es erst in der Zeile davor leer instanziert wird?

Und warum willst Du eigentlich krampfhaft mit einem hash arbeiten, wenn die Werte doch schon in einem array stehen, das Du entsprechend verwenden kannst?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Die Aufgabe besteht darin, durch ein notify eine Liste mit 3 zufälligen 4-stelligen (!) Werten zu befüllen, indem jeweils ein "verbrauchter" Wert durch einen anderen ersetzt wird - korrekt?

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

TomLee

ZitatUnd warum willst Du eigentlich krampfhaft mit einem hash arbeiten, wenn die Werte doch schon in einem array stehen, das Du entsprechend verwenden kannst?

Ist es verständlicher nach meinem letzten Beitrag ?

TomLee

Zitat von: betateilchen am 25 Juni 2023, 14:32:24Die Aufgabe besteht darin, durch ein notify eine Liste mit 3 zufälligen 4-stelligen (!) Werten zu befüllen, indem jeweils ein "verbrauchter" Wert durch einen anderen ersetzt wird - korrekt?

Genau, mit qrencode, will ich noch entsprechende QR-Codes erzeugen und den jewiligen verbrauchten löschen und eunen neuen ergänzen.
Damit hab ich mich bisher aber noch nicht beschäftigt wie ich das umsetze  ::)

betateilchen

#6
Zitat von: TomLee am 25 Juni 2023, 14:32:44Ist es verständlicher nach meinem letzten Beitrag ?

Nein, es erklärt nicht, warum Du den hash brauchst.

Zitat von: betateilchen am 25 Juni 2023, 14:32:24Die Aufgabe besteht darin, durch ein notify eine Liste mit 3 zufälligen 4-stelligen (!) Werten zu befüllen, indem jeweils ein "verbrauchter" Wert durch einen anderen ersetzt wird - korrekt?

sub du_test {
  my $checkVal = shift // "0000";
  my @codes = split(' ',ReadingsVal('du_reed','codes',"0 0 0"),3);
  my $newCode = sprintf("%04d",rand(9999));
  @codes = map { $_ eq $checkVal ? $newCode : $_ } @codes;
  return join(" ",@codes);
}

Die Funktion wird vom notify aus mit dem Wert aus du_doorpen aufgerufen.

du_reed:on {du_test(ReadingsVal('du_doorpen','state','0000'))}

Das setreading ist in der Funktion noch nicht enthalten.

Ansonsten tut die Funktion genau das was Du möchtest:
Sie ersetzt einen vorhandenen Wert, der als Parameter übergeben wird, durch einen neuen, wenn der übergebene Wert im Array gefunden wurde.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

#7
Hier noch die Variante mit eingebautem setreading:

sub du_test {
  my $checkVal = shift // "0000";
  my @codes = split(' ',ReadingsVal('du_reed','codes',"0 0 0"),3);
  my $newCode = sprintf("%04d",rand(9999));
  @codes = map { $_ eq $checkVal ? $newCode : $_ } @codes;
  CommandSetReading(undef,"du_reed codes ".join(" ",@codes));
}

Zitat von: TomLee am 25 Juni 2023, 14:36:47mit qrencode will ich noch entsprechende QR-Codes erzeugen

Das lässt sich problemlos in die Funktion einbauen.

Dass es für die Erzeugung von QR-Codes in FHEM ein eigenes Modul gibt, weißt Du hoffentlich.
Vielleicht lässt sich das sogar hier einbinden.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

ZitatNein, es erklärt nicht, warum Du den hash brauchst.

Ich war der Meinung man kann in einem Array ein bestimmtes Element nicht ersetzen, nur anfügen, darum dann der Gedanke das über den Schlüssel eines Hash zu machen.

Auf den Vergleich und ersetzen in der Schleife wär/bin ich nicht gekommen, das ist sehr cool, vielen Dank dafür.

Warum du in split den Parameter LIMIT extra angegeben hast und den Ersatzwert mit Komma getrennt, versteh ich noch nicht, aber ich merk mir das und werd mich mit beschäftigen.

Das Beispiel mit dem setreading wär nicht nötig gewesen soviel hab ich bis jetzt schon verstanden das selbst umzusetzen, trotzdem aber auch danke dafür. Ich werd aber bei setreading bleiben und nicht CommandSetReading verwenden.

Ich bin nicht der schnellste aber ich werd das mit qrencode auch hinbekommen, die Frage die sich mir halt als erstes stellt, ist es ein Problem immer alle Dateien zu ersetzen oder soll man es so umsetzen das nur die ersetzt wird deren Code verbraucht wurde.

Ich hab mich bisher schon mit dem Modul beschäftigt und mit qrencode, das Modul nutzt einen externen Service und ich frag mich ob das sein muss wenn es auch einfach mit qrencode geht.

betateilchen

#9
Zitat von: TomLee am 25 Juni 2023, 16:09:09Warum du in split den Parameter LIMIT extra angegeben hast

Weil ich nicht mehr als 3 Werte zurückbekommen möchte.
Um den Code an dieser Stelle in diesem Punkt auch in 2 Jahren noch nachvollziehbar zu machen, gebe ich den Parameter explizit an.

Zitat von: TomLee am 25 Juni 2023, 16:09:09und den Ersatzwert mit Komma getrennt, versteh ich noch nicht,

Weil Du deinen Code immer auch mindestens einmal mit den "default" Werten aus ReadingsVal() oder ReadingsNum() durchspielen solltest, um zu prüfen, ob er auch dann noch fehlerfrei funktioniert. Wenn Du bei ReadingsVal() einen numerischen Wert als default zurückgibst, kannst Du den nicht mit split() als String aufteilen.

Zitat von: TomLee am 25 Juni 2023, 16:09:09die Frage die sich mir halt als erstes stellt, ist es ein Problem immer alle Dateien zu ersetzen oder soll man es so umsetzen das nur die ersetzt wird deren Code verbraucht wurde.

Das verstehe ich nicht.

Zitat von: TomLee am 25 Juni 2023, 16:09:09das Modul nutzt einen externen Service und ich frag mich ob das sein muss wenn es auch einfach mit qrencode geht.

qrencode ist nicht "einfach".
Man kann sich fragen, ob man einen externen Service verwenden möchte oder nicht, ok.
Aber man muss auch nicht permanent versuchen, das Rad neu zu erfinden.
Wenn sich jemand schon soweit Gedanken gemacht hat, dass man an eine URL nur einen Wert anhängen muss, um einen QR-Code zu bekommen, kann und soll man diese Vorarbeit ruhig nutzen.

sub du_test {
  my $checkVal = shift // "0000";
  my $oldSet   = ReadingsVal('du_reed','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);
  CommandSetReading(undef,"du_reed codes $newSet");
  return "<html><img src=\"http://qrcode.tec-it.com/API/QRCode?data=$newCode\" /></html>";
}

Testen kannst Du das in der FHEM Befehlszeile mit {du_test "<gültiger CODE>"}, Du bekommst dann automatisch den QR-Code für den neuen Code angezeigt.



Zitat von: TomLee am 25 Juni 2023, 16:09:09Ich war der Meinung man kann

Meinung != Wissen
-----------------------
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 25 Juni 2023, 16:09:09den Ersatzwert mit Komma getrennt, versteh ich noch nicht,

Stimmt, an dieser Stelle wären Leerzeichen richtig gewesen, habs korrigiert.
War gedanklich beim Schreiben an einer anderen Stelle.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

Lass mir mal etwas Zeit (kann auch bis morgen dauern) das alles zu verarbeiten/Gedanken über eine Umsetzung mit qrencode zu machen.

Ich brauch am Ende die Dateien, die Anzeige des QR-Code in FHEMWEB bringt mir nix, kann aber auch hier wieder sein das ich nicht sehe was du aufzeigen möchtest.


TomLee

Ah, schon beim abschicken kam mir was du zeigen wolltest, ich brauch nur die URL, die Anzeige in FHEMWEB ist nur ein Beispiel.

Trotzdem, ich würd das gerne erstmal alles selbst verarbeiten und selbst Gedanken machen und nicht alles vorgeworfen bekommen, auch wenn das nett gemeint ist.

betateilchen

Zitat von: TomLee am 25 Juni 2023, 16:48:36Trotzdem, ich würd das gerne erstmal alles selbst verarbeiten und selbst Gedanken machen und nicht alles vorgeworfen bekommen, auch wenn das nett gemeint ist.

Du 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.

Fang doch mal damit an, einfaches und logisches Denken zu lernen.

Zum Beispiel die eigentliche Aufgabenstellung, die Du lösen möchtest, in einem Satz zu beschreiben anstatt in drei nicht funktionierenden CODE-Schnipseln.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

Zitat von: betateilchen am 25 Juni 2023, 16:23:22Das verstehe ich nicht.

Nochmal anders.
Obs 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?

sub du_test {
  my $checkVal = shift // "0000";
  my $oldSet   = ReadingsVal('du_reed','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 du_reed codes $newSet");
  system("rm www/scripts/tmp/$checkVal.png &");
  for (@codes) {
  system("qrencode -o www/scripts/tmp/$_.png $_ &")};
}

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;
 }

betateilchen

Zitat von: TomLee am 08 Juli 2023, 20:15:59Spricht was gegen die Match-Variante:

Mal wieder nicht zu Ende gedacht?

Kann man so machen, wird dann halt Mist...

codes = "1234 5678 9012"
code = "1234"

  • passt
  • die Tür geht auf

Aber:

codes = "1234 5678 9012"
code = "12"

  • passt auch - sogar zweimal
  • die Tür geht auf
  • Du findest aber mit 12 keinen passenden Code, den Du als "verbraucht" erkennen und ersetzen kannst

Wenn man das Öffnen einer Tür von einem Code abhängig macht, dann sollte man den Code auch eindeutig und genau prüfen und nicht anhand eines Musters "schätzen".
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

#31
Ok.

Ich hab mich gestern nicht mehr dran gemacht, mein Plan war mich jetzt die nächsten zwei Stunden mit zu beschäftigen, vlt. wär ich da dann auch selbst drauf gekommen, Danke.

Das ist ja ein regulärer Ausdruck, kann man den Match nicht genau auf das "Suchmuster" einschränken, mit ^ und  $ ?

Fang jetzt an mich dazu einzulesen / damit zu beschäftigen.

TomLee

#32
Es scheint mit \b umsetzbar zu sein:

Bei der Notation bin ich aber unsicher wie jetzt genau, es klappt mit und ohne m
fhem("set $devactor on") if $codes =~ /\b$code\b/;fhem("set $devactor on") if $codes =~ m/\b$code\b/;
Was sagst du dazu/ hältst du davon ?

betateilchen

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

TomLee

#34
Aus welchem Grund ?

Ich soll also bei der grep-Variante bleiben ?

betateilchen

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

TomLee

#36
ZitatWas verstehst Du an "nix" nicht?

Darum gehts net, den Thread werden viele lesen, mitunter so Laien wie ich .
Die (evtl. nicht nur die Laien) werden sich die gleiche Frage stellen, aus welchem Grund du deine Meinung zu der Match-Variante für dich behältst.