FHEM Forum

FHEM => Automatisierung => Thema gestartet von: betateilchen am 14 März 2024, 12:48:20

Titel: [patch] 98_structure.pm: Zufällige Auswahl der beinhalteten devices schalten
Beitrag von: betateilchen am 14 März 2024, 12:48:20
Seit einiger Zeit überlege ich, wie ich folgendes Szenario am einfachsten lösen könnte.

Es gibt in meiner Bücherwand verteilt zehn Deko-Leuchten, die in einer structure zusammengefasst sind.
Nun suche ich eine Möglichkeit, aus diesen zehn nur eine bestimmte Anzahl zufällig ausgewählter Leuchten einzuschalten.

Irgendwas in der Art

set structureName on random 4
um vier von den zehn Leuchten einzuschalten.

Aktuell behelfe ich mir mit mehreren structures, in denen immer vier Leuchten (fest) eingetragen sind und die mittels EACH() nacheinander geschaltet werden.
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: MadMax-FHEM am 14 März 2024, 13:06:01
cmdalias?

Dann in Perl: z.B. Array aus deinen Lampen und per "random" dann einen (oder 4) index wählen und schalten?
Müsste sogar mit unterschiedlichen Anzahlen gehen? Weiß grad nicht, wie man an die "Parameter" bei cmdalias kommt...
$EVTPARTx?

Würde ich mal versuchen, wenn ich sowas bräuchte/wollte...

Gruß, Joachim
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: betateilchen am 14 März 2024, 13:23:04
Zitat von: MadMax-FHEM am 14 März 2024, 13:06:01Dann in Perl: z.B. Array aus deinen Lampen und per "random" dann einen (oder 4) index wählen und schalten?

Natürlich kann man das alles auch in eine Funktion in den myUtils packen. Aber die Aufgabe ist schon ein bisschen komplexer. Es sollen ja immer genau 4 (oder eine andere vorgegebene Anzahl) geschaltet werden und nicht nur "bis zu 4". Man muss deshalb auch prüfen, ob ein zufällig ermittelter Index schon für die "Ergebnisliste" ausgewählt wurde.

Wahrscheinlich handelt es sich aber um ein Einzelschicksal...  8)
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: MadMax-FHEM am 14 März 2024, 13:38:40
Zitat von: betateilchen am 14 März 2024, 13:23:04ob ein zufällig ermittelter Index schon für die "Ergebnisliste" ausgewählt wurde.
Ja klar, dachte aber dass das auch für dich klar ist ;)

"Man" kann sich doch leicht merken, welcher Index schon per random ermittelt wurde...

Ja, klar nicht so einfach wie das structure Modul zu erweitern/erweitern zu lassen und dann einfach benutzen 8)

Viel Erfolg, Joachim
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: betateilchen am 14 März 2024, 22:03:48
Zitat von: betateilchen am 14 März 2024, 13:23:04Wahrscheinlich handelt es sich aber um ein Einzelschicksal...  8)

- verbesserter code im weiteren Verlauf -

Mit

set <structName> on random:3
kann ich jetzt (beispielsweise) drei zufällig ausgewählte Leuchten einschalten.
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: LutzG am 15 März 2024, 00:15:28
Hallo betateilchen,

mir fallen dabei Lotto-Zahlen ein:
http://www.hidemail.de/blog/rand-perl.shtml

Viele Grüße, Lutz
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: betateilchen am 15 März 2024, 09:14:11
Ja, das ist so ähnlich.
Meine Lösung oben funktioniert ja wie gewünscht, trotzdem danke für Deinen Link.
Das dort im Beispiel aufgeführte "redo" innerhalb einer Schleife kannte ich bis heute noch nicht (oder ich hatte es erfolgreich verdrängt) :)

Damit geht das Ganze sogar noch einfacher.

Index: /opt/fhem/FHEM/98_structure.pm
===================================================================
--- /opt/fhem/FHEM/98_structure.pm      (Revision 28667)
+++ /opt/fhem/FHEM/98_structure.pm      (Arbeitskopie)
@@ -429,6 +429,21 @@
     @devList = reverse @devList;
   }
 
+  if(@list > 1 && $list[$#list] =~ m/^random:(\d+)/) {
+    my $selCount = $1;
+    my $devCount = $#devList + 1;
+    $selCount    = $devCount if ($selCount > $devCount || $selCount < 1);
+    my @selDev   = @devList;
+    @devList     = ();
+    for (1..$selCount) {
+      my $n = int(rand($devCount));
+      redo if ($selDev[$n] eq "");   
+      push(@devList,$selDev[$n]);
+      $selDev[$n] = "";
+    }
+    pop @list;   
+  }
+
   if($list[1] =~ m/^(save|restore)StructState$/) {
     return "Usage: set $me $list[1] readingName" if(@list != 3);
     return "Bad reading name $list[2]" if(!goodReadingName($list[2]));
@@ -670,7 +685,9 @@
     propagated set for the attached devices like this: <code>set
     &lt;devN&gt;:FILTER=&lt;filter&gt; &lt;type-specific&gt;</code><br>
     If the last set parameter is "reverse", then execute the set commands in
-    the reverse order.
+    the reverse order.<br/>
+    If the last set parameter is given as "random:4" only 4 structure members will
+    be selected randomly which will receive the given command.<br/>
   </ul>
   <br>
 
@@ -899,15 +916,17 @@
       </li><br>
     Jedes andere set Kommando wird an alle Devices dieser Struktur
     weitergegeben.<br>
-    Aussnahme: das Attribut structexclude ist in einem Device definiert und
+    Ausnahme: das Attribut structexclude ist in einem Device definiert und
     dessen Attributwert matched als Regexp zum Namen der aktuellen
     Struktur.<br> Wenn das set Kommando diese Form hat <code>set
     &lt;structure&gt; [FILTER=&lt;filter&gt;] &lt;type-specific&gt;</code> wird
-    :FILTER=&lt;filter&gt; bei der Weitergebe der set an jeden Devicenamen wie
+    :FILTER=&lt;filter&gt; bei der Weitergabe der set an jeden Devicenamen wie
     folgt angeh&auml;ngt: <code>set &lt;devN&gt;:FILTER=&lt;filter&gt;
     &lt;type-specific&gt;</code><br>
     Falls der letzte Parameter reverse ist, dann werden die Befehle in der
-    umgekehrten Reihenfolge ausgef&uuml;hrt.
+    umgekehrten Reihenfolge ausgef&uuml;hrt.<br/>
+    Falls der letzte Parameter dem Muster "random:4" entspricht, erhalten nur 4
+    zuf&auml;llig ausgew&auml;hlte Devices den Befehl.<br/>
   </ul>
   <br>
   <a id="structure-get"></a>
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: UweH am 16 März 2024, 17:43:35
Zitat von: betateilchen am 14 März 2024, 13:23:04Wahrscheinlich handelt es sich aber um ein Einzelschicksal...  8)

Nee, wir sind dann mal eine Schicksalsgemeinschaft.  ;)
Sowas brauche ich auch. Spätestens zur nächsten Weihnachtsdekoration.

Gruß
Uwe
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: betateilchen am 16 März 2024, 18:11:27
Nagut, dann sind wir schon zwei.
Normalerweise baut Rudi solche Änderungen ab 3 Fürsprechern ein.
Mal schauen, ob noch jemand kommt, der das gebrauchen kann 8)

Die commandref-Ergänzung würde ich dann noch beisteuern.
Titel: Aw: [structure] Suche Idee: Zufällige Auswahl der beinhalteten devices einschalten
Beitrag von: enno am 16 März 2024, 19:39:13
Moin zusammen,

Ich könnte mir auch vorstellen das zu nutzen. Wenn keiner Zuhause, ich mache das zur Zeit mit einer etwas aufwendigen "Konstruktion". Mit so einer zufälligen Version ginge es einfacher.

https://forum.fhem.de/index.php?topic=96488.msg895404#msg895404

Gruss
  Enno
Titel: Aw: [patch] 98_structure.pm: Zufällige Auswahl der beinhalteten devices schalten
Beitrag von: betateilchen am 16 März 2024, 19:45:31
Zitat von: betateilchen am 16 März 2024, 18:11:27Die commandref-Ergänzung würde ich dann noch beisteuern.

Ist inzwischen erledigt und im patch oben enthalten.
Titel: Aw: [patch] 98_structure.pm: Zufällige Auswahl der beinhalteten devices schalten
Beitrag von: rudolfkoenig am 17 März 2024, 10:16:56
Habs unveraendert eingecheckt.
Achtung: "set struct X random:Y" kann theoretisch(!) eine Endlosschleife produzieren.
Titel: Aw: [patch] 98_structure.pm: Zufällige Auswahl der beinhalteten devices schalten
Beitrag von: betateilchen am 17 März 2024, 10:42:58
Zitat von: rudolfkoenig am 17 März 2024, 10:16:56Habs unveraendert eingecheckt.

Danke.

Zitat von: rudolfkoenig am 17 März 2024, 10:16:56Achtung: "set struct X random:Y" kann theoretisch(!) eine Endlosschleife produzieren.

Ja, theoretisch schon.

Über eine zusätzliche Abbruchbedingung hatte ich zwar nachgedacht, aber dann hätte ich einen Zähler für die Durchläufe gebraucht, den ich mit einer Maximalzahl vergleiche. Den zusätzlichen Aufwand wollte ich nicht betreiben, zumal mir kein klares Kriterium für eine Maximalzahl einfiel.