Pünktlich zu Ostern gibt es wieder neue Features. Wie bereits angekündigt, habe ich DOIF eine Aggregationsfunktion spendiert.
Die Aggregationsfunktion kann sowohl in den Bedingungen als auch im Ausführungsteil angegeben werden.
Syntax:
[<Funktion>:"<regex Device>:<regex Event>":<reading>:<condition>,<default>]
<Funktion> :
# Anzahl der Treffer
@ kommagetrennte Liste Devices
#sum Summe
#max:d<Number> höchster Wert
#min:d<Number> niedrigster Wert
#average:d<Number> Durchschnitt
@max Device des höchsten Wertes
@min Device de niedrigsten Wertes
Der danach folgende Doppelpunkt als Trennzeichen kann weggelassen werden, das bietet sich allerdings zwecks besserer Lesbarkeit nur bei den beiden einstelligen Angaben #,@ an.
"<regex Device>:<regex Event>" spezifiziert sowohl den Trigger, als auch die betroffenen Devices, die Syntax entspricht der DOIF-Syntax für Ereignistrigger.
Die Angabe <regex Event> ist im Ausführungsteil nicht sinnvoll und sollte weggelassen werden.
<reading> Reading, welches überprüft werden soll
<condition> Aggregations-Bedingung, $_ ist der Platzhalter für den aktuellen Wert des internen Schleifendurchlaufs, Angaben in Anführungszeichen der Art "<value>" entsprechen $_ =~ "<value>" , hier sind alle Perloperatoren möglich.
<default> Default-Wert, falls kein Device gefunden wird, entspricht der Syntax des Default-Wertes bei Readingangaben
<reading>, <condition> <default> sind optional
Syntax-Beispiele im Ausführungteil
Anzahl der Devices, die mit "window" beginnen:
[#"^window"]
Liste der Devices, die mit "window" beginnen:
[@"^window"]
Liste der Devices, die mit "windows" beginnen und ein Reading "myreading" beinhalten:
[@"^window":myreading]
Liste der Devices, die mit "windows" beginnen und im Status das Wort "opened" vorkommt:
[@"^window":state:"opened"]
entspricht:
[@"^window":state:$_ =~ "opened"]
siehe Aggregationsbedingung.
In der Aggregationsbedingung <condition> können alle in FHEM definierten Perlfunktionen genutzt werden. Folgende Variablen sind vorbelegt und können ebenfalls benutzt werden:
$_ Inhalt des angegebenen Readings (s.o.)
$number Nach Zahl gefilteres Reading
$name Name des Devices
$TYPE Devices-Typ
$STATE Status des Devices (nicht das Reading state)
$room Raum des Devices
$group Gruppe des Devices
Beispiele für Definition der Aggregationsbedingung <condition>
Liste der Devices, die mit "rooms" enden und im Reading "temperature" einen Wert größer 20 haben.
[@"rooms$":temperature:$_ > 20]
Liste der Devices im Raum "livingroom", die mit "rooms" enden und im Reading "temperature" einen Wert größer 20 haben:
[@"rooms$":temperature:$_ > 20 and $room eq "livingroom"]
Liste der Devices in der Gruppe "windows", die mit "rooms" enden, deren Status (nicht state-Reading) "on" ist:
[@"rooms$"::$STATE eq "on" and $group eq "windows"]
Liste der Devices, deren state-Reading "on" ist und das Attribut disable nicht auf "1" gesetzt ist:
[@"":state:$_ eq "on" and AttrVal($name,"disable","") ne "1"]
Aggregationsangaben in der Bedingung reagieren zusätzlich auf Trigger, hier sollte die regex-Angabe für das Device um eine regex-Angabe für das zu triggernde Event erweitert werden.
Anzahl der Devices, die mit "window" beginnen. Getriggert wird, wenn ein Eventzeile beginnend mit "window" und dem Wort "opened" vorkommt:
[#"^window:opened"]
Anwendungsbeispiele
Fenster Status/Meldung:
define di_Fenster DOIF ([#"^Window:open":state:"open"] != 0) (push "Fenster $DEVICE wurde geöffnet. Es sind folgende Fenster offen: [@"^Window":state:"open"]")
DOELSEIF ([#"^Window:closed":state:"open"] == 0) (push "alle Fenster geschlossen")
attr di_Fenster do always
attr di_Fenster cmdState $DEVICE zuletzt geöffnet|alle geschlossen
Raumtemperatur-Überwachung:
define di_Raumtemp DOIF (["^Rooms:temperature"])
(push "In folgenden Zimmern ist zu kalt [@"^Rooms":temperature: $_ < 20]")
DOELSEIF ([#"^Rooms:temperature":temperature: $_ >= 20] == 0)
(push "alle Zimmmer sind warm")
attr di_Raumtemp cmdState es muss geheizt werden|alle Räume sind warm
Durchschnittstemperatur:
define di_average DOIF ([08:00] or [12:00]) (push "Die durchschnittliche Temperatur aller Zimmer beträgt [#average:"^Rooms":temperature]")
attr di_average do always
Es soll beim Öffnen eines Fenster eine Meldung über alle geöffneten Fenster erfolgen:
define di_Fenster DOIF (["^Window:open"]) (push "Folgende Fenster: [@"^Window:state:"open"] sind geöffnet")
attr di_Fenster do always
Wenn im Wohnzimmer Lampe ausgeschaltet wird, sollen alle anderen Lampen ausgeschaltet werden, die noch an sind:
define di_lamp DOIF (["livingroom_lamp: off"]) (set [@"room_lamp",state,"on"] off)
attr di_lamp DOIF do always
Für Perl-Anwender:
Für reine Perlangaben gibt es eine entsprechende Perlfunktion namens AggrDoIf(<function>,<regex Device>,<reading>,<condition>) diese liefert bei der Angabe @ ein Array statt einer Stringliste, dadurch lässt sie sich gut bei foreach-Schleifen verwenden.
Beispiele
define di_Fenster DOIF (["^Window:open"]) {foreach (AggrDoIf('@','^windows','state','"open"')) {Log3 "di_Fenster",3,"Das Fenster $_ ist noch offen"}}
define di_Temperature DOIF (["^room:temperature"]) {foreach (AggrDoIf('@','^room','temperature','$_ < 15')) {Log3 "di_Temperatur",3,"im Zimmer $_ ist zu kalt"}}
Es handelt sich um eine Testversion. Sie ist zur bisherigen Version abwärtskompatibel.
Intern wurde die Aggregationsfunktion durch die Nutzung des grep-Befehls optimiert, daher gehe ich nicht von Performance-Problemen aus.
Aktuelle Version: eingecheckt
Damit das Interesse für die neue Aggregationsfunktion geweckt wird, bedarf es natürlich einer Killer-Anwendung :)
Hier mal eine als Zweizeiler:
defmod di_Battery DOIF
attr di_Battery state [@":battery":battery:$_ ne "ok"]
Dieses Modul zeigt immer aktuell im Status alle Devices des Systems, deren battery-Reading nicht "ok" ist.
Ein lang gehegter Wunsch wird wahr :) .
Danke!
Zitat von: Ralli am 17 April 2017, 12:30:47
Ein lang gehegter Wunsch wird wahr :) .
Danke!
Man kann es auch als Structure-Ersatz nutzen, ohne diese pflegen zu müssen. Ebenfalls ist es als universeller Filter nutzbar. Ich habe gerade noch den TYPE (Version v0.4) ergänzt. Damit könnte man z. B. alle HM-Lampen im Wohnzimmer einschalten die noch aus sind:
set [@"":state:$_ eq "off" and $TYPE eq "CUL_HM" and $room eq "livingroom")] on
Da man in der Bedingung beliebigen Perl-Code mit allen erdenklichen FHEM-Funktionen definieren kann, dürften die Filter-Möglichkeiten vielfältiger sein als beim set-FILTER.
Danke für die neuen Features!
Ich habe gerade mal etwas rumgespielt. Kann es sein, dass sich die Funktion "#average" noch leicht verrechnet? Ich wollte mir die durchschnittliche Helligkeit meiner drei HM-Bewegungsmelder anzeigen lassen.
Internals:
CFGFN
NAME brightness_average
NR 12437
NTFY_ORDER 50-brightness_average
STATE 17.875
TYPE DOIF
Readings:
2017-04-17 20:58:45 Device BMelder1
2017-04-17 20:34:32 cmd 0
2017-04-17 20:58:45 state 17.875
Condition:
Devices:
Do:
0:
Helper:
event brightness: 68
globalinit 1
last_timer 0
sleeptimer -1
triggerDev BMelder1
triggerEvents:
brightness: 68
triggerEventsState:
brightness: 68
Internals:
Itimer:
Readings:
Regexp:
All:
State:
State:
0 ^BMelder
Trigger:
Attributes:
state [#average"^BMelder":brightness]
Hier ein exemplarischer Melder.
Internals:
DEF 2EECD0
HMLAN1_MSGCNT 391
HMLAN1_RAWMSG E2EECD0,0000,14F53E53,FF,FFBA,7184102EECD029A2F706014F00
HMLAN1_RSSI -70
HMLAN1_TIME 2017-04-17 20:53:09
IODev HMLAN1
LASTInputDev HMLAN1
MSGCNT 391
NAME BMelder1
NOTIFYDEV global
NR 399
NTFY_ORDER 50-BMelder1
STATE 79
TYPE CUL_HM
lastMsg No:71 - t:10 s:2EECD0 d:29A2F7 06014F00
peerList Terrassenlicht,
protLastRcv 2017-04-17 20:53:09
rssi_at_HMLAN1 cnt:391 max:-63 avg:-69.28 min:-85 lst:-70
Readings:
2017-04-16 14:38:12 Activity alive
2016-02-19 20:57:32 CommandAccepted yes
2016-02-19 20:55:37 D-firmware 1.6
2016-02-19 20:55:37 D-serialNr LEQ0657403
2016-02-19 20:57:32 PairedTo 0x29A2F7
2016-02-19 20:57:34 R-Terrassenlicht_chn-01-peerNeedsBurst off
2016-02-19 15:12:28 R-brightFilter 7
2016-02-19 15:12:28 R-captInInterval off
2016-02-19 15:11:40 R-evtFltrNum 1
2016-02-19 15:11:40 R-evtFltrPeriod 1 s
2016-02-19 15:12:28 R-minInterval 15
2016-02-19 15:11:40 R-pairCentral 0x29A2F7
2017-04-17 20:53:09 battery ok
2017-04-17 20:53:09 brightness 79
2017-04-17 20:53:09 cover closed
2017-04-17 18:14:42 motion off
2017-04-17 18:14:25 motionCount 45_next:15s
2017-04-17 18:14:42 motionDuration 17
2017-04-16 14:28:10 peerList Terrassenlicht,
2016-02-26 10:36:49 powerOn 2016-02-26 10:36:49
2017-04-17 20:53:09 recentStateType info
2017-04-17 18:14:42 state noMotion
2017-01-28 10:18:11 state_toggle 188
2016-02-19 20:57:30 trigDst_29A2F7 noConfig
2017-04-17 18:14:25 trigger_cnt 45
Helper:
HM_CMDNR 113
mId 00C1
rxType 28
supp_Pair_Rep 0
Ack:
Expert:
def 1
det 0
raw 1
tpl 0
Io:
newChn +2EECD0,00,00,00
nextSend 1492455189.44373
prefIO
rxt 2
vccu
p:
2EECD0
00
00
00
Mrssi:
mNo 71
Io:
HMLAN1 -68
Prt:
bErr 0
sProc 0
sleeping 1
Q:
qReqConf 00
qReqStat
Role:
chn 1
dev 1
Rssi:
At_hmlan1:
avg -69.2864450127877
cnt 391
lst -70
max -63
min -85
Tmpl:
Attributes:
IODev HMLAN1
actCycle 000:10
actStatus alive
autoReadReg 4_reqStatus
devStateIcon alive:message_ok@green
event-on-change-reading Activity,battery,brightness,motion
expert 2_raw
firmware 1.6
icon people_sensor
model HM-Sen-MDIR-O-2
peerIDs 00000000,3ECCDB01,
room CUL_HM
serialNr LEQ0657403
stateFormat brightness
subType motionDetector
Der berechnete Wert liegt leider deutlich unter dem tatsächlichen durchschnittlichen Helligkeitswert.
Frohe Restostern!
Oli
Kann ich bei mir nicht feststellen. Möglicherweise hat er mehr Sensoren erwischt, als du erwartest.
Du kannst mal folgendes im Status definieren und dann mal selber nachrechnen sum/anzahl. Zusätzlich werden alle gezählten Sensoren angezeigt:
[#average"^BMelder":brightness] [#"^BMelder":brightness] [#sum"^BMelder":brightness] [@"^BMelder":brightness]
Man kann zwar mit sprintf die Nochkommastellen formatieren, aber ich werde noch eine Formatierungsfunktion für Dezimalzahlen einbauen.
Version V.05
Ich habe das allgemeine Filtern nach Zahl mit dem Buchstaben "d" um das Runden auf Nachkommastellen erweitert:
Syntax:
[<device>:<reading>:d<Number>]
<Number> ist eine einstellige Ziffer für die Anzahl der Nachkommastellen, Mit 0 wird auf ganze Zahlen gerundet.
Auch die Aggregationsfunktion hat das Runden als Option bekommen, sinnvoll bei #average, #sum, #min, #max
Beispiel:
Durchschnitt auf zwei Nachkommastellen runden:
[#average:d2:"...]
Desweiteren gibt es jetzt die Variable $number als "nach Zahl gefiltertes Reading" für die Aggregationsbedingung. Die Nutzung ist sinnvoll bei Vergleichen von Zahlen, die Einheiten beinhalten.
Beispiel:
[#"":power:$number > 10]
Jetzt fehlt noch die Doku für die Commandref und noch etwas Testen, dann kann man die Sache eintüten und ich kann mich wieder anderen Sachen widmen. :)
Hallo Damian,
ich hab mal diesen Code bei mir probiert
defmod di_Battery DOIF
attr di_Battery state [@":battery":battery:$_ ne "ok"]
jetzt haben alle Device und Kanäle ein battery-Reading. :)
Ist das so gewollt?
vg Jesn
Zitat von: Damian am 17 April 2017, 21:32:20
Kann ich bei mir nicht feststellen. Möglicherweise hat er mehr Sensoren erwischt, als du erwartest.
Du hattest natürlich Recht. Das RegEx hat noch auf einige DOIF gematcht, welche nach dem Schema benannt wurden. Daraufhin habe ich versucht, Deine neuen Filter zu kombinieren, was leider nicht funktioniert hat.
attr brightness_average state [#average:"BMelder":brightness and $TYPE eq "CUL_HM"]
Hier bekomme ich als Ausgabe in state "0".
Durch Umbenennung der mitgematchten DOIF funktioniert es nun. Auch die neuere Version mit dem Kürzen der Nachkommastellen. Allerdings ist mir noch nicht so ganz klar, warum die Kombination aus der Funktion #average und dem Filter $TYPE nicht funktioniert.
Oli
Zitat von: Newbie am 18 April 2017, 10:35:09
Hallo Damian,
ich hab mal diesen Code bei mir probiert
defmod di_Battery DOIF
attr di_Battery state [@":battery":battery:$_ ne "ok"]
jetzt haben alle Device und Kanäle ein battery-Reading. :)
Ist das so gewollt?
vg Jesn
Kann ich bestätigen, alle Geräte haben jetzt ein "battery" Reading, die zugefügten Readings haben Wert 0 .
Falls es keine Geräte gibt, für die ein Reading "battery" mit dem Wert 0 ein gültiger Wert ist, könnte man die Readings über die Befehlszeile löschen mit
{foreach my $item (keys %defs) {delete $defs{$item}{READINGS}{battery} if ($defs{$item}{READINGS}{battery}{VAL} == 0)}}
Zitat von: Ellert am 18 April 2017, 17:08:00
Kann ich bestätigen, alle Geräte haben jetzt ein "battery" Reading, die zugefügten Readings haben Wert 0 .
Falls es keine Geräte gibt, für die ein Reading "battery" mit dem Wert 0 ein gültiger Wert ist, könnte man die Readings über die Befehlszeile löschen mit
{foreach my $item (keys %defs) {delete $defs{$item}{READINGS}{battery} if ($defs{$item}{READINGS}{battery}{VAL} == 0)}}
tja, komisch.
Ich habe das auch mal beobachtet, dachte aber, dass es von irgendwelchen set-Experimenten in Verbindung mit der Aggregationsfunktion zusammen hing.
Ich kann keinen schreibenden Zugriff auf das vermeintliche Reading in der Aggregationsfunktion erkennen.
Ich kann es auch mit der aktuellen Version v0.6, die ich hier gleich hochladen werde, nicht mehr nachstellen.
Mit Version v0.6 ist das Problem des Anlegens von Readings mit Wert 0 behoben (mal zur Info: wer hätte es gedacht: alleine die Abfrage if (defined $defs{$name}{READINGS}{$reading}{VAL})
führt zum Anlegen des Readings!!!)
Man kann jetzt auch einen Defaultwert vorgeben, wenn kein Treffer da ist (siehe erster Post).
Sinnvoll bei Angaben der Art:
set [@"room_lamp",state,"on","defaultdummy"] off
Ansonsten würde set ohne Device-Angabe einen Fehler produzieren.
Guten Morgen,
Damian, kannst Du bestätigen, dass eine Kombi der Filter nach folgendem Muster
[#average:"BMelder":brightness and $TYPE="CUL_HM"]
nicht funktioniert?
Oli
Zitat von: OliS. am 19 April 2017, 06:40:31
Guten Morgen,
Damian, kannst Du bestätigen, dass eine Kombi der Filter nach folgendem Muster
[#average:"BMelder":brightness and $TYPE="CUL_HM"]
nicht funktioniert?
Oli
Dein Vergleichsoperator ist entweder unvollständig oder falsch, was Du geschrieben hast ist eine Zuweisung, siehe https://wiki.selfhtml.org/wiki/Perl/Operatoren oder https://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung.
Zitat von: OliS. am 19 April 2017, 06:40:31
Guten Morgen,
Damian, kannst Du bestätigen, dass eine Kombi der Filter nach folgendem Muster
[#average:"BMelder":brightness and $TYPE="CUL_HM"]
nicht funktioniert?
Oli
Die Syntax passt nicht. Die Aggregationsbedingung ist reines Perl, daher ist dort brightness nicht bekannt. Du musst erst mal sagen, was das Reading ist und dann könntest du über $_ oder gefiltert nach Zahl über $number in der Aggregationsbedingung darauf zugreifen. Wenn du brightness nicht abfragen willst - ist auch ok, trotzdem muss die Aggregationsfunktion wissen um welches Reading es sich handelt um nur die Devices, die auch das Reading beinhalten über die Bedingung abzufragen, daher:
[#average:"BMelder":brightness:$TYPE eq "CUL_HM"]
und mit Version v0.6 auch möglich:
[#average:"BMelder":brightness:$TYPE eq "CUL_HM","keine Melder vorhanden"]
Ah, jetzt wird's klar. Danke.
Es gibt ein paar Warnungen beim restart (v 0.6)
2017.04.19 09:49:36.890 1: PERL WARNING: Use of uninitialized value $type in string eq at ./FHEM/98_DOIF.pm line 355, <$fh> line 578.
2017.04.19 09:49:36.892 1: PERL WARNING: Use of uninitialized value $type in string eq at ./FHEM/98_DOIF.pm line 358, <$fh> line 578.
2017.04.19 09:49:36.893 1: PERL WARNING: Use of uninitialized value $type in string eq at ./FHEM/98_DOIF.pm line 360, <$fh> line 578.
2017.04.19 09:49:36.894 1: PERL WARNING: Use of uninitialized value $num in numeric eq (==) at ./FHEM/98_DOIF.pm line 378, <$fh> line 578.
Zitat von: Ellert am 19 April 2017, 10:04:07
Es gibt ein paar Warnungen beim restart (v 0.6)
2017.04.19 09:49:36.890 1: PERL WARNING: Use of uninitialized value $type in string eq at ./FHEM/98_DOIF.pm line 355, <$fh> line 578.
2017.04.19 09:49:36.892 1: PERL WARNING: Use of uninitialized value $type in string eq at ./FHEM/98_DOIF.pm line 358, <$fh> line 578.
2017.04.19 09:49:36.893 1: PERL WARNING: Use of uninitialized value $type in string eq at ./FHEM/98_DOIF.pm line 360, <$fh> line 578.
2017.04.19 09:49:36.894 1: PERL WARNING: Use of uninitialized value $num in numeric eq (==) at ./FHEM/98_DOIF.pm line 378, <$fh> line 578.
wird mit dem nächsten Update behoben
Zitat von: Damian am 19 April 2017, 00:33:44
Mit Version v0.6 ist das Problem des Anlegens von Readings mit Wert 0 behoben (mal zur Info: wer hätte es gedacht: alleine die Abfrage if (defined $defs{$name}{READINGS}{$reading}{VAL})
führt zum Anlegen des Readings!!!)
Dazu gab es mal mehrere Posts im Developer Forum. Ein
if( defined($hash->{a}{b}))
führt zum anlegen von $hash->{a} wenn es $hash->{a} noch nicht gab.
Ich versuche das mal zu finden.
Grüße
Zitat von: CoolTux am 19 April 2017, 10:20:25
Dazu gab es mal mehrere Posts im Developer Forum. Ein
if( defined($hash->{a}{b}))
führt zum anlegen von $hash->{a} wenn es $hash->{a} noch nicht gab.
Ich versuche das mal zu finden.
Grüße
ganz schön blöd, selbst wenn man über defined abfragt (würde ich fast als bug ansehen) - ist wohl Perl geschuldet.
Rudi hatte das auch mal erklärt. Finde es leider nicht mehr.
Aber Du kannst
if( defined($hash->{a}) and defined($hash->{a}{b}) )
machen glaube ich. Das war glaube Rudis Lösungsvorschlag.
Zitat von: CoolTux am 19 April 2017, 10:33:20
Rudi hatte das auch mal erklärt. Finde es leider nicht mehr.
Aber Du kannst
if( defined($hash->{a}) and defined($hash->{a}{b}) )
machen glaube ich. Das war glaube Rudis Lösungsvorschlag.
so mache ich es jetzt auch.
daher auch dieses:
sub
ReadingsVal($$$)
{
my ($d,$n,$default) = @_;
if(defined($defs{$d}) &&
defined($defs{$d}{READINGS}) &&
defined($defs{$d}{READINGS}{$n}) &&
defined($defs{$d}{READINGS}{$n}{VAL})) {
return $defs{$d}{READINGS}{$n}{VAL};
}
return $default;
}
Und was soll ich sagen, er kann es noch.
https://forum.fhem.de/index.php/topic,63709.msg614819.html#msg614819
Bitte schön
LG
Zitat von: CoolTux am 19 April 2017, 10:38:10
Und was soll ich sagen, er kann es noch.
https://forum.fhem.de/index.php/topic,63709.msg614819.html#msg614819
Bitte schön
LG
ja, dann ist das in Perl halt so.
Ich programmiere schon seit fast 40 Jahren und kann keinen vergleichbaren Fall finden, wo ich durch eine Abfrage eine Struktur generiere, zumal es in Perl die Abfragemöglichkeit "defined" gibt, die es in vielen anderen Programmiersprache erst gar nicht gibt.
Perl halt ;)
Aber so lange es eine "Lösung" gibt passt es schon. Auch wenn es umständlich ist. Aber wie oft fragt man schon so komplexe Hash's ab. Ok, ausser Du ;D
Dann mal weiterhin viel Erfolg. Auf die nächsten 40 Jahre mein Lieber.
Grüße
Zitat von: CoolTux am 19 April 2017, 11:10:08
Perl halt ;)
Aber so lange es eine "Lösung" gibt passt es schon. Auch wenn es umständlich ist. Aber wie oft fragt man schon so komplexe Hash's ab. Ok, ausser Du ;D
Dann mal weiterhin viel Erfolg. Auf die nächsten 40 Jahre mein Lieber.
Grüße
Was heißt hier komplexe Hashes. Such mal nach $defs hier im Forum, da wirst du schon einige Abfragen finden - und nicht nur im Developer-Forum ;)
Ich habe im ersten Post eine fehlerbereinigte eincheckfähige Version v0.7 mit Doku angehängt. Es ist ein neuer Punkt "Aggregieren von Werten" in der Commandref hinzugekommen. Auch das Filtern nach Zahl mit Nachkommastellen d<number> wurde in der Doku ergänzt.
Wenn in den nächsten Tagen keine weiteren Probleme gemeldet werden, werde ich sie einchecken.
Ich habe noch an paar Stellen die Doku angepasst (z. T. Tippfehler).
Folgende drei Beispiele habe ich als "Killer"-Anwendungen in der Doku aufgenommen:
Anwendungsbeispiele
Statusanzeige: Offene Fenster:
define di_window DOIF
attr di_window state Offene Fenster: [@"^window:opened":state:"opened","keine"]
Statusanzeige: Alle Devices, deren Batterie nicht ok ist:
define di_battery DOIF
attr di_battery state [@":battery":battery:$_ ne "ok"]
Statusanzeige: Durchschnittstemperatur aller Temperatursensoren in der Gruppe "rooms":
define di_average_temp DOIF
attr di_average_temp state [#average:d2:":temperature":temperature:$group eq "rooms"]
Vielleicht hat jemand noch ein Beispiel für eine effiziente Nutzung der Aggregationsfunktion, welches man noch in die Commandref aufnehmen sollte.
Zitat von: Damian am 22 April 2017, 16:07:08Vielleicht hat jemand noch ein Beispiel für eine effiziente Nutzung der Aggregationsfunktion, welches man noch in die Commandref aufnehmen sollte.
Ein Beispiel habe ich selbst nicht, aber ich könnte alle drei Funktionen nicht 1:1 übernehmen.
1. Habe ich Fenster und Türen sowie drei verschiedene Sensoren/Aktoren mit verschiedenen Status (zu: "closed" & "locked", offen: "open", "tilt" & 0-100%).
2. Akkus (%) und Batterien ("ok")
3. Hätte verschiedene Gerätennamen, wäre daher aus 1. abzuleiten. Das traue ich selbst mir als Nicht-Perle zu.
Zitat von: Per am 23 April 2017, 11:58:59
Ein Beispiel habe ich selbst nicht, aber ich könnte alle drei Funktionen nicht 1:1 übernehmen.
1. Habe ich Fenster und Türen sowie drei verschiedene Sensoren/Aktoren mit verschiedenen Status (zu: "closed" & "locked", offen: "open", "tilt" & 0-100%).
2. Akkus (%) und Batterien ("ok")
3. Hätte verschiedene Gerätennamen, wäre daher aus 1. abzuleiten. Das traue ich selbst mir als Nicht-Perle zu.
Was geht:
Zu 1. [@"":state:"closed|locked"]
Zu 2. [@"":state:$number == 100]
Zu 3. [@"Gerät1|Gerät2|Gerät3":...] besser aber in einer Gruppe packen und dann [@"":state:$group eq "mygroup"] abfragen.
Version wurde eingecheckt.
Zitatoffen: "open", "tilt" & 0-100%
so etwas sollte so funktionieren
[@"",state,$_ =~ "open|tilt" or $number != 0]
danke für die tolle Erweiterung. hab meine Fenster-Abfrage jetzt damit gelöst.
gibt es eine Möglichkeit eine Liste aller abgefragten Geräte [@"^Window:state:"open|closed"] in ein UserReading zu schreiben?
Hab es auch schon mit der Perl-Funktion AggrDoif versucht aber es will irgendwie nicht....
Meinst Du ein selbst angelegtes Reading oder das Attribut userReadings?
ich wollte mit dem Attribut UserReading ein eigenes Reading in meinem DOIF anlegen. Im Attribut wollte ich das Reading dann so definieren, dass es die Liste aller überwachten Geräte anzeigt
Dafür sind userReadings nicht gedacht, es reicht ein einfaches setreading $SELF P_geraeteliste [@...]
im Ausführungsteil des DOIF
Zitat von: Ellert am 24 April 2017, 18:17:27
Dafür sind userReadings nicht gedacht, es reicht ein einfaches setreading $SELF P_geraeteliste [@...]
im Ausführungsteil des DOIF
Das geht schon, ist halt nur etwas umständlich:
attr di_modul userReadings window:Window.* {join(",",AggrDoIf('@','^Window','state','"open|closed"'))}
entspricht demnächst:
attr di_modul myReadings window:[@"^Window":state:"open|closed"]
da wäre ich nicht drauf gekommen. Bis demnächst (sieht einfacher aus) hab ich es jetzt erst mal mit setReadings umgesetzt, geht auch:-).
Jetzt noch eine letzte Frage:
Wenn ich mir eine Liste generiere nimmt er die Device-Namen. Kann ich auch die Aliase in der Liste darstellen?
Für ein EVENT im DOIF mach ich das mit {AttrVal("$DEVICE","alias", "$DEVICE")} .. aber geht das auch für die Komma-Getrennte @-Liste?
Zitat von: StephanFHEM am 24 April 2017, 18:44:08
da wäre ich nicht drauf gekommen. Bis demnächst (sieht einfacher aus) hab ich es jetzt erst mal mit setReadings umgesetzt, geht auch:-).
Jetzt noch eine letzte Frage:
Wenn ich mir eine Liste generiere nimmt er die Device-Namen. Kann ich auch die Aliase in der Liste darstellen?
Für ein EVENT im DOIF mach ich das mit {AttrVal("$DEVICE","alias", "$DEVICE")} .. aber geht das auch für die Komma-Getrennte @-Liste?
ja, allerdings auch noch etwas umständlich:
attr di_modul userReadings window:Window.* {my @list;foreach(AggrDoIf('@','^Window','state','"open|closed"')){push (@list, AttrVal($_,"alias", $_))};join(",",@list)}
demnächst voraussichtlich so (mit a wie alias):
attr di_modul myReadings window:[@:a:"^Window":state:"open|closed"]
ach mist....
ich habe jetzt im DOIF folgendes stehen:
DOIF (Trigger)({my @list;foreach(AggrDoIf('@','_Fenster|_Tuer','state','"open|closed"')){push(@list, AttrVal($_,"alias", $_));join(", ", @list);};fhem("setreading $SELF Sensoren @list")})
Das funktioniert auch soweit nur: er macht die blöden Kommata nicht zur Abgrenzung der einzelnen Variablen. Kannst du noch mal schauen welches Semikolon, geschweifte Klammer oder sonstiges ich falsch gesetzt habe?
Zitat von: StephanFHEM am 24 April 2017, 21:30:53
ach mist....
ich habe jetzt im DOIF folgendes stehen:
DOIF (Trigger)({my @list;foreach(AggrDoIf('@','_Fenster|_Tuer','state','"open|closed"')){push(@list, AttrVal($_,"alias", $_));join(", ", @list);};fhem("setreading $SELF Sensoren @list")})
Das funktioniert auch soweit nur: er macht die blöden Kommata nicht zur Abgrenzung der einzelnen Variablen. Kannst du noch mal schauen welches Semikolon, geschweifte Klammer oder sonstiges ich falsch gesetzt habe?
Überlass mal lieber die Perl-Basteleien den Perl-Puristen und nimm die angehängte Version. Sie kann jetzt auch Aliasnamen ausgeben :)
DOIF (Trigger)(setreading $SELF Sensoren [@a"_Fenster|_Tuer",state,"open|closed"])
Gesucht wird allerdings (hier: "_Fenster|_Tuer") immer nach den echten Namen und nicht nach Aliasnamen, das geht auch schlecht anders, weil es gleichzeitig das Triggerdevice ist und das ist kein Aliasname.
klasse:-) Hätte ich geahnt, dass "demnächst" für dich noch heute Abend ist hätte ich mir 2 Stunden basteln mit Perl-Viertelwissen gespart:-)
Das ist schon gut so, dass ich nach den echten Namen suche. Die Aliase sind für den WAF und die echten Namen sind die logischen... 8)
edit: getestet und es funktioniert wie ein Traum. Eine Anmerkung (Verbesserungsvorschlag) hätte ich aber noch -> kannst du nicht nach dem Komma immer noch ein Leerzeichen einfügen. Sieht optisch etwas besser aus wenn man sich die Liste aufs Handy sendet
Zitat von: StephanFHEM am 24 April 2017, 22:09:37
klasse:-) Hätte ich geahnt, dass "demnächst" für dich noch heute Abend ist hätte ich mir 2 Stunden basteln mit Perl-Viertelwissen gespart:-)
Das ist schon gut so, dass ich nach den echten Namen suche. Die Aliase sind für den WAF und die echten Namen sind die logischen... 8)
Doku ist auch schon angepasst. Ich werde es noch einen Tag lang testen und vermutlich morgen einchecken. Tja manche Dinge gehen schneller von der Hand als man denkt ;)
schau bitte noch mal nach meinem Edit:-)
Zitat von: StephanFHEM am 24 April 2017, 22:18:24
schau bitte noch mal nach meinem Edit:-)
Das Problem ist, dass man diese Liste auch für den set-Befehl nutzen kann und da müssen die Devicenamen mit Komma getrennt werden. Die Aliasnamen funktionieren jetzt aber auch bei der AggrDoIf-Funktion, das würde dann so aussehen:
DOIF (Trigger)(setreading $SELF Sensoren {(join(" ",AggrDoIf('@a','_Fenster|_Tuer',state,'"open|closed"')))})
Hier ist der Perl-Aufruf noch überschaubar.
Edit: Ich sehe gerade, du wolltest Komma mit Leerzeichen, dann halt:
DOIF (Trigger)(setreading $SELF Sensoren {(join(", ",AggrDoIf('@a','_Fenster|_Tuer',state,'"open|closed"')))})
also...mit dem Perl-Aufruf von dir schreibt er leider gar nichts mehr ins Reading. Das Reading bekommt keine Änderung
Da fehlten noch Anführungszeichen bei state:
{(join(", ",AggrDoIf('@a','_Fenster|_Tuer','state','"open|closed"')))}
jetzt gehts. Super danke!
naja auch das ist inzwischen überholt ;)
man kann jetzt auch Trennzeichen definieren mit s(<Trennzeichen>)
bei dir dann:
setreading $SELF Sensoren [@as(, )"_Fenster|_Tuer",state,"open|closed"]
Ich dachte mir, den Wunsch werden noch ein paar andere User haben ;)
geändert mit as(, ) und läuft!
Version eingecheckt.
Was vllt. auch noch interessant wäre, ist die Anzahl der in die Listen aufgenommenen Devices (z.B. $count ?) als Variable für #.
Zitat von: Per am 27 April 2017, 12:52:15
Was vllt. auch noch interessant wäre, ist die Anzahl der in die Listen aufgenommenen Devices (z.B. $count ?) als Variable für #.
gibt es doch mit #
([#:"Fenster":state:"offen","closed"] > 0) (set msg # Fenster sind noch offen)
geht also?
Zitat von: Per am 27 April 2017, 13:32:15
([#:"Fenster":state:"offen","closed"] > 0) (set msg # Fenster sind noch offen)
geht also?
natürlich, ist doch in der commandref auch so beschrieben mit:
Zitat# Anzahl der betroffenen Devices, der folgende Doppelpunkt kann weggelassen werden
allerdings meinst du wahrscheinlich:
([#:"Fenster:closed":state:"offen"] > 0)
wenn "closed" das zu triggernde Ereignis sein soll.
Hallo,
Ich habe diese neuen Funktionen durch Zufall entdeckt und auch den Hinweis, dass man damit Strukturen ersetzen kann. Da ich mit meinen Strukturen nie ganz zufrieden war, wollte ich diese durch DOIFs ersetzen. Nun meine Frage: die Strukturen für meine Lampen haben entweder den Status All_Off oder Any_On - gibt es im DOIF die Möglichkeit, bei der Anzahl die 0 durch All_Off und alles größer 0 durch Any_On zu ersetzen?
Vielen Dank
Ronny
Gesendet von meinem SM-G935F mit Tapatalk
Zitat von: RoBra81 am 05 Mai 2017, 09:44:02
Hallo,
Ich habe diese neuen Funktionen durch Zufall entdeckt und auch den Hinweis, dass man damit Strukturen ersetzen kann. Da ich mit meinen Strukturen nie ganz zufrieden war, wollte ich diese durch DOIFs ersetzen. Nun meine Frage: die Strukturen für meine Lampen haben entweder den Status All_Off oder Any_On - gibt es im DOIF die Möglichkeit, bei der Anzahl die 0 durch All_Off und alles größer 0 durch Any_On zu ersetzen?
Vielen Dank
Ronny
Gesendet von meinem SM-G935F mit Tapatalk
Anzahl wovon?
Ich zähle mit der neuen Aggregationsfunktion die eingeschalteten Lampen eines Raumes:
define OG.fk.STR.Licht DOIF
attr OG.fk.STR.Licht room Flur_Kinder
attr OG.fk.STR.Licht state [#"OG\.fk\.LI\.\w*.":state:"on"]
Nun möchte ich aber nicht die Anzahl haben, sondern bei 0 den state "All_Off" und bei größer 0 den state "Any_On"...
Ronny
Zitat von: RoBra81 am 05 Mai 2017, 09:56:14
Ich zähle mit der neuen Aggregationsfunktion die eingeschalteten Lampen eines Raumes:
define OG.fk.STR.Licht DOIF
attr OG.fk.STR.Licht room Flur_Kinder
attr OG.fk.STR.Licht state [#"OG\.fk\.LI\.\w*.":state:"on"]
Nun möchte ich aber nicht die Anzahl haben, sondern bei 0 den state "All_Off" und bei größer 0 den state "Any_On"...
Ronny
ok.
state {([#"OG\.fk\.LI\.\w*.":state:"on"]==0) ? "All_Off" : "Any_On"}
Super, das geht ;D
Danke!
Zitat von: RoBra81 am 05 Mai 2017, 10:19:02
Super, das geht ;D
Hast du etwas anderes erwartet? :)
Nicht wirklich ;-), aber als ich gestern was mit (...) oder {...} probiert hatte, stand exakt der Text im state und nicht das errechnete Ergebnis...
Gesendet von meinem SM-G935F mit Tapatalk
Hallo Damian,
funktioniert das?
define DOIF_Aussensteckdosen DOIF ([23:00] and [#".*Aussensteck.*":state:"off"] != 0) (set .*Aussensteck.*:FILTER=STATE=on off)
Um 23 Uhr soll geschaut werden, ob es noch eine Außensteckdose mit Saft gibt und dieser dann abgedreht werden.
Alternativ?
define DOIF_Aussensteckdosen DOIF ([23:00]) (set [@".*Aussensteck.*":state:$_ ne "off" and $TYPE eq "HMCCUDEV"] off)
Zitat von: Ralli am 27 Mai 2017, 12:08:12
Hallo Damian,
funktioniert das?
define DOIF_Aussensteckdosen DOIF ([23:00] and [#".*Aussensteck.*":state:"off"] != 0) (set .*Aussensteck.*:FILTER=STATE=on off)
Um 23 Uhr soll geschaut werden, ob es noch eine Außensteckdose mit Saft gibt und dieser dann abgedreht werden.
Alternativ?
define DOIF_Aussensteckdosen DOIF ([23:00]) (set [@".*Aussensteck.*":state:$_ ne "off" and $TYPE eq "HMCCUDEV"] off)
Warum sollte es nicht gehen? Hast du schon probiert?
damit
([23:00] and [?#"Aussensteck":state:"off"] != 0)
wird dein Modul nur um 23:00 Uhr getriggert. Die Regexangabe .* kannst du dir bei DOIF auch sparen.
Zitat von: Damian am 28 Mai 2017, 08:38:12
Warum sollte es nicht gehen? Hast du schon probiert?
damit
([23:00] and [?#"Aussensteck":state:"off"] != 0)
wird dein Modul nur um 23:00 Uhr getriggert. Die Regexangabe .* kannst du dir bei DOIF auch sparen.
auch das würde funktionieren
([23:00] and [?#"Aussensteck":state:"off"])
da es hier mit != 0 gleichzusetzen ist.
Danke :)
Ja, probiert. Im Endeffekt wollte ich wissen, ob das so noch zu "kompliziert" ist - und du hast mir eine kürzere Variante gezeigt.
Edit: Wobei ich ja selbst einen Logikfehler drin habe. Ich möchte ja prüfen, ob irgendeine Aussensteckdose noch eingeschaltet ist und nur dann an die eingeschalteten einen Ausschaltbefehl senden.
([23:00] and ![?#"Aussensteck":state:"^((?!off).)*$"])
Zitat von: Ralli am 28 Mai 2017, 09:17:40
Danke :)
Ja, probiert. Im Endeffekt wollte ich wissen, ob das so noch zu "kompliziert" ist - und du hast mir eine kürzere Variante gezeigt.
Edit: Wobei ich ja selbst einen Logikfehler drin habe. Ich möchte ja prüfen, ob irgendeine Aussensteckdose noch eingeschaltet ist und nur dann an die eingeschalteten einen Ausschaltbefehl senden.
([23:00] and ![?#"Aussensteck":state:"^((?!off).)*$"])
sollte dann nicht schon reichen
([23:00] and [?#"Aussensteck":state:"on"])
ist wahr, wenn irgendwo noch ein state mit "on" als Teilstring vorkommt.
Grundsätzlich hast du recht. Aber was ist, wenn eine der Aussensteckdosen einen undefinierten Zustand hat? Das fange ich so auch ab.
Falls jemand "offene Fenster" nicht in einer Liste hintereinander, sondern untereinander darstellen möchte, so kann er den Separator s(...) mit Hilfe von html-Syntax angeben, hier mit <br>:
attr Offene_Fenster state [@s(<br> )"Fenster$":state:"open","keine"]
sieht dann so aus:
Zitat von: CommandRefListe der Devices in der Gruppe "windows", die mit "rooms" enden, deren Status (nicht state-Reading) "on" ist:
[@"rooms$"::$STATE eq "on" and $group eq "windows"]
Tippfehler oder Absicht?
Zitat von: Per am 25 Juni 2017, 11:03:57
Tippfehler oder Absicht?
Absicht. Du kannst an der Stelle ein Reading angeben. Aber nach diesem wird hier nicht gesucht.
Die Aggregationsfunktion wurde um Regex-Angabe für Readings erweitert.
Die Syntax lautet nun:
[<function>:<format>:"<regex device>:<regex event>":<reading>|"<regex reading>":<condition>,<default>]
Damit kann man jetzt nicht nur über mehrer Devices, sondern auch über mehrer Readings aggregieren:
Beispiele:
Kleinster Wert der Readings des Devices "abfall", in deren Namen "Gruenschnitt" vorkommt und die mit "_days" enden:
[#min:"^abfall$":"Gruenschnitt.*_days$"]
oder
Durchschnitt von Readings aller Devices, die mit "T_" beginnen, in deren Reading-Namen "temp" vorkommt.
[#average:"^T_":"temp"]
oder
Durchschnitt von Readings aller Devices, die mit "T_" beginnen, in deren Reading-Namen "temp" vorkommt, die größer als 15 sind:
[#average:"^T_":"temp":$_ > 15]
Neue Version ist ab morgen per Update verfügbar.
Hey.
Super neue Funktionen. Vielen, vielen Dank für deine Mühe.
Ich habe das mal für meine Alarmanlage versucht zu integrieren.
DOIF wird getriggert, wenn der AnwesenheitsTrigger aktiviert wird und die Alarmanlage off ist - sofern eines der Fenster offen ist. Also im Grunde so, wie es hier schon oft beschrieben wurde, nur eben mit mehreren Bedingungen.
( ([@"Fenster"::$STATE ne "closed" and $group eq "Fenster_Alarm"]) && (([AnwesenheitsTrigger] eq "on") && ([Alarmanlage_dummy] eq "off")) ) (set AnwesenheitsTrigger off) (set Alarmanlage_dummy $DEVICE SCHLIESSEN)
Problem ist nur, dass ich ein "AnwesenheitsTrigger SCHLIESSEN" als Antwort bekomme. Obwohl ich ganz gerne die geöffneten Fenster mit $DEVICE angezeigt bekommen würde.
Ich habe nur leider keine Ahnung wie ich genau diesen Part auslese.
Würde mich über hilfe sehr freuen. Danke!
Wie viele Fenster hast du beim triggernden $DEVICE? Normaler weise doch nur eins.
ansonsten:
DOIF ( <Trigger auf Schließen>) (set dummy [@"$DEVICE"])
Oh. Ich dachte damit würde eine Liste der Devices (eines von 4 Fenstern in der Gruppe Fenster_Alarm) ausgegeben werden, die nicht geschlossen sind. Jedenfalls war das der Plan :)
Zitat von: snickers2k am 24 Januar 2018, 22:00:13
Oh. Ich dachte damit würde eine Liste der Devices (eines von 4 Fenstern in der Gruppe Fenster_Alarm) ausgegeben werden, die nicht geschlossen sind. Jedenfalls war das der Plan :)
Dann musst du die Aggregationsfunktion im Ausführungsteil angeben:
DOIF ( <Trigger auf Schließen>) (set dummy [@"Fenster"::$STATE eq "open" and $group eq "Fenster_Alarm"])
Super. So hats funktioniert! Vielen, vielen dank!
Zitat von: Damian am 20 Juni 2017, 17:55:13
Falls jemand "offene Fenster" nicht in einer Liste hintereinander, sondern untereinander darstellen möchte, so kann er den Separator s(...) mit Hilfe von html-Syntax angeben, hier mit <br>:
attr Offene_Fenster state [@s(<br> )"Fenster$":state:"open","keine"]
sieht dann so aus:
Moin,
kann man @s mit :a verbinden? Ich würde nämlich gerne den Alias nutzen, aber trotzdem einen Separator abgeben.
Aktueller Code:
Zitat(([22:00] or [HomeStatus] eq "Abwesend" or [HomeStatus] eq "Schlafen") and [?#".*":state: $_ eq "open"]) ({fhem ("set telebot message [@:a".*":state:"open"] \n ist/sind geoeffnet \nam $mday.$month.$year um $hms Uhr") }) DOELSE ()
Danke
Viele Grüße
Schon probiert? ;)
Zitat von: Damian am 10 März 2018, 19:59:57
Schon probiert? ;)
Klar, hier mal ein paar Beispiel ;)
[@:s(\n)a".*":state:"closed"]
[@:a,s(<br>)".*":state:"open"]
[@:a s(<br>)".*":state:"open"]
So gehts aber. Danke.
[@:as(\n)".*":state:"closed"]
nebenbei: ".*" entspricht "" und ist ein Performance-Schlucker, da bei jedem Event alle Devices nach "closed" geprüft werden.
Zitat von: Damian am 10 März 2018, 20:31:55
nebenbei: ".*" entspricht "" und ist ein Performance-Schlucker, da bei jedem Event alle Devices nach "closed" geprüft werden.
Effektiv kann aber dabei nur über den Devicenamen gefiltert werden oder übersehe ich da eine Möglichkeit?
Zitat von: stephanr am 10 März 2018, 22:50:47
Effektiv kann aber dabei nur über den Devicenamen gefiltert werden oder übersehe ich da eine Möglichkeit?
und das Ereignis:
z. B.
[@:as(\n)":closed":state:"closed"]
Zitat von: Damian am 10 März 2018, 22:51:56
und das Ereignis:
z. B.
[@:as(\n)":closed":state:"closed"]
Ok, aber für meinen Fall passt das dann ja nicht, weil ich dann z. B. genau um 22:00 Uhr oder wenn der Home-Status auf "Schlafen" gesetzt wird zusätzlich ein Event :closed haben müsste, oder verstehe ich das mit dem Event falsch?
Für mein Verständnis: Die Einschränkung auf das Event :closed müsste sowohl in der Ereignis, als auch in der Ausführung gesetzt werden?
Mein aktueller Code:
(([22:00] or [HomeStatus] eq "Abwesend" or [HomeStatus] eq "Schlafen") and [?#".*":state: $_ eq "open"]) ({fhem ("set telebot message [@:as(\n)".*":state:"open"] \nist/sind geoeffnet \nam $mday.$month.$year um $hms Uhr") }) DOELSE ()
Danke Dir schon mal.
ja, wenn du im Ausführungsteil die Aggregationsfunktion benutzt, ist es kein Problem, da gibt es keinen Trigger. Wenn du in der Bedingung die Triggerung mit ? ausschaltest und nur bei seltenen Triggern prüfst, ist es sicherlich auch kein Problem.
Ich wollte die Funktion mal ausprobieren und bin darüber gestolpert, das $DEVICE in cmdState nicht aufgelöst werden kann. Hat jemand eine Idee?
defmod di_Fenster DOIF ([#"^FENSTER:open":state:"open"] != 0) () DOELSEIF ([#"^FENSTER:closed":state:"open"] == 0) ()
attr di_Fenster cmdState $DEVICE zuletzt geöffnet|alle geschlossen
attr di_Fenster do always
attr di_Fenster room CUL_HM
setstate di_Fenster $DEVICE zuletzt geöffnet
setstate di_Fenster 2018-04-03 21:46:35 Device FENSTER_E2
setstate di_Fenster 2018-04-03 21:46:21 cmd 1
setstate di_Fenster 2018-04-03 21:46:21 cmd_event FENSTER_W2
setstate di_Fenster 2018-04-03 21:46:21 cmd_nr 1
setstate di_Fenster 2018-04-03 17:04:06 mode enabled
setstate di_Fenster 2018-04-03 21:46:21 state $DEVICE zuletzt geöffnet
Zitat von: mumpitzstuff am 03 April 2018, 21:49:21
Ich wollte die Funktion mal ausprobieren und bin darüber gestolpert, das $DEVICE in cmdState nicht aufgelöst werden kann. Hat jemand eine Idee?
defmod di_Fenster DOIF ([#"^FENSTER:open":state:"open"] != 0) () DOELSEIF ([#"^FENSTER:closed":state:"open"] == 0) ()
attr di_Fenster cmdState $DEVICE zuletzt geöffnet|alle geschlossen
attr di_Fenster do always
attr di_Fenster room CUL_HM
setstate di_Fenster $DEVICE zuletzt geöffnet
setstate di_Fenster 2018-04-03 21:46:35 Device FENSTER_E2
setstate di_Fenster 2018-04-03 21:46:21 cmd 1
setstate di_Fenster 2018-04-03 21:46:21 cmd_event FENSTER_W2
setstate di_Fenster 2018-04-03 21:46:21 cmd_nr 1
setstate di_Fenster 2018-04-03 17:04:06 mode enabled
setstate di_Fenster 2018-04-03 21:46:21 state $DEVICE zuletzt geöffnet
ja, $DEVICE wird nicht überall expandiert
Was neuerdings auf jeden Fall funktioniert ist dieses:
defmod di_Fenster DOIF {if ([#"^FENSTER:open":state:"open"] != 0) {set_Reading ("state","$DEVICE zuletzt geöffnet",1)}}
{if ([#"^FENSTER:closed":state:"open"] == 0){set_Reading ("state","alle geschlossen",1)}}
ohne Attribute.
Danke!
Kannst du dann vielleicht auch dein Beispiel in deiner Hilfe entsprechend anpassen, nicht das sonst noch jemand drüber stolpert... :)
Zitat von: mumpitzstuff am 04 April 2018, 11:08:11
Danke!
Kannst du dann vielleicht auch dein Beispiel in deiner Hilfe entsprechend anpassen, nicht das sonst noch jemand drüber stolpert... :)
ja, beim nächsten Update.
Bei cmdState oder state (state überlagert übrigens cmdState, daher sind beide nicht miteinander kombinierbar) kannst du statt [$DEVICE] [$SELF:Device] angeben - das funktioniert.
Oh wollte ich grad schreiben das es so geht. Bist mir zuvor gekommen.
Hallo zusammen,
irgendwie passen die obigen Lösungen nicht auf mein Problem, oder ich sehe irgendetwas noch falsch (sehr wahrscheinlich).
Ein DOIF soll liefern: "Alle zu" wenn alle Fenster geschlossen sind und z. B. "Badezimmerfenster,Schlafzimmerfenster" wenn diese beiden geöffnet sind. Wenn das Badezimmerfenster geschlossen wird, soll natürlich nur noch "Schlafzimmerfenster" angezeigt werden, soweit, so klar.
Bei mir zeigen die DOIFs noch nicht das Richtige an.
Das hier scheint zunächst zu funktionieren und ist FAST richtig, aber reduziert nicht die Liste der Fensternamen, wenn von z. B. 2 Fenstern eines geschlossen wird:
defmod di_Fenster_perl DOIF {if ([#"^Melder_":state:"open"] != 0) \
{set_Reading ("state",[@:a"^Melder_:open":state:"open"],1)}\
}\
\
{if ([#"^Melder_:closed":state:"open"] == 0)\
{set_Reading ("state", "alle zu",1)}\
}\
Das Beispiel aus der Referenz:
Statusanzeige: Offene Fenster:
define di_window DOIF
attr di_window state Offene Fenster: [@"^window:open":state:"open","keine"]
liefert bei mir NIE den Wert "keine" zurück, sondern es bleibt immer eine Liste offener Fenster, auch wenn alle geschlossen sind.
Kann mir jemand noch einen Denktipp geben?
Vielen Dank!
Gruß
Friedhelm
Zitat von: FFHEM am 27 Januar 2019, 13:16:19
Hallo zusammen,
irgendwie passen die obigen Lösungen nicht auf mein Problem, oder ich sehe irgendetwas noch falsch (sehr wahrscheinlich).
Ein DOIF soll liefern: "Alle zu" wenn alle Fenster geschlossen sind und z. B. "Badezimmerfenster,Schlafzimmerfenster" wenn diese beiden geöffnet sind. Wenn das Badezimmerfenster geschlossen wird, soll natürlich nur noch "Schlafzimmerfenster" angezeigt werden, soweit, so klar.
Bei mir zeigen die DOIFs noch nicht das Richtige an.
Das hier scheint zunächst zu funktionieren und ist FAST richtig, aber reduziert nicht die Liste der Fensternamen, wenn von z. B. 2 Fenstern eines geschlossen wird:
defmod di_Fenster_perl DOIF {if ([#"^Melder_":state:"open"] != 0) \
{set_Reading ("state",[@:a"^Melder_:open":state:"open"],1)}\
}\
\
{if ([#"^Melder_:closed":state:"open"] == 0)\
{set_Reading ("state", "alle zu",1)}\
}\
Das Beispiel aus der Referenz:
Statusanzeige: Offene Fenster:
define di_window DOIF
attr di_window state Offene Fenster: [@"^window:open":state:"open","keine"]
liefert bei mir NIE den Wert "keine" zurück, sondern es bleibt immer eine Liste offener Fenster, auch wenn alle geschlossen sind.
Kann mir jemand noch einen Denktipp geben?
Vielen Dank!
Gruß
Friedhelm
ohne konkrete Hinweise wird man dir nicht helfen können.
Was liefert?:
list window.*
list der einzelnen window-devices
list des DOIF-Devices
Hallo Damian,
danke und klar, ohne Infos nix los:
Das Beispiel aus der Commandref auf meine Sensoren geändert:
Symptom: offene Fenstermelder werden angezeigt, wenn diese schließen, bleiben diese Fenster aber angeblich offen, der Fall "keine" tritt hier nie ein:
Internals:
CFGFN
DEF ##
FUUID 5c4dc82f-f33f-26cd-f247-414e471567a4b3b0
MODEL FHEM
NAME di_window
NR 12599
NTFY_ORDER 50-di_window
STATE Offene Fenster: Melder_Bad_links,Melder_Bad_rechts
TYPE DOIF
READINGS:
2019-01-27 16:03:11 cmd 0
2019-01-27 16:03:11 mode enabled
2019-01-27 16:05:37 state Offene Fenster: Melder_Bad_links,Melder_Bad_rechts
Regex:
STATE:
:
STATE:
"^Melder_:open" ^Melder_:open
condition:
devices:
do:
0:
helper:
event battery: ok,contact: open (to VCCU),open,trigger_cnt: 40
globalinit 1
last_timer 0
sleeptimer -1
triggerDev Melder_Bad_links
DOIF_eventas:
state: Offene Fenster: Melder_Bad_links,Melder_Bad_rechts
triggerEvents:
battery: ok
contact: open (to VCCU)
open
trigger_cnt: 40
triggerEventsState:
battery: ok
contact: open (to VCCU)
state: open
trigger_cnt: 40
itimer:
uiState:
uiTable:
Attributes:
room Test
state Offene Fenster: [@"^Melder_:open":state:"open","keine"]
Melder_Bad_links ist, wie man sieht, "open"
Internals:
CFGFN ./FHEM/fhem_geraete.cfg
DEF 5F5A30
FUUID 5c444ff0-f33f-26cd-7af2-bb9dcc4a82a83f42
IODev myHmUART
LASTInputDev myHmUART
MSGCNT 56
NAME Melder_Bad_links
NOTIFYDEV global
NR 358
STATE open
TYPE CUL_HM
lastMsg No:BD - t:41 s:5F5A30 d:FF3004 0128C8
myHmUART_MSGCNT 56
myHmUART_RAWMSG 05010044BDA6415F5A30FF30040128C8
myHmUART_RSSI -68
myHmUART_TIME 2019-01-27 16:05:37
peerList Badthermostat_WindowRec,
protLastRcv 2019-01-27 16:05:37
protRcv 56 last_at:2019-01-27 16:05:37
protRcvB 15 last_at:2019-01-27 16:05:37
protSnd 41 last_at:2019-01-27 16:05:37
protState CMDs_done
rssi_at_myHmUART cnt:56 min:-75 max:-58 avg:-63.85 lst:-68
READINGS:
2019-01-26 16:50:39 Activity alive
2018-12-29 16:28:16 CommandAccepted no
2018-12-07 10:19:34 D-firmware 1.0
2019-01-05 16:15:27 PairedTo 0xFF3004
2018-12-07 12:22:37 R-Badthermostat_WindowRec-expectAES off
2018-12-07 12:22:37 R-Badthermostat_WindowRec-peerNeedsBurst on
2018-12-07 12:22:36 R-cyclicInfoMsg on
2018-12-07 12:22:36 R-eventDlyTime 0 s
2018-12-07 12:22:36 R-pairCentral 0xFF3004
2018-12-07 12:22:36 R-sabotageMsg on
2018-12-07 12:22:36 R-sign on
2019-01-05 16:15:27 RegL_00. 00:00 02:01 09:01 0A:FF 0B:30 0C:04 10:01 14:06
2019-01-05 16:15:27 RegL_01. 00:00 08:01 20:9C 21:00 30:06
2019-01-05 16:15:28 RegL_04.Badthermostat_WindowRec 00:00 01:01
2019-01-27 15:10:18 alive yes
2019-01-27 16:05:37 battery ok
2019-01-02 12:23:13 battery_warning 1546428192.65447
2019-01-27 16:05:37 contact open (to VCCU)
2019-01-26 16:50:39 peerList Badthermostat_WindowRec,
2019-01-05 09:58:19 powerOn 2019-01-05 09:58:19
2019-01-27 15:10:18 recentStateType info
2019-01-27 15:10:18 sabotageError off
2019-01-27 16:05:37 state open
2019-01-27 16:05:37 trigger_cnt 40
helper:
HM_CMDNR 189
mId 00C7
regLst ,0,1,4p
rxType 28
supp_Pair_Rep 0
ack:
expert:
def 1
det 0
raw 1
tpl 0
io:
newChn +5F5A30,00,00,00
nextSend 1548601537.98151
rxt 2
vccu VCCU
p:
5F5A30
00
00
00
prefIO:
myHmUART
mRssi:
mNo BD
io:
myHmUART:
-64
-64
prt:
bErr 0
sProc 0
sleeping 0
rspWait:
q:
qReqConf
qReqStat
role:
chn 1
dev 1
rpt:
IO myHmUART
flg A
ts 1548601537.6884
ack:
HASH(0x3af6998)
BD8002FF30045F5A300101C800
rssi:
at_myHmUART:
avg -63.8571428571429
cnt 56
lst -68
max -58
min -75
tmpl:
Attributes:
IODev myHmUART
IOgrp VCCU:myHmUART
actCycle 002:50
actStatus alive
alias Badezimmer links
autoReadReg 4_reqStatus
devStateIcon open:10px-kreis-rot closed:10px-kreis-gruen
expert 2_raw
firmware 1.0
group Fenster/Tür
model HM-SEC-SCo
peerIDs 00000000,633A0803,
room Alarmanlage
subType threeStateSensor
userattr room_map structexclude
während Melder_Bad_rechts, nachdem er einmal "open" war, nun wieder "closed" ist, und trotzdem als offen angezeigt wird:
Internals:
CFGFN ./FHEM/fhem_geraete.cfg
DEF 5F5A5A
FUUID 5c444ff0-f33f-26cd-2882-7f01903d706a6642
IODev myHmUART
LASTInputDev myHmUART
MSGCNT 94
NAME Melder_Bad_rechts
NOTIFYDEV global
NR 362
STATE closed
TYPE CUL_HM
lastMsg No:5B - t:10 s:5F5A5A d:FF3004 06010000
myHmUART_MSGCNT 94
myHmUART_RAWMSG 050100425BA6105F5A5AFF300406010000
myHmUART_RSSI -66
myHmUART_TIME 2019-01-27 16:06:00
peerList Badthermostat_WindowRec,
protLastRcv 2019-01-27 16:06:00
protRcv 94 last_at:2019-01-27 16:06:00
protRcvB 34 last_at:2019-01-27 16:05:54
protSnd 60 last_at:2019-01-27 16:06:00
protState CMDs_done
rssi_at_myHmUART cnt:94 min:-77 max:-64 avg:-67.46 lst:-66
READINGS:
2019-01-26 16:50:39 Activity alive
2018-12-09 09:05:47 CommandAccepted no
2018-12-07 10:19:34 D-firmware 1.0
2018-12-28 21:37:55 PairedTo 0xFF3004
2018-12-07 11:37:57 R-Badthermostat_WindowRec-expectAES off
2018-12-07 11:37:57 R-Badthermostat_WindowRec-peerNeedsBurst on
2018-12-07 11:37:56 R-cyclicInfoMsg on
2018-12-07 11:37:56 R-eventDlyTime 0 s
2018-12-07 11:37:56 R-pairCentral 0xFF3004
2018-12-07 11:37:56 R-sabotageMsg on
2018-12-07 11:37:56 R-sign on
2018-12-28 21:37:55 RegL_00. 00:00 02:01 09:01 0A:FF 0B:30 0C:04 10:01 14:06
2018-12-28 21:37:55 RegL_01. 00:00 08:01 20:9C 21:00 30:06
2018-12-28 21:37:56 RegL_04.Badthermostat_WindowRec 00:00 01:01
2019-01-27 16:06:00 alive yes
2019-01-27 16:06:00 battery ok
2019-01-24 08:28:25 battery_warning 1548314903.68419
2019-01-27 16:06:00 contact closed (to VCCU)
2019-01-26 16:50:39 peerList Badthermostat_WindowRec,
2019-01-04 17:41:10 powerOn 2019-01-04 17:41:10
2019-01-27 16:06:00 recentStateType info
2019-01-27 16:06:00 sabotageError off
2019-01-27 16:06:00 state closed
2019-01-27 16:05:55 trigger_cnt 112
helper:
HM_CMDNR 91
mId 00C7
regLst ,0,1,4p
rxType 28
supp_Pair_Rep 0
ack:
expert:
def 1
det 0
raw 1
tpl 0
io:
newChn +5F5A5A,00,00,00
nextSend 1548601560.39845
rxt 2
vccu VCCU
p:
5F5A5A
00
00
00
prefIO:
myHmUART
mRssi:
mNo 5B
io:
myHmUART:
-62
-62
prt:
bErr 0
sProc 0
sleeping 0
rspWait:
q:
qReqConf
qReqStat
role:
chn 1
dev 1
rpt:
IO myHmUART
flg A
ts 1548601560.10431
ack:
HASH(0x3ad3768)
5B8002FF30045F5A5A00
rssi:
at_myHmUART:
avg -67.468085106383
cnt 94
lst -66
max -64
min -77
tmpl:
Attributes:
IODev myHmUART
IOgrp VCCU:myHmUART
actCycle 002:50
actStatus alive
alias Badezimmer rechts
autoReadReg 4_reqStatus
devStateIcon open:10px-kreis-rot closed:10px-kreis-gruen
expert 2_raw
firmware 1.0
group Fenster/Tür
model HM-SEC-SCo
peerIDs 00000000,633A0803,
room Alarmanlage
subType threeStateSensor
userattr room_map structexclude
Meiner Meinung nach erfolgt ja kein Rücksetzen durch die Abfrage auf "closed".
-------------------------------------------------------------------------------------
Und hier ein abgewandeltes Beispiel, was zwar erkennt, wenn alle Fenster geschlossen sind, aber nicht, wenn von den 2 Fenstern eins wieder geschlossen wird:
Internals:
CFGFN
DEF ([#"^Melder_:open":state:"open"] != 0)
()
DOELSEIF ([#"^Melder_:closed":state:"open"] == 0)
()
FUUID 5c4d979b-f33f-26cd-2b75-bea1e71e89070f51
MODEL FHEM
NAME di_Fenster
NR 10765
NTFY_ORDER 50-di_Fenster
STATE Badezimmer links,Badezimmer rechts
TYPE DOIF
READINGS:
2019-01-27 16:17:16 Device Melder_Bad_rechts
2019-01-27 16:17:12 cmd 1
2019-01-27 16:17:12 cmd_event Melder_Bad_links
2019-01-27 16:17:12 cmd_nr 1
2019-01-27 12:53:33 mode enabled
2019-01-27 16:17:12 state Badezimmer links,Badezimmer rechts
Regex:
STATE:
:
STATE:
"^Melder_:open" ^Melder_:open
cond:
:
0:
"^Melder_:open" ^Melder_:open
1:
"^Melder_:closed" ^Melder_:closed
attr:
cmdState:
wait:
waitdel:
condition:
0 ::AggregateDoIf($hash,'#','^Melder_','state','"open"') != 0
1 ::AggregateDoIf($hash,'#','^Melder_','state','"open"') == 0
devices:
do:
0:
0
1:
0
2:
helper:
event battery: ok,contact: closed (to VCCU),closed,trigger_cnt: 116
globalinit 1
last_timer 0
sleeptimer -1
timerdev Melder_Bad_links
timerevent battery: ok,contact: open (to VCCU),open,trigger_cnt: 42
triggerDev Melder_Bad_rechts
DOIF_eventas:
cmd_nr: 1
cmd: 1
cmd_event: Melder_Bad_links
state: Badezimmer links,Badezimmer rechts
timerevents:
battery: ok
contact: open (to VCCU)
open
trigger_cnt: 42
timereventsState:
battery: ok
contact: open (to VCCU)
state: open
trigger_cnt: 42
triggerEvents:
battery: ok
contact: closed (to VCCU)
closed
trigger_cnt: 116
triggerEventsState:
battery: ok
contact: closed (to VCCU)
state: closed
trigger_cnt: 116
internals:
itimer:
readings:
trigger:
uiState:
uiTable:
Attributes:
do always
room Test
state [@:a"^Melder_:open":state:"open","alle zu"]
Zitat von: FFHEM am 27 Januar 2019, 16:24:01
Und hier ein abgewandeltes Beispiel, was zwar erkennt, wenn alle Fenster geschlossen sind, aber nicht, wenn von den 2 Fenstern eins wieder geschlossen wird:
Internals:
CFGFN
DEF ([#"^Melder_:open":state:"open"] != 0)
()
DOELSEIF ([#"^Melder_:closed":state:"open"] == 0)
()
Klar nicht! Den Fall ([#"^Melder_:closed":state:"open"] > 0 hast du auch nicht definiert.
ZitatKlar nicht! Den Fall ([#"^Melder_:closed":state:"open"] > 0 hast du auch nicht definiert.
Oh Mann,
da hatte ich wieder 2 dicke Tomaten auf den Augen,
vielen Dank!!!!
Hi,
Ich weiß jetzt nicht ob ich die Funktion falsch verstehe oder irgendwo einen Fehler habe.
Ich möchte, wenn ich das Haus verlasse eine Meldung darüber bekommen, welche Fenster (OK, im Moment gibts nur eins mit passendem Sensor...aber der Rest kommt, wenn das hier dann funktioniert ;-)) noch offen sind.
Dafür hab ich Tasker auf meinem Handy so eingerichtet, dass er beim Berühren eines bestimmten NFC-Tags ein Dummy-Device auf 1 setzt. Dadurch wird dann ein DOIF getriggert, welches mir dann per Telegram mitteilt, welche Fenster noch offen sind
mein DOIF sieht jetzt so aus:
([d_Fenster_Check] eq 1)(
IF ([#"Fenster:open":state:"open"] != 0) (
{Log 1, "Folgende Fenster sind offen: [@"Fenster":state:"open"]"}
) ELSEIF ([#"Fenster:closed":state:"open"] == 0) (
{Log 1, "alle Fenster geschlossen"}
)
)
Als Fehler bekomme ich imm:
IF: unknown Device: #"Fenster
Danke für eure Hilfe.
Paddie
Der Befehl IF kennt keine Aggregation, die Abfrage musst du in die DOIF-Bedingung verlagern:
([d_Fenster_Check] eq 1 and [#"Fenster:open":state:"open"] != 0)...
Hmm..stimmt, dann funktionierts ;-).
Wobei jetzt aber bei "alle geschlossen" gar nichts ausgegeben wird. Wobei das eigentlich auch nicht soooo wichtig ist
...kleiner Edit... OK, ich bin doof, ich kann das ja einfach in den doelseif packen ... ;-) 8) ::)
Vielen Dank
Hallo,
ich habe Probleme mit der Filterung nach Gruppen:
defmod di_average_temp DOIF ##
attr di_average_temp state [#sum"^MQTT":power:$group eq "test2"]
setstate di_average_temp 53
setstate di_average_temp 2020-01-26 13:54:30 cmd 0
setstate di_average_temp 2020-01-26 13:54:30 mode enabled
setstate di_average_temp 2020-01-26 14:52:14 state 53
Sind die zu Summierenden Device nur EINER einzigen Gruppe zugeordnet ist alles OK.
Bei mehreren Gruppenzuweisungen llaufe ich vor die Pumpe ...
Bug oder Feature oder Problem vor dem Bildschirm?
Cheers
Joerg
Hallo und moin, moin,
ich stehe auf dem Schlauch und wäre für einen "rettenden" Hinweis sehr dankbar:
Ich möchte aggregiert bei allen Devices des Typs "MQTT2_DEVICE" abfragen, ob das Reading "new_fw" true ist,
aber hiermit funktioniert es noch nicht:
DOELSEIF ([@"":new_fw:$_ eq "true" and $TYPE eq "MQTT2_DEVICE"])
(set Telegram _msg $DEVICE Neue Firmware,
set $DEVICE x_update)
Was mache ich falsch ?
Dank euch !
VG
Moin,
ich habe bei mir folgendes am laufen:
attr XYZ DOIF_Readings neueFW:[@as(<br>)":new_fw":new_fw:$_ eq "true" and $TYPE eq "MQTT2_DEVICE"]
liefert das Reading neueFW als Liste untereinander. Für Deinen Zweck musst Du evtl. das s(<br>) weglassen für eine kommaseparierte Zeile.
Viel Erfolg!
Hallo zusammen,
mit diesem Code konnte ich den Fenster-Status super erdarstellen.
DEF
([#"^FS_:open":state:"open"] != 0) DOELSEIF ([#"^FS_:closed":state:"open"] == 0) DOELSEIF ([#"^FS_:closed":state:"open"] > 0)
attr state Offene Fenster: [@"^window:open":state:"open","keine"]
Nun würde ich aber gerne die Alias Device Namen darstellen um diese in FTUI anzeigen zu können.
Wie könnte das erreicht werden ?
würde mich über einen Tipp freuen, Gruß Peter
Zitat von: Peter aus Calw am 22 November 2021, 18:01:26
Hallo zusammen,
mit diesem Code konnte ich den Fenster-Status super erdarstellen.
DEF
([#"^FS_:open":state:"open"] != 0) DOELSEIF ([#"^FS_:closed":state:"open"] == 0) DOELSEIF ([#"^FS_:closed":state:"open"] > 0)
attr state Offene Fenster: [@"^window:open":state:"open","keine"]
Nun würde ich aber gerne die Alias Device Namen darstellen um diese in FTUI anzeigen zu können.
Wie könnte das erreicht werden ?
würde mich über einen Tipp freuen, Gruß Peter
Für Aliasnamen musst du a angeben, wie in der Doku beschrieben, also:
[@a"^window:open":state:"open","keine"]
Hallo Damian,
es ist immer wieder ein Erlebnis wie Du mir und vielen anderen prompt und so super hilfst.
Also es funktioniert wie gewünscht.
Besten Dank und Gruß Peter
Hallo Damian und alle Fhemler,
die Lösung von Damian schreibt nun alle Alias der geöffneten Fenster ins "state", das hat zur Folge, daß das in FTUI-Tablet übernommen wird.
Allerdings fortschreibend. Ist es möglich die Device state jeweils in eine neue Zeile im tablet zu schreiben - also in Form einer Device Liste ?
Das müßte vermutlich in FTUI-Tablet passieren, also hier :
<td>
<div data-type="label" data-device="FENSTER_STATUS" data-get="state" class="large"</div>
</td>
Hier werden die Device-Alias durch ein Komma getrennt angezeigt.
Habe keine Ahnung das in eine Listenförm zu bringen oder nach dem Komma in die nächste Zeile ?
Brauche also noch einmal eure Unterstützung.
Gruß Peter
Untereinander geht mit:
[@as(<br>)"^window:open":state:"open","keine"]
siehe Commandref
Hallo Damian,
habe Deine Antwort vor lauter verzweifelter Suche eben erst bemerkt, es ist einfach der Wahnsinn, daß man solche Sachen als Greenhorn nicht findet.
Ohne Deine nun schon langjährige Unterstützung wäre ich nie auf den Level meiner kleinen Anlage gekommen und vielleicht wäre meine Frau wegen Wärmemangel abgehauen ???
Also einfach mal wieder ein SUPER Danke und Gruß von Peter