Hallo herrmannj,
besteht die Möglichkeit, dass du folgende Features in JsonMod implementierst?
Status: Wenn JsonMod einen Request macht, soll das Modul success/error in state schreiben, je nachdem ob der Request erfolgreich war oder nicht. Das Internal API__LAST_MSG wäre eigentlich auch als Reading interessant (damit man z.B. mit userReading darauf reagieren kann).
Raw: Ähnlich wie bei HTTPMod wäre es sehr hilfreich, wenn man, gesteuert über ein Attribut, die unbehandelten Ausgaben des Requests in ein Reading schreiben lassen könnte.
Was denkst du dazu?
Geht schon. Ich frag besser nicht wozu das gut ist :)
Zitatdie unbehandelten Ausgaben des Requests in ein Reading schreiben lassen könnte.
Den ganzen Json?
vg
Zitat von: herrmannj am 01 Dezember 2020, 23:43:51
Geht schon. Ich frag besser nicht wozu das gut ist :)
Ich kann's dir gerne erläutern: Ich hab z.B. einen Feinstaubsensor, der zwar Werte liefert, aber keinen Timestamp zum Wert. Ich sehe also nicht, wann ein Wert zuletzt gelesen wurde (natürlich sehe ich den Timestamp des Readings, aber der kann ja auch mal "hängen" bleiben, wenn das Sensor nicht erreichbar ist und JsonMod keine Events generiert). Andersrum bedeutet ein älterer Timestamp auch nicht automatisch, dass das Gerät keine Daten mehr sendet. Zusätzlich sehe ich auch nicht, ob der Request an sich funktioniert hat, außer wenn ich API__LAST_MSG über einen watchdog überwache - so mache ich das aktuell, aber schön ist was anderes ;-)).
Zitat von: herrmannj am 01 Dezember 2020, 23:43:51
Den ganzen Json?
Am besten eigentlich zwei Readings:
Einmal die rohen Json-Daten, einmal die response header aus dem Request.
ok - verstehe. Du möchtest darauf reagieren wenn was schiefgeht. Ich würde es schön finden wenn das von den readings getrennt stattfinden kann.
Würde das so für Dich passen?: per attr wird definiert was ein Fehler ist. Kann dann, neben "keine Antwort" auch ein von 200 OK abweichender Server Code sein und / oder eine Bedingung für den body. (maybe als Regex). Wenn erfüllt wird ein event generiert (e.g. "error reading bla") und ein internal wird gesetzt. Auf das event kannst Du nach Lust und Laune reagieren.
ZitatAm besten eigentlich zwei Readings:
Einmal die rohen Json-Daten, einmal die response header aus dem Request.
Ich kann Dir ein attr "debug" oder so anbieten und den Kram dann ins Log oder einzeln auf die Platte schreiben.
fyi: ich hab es in die JsonMod Wunschliste (https://forum.fhem.de/index.php/topic,111489.0.html) aufgenommen.
Zitat von: herrmannj am 01 Dezember 2020, 23:59:47
ok - verstehe. Du möchtest darauf reagieren wenn was schiefgeht. Ich würde es schön finden wenn das von den readings getrennt stattfinden kann.
Ich zeig dir mal, was ich aktuell habe:
out.sensors.environment.6 fragt den Feinstaubsensor nach Meta-Daten ab (Verbindungsqualität).
Internals:
.eventMapCmd update:noArg
.triggerUsed 1
API_LAST_RES 1606896007.72709
API__LAST_MSG 200
CFGFN
DEF http://feinstaubsensor.fritz.box/data.json
FUUID 5fc6bbeb-f33f-3475-418c-7b068242fa3cfc85
NAME out.sensors.environment.6
NEXT 2020-12-02 10:00:00
NR 9951
SOURCE http://feinstaubsensor.fritz.box/data.json
(200)
STATE device_alive
rssi_bad
SVN 22987 2020-10-18 13:26:05 UTC
TYPE JsonMod
.attraggr:
.attrminint:
.userReadings:
HASH(0x560fbc435f38)
HASH(0x560fbcb88548)
HASH(0x560fb1b7c490)
HASH(0x560fbc7c8358)
CONFIG:
IN_REQUEST 0
SOURCE http://feinstaubsensor.fritz.box/data.json
SECRET:
Helper:
DBLOG:
activity:
general.system.log.db:
TIME 1606862566.21409
VALUE alive
activity_state:
general.system.log.db:
TIME 1606862566.21409
VALUE device_alive
last_readout_ts:
general.system.log.db:
TIME 1606860978.87839
VALUE 1606860978
rssi:
general.system.log.db:
TIME 1606860128.99689
VALUE -89
rssi_device:
general.system.log.db:
TIME 1606896007.72998
VALUE -86
rssi_quality:
general.system.log.db:
TIME 1606896007.72998
VALUE rssi_bad
state:
general.system.log.db:
TIME 1606862317.92322
VALUE update
ttl_alert:
general.system.log.db:
TIME 1606860978.87839
VALUE false
OLDREADINGS:
READINGS:
2020-12-02 09:00:07 .computedReadings rssi_device
2020-12-02 09:00:07 activity alive
2020-12-01 23:42:46 activity_state device_alive
2020-12-02 09:00:07 last_readout_ts 1606896007
2020-12-02 09:00:07 request_result 200
2020-12-02 09:00:07 rssi_device -86
2020-12-02 09:00:07 rssi_quality rssi_bad
2020-12-02 09:00:07 ttl_alert false
Attributes:
alias Feinstaubsensor SDS011
cmdIcon update:rc_REPEAT@black
devStateIcon rssi_good:it_wifi@42BC0A rssi_medium:it_wifi@sandybrown rssi_bad:it_wifi@E50005 rssi_check:unknown@gray
device_alive:device_alive@42BC0A device_dead:device_dead@E50005
eventMap reread:update
group Feinstaubsensor außen
httpTimeout 30
icon circuit@black
readingList single(jsonPath("\$.sensordatavalues.[?(\@.value_type in ['signal'])].value"), 'rssi_device', undef)
room Außen->Sensoren->Umwelt
sortby 100
stateFormat activity_state
rssi_quality
ttl_alert_time 30
userReadings rssi_quality:rssi_device:.+ {
FHEM::MyUtils::Readings::rssi_quality($name, q(rssi_device));
},
last_readout_ts:request_result:.+ {
return time_str2num ::ReadingsTimestamp($name, q(rssi_device), 0);
},
ttl_alert:last_readout_ts:.+ {
my $ttl = ::AttrVal($name, q(ttl_alert_time), 300);
my $last_readout = ::ReadingsVal($name, q(last_readout_ts), undef);
return q(error) if (!$last_readout);
return q(true) if (time - $ttl > $last_readout);
return q(false);
},
activity:ttl_alert:.+ {
return (::ReadingsVal($name, q(ttl_alert), q(true)) eq q(true))
? "dead"
: "alive";
}
userattr ttl_alert_time
webCmd update
out.sensors.environment.6.watchdog macht aus
API__LAST_MSG ein Reading, auf dessen Basis ich dann im Device entscheide, ob der Feinstaubsensor dead/alive ist.
Internals:
CFGFN
DEF ([out.sensors.environment.6:&API__LAST_MSG])
(
setreading $DEVICE request_result [out.sensors.environment.6:&API__LAST_MSG]
)
FUUID 5fc6c4b3-f33f-3475-52d1-f664d76cdf5ed20f
MODEL FHEM
NAME out.sensors.environment.6.watchdog
NOTIFYDEV out.sensors.environment.6,global
NR 10185
NTFY_ORDER 50-out.sensors.environment.6.watchdog
STATE cmd_1
TYPE DOIF
VERSION 23235 2020-11-25 22:42:28
.attraggr:
.attrminint:
Helper:
DBLOG:
cmd:
general.system.log.db:
TIME 1606896007.73503
VALUE 1
cmd_event:
general.system.log.db:
TIME 1606896007.73503
VALUE out.sensors.environment.6
cmd_nr:
general.system.log.db:
TIME 1606896007.73503
VALUE 1
mode:
general.system.log.db:
TIME 1606863798.7235
VALUE enabled
state:
general.system.log.db:
TIME 1606896007.73503
VALUE cmd_1
READINGS:
2020-12-02 09:00:07 Device out.sensors.environment.6
2020-12-02 09:00:07 cmd 1
2020-12-02 09:00:07 cmd_event out.sensors.environment.6
2020-12-02 09:00:07 cmd_nr 1
2020-12-02 09:00:07 e_out.sensors.environment.6_API__LAST_MSG 200
2020-12-02 00:03:18 mode enabled
2020-12-02 09:00:07 state cmd_1
Regex:
accu:
cond:
out.sensors.environment.6:
0:
&API__LAST_MSG ^out.sensors.environment.6$
attr:
cmdState:
wait:
waitdel:
condition:
0 ::InternalDoIf($hash,'out.sensors.environment.6','API__LAST_MSG')
do:
0:
0 setreading $DEVICE request_result [out.sensors.environment.6:&API__LAST_MSG]
1:
helper:
DEVFILTER ^global$|^out.sensors.environment.6$
NOTIFYDEV global|out.sensors.environment.6
event rssi_device: -86,rssi_quality: rssi_bad
globalinit 1
last_timer 0
sleeptimer -1
timerdev out.sensors.environment.6
timerevent rssi_device: -86,rssi_quality: rssi_bad
triggerDev out.sensors.environment.6
timerevents:
rssi_device: -86
rssi_quality: rssi_bad
request_result: 200
last_readout_ts: 1606896007
ttl_alert: false
activity: alive
timereventsState:
rssi_device: -86
rssi_quality: rssi_bad
request_result: 200
last_readout_ts: 1606896007
ttl_alert: false
activity: alive
triggerEvents:
rssi_device: -86
rssi_quality: rssi_bad
request_result: 200
last_readout_ts: 1606896007
ttl_alert: false
activity: alive
triggerEventsState:
rssi_device: -86
rssi_quality: rssi_bad
request_result: 200
last_readout_ts: 1606896007
ttl_alert: false
activity: alive
internals:
all out.sensors.environment.6:API__LAST_MSG
readings:
trigger:
uiState:
uiTable:
Attributes:
do always
Per se funktioniert das soweit, ideal wäre es, wenn mir JsonMod direkt einen request result status geben würde. Ein HTTP-Statuscode wäre z.B. auch ok.
(Im weiteren Verlauf entscheidet sich, ob die ausgelesen PM-Werte noch aktuell sind und für Logiken benutzt werden können.)
Zitat von: herrmannj am 01 Dezember 2020, 23:59:47
Würde das so für Dich passen?: per attr wird definiert was ein Fehler ist. Kann dann, neben "keine Antwort" auch ein von 200 OK abweichender Server Code sein und / oder eine Bedingung für den body. (maybe als Regex). Wenn erfüllt wird ein event generiert (e.g. "error reading bla") und ein internal wird gesetzt. Auf das event kannst Du nach Lust und Laune reagieren.
Ich kann Dir ein attr "debug" oder so anbieten und den Kram dann ins Log oder einzeln auf die Platte schreiben.
Tatsächlich wäre das für das Json-Result ok, aber ich überlege noch, wie ich hier einen Brückenschlag z.B. zu einem User-Reading bekomme (activity).