Hallo,
ich habe ein DOIF, das einfach Daten von anderen Devices zusammensammelt, damit alles was zusammengehört auch an einem Ort ist.
Internals:
DEF (["ESPEasy_Werkstatt"])
NAME a_ESP_Werkstatt
NR 161
NTFY_ORDER 50-a_ESP_Werkstatt
STATE low
TYPE DOIF
READINGS:
2017-11-09 18:09:15 Device ESPEasy_Werkstatt_SystemInfo
2017-11-09 18:09:15 RSSI -65
2017-11-09 18:09:15 Relais_A on
2017-11-09 18:09:15 Relais_B off
2017-11-09 18:09:15 cmd 1
2017-11-09 18:09:15 cmd_event ESPEasy_Werkstatt_SystemInfo
2017-11-09 18:09:15 cmd_nr 1
2017-11-09 18:09:15 dewpoint 9.9
2017-11-08 22:56:09 fan on
2017-11-09 18:09:15 humidity 60
2017-11-09 18:09:15 matched_event_c1_1 RSSI: -65,RSS: -65
2017-11-09 18:09:15 presence present
2017-11-09 18:09:15 presence2 present
2017-11-09 18:09:15 state cmd_1
2017-11-09 18:09:15 temperature 17.8
2017-11-09 18:09:15 ventilator low
condition:
0 EventDoIf('ESPEasy_Werkstatt',$hash,'',0)
devices:
do:
0:
0
1:
helper:
event RSSI: -65,RSS: -65
globalinit 1
last_timer 0
sleeptimer -1
timerdev ESPEasy_Werkstatt_SystemInfo
timerevent RSSI: -65,RSS: -65
triggerDev ESPEasy_Werkstatt_SystemInfo
timerevents:
RSSI: -65
RSS: -65
timereventsState:
RSSI: -65
state: RSS: -65
triggerEvents:
RSSI: -65
RSS: -65
triggerEventsState:
RSSI: -65
state: RSS: -65
internals:
itimer:
readings:
regexp:
0:
0 ESPEasy_Werkstatt
all:
0 ESPEasy_Werkstatt
state:
STATE:
trigger:
Attributes:
adminlink 192.168.0.31
devStateIcon off:off low:half high:on
do always
room Abstracts
stateFormat ventilator
userReadings presence { ReadingsVal("Pres_ESPEasy_Werkstatt", "presence", "null") },
presence2 { ReadingsVal("ESPEasy_Werkstatt_SystemInfo", "presence", "null") },
RSSI { ReadingsVal("ESPEasy_Werkstatt_SystemInfo", "RSSI", "null") },
temperature { ReadingsVal("ESPEasy_Werkstatt_DHT_innen", "temperature","null") },
humidity { ReadingsVal("ESPEasy_Werkstatt_DHT_innen", "humidity", "null") },
Relais_A { ReadingsVal("ESPEasy_Werkstatt_Relais_A", "Relais_A", "null") },
Relais_B { ReadingsVal("ESPEasy_Werkstatt_Relais_B", "Relais_B", "null") },
ventilator { ReadingsVal("ESPEasy_Werkstatt_Fan", "state", "null") }
Jetzt will ich die Daten loggen, und zwar alle userReadings. Es entstehen aber viel zu viele Zeilen im Log. Daher möchte ich event-on-change-reading einsetzen.
attr a_ESP_Werkstatt event-on-change-reading Relais_A,Relais_B
Bei anderen Devices funktioniert das auch gut, aber hier nicht. In der obigen Form entstehen überhaupt gar keine Logzeilen mehr.
1) Woran hakt es? Hängt das mit den Events zusammen, die das DOIF triggern? Die heißen ja anders als die userReadings (die dann auch in event-on-change-reading aufgeführt werden).
2) Zur Architektur. Ich hatte das gleiche Ziel -- Zusammenfassen aller Daten in einem Device -- auch mal mit einem dummy erreicht. Der dummy wurde mittels notify und setreading mit Daten versorgt. Also ein "Push"-Ansatz im Gegensatz zu den userReadings, die sich die Daten selbst holen ("Pull"). Ist das womöglich der bessere Ansatz?
Ohne mir jetzt Dein ganzes DOIF angeschaut zu haben vermute ich erstmal folgendes:
userreadings werden nur neu berechnet, wenn andere Readings einen Event auslösen - Dein event-on-change enthält nur userreadings, damit werden alle anderen reading änderungen keinen event mehr auslösen - ergo werden die user readings nie upgedated da es nie einen event gibt
verstehe. Ich habe mal testweise folgendes eingestellt:
attr a_ESP_Waesche event-on-change-reading fan,Relais_A,Relais_B
fan ist kein userReadings, Relais_A und Relais_B aber schon.
fan ändert sich grad nicht.
Wenn sich jetzt Relais_A ändert, gibt es keinen Logeintrag. Weil sich fan nicht geändert hat, richtig?
Wenn das so ist, dann würde das aber bedeuten, dass event-on-change-reading für userReadings in einem DOIF prinzipiell nicht funktioniert, oder sehe ich das falsch?
D.h. ich müsste dann einen dummy nehmen statt des DOIF?
Zitatfan ändert sich grad nicht.
Wenn sich jetzt Relais_A ändert, gibt es keinen Logeintrag. Weil sich fan nicht geändert hat, richtig?
Richtig
Aktualisierung eines Readings, das nicht durch event-on-change ausgefiltert ist => Event => Aktualisierung des userReadings
Kein Event, oder durch event-on-change ausgefiltertes Event => Kein Event => keine Aktualisierung
ZitatWenn das so ist, dann würde das aber bedeuten, dass event-on-change-reading für userReadings in einem DOIF prinzipiell nicht funktioniert, oder sehe ich das falsch?
Naja
event-on-change-reading NUR auf userReadings => nix passiert. Siehe oben.
Aber probier mal mit
event-on-change-reading Relais_A,Relais_B
event-on-update-reading cmd
schade, das klang gut, aber es erzeugt im Logging
2017-11-09_21:15:09 a_ESP_Werkstatt cmd: 1
2017-11-09_21:15:20 a_ESP_Werkstatt cmd: 1
2017-11-09_21:15:47 a_ESP_Werkstatt cmd: 1
2017-11-09_21:16:09 a_ESP_Werkstatt cmd: 1
2017-11-09_21:16:20 a_ESP_Werkstatt cmd: 1
2017-11-09_21:16:47 a_ESP_Werkstatt cmd: 1
2017-11-09_21:17:09 a_ESP_Werkstatt cmd: 1
Und mit
event-on-change-reading Relais_A,Relais_B
event-on-update-reading Relais_A,Relais_B
erzeuge ich zwar ein Logging, aber event-on-change-reading greift nicht:
2017-11-09_21:17:20 a_ESP_Werkstatt Relais_A: off
2017-11-09_21:17:20 a_ESP_Werkstatt Relais_B: off
2017-11-09_21:17:47 a_ESP_Werkstatt Relais_A: off
2017-11-09_21:17:47 a_ESP_Werkstatt Relais_B: off
2017-11-09_21:17:49 a_ESP_Werkstatt Relais_A: off
2017-11-09_21:17:49 a_ESP_Werkstatt Relais_B: off
Ich hab auch noch mit checkReadingEvent und timestamp-on-change-reading herumexperimentiert, aber ich bekomme das Logging der userReadings entweder alle paar Sekunden oder gar nicht, aber nicht on-change.
Mach mal ein "list ESPEasy_Werkstatt_Relais_A" und ein "list ESPEasy_Werkstatt_Relais_B" bitte.
Internals:
DEF 192.168.0.31 80 EspBridge Werkstatt_Relais_A
ESP_BUILD 20000
ESP_BUILD_GIT v2.0.0-dev12
ESP_BUILD_NOTES - Mega
ESP_NODE_TYPE_ID 17: ESP Easy Mega
ESP_SLEEP 0
ESP_UNIT 1
ESP_VERSION 2
EspBridge_MSGCNT 297
EspBridge_TIME 2017-11-09 22:28:19
HOST 192.168.0.31
IDENT Werkstatt_Relais_A
INTERVAL 300
IODev EspBridge
LASTInputDev EspBridge
MSGCNT 297
NAME ESPEasy_Werkstatt_Relais_A
NOTIFYDEV global
NR 91
NTFY_ORDER 50-ESPEasy_Werkstatt_Relais_A
PORT 80
STATE off
SUBTYPE device
TYPE ESPEasy
VERSION 1.33
READINGS:
2017-11-09 22:28:19 Relais_A off
2017-11-09 22:28:08 presence present
2017-11-09 22:28:19 state Rel: off
helper:
fpc 1510245343
pm:
Encode 1
JSON 1
received:
Relais_A 1510262899
Attributes:
IODev EspBridge
Interval 300
eventMap /gpio 16 on:off/gpio 16 off:on/
group ESPEasy Device
presenceCheck 1
readingSwitchText 1
room Basisdaten
setState 3
stateFormat Relais_A
Internals:
DEF 192.168.0.31 80 EspBridge Werkstatt_Relais_B
ESP_BUILD 20000
ESP_BUILD_GIT v2.0.0-dev12
ESP_BUILD_NOTES - Mega
ESP_NODE_TYPE_ID 17: ESP Easy Mega
ESP_SLEEP 0
ESP_UNIT 1
ESP_VERSION 2
EspBridge_MSGCNT 296
EspBridge_TIME 2017-11-09 22:29:37
HOST 192.168.0.31
IDENT Werkstatt_Relais_B
INTERVAL 300
IODev EspBridge
LASTInputDev EspBridge
MSGCNT 296
NAME ESPEasy_Werkstatt_Relais_B
NOTIFYDEV global
NR 92
NTFY_ORDER 50-ESPEasy_Werkstatt_Relais_B
PORT 80
STATE off
SUBTYPE device
TYPE ESPEasy
VERSION 1.33
READINGS:
2017-11-09 22:29:37 Relais_B off
2017-10-23 23:50:28 Switch off
2017-11-09 22:28:20 presence present
2017-11-09 22:29:37 state Rel: off
helper:
fpc 1510245343
pm:
Encode 1
JSON 1
received:
Relais_B 1510262977
Attributes:
IODev EspBridge
Interval 300
eventMap /gpio 5 on:off/gpio 5 off:on/
group ESPEasy Device
presenceCheck 1
readingSwitchText 1
room Basisdaten
setState 3
stateFormat Relais_B
Zitat2017-11-09_21:15:09 a_ESP_Werkstatt cmd: 1
2017-11-09_21:15:20 a_ESP_Werkstatt cmd: 1
2017-11-09_21:15:47 a_ESP_Werkstatt cmd: 1
2017-11-09_21:16:09 a_ESP_Werkstatt cmd: 1
2017-11-09_21:16:20 a_ESP_Werkstatt cmd: 1
2017-11-09_21:16:47 a_ESP_Werkstatt cmd: 1
2017-11-09_21:17:09 a_ESP_Werkstatt cmd: 1
Hat sich zwischen 21:15 und 21:17 Werkstatt_Relais_A:Relais_A oder Werkstatt_Relais_B:Relais_B geändert (von "off" auf "on")?
nein. (EDIT:doch, s.u.)
Dann klar hast Du nix anderes in der Log als "cmd1"
event-on-change-reading = er wird ein Event generiert, wenn sich der Wert ändert
Relais_A { ReadingsVal("ESPEasy_Werkstatt_Relais_A", "Relais_A", "null") }
bedeutet:
a_ESP_Werkstatt:Relais_A = ESPEasy_Werkstatt_Relais_A:Relais_A
Wenn ESPEasy_Werkstatt_Relais_A:Relais_A sich nicht ändert, ändert sich a_ESP_Werkstatt:Relais_A auch nicht => es wird kein Event generiert, wenn event-on-change-reading gesetzt.
ja, schon klar. Das bedeutet dann aber auch: event-on-change-reading ist nicht für userReadings verwendbar, sondern nur für Readings, die von außen über einen Event hereinkommen.
Ich hab jetzt ein notify, das genau das macht:
defmod n_copy_to_esp_waesche notify ESPEasy_Waesche.*:(RSSI|Relais_A|Relais_B|humidity|temperature|ventilator).*|ESPEasy_Waesche_DHT.*:presence.* {\
fhem( copyreading_command("a_ESP_Waesche", $EVENT) );; \
}
und in 99_myUtils.pm:
sub copyreading_command($$){
my $ziel = $_[0];
my $eventstring = $_[1];
$eventstring =~ tr/://d; # Doppelpunkt streichen
'setreading '.$ziel.' '.$eventstring;
}
Ich wundere mich nur, warum das so kompliziert ist und warum ich im jahrelangem Forum-Wissensschatz auch nichts darüber finde. Es scheint eine total exotische Idee zu sein, Readings zusammenzufassen, zu kopieren und damit umzustrukturieren. Dabei habe ich das an gleich mehreren Stellen:
- obiges DOIF fasst verschiedene Devices wieder zusammen, die eigentlich auch ein physikalisches Gerät sind
- Es gibt noch ein a_Internet-Device, das Auskunft über den Status der Internet-Konnektivität gibt, derzeit bestehend aus ping-Test und Speedtest
- und es gibt ein a_Umwelt-Device, das für einige Werte jeweils den Mittelwert von Yahoo-Wetter und einer Wunderground-Wetterstation liefert und außerdem statt 100 Readings nur die 5 Readings liefert, die ich brauche
Ist dieses Bündeln und Filtern von Readings wirklich ein so ungewöhnlicher, exotischer Usecase? Oder wenn nicht, wie macht man das als FHEM-Profi?
@amenomade: Sorry, ich hatte dir eine falsche Information gegeben und deine Antwort auch erst falsch verstanden.
Doch, der Zustand des Relais hat sich geändert.
Ich habe es nochmal ausprobiert.
Also folgendes eingestellt:
attr a_ESP_Werkstatt event-on-change-reading Relais_A,Relais_B
attr a_ESP_Werkstatt event-on-update-reading cmd
Jetzt das Relais geschaltet (mit einem anderen Device).
Der Zustand des Relais hat sich geändert.
Logging ist:
2017-11-09_23:33:55 a_ESP_Werkstatt cmd: 1
2017-11-09_23:33:57 a_ESP_Werkstatt cmd: 1
2017-11-09_23:33:57 a_ESP_Werkstatt cmd: 1
2017-11-09_23:34:06 a_ESP_Werkstatt cmd: 1
2017-11-09_23:34:25 a_ESP_Werkstatt cmd: 1
2017-11-09_23:34:42 a_ESP_Werkstatt cmd: 1
2017-11-09_23:35:06 a_ESP_Werkstatt cmd: 1
2017-11-09_23:35:25 a_ESP_Werkstatt cmd: 1
2017-11-09_23:35:44 a_ESP_Werkstatt cmd: 1
2017-11-09_23:36:06 a_ESP_Werkstatt cmd: 1
D.h. die Relais wurden nicht geloggt. Aber wenn es seinen Wert verändert, wird cmd geloggt.
Wenn dein Ziel ist, verschiedene Readings von verschiedene Devices zusammenzufassen, probier mal https://wiki.fhem.de/wiki/ReadingsGroup
Sonst gibt es auch das: https://forum.fhem.de/index.php/topic,77690.0.html
klar, ich kenne readingsGroups. Meine readingsGroups nutzen ja gerade die vorstrukturierten Informationen, statt sie sich erst aus verstreuten Raw-Quellen zusammenzusammeln.