Hallo,
ich möchte eine Perl Routine schreiben, die mir aus einem übergebenen Device alle Attribute,
in denen "Zeit" vorkommt, in zwei Readings (Stunde, Minute) aufteilt. Ich kann hier gerade
nur "Drockenübungen" machen, da ich gerade keinen Zugang zur fhem Umgebung habe.
Kann das so in etwa funktionieren und wie bekomme ich die Attribute mit "*Zeit*" heraus gefiltert ?
my $dev = @_;
my @attr = AttrVal($dev, --> wie finde ich hier die Attribute mit *Zeit ?
foreach (@attr) {
my @zeit = split(/:/,$attr);
my $stunde = sprintf("%02d",$zeit[0]);
my $minute = sprintf("%02d",$zeit[1]);
my $reading_stunde = $attr.'_Stunde'; --> Ergebnis soll sein : "ZeitAttribut_stunde"
my $reading_minute = $attr.'_minute'; --> Ergebnis soll sein : "ZeitAttribut_minute"
fhen("setreading $dev $reading_stunde $stunde");
fhen("setreading $dev $reading_stunde $stunde");
}
Nicht mit array, sondern mit hash arbeiten :)
my $a = $attr{$dev};
liefert "return Dumper $a" für "global" z.B. sowas:
$VAR1 = {
'nrarchive' => '3',
'commandref' => 'modular',
'userattr' => 'DbLogExclude DbLogInclude cmdIcon devStateIcon devStateStyle icon sortby webCmd webCmdLabel:textField-long widgetOverride',
'statefile' => './log/fhem.save',
'mseclog' => '1',
'version' => 'fhem.pl:15522/2017-11-29',
'room' => '99 System',
'group' => '00 System',
'devStateIcon' => 'no.*:icoEverything',
'logfile' => './log/fhem-%Y-%m-%d_%H.log',
'motd' => 'none',
'modpath' => '.',
'configfile' => 'configDB',
'verbose' => 4
}
dann kannst Du über den gesamten hash loopen und per regexp prüfen, ob der Attributname "Zeit" enthält.
erst einmal vielen Dank. Leider habe ich das so nicht ganz verstanden. Kannst du das etws detaillierter erklären ?
Noch genauer kann man es eigentlich nicht erklären
my $a = $attr{$dev};
$attr ist ein globaler Hash. Wenn du für $dev den Namen Deines Devices an gibst bekommst Du ein Hash mit allen Attributen des Devices $a
In diesem Hash kannst du nun suchen
Ah ... das mit dem globalen Hash wusste ich nicht. Jetzt wird es klarer .
Danke !
Zitat von: CoolTux am 12 Dezember 2017, 18:48:34
$attr ist ein globaler Hash
Falsch... %attr ist der hash ;)
Zitat von: betateilchen am 13 Dezember 2017, 11:38:10
Falsch... %attr ist der hash ;)
Ja Du hast Recht.
Wie genau nennt man am besten diese Konstellation.
$attr{$dev};
%attr ist der Hash und $attr{} ist der ??
Danke Dir
Zitat von: CoolTux am 13 Dezember 2017, 11:41:45
$attr{}
"$attr{irgendwas}" ist auch ein hash, nämlich die Teilmenge aus dem hash "%attr" mit dem key "irgendwas"
Aber "$attr" alleine ist kein hash, sondern eine Variable.
Ah ok, jetzt verstehe ich was du meinst.
Es fehlte also die ganze Menge $attr{} ist ein Hash.
Bin da ganz bei Dir. Wenn man schon erklärt sollte man es auch korrekt machen. DankeDir
Zitat von: CoolTux am 13 Dezember 2017, 11:41:45
Wie genau nennt man am besten diese Konstellation.
%attr ist der Hash und $attr{} ist der ??
Jetzt ist mir der Begriff wieder eingefallen: $attr{} bezeichnet ein "Hashelement"
Ein Hashelement kann natürlich selbst wieder einen hash beinhalten, diese lassen sich beliebig tief schachteln.
Das Wort kommt mir bekannt vor. Habe ich schon des öfteren gelesen.
Danke Dir fürs Bescheid geben.
Verstehe ich das denn richtig, dass das hash %attr weitere hash beinhaltet ?
In etwa so : %attr = (device1 => {attr1 => wert1,
attr2 => wert2}
device2 => {attr3 => wert3,
attr4 => wert4}
Ansonsten könnte ich ja nicht mit $attr{device1} auf attr1 => wert1 zugreifen. Oder ??
Bitte perl Doku zum Thema hash lesen. Das ist kein FHEM spezifisches Thema.
Danke.
Das sollte auch keine große Fach-Diskussion werden. Ich wollte lediglich wissen, ob ich das , nach dem Studieren der perl Doku zum Thema "Hashes of Hashes" , richtig verstanden habe.
Trotzdem Danke für die Hilfe !
Schau Dir den %attr hash einfach selbst an. Per telnet oder FHEM Eingabezeile:
{use Data::Dumper;; Dumper \%attr}
:) cool !! Danke. So hatte ich mir das vorgestellt !
Dank eurer Hilfe, bekomme ich die Attribute jetzt ausgewertet und ich kann entsprechende Readings anlegen.
Jetzt möchte ich noch alle Readings eines Device auslesen bzw. mit Wildcards "*Zeit*" ausgeben.
Stehen die auch in einem globalen Hash ?
https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Readings
https://fhem.de/commandref.html#perl
Ich bin wieder einen Schritt weiter :-)
So funktioniert meine Routine:
sub test($) {
my $dev = @_;
foreach my $readings (keys %{$defs{'Roll.Kueche'}{READINGS}}) {
if ($readings =~ /Auto/) {
Log 1, ("$readings gefunden");
}
}
}
So leider nicht:
sub test($) {
my $dev = @_;
foreach my $readings (keys %{$defs{$dev}{READINGS}}) {
if ($readings =~ /Auto/) {
Log 1, ("$readings gefunden");
}
}
}
Aufruf der Funktion über : {test("Roll.Kueche")}
Wo liegt mein Fehler ?
my ($dev) = @_;
Ohne Klammern bekommst Du nur die Anzahl der Arrayelemente geliefert.
Klasse ! Auch das hat funktioniert. Danke !