Diese Daten können auch direkt von der Homematic ausgelesen werden. Das Script dazu läuft bei mir inzwischen gut 2 Jahre fehlerfrei.
Da es in der Vergangenheit den einen oder anderen User gab, der ebenfalls einen entspr. Speicher einsetzt, stelle ich mein Script hier nun gerne zur Verfügung.
Wichtig: Ich kann nicht garantieren, dass das Script auch auf Systeme zugreifen kann, welche die Senec.cloud Lösung einsetzen. In diesen Fällen scheint die betreffende Schnittstelle im Speicher deaktiviert zu werden. Kurzum: Solange man auf das integrierte Webinterface zugreifen kann, sollte das Script auch funktionieren.
Ältere Speicher (Pb statt Li) nutzen meines Wissens eine andere Schnittstelle. Die aktuellen (V3) Speicher sind mir noch unbekannt - falls sie aber ebenfalls auf "lala.cgi" setzen, besteht eine gute Chance, dass das Script mit diesen ebenfalls funktioniert (evtl. müssen Datenpunkte angepasst werden).
Das Script genötigt einen funktionsfähigen CUXD und nutzt speichert die abgerufenen Daten in Systemvariablen.
Die Bezeichner dieser Systemvariablen sind vorgegeben - können allerdings mit einem individuellen Präfix versehen werden.
Angelegt werden die Systemvariablen automatisch, so sie nicht vorhanden sind.
Es werden folgende Datenpunkte von Senec abgegriffen:
Code: Alles auswählen
STAT_DAY_E_HOUSE (value in kWh)
STAT_DAY_E_PV (value in kWh)
STAT_DAY_BAT_CHARGE (value in kWh)
STAT_DAY_BAT_DISCHARGE (value in kWh)
STAT_DAY_E_GRID_IMPORT (value in kWh)
STAT_DAY_E_GRID_EXPORT (value in kWh)
GUI_BAT_DATA_FUEL_CHARGE (value is in percentage)
GUI_BAT_DATA_POWER (value in Watts, stored in kW) --> negative = draining
GUI_INVERTER_POWER (value in Watts, stored in kW)
GUI_HOUSE_POW (value in Watts, stored in kW)
GUI_GRID_POW (value in Watts, stored in kW) --> negative = export into net
- Netzwerkadresse des Senec Speichers
- ggfls. Präfix der Systemvariablen
- ggfls. CUXD
Code: Alles auswählen
string hostName="192.168.178.x";
string svPrefix="PV.Senec.";
string cuxdDeviceId="CUxD.CUX2801001:1";
Hier das Script:
Code: Alles auswählen
! Senec.Home V2.1 auslesen
! v1.0 (c) by trevyn
! Requires CUXD
string hostName="192.168.178.xxx";
string svPrefix="PV.Senec."; ! prefix for sysvars. the stat's name is added automatically
string cuxdDeviceId="CUxD.CUX2801001:1";
! Per default dealing with these data points
!STAT_DAY_E_HOUSE (value in kWh)
!STAT_DAY_E_PV (value in kWh)
!STAT_DAY_BAT_CHARGE (value in kWh)
!STAT_DAY_BAT_DISCHARGE (value in kWh)
!STAT_DAY_E_GRID_IMPORT (value in kWh)
!STAT_DAY_E_GRID_EXPORT (value in kWh)
!GUI_BAT_DATA_FUEL_CHARGE (value is in percentage)
!GUI_BAT_DATA_POWER (value in Watts, stored in kW) --> negative = draining
!GUI_INVERTER_POWER (value in Watts, stored in kW)
!GUI_HOUSE_POW (value in Watts, stored in kW)
!GUI_GRID_POW (value in Watts, stored in kW) --> negative = export into net
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! no changes beyond here !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! if you want Watts instead of kWh for GUI stats: change 1000 to 1 and also change the unit
!string statistics = "Value1:DivideByFactorValue1:DescriptionVal1\tValue2:DivideByFactorValue2...";
string statistics = "STAT_DAY_E_HOUSE:1:kWh:House Energy Day\t";
statistics = statistics # "STAT_DAY_E_PV:1:kWh:PV Production Day\t";
statistics = statistics # "STAT_DAY_BAT_CHARGE:1:kWh:Battery charge day\t";
statistics = statistics # "STAT_DAY_BAT_DISCHARGE:1:kWh:Battery discharge day\t";
statistics = statistics # "STAT_DAY_E_GRID_IMPORT:1:kWh:Grid Import day\t";
statistics = statistics # "STAT_DAY_E_GRID_EXPORT:1:kWh:Grid Export Day\t";
statistics = statistics # "GUI_BAT_DATA_FUEL_CHARGE:1:%:Battery Level\t";
statistics = statistics # "GUI_BAT_DATA_POWER:1000:kW:Battery load current\t";
statistics = statistics # "GUI_INVERTER_POWER:1000:kW:Power generation current\t";
statistics = statistics # "GUI_HOUSE_POW:1000:kW:Power usage house current\t";
statistics = statistics # "GUI_GRID_POW:1000:kW:Power grid current";
!grabs ALL possible values
string curl = "extra/curl --data-binary '{\"STATISTIC\":{\"STAT_DAY_E_HOUSE\":\"\",\"STAT_DAY_E_PV\":\"\",\"STAT_DAY_BAT_CHARGE\":\"\",\"STAT_DAY_BAT_DISCHARGE\":\"\",\"STAT_DAY_E_GRID_IMPORT\":\"\",\"STAT_DAY_E_GRID_EXPORT\":\"\",\"STAT_YEAR_E_PU1_ARR\":\"\"},\"ENERGY\":{\"STAT_STATE\":\"\",\"STAT_STATE_DECODE\":\"\",\"GUI_BAT_DATA_POWER\":\"\",\"GUI_INVERTER_POWER\":\"\",\"GUI_HOUSE_POW\":\"\",\"GUI_GRID_POW\":\"\",\"STAT_MAINT_REQUIRED\":\"\",\"GUI_BAT_DATA_FUEL_CHARGE\":\"\",\"GUI_CHARGING_INFO\":\"\",\"GUI_BOOSTING_INFO\":\"\"},\"WIZARD\":{\"CONFIG_LOADED\":\"\"},\"SYS_UPDATE\":{\"UPDATE_AVAILABLE\":\"\"}}' http://" # hostName # "/lala.cgi";
string hex2bin = "0:0000\t1:0001\t2:0010\t3:0011\t4:0100\t5:0101\t6:0110\t7:0111\t8:1000\t9:1001\tA:1010\tB:1011\tC:1100\tD:1101\tE:1110\tF:1111";
dom.GetObject(cuxdDeviceId#".CMD_SETS").State(curl);
dom.GetObject(cuxdDeviceId#".CMD_QUERY_RET").State(1);
string response = dom.GetObject(cuxdDeviceId#".CMD_RETS").State();
string dataGroup;
object svObject; object svObjectList;
foreach(dataGroup, response.Split("{")) {
string dataSet;
foreach(dataSet, dataGroup.Split(",")) {
dataSet = dataSet.Replace("\"","");
dataSet = dataSet.Trim("}");
string statisticsIdx;
! iterate over those statistics we want
foreach(statisticsIdx, statistics) {
if(dataSet.StrValueByIndex(":", 0) == statisticsIdx.StrValueByIndex(":", 0)) {
string valueHex = dataSet.StrValueByIndex(":", 1);
valueHex = valueHex.StrValueByIndex("_", 1);
! hex to bin IEEE754
integer hexIndex = 0;
string valueBin = "";
while (hexIndex < valueHex.Length()) {
string hex2binIdx;
foreach(hex2binIdx, hex2bin) {
if (hex2binIdx.Substr(0,1) == valueHex.Substr(hexIndex,1)) {
valueBin = valueBin#hex2binIdx.StrValueByIndex(":", 1);
}
}
hexIndex = hexIndex + 1;
}
! bin -> float IEEE754
integer sign = valueBin.Substr(0,1);
string exp = valueBin.Substr(1,8);
string mantissa = "1"#valueBin.Substr(9,24);
integer exponent = -127;
integer n = exp.Length()-1;
while (n>=0) {
exponent = exponent + (exp.Substr(n,1)=='1').ToInteger()*(exp.Length()-(n+1)).Exp2();
n=n-1;
}
real significand = 0.0;
integer i = 0;
while (i < 24) {
real mant = 0.0 + mantissa.Substr(i,1);
significand = significand + ((1.0 / (0.0 + i).Exp2()) * mant);
i = i + 1;
}
i = 2;
significand = significand * i.Pow(exponent);
if (sign == 1) {
significand = significand * (-1.0);
}
real value = (significand / statisticsIdx.StrValueByIndex(":", 1).ToInteger()).Round(2);
! WriteLine("Found: "#statisticsIdx#" | Value: "#valueHex#" | "#valueBin#" | Exp: "#exponent#" | Sig: "#significand#" | Sign: " # sign # " | Value: "#value);
string senecStat = statisticsIdx.StrValueByIndex(":", 0);
string svSenec = svPrefix # senecStat;
svObject = dom.GetObject(svSenec);
if(!svObject) { ! create sysvar if not exists
svObjectList = dom.GetObject(ID_SYSTEM_VARIABLES);
svObject = dom.CreateObject(OT_VARDP);
svObjectList.Add(svObject.ID());
svObject.Name(svSenec);
svObject.DPInfo(statisticsIdx.StrValueByIndex(":", 3));
svObject.Internal(false);
svObject.Visible(true);
svObject.ValueType(ivtFloat);
svObject.ValueSubType(istGeneric);
svObject.ValueUnit(statisticsIdx.StrValueByIndex(":", 2));
svObject.ValueMin(-99999);
svObject.ValueMax(99999);
dom.RTUpdate(true);
}
var senec = dom.GetObject(svSenec);
senec.State(value);
}
}
}
}