Diese Seite wurde vor mehr als 2 Jahren erstellt und vor über einem Monat zuletzt bearbeitet. Eventuell ist längst ihr Mindesthaltbarkeitsdatum überschritten!
Zur Steuerung verschiedener Abläufe muss die CCU die aktuellen Daten der PV-Anlage (Status, Produktion, Verbrauch und somit auch Einspeisung bzw. Bezug) kennen.
Diese werden jede Minute von einem PHP-Cronjob auf dem Controller Server aus dem Fronius-Wechselrichter ausgelesen, (dort ebenfalls verarbeitet) und über die XML-API in Systemvariablen der HomeMatic-Zentrale geschrieben.
Auf der CCU folgende Systemvariablen anlegen:
Haus_Verbrauch
, Typ: Integer, Einheit Watt, ise_id
bei mir: 9021PVA_Produktion
, Typ: Integer, Einheit Watt, ise_id
bei mir: 7482PVA_Status
, Typ: String, ohne Einheit, ise_id
bei mir: 9022Strom_Einspeisung
, Typ: Integer, Einheit Watt, ise_id
bei mir: 12511Strom_Bezug
, Typ: Integer, Einheit Watt, ise_id
bei mir: 12512Die ise_id
der Variablen wird benötigt, um sie später ansprechen zu können.
Das Skript benötigt neben dem Wechselrichter auch einen Verbrauchs-Zähler wie z.B. einen Fronius Smart Meter 63A-3 für die Abfrage von GetMeterRealtimeData
.
Über die JSON-basierte Fronius Solar-API werden die Kenndaten ausgelesen, sortiert und in die CCU geschoben.
Die Datenlogger-URL für die Produktions-Daten des Wechselrichters lautet
$data_url_production = "http://".HOST_INV."/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceId=".DEV_ID_INVERTER."&DataCollection=CommonInverterData";
Die URL für die Daten des SmartMeters
$data_url_consumption = "http://".HOST_INV."/solar_api/v1/GetMeterRealtimeData.cgiScope=Device&DeviceId=".DEV_ID_METER."&DataCollection=MeterRealtimeData";
Als Beispiel wird über die XML-API der Variable mit der ise_id
VAR_STATUS
der neue Wert $inverter_statusmsg
zugewiesen:
$update_url_status = "https://".HOST_CCU."/addons/xmlapi/statechange.cgi?ise_id=".VAR_STATUS."&new_value=".$inverter_statusmsg;
Hier das PHP-Skript, das als Cronjob die Aufgabe erledigt. Die Konfiguration in den markierten Zeilen muss angepasst werden.
Dies ist ein Rohgerüst ohne Fehlerbehandlung. "Works for me", macht was draus.
<?php
// cron_pva2ccu.php
// Stefan Onderka, www.onderka.com
// symo.local.lan 192.168.129.X
// homematic.local.lan 192.168.129.Y
// Konfiguration
define("DEBUG_JSON", false);
define("DEBUG_XMLAPI", false);
define("VERSION_STRING", "1.1-controller");
// HTTP Host Wechselrichter
define("HOST_INV", "symo.local.lan");
// HTTP Host CCU
define("HOST_CCU", "homematic.local.lan");
// Fronius JSON-API Geräte-ID Wechselrichter
define("DEV_ID_INVERTER", 1);
// Fronius JSON-API Geräte-ID SmartMeter
define("DEV_ID_METER", 0);
// ISE_ID und Name Systemvariable für Produktion
define("VAR_PRODUCTION", 7482);
define("VAR_NAME_PRODUCTION", "PVA_Produktion");
// ISE_ID und Name Systemvariable für WR-Status
define("VAR_STATUS", 9022);
define("VAR_NAME_STATUS", "PVA_Status");
// ISE_ID und Name Systemvariable für Verbrauch
define("VAR_CONSUMPTION", 9021);
define("VAR_NAME_CONSUMPTION", "Haus_Stromverbrauch");
// ISE_ID und Name Systemvariable für Einspeisung
define("VAR_FEEDIN", 12511);
define("VAR_NAME_FEEDIN", "Strom_Einspeisung");
// ISE_ID und Name Systemvariable für Bezug
define("VAR_DRAW", 12512);
define("VAR_NAME_DRAW","Strom_Bezug");
// Fronius Wechselrichter Status-Codes
$inverter_status_codes = array(
"" => "Kein Status",
0 => "Sleep",
1 => "Sleep",
2 => "Sleep",
3 => "Sleep",
4 => "Sleep",
5 => "Sleep",
6 => "Start",
7 => "Produktion",
8 => "Standby",
9 => "Bootloader",
10 => "Fehler",
11 => "Nicht erreichbar",
12 => "Nicht erreichbar",
13 => "CommonINV fehlt",
14 => "Meter fehlt",
15 => "MinMax fehlt"
);
// HTTP-Optionen
$opts = array(
'http' => array(
'method' => "GET",
'user_agent' => "PVA2CCU-".VERSION_STRING."/monster.local.lan",
'timeout' => 5,
'ignore_errors' => true
),
'ssl'=>array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
$context = stream_context_create($opts);
// Fronius JSON-API URLs
$data_url_production= "http://".HOST_INV."/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceId=".DEV_ID_INVERTER."&DataCollection=CommonInverterData";
$data_url_consumption = "http://".HOST_INV."/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=".DEV_ID_METER."&DataCollection=MeterRealtimeData";
// HTTP Request ausführen
echo "Reading inverter data from ".HOST_INV."\n";
$data_production_json = file_get_contents($data_url_production, false, $context);
echo "Reading meter data from ".HOST_INV."\n";
$data_consumption_json = file_get_contents($data_url_consumption, false, $context);
// JSON-Antwort zu Array konvertieren
$data_production_array = json_decode($data_production_json, true);
$data_consumption_array = json_decode($data_consumption_json, true);
if ( DEBUG_JSON ) {
// Debug
echo "--- prod -------------------------------------------";
print_r($data_production_array);
echo "--- cons -------------------------------------------";
print_r($data_consumption_array);
}
// Werte aus Inverter
$inverter_status= $data_production_array["Body"]["Data"]["DeviceStatus"]["StatusCode"];
$inverter_statusmsg = $inverter_status_codes[$inverter_status];
$today_production = $data_production_array["Body"]["Data"]["DAY_ENERGY"]["Value"];
$year_production= $data_production_array["Body"]["Data"]["YEAR_ENERGY"]["Value"];
if ( $inverter_status == 7 ) {
// Produktion
$current_production = $data_production_array["Body"]["Data"]["PAC"]["Value"];
} else {
// Keine Produktion
$current_production = 0;
}
// Werte aus Smart Meter
$current_comsumption_phase1 = $data_consumption_array["Body"]["Data"]["PowerReal_P_Phase_1"];
$current_comsumption_phase2 = $data_consumption_array["Body"]["Data"]["PowerReal_P_Phase_2"];
$current_comsumption_phase3 = $data_consumption_array["Body"]["Data"]["PowerReal_P_Phase_3"];
$current_consumption= $data_consumption_array["Body"]["Data"]["PowerReal_P_Sum"];
$current_consumption= intval($current_consumption * -1);
// Einspeisung
$current_feedin = $current_production - $current_consumption;
if ( $current_feedin < 0 ) {
// Keine Einspeisung
$current_feedin = 0;
}
// Bezug
$current_draw = $current_consumption - $current_production;
if ( $current_draw < 0 ) {
// Kein Bezug
$current_draw = 0;
}
// Fixes
if ( $current_production == "" ) {
$current_production = 0;
}
// Variablen in HomeMatic CCU setzen
$update_url_status= "https://".HOST_CCU."/addons/xmlapi/statechange.cgi?ise_id=".VAR_STATUS."&new_value=".$inverter_statusmsg;
$update_url_production= "https://".HOST_CCU."/addons/xmlapi/statechange.cgi?ise_id=".VAR_PRODUCTION."&new_value=".$current_production;
$update_url_consumption = "https://".HOST_CCU."/addons/xmlapi/statechange.cgi?ise_id=".VAR_CONSUMPTION."&new_value=".$current_consumption;
$update_url_einspeisung = "https://".HOST_CCU."/addons/xmlapi/statechange.cgi?ise_id=".VAR_FEEDIN."&new_value=".$current_feedin;
$update_url_bezug = "https://".HOST_CCU."/addons/xmlapi/statechange.cgi?ise_id=".VAR_DRAW."&new_value=".$current_draw;
echo "Writing inverter data to ".HOST_CCU."\n";
$request_status_xml = file_get_contents($update_url_status, false, $context);
$request_production_xml = file_get_contents($update_url_production, false, $context);
echo "Writing meter data to ".HOST_CCU."\n";
$request_consumption_xml = file_get_contents($update_url_consumption, false, $context);
$request_einspeisung_xml = file_get_contents($update_url_einspeisung, false, $context);
$request_bezug_xml= file_get_contents($update_url_bezug, false, $context);
$status_xml = json_decode(json_encode(simplexml_load_string($request_status_xml)));
$production_xml = json_decode(json_encode(simplexml_load_string($request_production_xml)));
$consumption_xml = json_decode(json_encode(simplexml_load_string($request_consumption_xml)));
$einspeisung_xml = json_decode(json_encode(simplexml_load_string($request_einspeisung_xml)));
$bezug_xml= json_decode(json_encode(simplexml_load_string($request_bezug_xml)));
// Ausgabe
echo "\n";
echo "Status: ".$inverter_status." (".$inverter_statusmsg.")\n";
echo "Produktion: ".$current_production." Watt\n";
echo "Verbrauch:".$current_consumption." Watt\n";
echo "Einspeisung: ".$current_feedin." Watt\n";
echo "Bezug:".$current_draw." Watt\n";
if ( DEBUG_XMLAPI ) {
// Debug
print_r($status_xml);
echo "\n";
print_r($production_xml);
echo "\n";
print_r($consumption_xml);
echo "\n";
print_r($einspeisung_xml);
echo "\n";
print_r($bezug_xml);
echo "\n";
}
?>
Die erweiterten Status-Codes ($inverter_status
) des Wechselrichters aus der Dokumentation der Fronius-API:
Nach dem ersten Durchlauf sind die Werte für die weitere Verwendung verfügbar: