[JsonMod] Wunsch: Status-Ausgabe (error, success), raw

Begonnen von Christoph Morrison, 01 Dezember 2020, 23:29:51

Vorheriges Thema - Nächstes Thema

Christoph Morrison

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?

herrmannj

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

Christoph Morrison

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.

herrmannj

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.

yersinia

viele Grüße, yersinia
----
FHEM 6.4 (SVN) on RPi 4B with RasPi OS Bookworm (perl 5.36.0) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

Christoph Morrison

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).