FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: bicmac am 03 Juni 2019, 17:19:48

Titel: Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: bicmac am 03 Juni 2019, 17:19:48
Hallo,
ich würde gern die alle Readings eines Devices die mit "Station-" beginnen addieren und in ein UserReading mit dem Namen "Summe" des selben devices Zurückschreiben.
Ist sowas möglich? ich weiss das ich alle einzeln nacheinander addieren kann. Ich würde aber gern automatisch alle addieren ohne jedes mal den notify oder was auch immer anpassen zu müssen wenn die Anzahl der vorhandenen Stationen und damit die Anzahl der Readings sich ändert.

Das sind die momentanen readings im Device. Die Summe müsste also momentan 0 sein. Sobald sich eine Station auf 1 ändert sollte sich die "Summe" automatisch anpassen. (und beim zurückrudern das selbe wieder)


READINGS:
     2019-06-03 17:16:42   Station-1       0
     2019-06-03 17:16:42   Station-2       0
     2019-06-03 17:16:42   Station-3       0
     2019-06-03 17:16:42   Station-4       0
     2019-06-03 17:16:42   Station-5       0
     2019-06-03 17:16:42   Station-6       0
     2019-06-03 17:16:42   Station-7       0
     2019-06-03 17:16:42   Station-8       0
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Gisbert am 03 Juni 2019, 17:57:51
attr userreadings Summe {readingsVal($name,'Station-1','') + readingsVal($name,'Station-2','') + ...}
... bitte selbst ergänzen.

Bitte Groß/Kleinschreibung anhand der commandref und Wiki selbst überprüfen, da gerade mobil.

Edit: gerade nachgeschaut:
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: amenomade am 03 Juni 2019, 18:03:38
Das kann ein DOIF: https://fhem.de/commandref_DE.html#DOIF_aggregation
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: amenomade am 03 Juni 2019, 18:18:40
Geht auch mit einem userReading:
attr Devicename userReading Summe:Station-.* {
my $hash = $defs{"Devicename"};
my $summe = 0;
my $key;
while (($key) = each($hash->{READINGS})){
$summe += ReadingsNum("Devicename", $key, 0) if ($key =~ 'Station-');
}
return $summe;
}
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: bicmac am 06 Juni 2019, 11:15:46
ich bekomme einen Fehler wenn ich das mit dem user reading mache:

"Error evaluating Bewaesserung userReading Summe: Experimental each on scalar is now forbidden at (eval 149578) line 5."


attr Bewaesserung userReadings Summe:Station-.* {\
my $hash = $defs{"Bewaesserung"};;\
my $summe = 0;;\
my $key;;\
while (($key) = each($hash->{READINGS})){\
$summe += ReadingsNum("Bewaesserung", $key, 0) if ($key =~ 'Station-');;\
}\
return $summe;;\
}
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: amenomade am 06 Juni 2019, 22:21:42
Sorry. Funktionierte mit einer frühere Version von Perl, jetzt nicht mehr. Probier mal mit
while (($key) = each(%$hash->{READINGS})){\
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Frank_Huber am 10 November 2020, 11:15:04
Hallo,

Ich kapere mal diesen alten Thread da ich gerade genau das selbe vorhabe. :-)
per Sysstat SNMP frage ich die PoE Leistung einer Switch pro Port ab.
Daraus will ich eine Summe bilden.
Wen ich das UserReading anlege bekomme ich den Fehler "Experimental aliasing via reference not enabled at (eval 773) line 2."

Hier das userReading aus der RAW:
attr CWGE26FX2TX24MSPOE userReadings Summe:port-.* {\\
my $hash = $defs{'CWGE26FX2TX24MSPOE'};;\\
my $summe = 0;;\\
my $key;;\\
while (($key) = each(%$hash->{READINGS})){\\
$summe += ReadingsNum('CWGE26FX2TX24MSPOE', $key, 0) if ($key =~ 'port-');;\\
}\\
return $summe;;\\
}


Die Readings lauten "port-01_PoE_PowerUsed" "port-02_PoE_PowerUsed" usw...
Mache ich was falsch?

Danke & Grüße
Frank
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Otto123 am 10 November 2020, 12:18:21
Hallo Frank,

ich habe ein Beispiel mit for ... (das baut alle Readings eines Devices in einen json String)
{my $d="fuehler1";;my $hash = $defs{$d};;my $readings = $hash->{READINGS};;my $message="{ ";;foreach my $a ( keys %{$readings} ) {my $val=ReadingsVal($d,$a,"error");;$message .= toJSON($a)." : ".toJSON($val)." ," };;chop($message);;$message.="}"}


Wenn ich mir das anschaue, muss es bei Dir eventuell each(%{$hash->{READINGS}}) heissen?
Sagt Dir ein Perlziemlichunwissender :)

Oder Du nimmst meine for Schleife ;)

Gruß Otto
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Frank_Huber am 10 November 2020, 12:49:08
Danke Otto,

jedoch kommt mit each(%{$hash->{READINGS}}) die gleiche Fehlermeldung.
Das ist in Zeile 5, er mackert ja auch an Zeile 2: "my $hash = $defs{'CWGE26FX2TX24MSPOE'};;\\" an.

Ich glaube ich habe von Perl noch viel weniger Ahnung als Du. ;-)
Deine for Schleife macht einen JSON string, aber wie bekäme man daraus die Summe?
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Beta-User am 10 November 2020, 13:06:02
...wirklich eine Frage für den Anfängerbereich...

Hier mal ein dummy in RAW, der zu funktionieren scheint:
defmod test_sum dummy
attr test_sum userReadings Summe:port-.* { my $summe = 0;;\
for my $a ( keys %{$defs{$name}->{READINGS}} ) {\
$summe += ReadingsNum($name, $a, 0) if ($a =~ 'port-');;\
} return $summe;; }

setstate test_sum 2020-11-10 13:02:14 Summe 4
setstate test_sum 2020-11-10 13:01:58 port-1 1
setstate test_sum 2020-11-10 13:02:14 port-2 3

Bei dem Trigger sollte man aber aufpassen, ob es nicht Sinn macht, den noch weiter zu begrenzen (ist egal, wenn das via bulkUpdate kommt). Sonst werden halt die Berechnungen zu oft ausgeführt...
Und direkt auf die Hashes zugreifen ist auch nur bedingt zur Nachahmung zu empfehlen, ich weiß nur auf die Schnelle auch keine bessere Lösung.
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Otto123 am 10 November 2020, 13:13:12
Ich würde in deinem Raw Definition Ausdruck jede Zeile anmeckern :), sehe ich aber jetzt erst:
die doppelten \\ führen doch unweigerlich zu Fehlern?
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Frank_Huber am 10 November 2020, 14:23:32
Danke Jörg, das funktioniert! :-)

@Otto, habs auch als Einzeiler versucht ganz ohne "\".
Bin halt nur "Bastler" und "User".
Titel: Antw:Wie alle Readings eines Devices die einer Regex entsprechen addieren?
Beitrag von: Beta-User am 10 November 2020, 14:38:44
Danke für die Rückmeldung.

Vielleicht noch eine Anmerkung betr. "$name": Das funktioniert in userReadings immer und ist auch les- und übertragbarer (und nicht empfindlich gegen spätere Umbenennungen); "hartvercoded" sollte man m.E. nur machen, wenn man auf andere Devices zugreifen will (wobei das eh' zumindest gefühlt suboptimal ist; wenn, dann macht das nur für zentrale Infos Sinn, z.B. den aktuellen Strompreis oder so).

Ansonsten bin ich auch eher der c&p-Typ und hatte nur in jüngster Zeit häufiger das "Vergnügen", mit Hashes rumzuschubsen...

(btw. @Otto: das Grundgerüst aus https://forum.fhem.de/index.php/topic,115620.msg1099706.html#msg1099706 solltst du dir mal ansehen, kann man sicher auch woanders mal brauchen, und jetzt ist es auch (fast) auf einem "verständlichen" Stand...)