[patch] 98_structure.pm: Zufällige Auswahl der beinhalteten devices schalten

Begonnen von betateilchen, 14 März 2024, 12:48:20

Vorheriges Thema - Nächstes Thema

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

MadMax-FHEM

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
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

betateilchen

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)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

MadMax-FHEM

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
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

LutzG

DMZ: J5040 mit OpenMediaVault, in Docker: Portainer, Fhem, MariaDB, zigbee2mqtt, esphome, NextCloudPi, Jellyfin, Grocy.
Intranet: J5005 mit OpenMediaVault, in Docker: Portainer, Fhem-minimal, urbackup - läuft nur, wenn Rechner laufen.

betateilchen

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>
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

UweH

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

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

enno

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
Einfacher FHEM Anwender auf Intel®NUC

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Habs unveraendert eingecheckt.
Achtung: "set struct X random:Y" kann theoretisch(!) eine Endlosschleife produzieren.

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!