Hauptmenü

HTTPMOD alternative

Begonnen von Matthias_1968, 06 März 2017, 09:25:52

Vorheriges Thema - Nächstes Thema

Matthias_1968

Hallo,

ich lese aktuell Werte meiner Solarbatterie mit HTTPMOD aus.
define SonnenStatus HTTPMOD http://192.168.2.11:8080/api/v1/status 5

Die userReadings verarbeite ich dann weiter.

Das ganze funktioniert auch wunderbar.

Das Dumme ist, das sich die Werte jede Sekunde ändern und ich HTTPMOD nur auf 5 Sekunden reduzieren kann.

Ich rufe mit HTTPMOD die Seite auf
http://IPDerBatterie:8080/api/v1/status

und bekomme einen JSON formatierten Text zurück:
{"Consumption_W":2902,"Fac":50,"GridFeedIn_W":-2626,"IsSystemInstalled":1,"Pac_total_W":-5,"Production_W":282,"RSOC":4,"Timestamp":"2017-03-06 09:15:18","USOC":0,"Uac":229,"Ubat":48}


Lässt sich eine Abfrage jede Sekunde überhaupt realisieren oder verursache ich damit zuviel Datenlast?

Gruß
Matthias

CoolTux

Hallo Mathias,

Ohne Perlkenntnisse wirst da keine Möglichkeit haben. Mit Perlkenntnisse kannst Du Dir eine 99_myUtils schreiben mit eigener nicht blockierenden HttpUtils_NonblockingGet Funktion.



Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Matthias_1968

Danke für den Tip!

Ich werde mich mal rantrauen.

Gruß
Matthias

viegener

Als Workaround kannst Du auch über einen wiederholenden at den set-Befehl reread am HTTPMod-Device aufrufen (dadurch wird ja auch der Inhalt aufgefrischt). Da Du das lokal machst, kannst Du ja selber feststellen, ob das ein problem mit der Steuerung oder FHEM auslöst.

Für externe URLs und signifikante INhalte würde ich das nicht empfehlen, denn z.B. die Verarbeitung der Inhalte kostet Zeit etc...

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Matthias_1968

Hallo,

ZitatAls Workaround kannst Du auch über einen wiederholenden at den set-Befehl reread am HTTPMod-Device aufrufen

Das Funktioniert super!

Aber:
Ich habe einen DOIF Trigger gebaut, um jede Minute die gesammelten Werte zu teilen, aber daran beiße ich mir momentan die Zähne aus.
Mein Trigger:
define MY_Trigger DOIF ([+:01])\
   (set SB_MinuteVerbrauch Value([SonnenStatus:Sum_Verbrauch]/60))\
   (set SB_MinuteProduktion [SonnenStatus:Sum_Produktion])\
   (set SB_MinuteBezug [SonnenStatus:Sum_Bezug])\
   (set SB_MinuteEinspeisung [SonnenStatus:Sum_Einspeisung])\
   (set SB_MinuteLaden [SonnenStatus:Sum_Laden])\
   (set SB_MinuteEntladen [SonnenStatus:Sum_Entladen])\
   (set SB_MinuteBatLaden [SonnenStatus:BatterieLadung])\
   (set SB_MinuteBatEntladen [SonnenStatus:BatterieEntladung])\
   (setreading SonnenStatus Sum_Verbrauch 0)\
   (setreading SonnenStatus Sum_Produktion 0)\
   (setreading SonnenStatus Sum_Bezug 0)\
   (setreading SonnenStatus Sum_Einspeisung 0)\
   (setreading SonnenStatus Sum_Laden 0)\
   (setreading SonnenStatus Sum_Entladen 0)\


Mein Problem im Log steht:
2017.03.07 12:03:00 4: DbLog DBLOG -> ################################################################
2017.03.07 12:03:00 4: DbLog DBLOG -> ###              start of new Logcycle                       ###
2017.03.07 12:03:00 4: DbLog DBLOG -> ################################################################
2017.03.07 12:03:00 4: DbLog DBLOG -> amount of events received: 1 for device: SB_MinuteVerbrauch
2017.03.07 12:03:00 4: DbLog DBLOG -> check Device: SB_MinuteVerbrauch , Event: Value(28210/60)
2017.03.07 12:03:00 4: DbLog DBLOG -> added event - Timestamp: 2017-03-07 12:03:00, Device: SB_MinuteVerbrauch, Type: DUMMY, Event: Value(28210/60), Reading: state, Value: Value(28210/60), Unit:
2017.03.07 12:03:00 4: DbLog DBLOG -> processing event Timestamp: 2017-03-07 12:03:00, Device: SB_MinuteVerbrauch, Type: DUMMY, Event: Value(28210/60), Reading: state, Value: Value(28210/60), Unit:
2017.03.07 12:03:00 4: DbLog DBLOG -> 1 of 1 events successfully inserted into table history
2017.03.07 12:03:00 5: DbLog DBLOG -> DbLog_Push Returncode: 0
2017.03.07 12:03:00 5: End notify loop for SB_MinuteVerbrauch


In der Tabellesteht dann:


2017-03-07 12:26:00   SB_MinuteVerbrauch   DUMMY   Value(30030/60)   state   Value(30030/60)   
2017-03-07 12:26:00   SB_MinuteProduktion   DUMMY   25935   state   25935   
2017-03-07 12:26:00   SB_MinuteBezug   DUMMY   3904   state   3904   

Wie bekomme ich den Wert in die Tabelle? Egal was ich mache, es steht immer nur der Text in der Spalte Value.


Gruß
Matthias

viegener

Ich verstehe zwar nicht genau was Du da machst (sekundenweise Werte abholen aber nur minutenweise speichern  ???)

Aber die werte sind völlig richtig. Du setzt ja den Wert auf den String Value(30030/60)) zumindest wenn 30030 der Wert des entsprechenden Readings ist. Mit anderen Worten, was Du eigentlich willst ist eine Perl-Berechnung durchführen (Value und /) dazu muss der Ausdruck auch als perl-Ausdruck geklammert werden. Allerdings ist mir völlig unklar was Value( hier soll ? Ich verstehe aber auch die gesamte Klammerung nicht, das erscheint mir keine DOIF-Syntax und Value( zu sein. Du solltest Dich bei allen Themen mal einlesen.

Grundsätzlich sollte es so oder so ähnlich aussehen (ohne dass ich es versucht hätte):


define MY_Trigger DOIF ([+:01])\
  ({ fhem("set SB_MinuteVerbrauch". ([SonnenStatus:Sum_Verbrauch]/60) ) }) \


Alternativ noch einfacher wäre (set logik - siehe set-Befehl):


define MY_Trigger DOIF ([+:01])\
  ( set SB_MinuteVerbrauch {( [SonnenStatus:Sum_Verbrauch] / 60 )} ,  \
    set SB_MinuteProduktion [SonnenStatus:Sum_Produktion],

...

)


Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Matthias_1968

Super, Danke!

Das war was ich brauchte!

define MY_Trigger DOIF ([+:01])\
  ( set SB_MinuteVerbrauch {( [SonnenStatus:Sum_Verbrauch] / 60 )} ,  \
...
)


Ich habe immer mit () und {} getestet, aber nie {()}.

ZitatIch verstehe zwar nicht genau was Du da machst (sekundenweise Werte abholen aber nur minutenweise speichern  ???)

Ich möchte die gesammelten Werte pro Minute sammeln, um die mysql DB nicht voll zu müllen.

Ausserdem kann mir für die Sonnenbatterie die Werte als csv runterladen und dann mal mit den gesammelten Werten vergleichen.

Vielen Dank für eure Hilfe!

Matthias



thomas.wurm

Zitat von: Matthias_1968 am 06 März 2017, 09:25:52
Hallo,

ich lese aktuell Werte meiner Solarbatterie mit HTTPMOD aus.
define SonnenStatus HTTPMOD http://192.168.2.11:8080/api/v1/status 5

Die userReadings verarbeite ich dann weiter.

Das ganze funktioniert auch wunderbar.

Das Dumme ist, das sich die Werte jede Sekunde ändern und ich HTTPMOD nur auf 5 Sekunden reduzieren kann.

Ich rufe mit HTTPMOD die Seite auf
http://IPDerBatterie:8080/api/v1/status

und bekomme einen JSON formatierten Text zurück:
{"Consumption_W":2902,"Fac":50,"GridFeedIn_W":-2626,"IsSystemInstalled":1,"Pac_total_W":-5,"Production_W":282,"RSOC":4,"Timestamp":"2017-03-06 09:15:18","USOC":0,"Uac":229,"Ubat":48}


Lässt sich eine Abfrage jede Sekunde überhaupt realisieren oder verursache ich damit zuviel Datenlast?

Gruß
Matthias

Hallo Matthias,

kannst du mir bitte den Coden geben um den Json von der Sonnenbatterie auszulesen?
Ich würde das auch gerne machen.

Vielen Dank!

MFG


Benni

Meine Definition ist ähnlich der (unkommentierten) im Wiki:


defmod pvaBattery HTTPMOD http://x.x.x.x:8080/api/v1/status 15
attr pvaBattery alignTime 00:00
attr pvaBattery enforceGoodReadingNames 1
attr pvaBattery event-on-change-reading .*
attr pvaBattery event-on-update-reading Consumption_W,Production_W,GridFeedIn_W
attr pvaBattery extractAllJSON 1
attr pvaBattery handleRedirects 1
attr pvaBattery stateFormat USOC %
attr pvaBattery userReadings uCharging:BatteryCharging.* {(ReadingsVal($name,'BatteryCharging','x') eq 'true') ? 1:0 },\
uDischarging:BatteryDischarging.* {(ReadingsVal($name,'BatteryDischarging','x') eq 'true') ? 1:0},\
uGridFeedIn_Abs_W:GridFeedIn_W.* {abs(ReadingsNum($name,'GridFeedIn_W',0))},\
uPac_total_Abs_W:Pac_total_W.* {abs(ReadingsNum($name,'Pac_total_W',0))},\
uReturnCode:ReturnCode.* {my $rc=ReadingsNum($name,'ReturnCode',-1);; return $rc==0?'success':($rc==5?'invalid request path':($rc==13?'internal error':($rc==16?'invalid http method':'unknown')))}


Ich weiß nicht, in wie weit es sinn macht, die Daten in so kurzen Abständen (5 Sekunden und kleiner) abzurufen. Ich rufe bei mir derzeit in 15-Sekunden Intervallen ab, das aber nur, weil ich mir damit einen virtuellen Zähler berechne. Je kleiner dabei das Intervall, desto weniger stark läuft der Virtuelle Zähler und der reale Zähler auseinander. Aber mit 15 Sekunden ist das ausreichend genau für mich.