lokale Anbindung SENEC Batterie an FHEM

Begonnen von cjung, 12 Januar 2020, 13:33:37

Vorheriges Thema - Nächstes Thema

cjung

Ich habe mich jetzt durch die Doku von HTTPMod gearbeitet und meinen Batteriespeicher lokal ausgelesen.
Der wichtigste Wert ist für mich PV1_POWER_RATIO, der in der normalen SENEC Oberfläche 'PV-Begrenzung' genannt ist. Da meine Einspeisung auf max 70 % limitiert ist, möchte ich beim Erreichen des Limits weitere Verbraucher einschalten um neben der Batterie auch noch z.B. die Wasch- oder Spülmaschine einzuschalten.

Mit der folgenden Konfiguration bekomme ich jetzt den Wert der PV-Begrenzung und die aktuelle Produktion ins FHEM:

define SENEC HTTPMOD http://192.168.178.123/lala.cgi 30
attr SENEC enableControlSet 1
attr SENEC reading01JSON PV1_POWER_RATIO
attr SENEC reading01Name PV-Begrenzung
attr SENEC reading01OExpr {hex( (split ('_',$val,0 ))[1] )}
attr SENEC reading02JSON ENERGY_GUI_INVERTER_POWER
attr SENEC reading02Name PV-Erzeugung
attr SENEC reading02OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading03JSON ENERGY_GUI_BAT_DATA_FUEL_CHARGE
attr SENEC reading03Name AKKU-Beladung
attr SENEC reading03OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading04JSON ENERGY_GUI_BAT_DATA_POWER
attr SENEC reading04Name AKKU-Entnahme
attr SENEC reading04OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading05JSON ENERGY_GUI_HOUSE_POW
attr SENEC reading05Name Haus-Stromverbrauch
attr SENEC reading05OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading06JSON PM1OBJ1_P_TOTAL
attr SENEC reading06Name Netz-Einspeisung
attr SENEC reading06OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC requestData {"PV1":{"POWER_RATIO":""},"ENERGY":{"GUI_HOUSE_POW":"","GUI_INVERTER_POWER":"","GUI_BAT_DATA_POWER":"","GUI_BAT_DATA_FUEL_CHARGE":"","STAT_STATE":""},"PM1OBJ1":{"P_TOTAL":""}}


Anmerkung: Wenn keine PV-Begrenzung aktiv ist, ist der Wert 100, wenn sie aktiv ist, geht der Wert in Schritten auf max 70 runter.
In meinem Fall gibt es einen ABB Zweirichtungszähler vor dem - leider nicht auslesbaren - Zähler des Versorgers (ECHELON Zähler), der per ModBus an der Batterie angeschlossen ist, um die tatsächliche Einspeisung zur ermitteln. Zusätzlich ist ein Fronius Wechselrichter per IP angeschlossen, den ich auch per HTTPMOD auslesen kann.

Besonderen Dank an die Diskussion zur HEX Umrechnung im Thread Thread sonst hätte ich nie verstanden, dass die beiden Werte unterschiedlich umzurechnen sind. Weitere Anregungen habe ich mir aus OpenHAB geholt

Es gibt noch eine größere Menge anderer Werte, aber leider scheint es keinen kumulierten Zähler zur Tageseinspeisung oder Produktion zu geben.
Senec bietet auf Mein-Senec ein Portal mit den kumulierten Daten an. Evtl. versuche ich die Daten dort auszulesen.

Wie haben andere das gelöst ?


Änderung27.01.: Ich habe weitere Felder aufgenommen und die Werte auf zwei Stellen hinter dem Komma erweitert.
Raspberry Pi 2 B
Funk: HM_CFG_USB2, HM-CFG-LAN 8*HM_CC_RT_DN, 3*HM-SEC-SD, 3*HM_TC_IT_WM_W_EU, 1*HM-LC-Dim1TPBU-FM,5*HM-SEC-SC-2, 1*HM-SEC-SCo
Wired: HMW: CFG-LAN, 8*LC_Bl1_DR, LC_Dim1L_DR

Nielsiwilsi

Super, Danke für deine Mühen. Den Speicher auslesen steht bei mir auf der ToDo Liste, allerdings hatte ich noch nicht die Zeit, das anzugehen.
Ich werde deinen Code heute Abend mal bei mir testen.
Habe ein ganz ähnliches Setup wie du, aber einen Wechselrichter von SolarEdge, den ich soweit ich weiß nicht auslesen kann. Es gibt aber ein Modul, dass die Web-API abfragt.

VG
Niels

ritter_runkel

#2
Guten Morgen,
ich habe auch einen Senec-Speicher und bin leicht gefrustet, das Senec trotz mehrfacher Nachfragen nicht willens scheint einen Zugang zu DEREN Daten aus MEINEM System bereit zu stellen.

Ich habe mit Freude Deinen Ansatz gelesen und versucht ihn für meine Zwecke anzupassen.
ACHTUNG - keine Ahnung von Programmierung - eher mutiges Reengineering ;-)

Ich habe versucht Deine Variablen ("ENERGY_GUI_INVERTER_POWER", "PV1_POWER_RATIO") einfach durch die für mich interessanten Werte
Batterieleistung(W) --> ENERGYGUI_BAT_DATA_POWER. (auf der gleichen Webpage)
Akkuentnahme --> GuiDataOverViewPowerBatteryDischarge (auf der Statusseite)
Akkubeladung --> GuiDataOverViewPowerBatteryCharge (auf der Statusseite)
zu ersetzen.

Ich bekomme es mit dieser Methode allerdings nicht mal hin, dass die Readings im Device entsprechend angelegt werden.

Habt Ihr einen Ansatz wie ich an diese Daten komme?
Grüße aus Leipzig!
Erik
Das Device sieht dann so aus:

defmod SENEC HTTPMOD http://192.168.100.68/lala.cgi 30
attr SENEC userattr reading01JSON reading01Name reading01OExpr reading02JSON reading02Name reading02OExpr reading03JSON reading03Name reading03OExpr requestData
attr SENEC enableControlSet 1
attr SENEC reading01JSON GuiDataOverViewPowerBatteryDischarge
attr SENEC reading01Name Akkuentnahme
attr SENEC reading01OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading02JSON ENERGYGUI_BAT_DATA_POWER
attr SENEC reading02Name Batterieleistung
attr SENEC reading02OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading03JSON GuiDataOverViewPowerBatteryCharge
attr SENEC reading03Name Akkubeladung
attr SENEC reading03OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC requestData {"Akkuentnahme":{"GuiDataOverViewPowerBatteryDischarge":""},"Batterieleistung":{"ENERGYGUI_BAT_DATA_POWER":""},"Akkubeladung":{"GuiDataOverViewPowerBatteryCharge":""}}


bzw:
Internals:
   BUSY       0
   CFGFN     
   CHANGED   
   DEF        http://192.168.100.68/lala.cgi 30
   FUUID      5e276be5-f33f-47a1-1ca1-06dfbfa4a53d9ebe
   Interval   30
   JSONEnabled 1
   LASTSEND   1579676919.78724
   MainURL    http://192.168.100.68/lala.cgi
   ModuleVersion 3.5.21 - 27.12.2019
   NAME       SENEC
   NOTIFYDEV  global
   NR         18660
   NTFY_ORDER 50-SENEC
   STATE      ???
   TRIGGERTIME 1579676949.78585
   TRIGGERTIME_FMT 2020-01-22 08:09:09
   TYPE       HTTPMOD
   addr       http://192.168.100.68:80
   auth       0
   code       200
   compress   1
   conn       
   data       {"Akkuentnahme":{"GuiDataOverViewPowerBatteryDischarge":""},"Batterieleistung":{"ENERGYGUI_BAT_DATA_POWER":""},"Akkubeladung":{"GuiDataOverViewPowerBatteryCharge":""}}
   displayurl http://192.168.100.68/lala.cgi
   header     
   host       192.168.100.68
   httpheader HTTP/1.0 200 OK
Content-Type: application/json; charset=utf-8
   httpversion 1.0
   hu_blocking 0
   hu_filecount 59
   hu_port    80
   hu_portSfx
   ignoreredirects 0
   loglevel   4
   path       /lala.cgi
   protocol   http
   redirects  0
   timeout    2
   url        http://192.168.100.68/lala.cgi
   value      0
   QUEUE:
   READINGS:
     2020-01-22 08:08:36   PV-Begrenzung   100
   REQUEST:
     data       {"Akkuentnahme":{"GuiDataOverViewPowerBatteryDischarge":""},"Batterieleistung":{"ENERGYGUI_BAT_DATA_POWER":""},"Akkubeladung":{"GuiDataOverViewPowerBatteryCharge":""}}
     header     
     ignoreredirects 0
     retryCount 0
     type       update
     url        http://192.168.100.68/lala.cgi
     value      0
   defptr:
     readingBase:
       PV-Begrenzung reading
     readingNum:
       PV-Begrenzung 01
     readingOutdated:
     requestReadings:
       update:
         PV-Begrenzung reading 01
   sslargs:
Attributes:
   enableControlSet 1
   reading01JSON GuiDataOverViewPowerBatteryDischarge
   reading01Name Akkuentnahme
   reading01OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
   reading02JSON ENERGYGUI_BAT_DATA_POWER
   reading02Name Batterieleistung
   reading02OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
   reading03JSON GuiDataOverViewPowerBatteryCharge
   reading03Name Akkubeladung
   reading03OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
   requestData {"Akkuentnahme":{"GuiDataOverViewPowerBatteryDischarge":""},"Batterieleistung":{"ENERGYGUI_BAT_DATA_POWER":""},"Akkubeladung":{"GuiDataOverViewPowerBatteryCharge":""}}
   userattr   reading01JSON reading01Name reading01OExpr reading02JSON reading02Name reading02OExpr reading03JSON reading03Name reading03OExpr requestData



FHEM auf Raspberry Pi 2B
2x eService 1WireHu, 7x DS1820, 2x Multisensoren Wiregate AMS 2.11 für Temperatur DS1820, relativer Luftfeuchte HIH4031, zwei IO-Ports DS2438, Analog-Eingang 0-10 V (bzw. 0-20 mA) DS2413
FritzDECT; HUE; 5xFibaro RollerShutter, Rauchmelder

cjung

Hallo ritter_runkel

Im Code der Seite ist Batterieleistung(W)  und Akkuentnahme der gleiche abgefragte Wert. Die Batterieleistung wird dabei als float umgerechnet und in W angezeigt, die Akkuentnahme wird auf positive Ganzzahl abgeschnitten und in kW angezeigt. Bei mir ist gerade Nacht und der Akku ist fast leer: BatterieLeistung ist -1.44 und Akkuentnahme ist 0

Ob ich die Floatzahl aber richtig umrechne, kann ich noch nicht sagen. Aber es kommen valide Werte raus.

Als erstes musst Du die richtigen Werte abfragen:
attr SENEC requestData {"PV1":{"POWER_RATIO":""},"ENERGY":{"GUI_INVERTER_POWER":"","GUI_BAT_DATA_POWER":"","GUI_BAT_DATA_FUEL_CHARGE":""}}

Dann die Werte extrahieren und umrechnen:

attr SENEC reading03JSON ENERGY_GUI_BAT_DATA_FUEL_CHARGE
attr SENEC reading03Name AKKU-Beladung
attr SENEC reading03OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading04JSON ENERGY_GUI_BAT_DATA_POWER
attr SENEC reading04Name AKKU-Entnahme
attr SENEC reading04OExpr {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}

Raspberry Pi 2 B
Funk: HM_CFG_USB2, HM-CFG-LAN 8*HM_CC_RT_DN, 3*HM-SEC-SD, 3*HM_TC_IT_WM_W_EU, 1*HM-LC-Dim1TPBU-FM,5*HM-SEC-SC-2, 1*HM-SEC-SCo
Wired: HMW: CFG-LAN, 8*LC_Bl1_DR, LC_Dim1L_DR

ritter_runkel

Erstmal lieben Dank für die Unterstützung!
es ist wieder dunkel - und da ist 0 in jeder Codierung 0 ;)

Ich schaue mir das morgen live mal an.

Den Code verstanden - im Sinne "ich kann ihn erweitern/verändern" - habe ich noch nicht. Dazu müsste ich die Website besser verstehen.
Aber das schaffe ich für meine Zwecke noch.

Grüße aus Leipzig
//Erik
FHEM auf Raspberry Pi 2B
2x eService 1WireHu, 7x DS1820, 2x Multisensoren Wiregate AMS 2.11 für Temperatur DS1820, relativer Luftfeuchte HIH4031, zwei IO-Ports DS2438, Analog-Eingang 0-10 V (bzw. 0-20 mA) DS2413
FritzDECT; HUE; 5xFibaro RollerShutter, Rauchmelder

cjung

Ich habe den Code im ersten Beitrag erweitert.
Raspberry Pi 2 B
Funk: HM_CFG_USB2, HM-CFG-LAN 8*HM_CC_RT_DN, 3*HM-SEC-SD, 3*HM_TC_IT_WM_W_EU, 1*HM-LC-Dim1TPBU-FM,5*HM-SEC-SC-2, 1*HM-SEC-SCo
Wired: HMW: CFG-LAN, 8*LC_Bl1_DR, LC_Dim1L_DR

Manylion

Danke! Das klappt auch bei mir einwandfrei, auf Anhieb.
Sehr schön.
RasPi, CUL868, HM Rolläden und Lichtschalter, Z-Wave, FB7490, FRITZ!DECT Steckdosen und Heizung, AVR Pioneer1183 mit Onkyo-Modul, Tradfri, Sonoff, 360°IR WLAN GW, HM-WLAN-GW

cjung

Ich habe noch etwas weiter getestet und hier noch die Statistikwerte gefunden:
Bitte beim Verwenden noch die IP Adresse anpassen.

defmod SENEC HTTPMOD http://192.168.XXX.XXX/lala.cgi 3600
attr SENEC enableControlSet 1
attr SENEC event-on-change-reading .*
attr SENEC reading01JSON PV1_POWER_RATIO
attr SENEC reading01Name PV-Begrenzung
attr SENEC reading01OExpr {hex( (split ('_',$val,0 ))[1] )}
attr SENEC reading02JSON STATISTIC_STAT_GRID_EXPORT
attr SENEC reading02Name Stat_Netzeinspeisung
attr SENEC reading02OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading03JSON STATISTIC_STAT_GRID_IMPORT
attr SENEC reading03Name Stat_Netzbezug
attr SENEC reading03OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading04JSON STATISTIC_STAT_HOUSE_CONSUMPTION
attr SENEC reading04Name Stat_Hausverbrauch
attr SENEC reading04OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC reading05JSON STATISTIC_STAT_PV_GENERATION
attr SENEC reading05Name Stat_PV_Erzeugung
attr SENEC reading05OExpr {sprintf("%.2f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)}
attr SENEC requestData {"PV1":{"POWER_RATIO":""},"STATISTIC": {"STAT_GRID_EXPORT":"","STAT_GRID_IMPORT":"","STAT_HOUSE_CONSUMPTION":"","STAT_PV_GENERATION":""}}
Raspberry Pi 2 B
Funk: HM_CFG_USB2, HM-CFG-LAN 8*HM_CC_RT_DN, 3*HM-SEC-SD, 3*HM_TC_IT_WM_W_EU, 1*HM-LC-Dim1TPBU-FM,5*HM-SEC-SC-2, 1*HM-SEC-SCo
Wired: HMW: CFG-LAN, 8*LC_Bl1_DR, LC_Dim1L_DR

Vize

Mahlzeit,

was genau bringen einem diese "Statistikwerte" bzw. was sollen die darstellen?
Ich habe mir die Werte mal angeschaut und finde keinen Bezug zu irgendwas.

VG
Andreas

cjung

#9
Hallo Andreas,

erstmal vielen Dank für Deine ganze Vorarbeit. Du hast die Übung offensichtlich ca. 1 Jahr vor mir gemacht und ich konnte in vielen Foren von Deinen Posts lernen. Danke dafür !!

Ich nutze die Statistikwerte um von meinen Zähler (EVU) Werte ins FHEM zu bekommen und damit ein Reporting für diese Werte im Jahresverlauf zu ermöglichen. Da ich schon den Erdgaszähler in FHEM habe, passt mir das gut.
Für die Steuerung in der www.openwb.de habe ich dort ein eigenes Pythonmodul geschrieben, das direkt EVU und Speicher ausließt. Daher brauche ich die dafür relevanten Werte nicht in FHEM.
Leider scheint SENEC allergisch auf Integrationen zu reagieren, daher wird es wohl nie in den openwb Standard kommen.

In meinem Setup zuhause ist der EinFluRi Zähler über Modbus am SENEC Speicher angeschlossen. Da ich in den Modbus mangels Wissen nicht hineinkomme, lese ich die Werte nun aus der Senec aus. Das ist für mich einfacher.

Als Antwort auf Deine Frage: Die Statistikwerte ermöglichen mir eine Summenbetrachtung am Zähler vor dem Netzbetreiber, der blöderweise ein Echelon ist und sich auch nicht direkt auslesen lässt.

Raspberry Pi 2 B
Funk: HM_CFG_USB2, HM-CFG-LAN 8*HM_CC_RT_DN, 3*HM-SEC-SD, 3*HM_TC_IT_WM_W_EU, 1*HM-LC-Dim1TPBU-FM,5*HM-SEC-SC-2, 1*HM-SEC-SCo
Wired: HMW: CFG-LAN, 8*LC_Bl1_DR, LC_Dim1L_DR

Vize

#10
Hallo Christoph,

erstmal vielen Dank für das Lob!

So ganz versteh ich aber immer noch nicht, was die Statistikwerte aussagen. Ich habe heute mal den Wert STATISTIC_STAT_PV_GENERATION hergenommen.
Soll das dann die gesamte PV-Produktion seit Installation sein? Passt bei mir aber nicht zum Wert des Wechselrichters...  ???

Und um deine Frage aus deiner e-mail zu beantworten...ja, schick mir mal das Python Modul. Vielleicht kann ich es ja für meine openWB gebrauchen...

Dank und Gruß
Andreas

cjung

Hallo Andreas,

Bei mir kommt der Wert, den ich aus meinem Wechselrichter bekomme und den mir die Senec meldet, sehr gut hin. Ich habe beides am gleichen Tag vor 2 Jahren montiert bekommen.

Gruß
christoph

Raspberry Pi 2 B
Funk: HM_CFG_USB2, HM-CFG-LAN 8*HM_CC_RT_DN, 3*HM-SEC-SD, 3*HM_TC_IT_WM_W_EU, 1*HM-LC-Dim1TPBU-FM,5*HM-SEC-SC-2, 1*HM-SEC-SCo
Wired: HMW: CFG-LAN, 8*LC_Bl1_DR, LC_Dim1L_DR

Vize

Moin,

ok, bei mir wurde mal ein Speichertausch wegen Defekt des ersten durchgeführt.
Dann kommen daher wohl die abweichende Werte bei meiner Konfiguration.
Woher soll der neue Speicher auch "wissen", was alles durch den alten lief...  ;)

Ich müsste dann wahrscheinlich den EnFluri anzapfen, um passende Werte zu erhalten...falls dort was hinterlegt ist...

VG
Andreas

the_m-pire

Vielen Dank für diesen erhellenden Thread. Dank der guten Ausführungen habe ich meinen SENEC.Home V3 hybrid duo sofort in fhem einbinden können.

Ich habe im Netz noch ein wenig herumgeschnüffelt, weil ich mir dachte, daß es doch sicherlich noch mehr Datenfelder geben würde und bei den Kollegen von IOBroker wurde ich fündig:
https://github.com/nobl/ioBroker.senec/blob/master/docs/de/README.md

Diese IOBroker Modul ist für Senec 2.1 geschrieben. Eingangs wird die Vermutung geäußert, daß die Felder wohl auch bei anderen Modellen mit .../lala.cgi vorhanden sein sollten. Das kann ich für zwei getestete Felder (z. B. Betriebsstunden) aber nicht bestätigen. Funktionieren tut aber z. B. der Datensatz ENERGY_GUI_BAT_DATA_CURRENT.

Inwiefern die Verrechnung / Transformation {sprintf("%.0f", unpack "f", pack "L", hex ((split('_',$val,0))[1]),0)} korrekt ist, habe ich aktuell noch nicht getestet. Andere Werte sollen ja auch Boolean sein...

Wenn ich mal wieder ein wenig Zeit dafür habe, tüftele ich weiter und werde berichten...

cjung

#14
Die möglichen Felder bekommst Du, wenn Du nur die jeweiligen Rootknoten abfragst. Ich habe dazu gerne Postman genutzt.

Bisher kenne ich die folgenden Rootknoten:
{"STATISTIC":{}}
{"PM1OBJ1":{}}
{"BAT1OBJ1":{}}
{"ENERGY":{}}
{"PV1":{}}


Kennt jemand weitere ?

Für die Berechnung kannst Du Dir die Senec.js Datei im Browser ansehen. Für mich waren die fl_ Werte die interessantesten.
Raspberry Pi 2 B
Funk: HM_CFG_USB2, HM-CFG-LAN 8*HM_CC_RT_DN, 3*HM-SEC-SD, 3*HM_TC_IT_WM_W_EU, 1*HM-LC-Dim1TPBU-FM,5*HM-SEC-SC-2, 1*HM-SEC-SCo
Wired: HMW: CFG-LAN, 8*LC_Bl1_DR, LC_Dim1L_DR