98_structure.pm: Status aller structure-members abfragen

Begonnen von betateilchen, 10 September 2025, 19:59:29

Vorheriges Thema - Nächstes Thema

betateilchen

Heute war ich auf der Suche nach einer simplen Möglichkeit, den Zustand aller in einer structure enthaltenen devices abzufragen, um die Informationen in einer Anwendung außerhalb der structure weiterzuverarbeiten.

Am Ende habe ich das Modul um eine GetFn erweitert.

Als Ergebnis von "get <structureName> structState" bekommt man einen serialisierten hash mit deviceName und state zurück:

d1,d1state,d2,d2state
Diese Daten kann man beispielsweise so weiterverarbeiten:

use Data::Dumper;
sub test {
my %t = split(",",CommandGet(undef,'<structureName> structState')) ;
return Dumper \%t;
}

und führt zum Ergebnis:

$VAR1 = {
          'd1' => 'd1state',
          'd2' => 'd2state'
        };

Die Lösung ist sicherlich nicht perfekt und für alle Eventualitäten geeignet (z.B. bei Komma im state...), aber sie erfüllt erstmal ihren Zweck, hat mir bei meinem Problem weitergeholfen und vielleicht kann ja noch jemand außer mir etwas damit anfangen :)


Index: 98_structure.pm
===================================================================
--- 98_structure.pm     (revision 30255)
+++ 98_structure.pm     (working copy)
@@ -40,6 +40,7 @@
   $hash->{UndefFn}   = "structure_Undef";
   $hash->{NotifyFn}  = "structure_Notify";
   $hash->{SetFn}     = "structure_Set";
+  $hash->{GetFn}     = "structure_Get";
   $hash->{AttrFn}    = "structure_Attr";
   no warnings 'qw';
   my @attrList = qw(
@@ -406,7 +407,23 @@
   return undef;
 }
 
+###################################
+sub
+structure_Get($@)
+{
+  my ($hash, @list) = @_;
+  my $me = $hash->{NAME};
+  my $ret = "";
+  my @devList = @{$hash->{".memberList"}};
 
+  if($list[1] eq 'structState') {
+    $ret = join(",", map { join(",",($_, ReadingsVal($_,"state","on"))) } @devList)
+  }
+
+  return $ret if($list[1] ne "?");
+  return "Unknown argument ?, choose one of structState:noArg";
+}
+
 ###################################
 sub
 structure_Set($@)
@@ -694,7 +711,10 @@
   <a id="structure-get"></a>
   <b>Get</b>
   <ul>
-    get is not supported through a structure device.
+    <a id="structure-get-structState"></a>
+    <li>structState<br>
+      Return a serialized hash of all members and their state reading.
+      </li><br>
   </ul>
   <br>
 
@@ -758,7 +778,7 @@
           <li>attr kitchen clientstate_priority An|On|on Aus|Off|off</li>
           <li>attr house clientstate_priority Any_On|An All_Off|Aus</li>
         </ul>
-        In this example the status of kitchen is either on or off.  The status
+        In this example the status of kitchen is either An or Aus.  The status
         of house is either Any_on or All_off.
         </li>
     <a id="structure-attr-struct_type_map" data-pattern=".*_map"></a>
@@ -932,7 +952,10 @@
   <a id="structure-get"></a>
   <b>Get</b>
   <ul>
-    Get wird im Structur-Device nicht unterst&uuml;tzt.
+    <a id="structure-get-structState"></a>
+    <li>structState<br>
+      Liefert einen serialisierten hash mit allen Strukturmitgliedern und ihren state-readings zurück.
+      </li><br>
   </ul>
   <br>
 
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

#1
ZitatAls Ergebnis von "get <structureName> structState" bekommt man einen serialisierten hash mit deviceName und state zurück:

Zitat(z.B. bei Komma im state...)

Wenn Du das CommandGet ohne dem split übergibst, werden Komma im Schlüssel oder Wert dann ignoriert ?


betateilchen

Steht doch oben:

Zitat von: betateilchen am 10 September 2025, 19:59:29Als Ergebnis von "get <structureName> structState" bekommt man einen serialisierten hash mit deviceName und state zurück:

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

TomLee

#3
Sry, Denkfehler von mir gestern Abend.

Das Ergebnis nicht direkt übergeben!

Erst aus dem Ergebnis ein Array machen, dann nimmt Perl immer das Element mit geradem Index aus @a als Key und das darauffolgende Element als Value. Komma in den Werten sind dann kein Problem, weil Perl nicht nach , trennt, sondern einfach die Array-Elemente nimmt, so wie sie sind.

sub get_data {
    return "d1","wert1","d1state","ok","d2","wert,mit,komma","d2state","fail";
}

sub udo {
my @a = get_data();
my %t = @a;

print Dumper(\%t);
}

Ergebnis:

$VAR1 = {
          'd1' => 'wert1',
          'd2state' => 'fail',
          'd1state' => 'ok',
          'd2' => 'wert,mit,komma'
        };

Oder hab ich dabei immer noch einen Denkfehler?


Käse, tut mir Leid.