Daten von Fronius-Wechselrichter an CCU mit PHP

In Hausautomation, Technik und Elektronik | Erstellt: 23.10.2018, 08:45 | Editiert: 27.10.2018, 13:48 (PHP-Code gerade gezogen) | 59 mal angesehen | Seite drucken

PHP-Cronjob zum Übertragen der Kenndaten eines Fronius Photovoltaik-Wechselrichters an einen HomeMatic-Zentrale

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.

Systemvariablen

Auf der CCU folgende Systemvariablen anlegen:

  • Name: Haus_Verbrauch, Typ: Integer, Einheit Watt, ise_id bei mir: 9021
  • Name: PVA_Produktion, Typ: Integer, Einheit Watt, ise_id bei mir: 7482
  • Name: PVA_Status, Typ: String, ohne Einheit, ise_id bei mir: 9022
  • Name: Strom_Einspeisung, Typ: Integer, Einheit Watt, ise_id bei mir: 12511
  • Name: Strom_Bezug, Typ: Integer, Einheit Watt, ise_id bei mir: 12512

Die ise_id der Variablen wird benötigt, um sie später ansprechen zu können.

Auslesen des Wechselrichters

Ü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";

Setzen der Systemvariablen in der CCU

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;

Skript

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.cgiScope=Device&DeviceId=".DEV_ID_INVERTER."&DataCollection=CommonInverterData";
$data_url_consumption   = "http://".HOST_INV."/solar_api/v1/GetMeterRealtimeData.cgiScope=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";
}
?>

Status-Codes des Wechselrichters

Die erweiterten Status-Codes ($inverter_status) des Wechselrichters aus der Dokumentation der Fronius-API:

  • 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

Gesetzte Systemvariablen

Nach dem ersten Durchlauf sind die Werte für die weitere Verwendung verfügbar:

Weitere Seiten in 'Hausautomation, Technik und Elektronik'

Schreibe einen Kommentar

Captcha * Time limit is exhausted. Please reload CAPTCHA.