Beispiel: Victron2MQTT (Interface zu Victron MPPT Ladereglern) einbinden

Welche Geräter können mit dieser Anzeige benutzt werden?
Laderegler, Wallboxen, Batterie-Management-Systeme, WLAN Schalter mit Tasmota Firmware und Wechselrichter

Moderator: Ulrich

Antworten
gzi
Beiträge: 153
Registriert: Mo 16. Jan 2023, 20:43
Hat sich bedankt: 20 Mal
Danksagung erhalten: 29 Mal

Beispiel: Victron2MQTT (Interface zu Victron MPPT Ladereglern) einbinden

Beitrag von gzi »

Das Github-Projekt Victron2MQTT realisiert eine WLAN-Einbindung für Victron SmartSolar MPPT-Laderegler. Von einem kleinen WemosD1 Mini Chip wird eine JSON Schnittstelle bereitgestellt und wie der Name schon sagt eine MQTT Datenquelle realisiert.

Die JSON Schnittstelle liefert folgende Daten über den Laderegler:

"ESP_Data": {
"IP": "10.0.0.21",
"sw_version": "1.1.3",
"ESP_VCC": 3.317,
"Wifi_RSSI": -80
},
"Device_name": "Victron2MQTT1",
"Device_model": "SmartSolar MPPT 75|15",
"Firmware_version_16": "161",
"Serial_number": "HQ2224AHEUV",
"Voltage": 26.15,
"Battery_current": 0.26,
"Panel_voltage": 31.19,
"Panel_power": 7,
"Operation_state": "Bulk",
"Tracker_operation_mode": "MPP Tracker active",
"Off_reason": "None",
"Current_error": "No error",
"Load_output_state": "ON",
"Load_current": 0,
"total_kWh": 0.03,
"today_kWh": 0.03,
"Max_pow_today": 34,
"Yesterday_kWh": 0,
"Max_pow_yesterday": 0,
"Day": 0

Man braucht nur ein passendes Kabel an den Chip anzulöten (man braucht dazu ein Kabel mit JST 2.0 PH 4 Pin Connector) und ein kleies Micro-USB Netzteil um den Chip mit Strom zu versorgen. Bei mir sieht das dann so aus.
Clipboard01.jpg
Clipboard01.jpg (30.68 KiB) 254 mal betrachtet
Und so sieht es dann am Grafana Dashboard aus:
Unbenannt.jpg
Ich habe den Code zur Abfrage der vier Laderegler in meine user_device.php eingebaut. Dabei nutze ich die JSON Schnittstelle. Wer es nachbauen will, hier ist der Code:

Code: Alles auswählen

// 1.6b Victron Laderegler via Victron2MQTT
//
$Victron_IP = array("10.0.0.21", "10.0.0.22", "10.0.0.23", "10.0.0.24");
$Victron_InfluxDB = "Insel";
$Victron_Measurement = "Laderegler";

function readWemosD1($WemosD1Name,$WemosD1_IP) {
	global $funktionen;
	global $User_Key;
	global $API_Token;
	global $Device;
	global $Messengerdienst;
	$query = "http://".$WemosD1_IP."/livejson"; 
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $query);
	curl_setopt($ch, CURLOPT_TIMEOUT, 5 ); //timeout in second s
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$data = curl_exec($ch);
	$errno = curl_errno( $ch );
	/*
	$context = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
	if(false === ($data = file_get_contents($query, false, $context))){	
	*/
	if ($errno) {
		// BMS Daten können nicht gelesen werden
		for ($Ui = 1; $Ui <= count( $User_Key ); $Ui++) {
			$rc = $funktionen->send_cached_message( $API_Token[$Ui], $User_Key[$Ui], 
			$Device."-Gerät ".$WemosD1Name." ".$WemosD1_IP.":80"." nicht erreichbar.".$errno.curl_error($ch), 0, "", $Messengerdienst[$Ui], "YmdH" );
		}
		$funktionen->log_schreiben( "Fehler! Kann ".$WemosD1Name." nicht abfragen: ".curl_errno( $ch )." : " .$query, "   ", 5 );
		curl_close($ch);
		return false;
	} else {	
		curl_close($ch);

		// BMS Daten gelesen
		$funktionen->log_schreiben("JSON gelesen...","+  ",9);
		return $data;
	}
} // readWemosD1
function evaluateVictronData($data,$laderegler,&$aktuelleDaten) {
		global $funktionen;
		global $zentralerTimestamp;
		global $txtmapping;
		$ergebnis = json_decode( $data, true );	
		//$funktionen->log_schreiben(print_r($data,true), "   ", 5 );
		$funktionen->log_schreiben("JSON decodiert:".print_r($ergebnis,true), "   ", 8 );
		/*
		{
		  "ESP_Data": {
			"IP": "10.0.0.21",
			"sw_version": "1.1.3",
			"ESP_VCC": 3.317,
			"Wifi_RSSI": -80
		  },
		  "Device_name": "Victron2MQTT1",
		  "Device_model": "SmartSolar MPPT 75|15",
		  "Firmware_version_16": "161",
		  "Serial_number": "HQ2224AHEUV",
		  "Voltage": 26.15,
		  "Battery_current": 0.26,
		  "Panel_voltage": 31.19,
		  "Panel_power": 7,
		  "Operation_state": "Bulk",
		  "Tracker_operation_mode": "MPP Tracker active",
		  "Off_reason": "None",
		  "Current_error": "No error",
		  "Load_output_state": "ON",
		  "Load_current": 0,
		  "total_kWh": 0.03,
		  "today_kWh": 0.03,
		  "Max_pow_today": 34,
		  "Yesterday_kWh": 0,
		  "Max_pow_yesterday": 0,
		  "Day": 0
		}
		*/
		$mapping = array(
		  "Battery_V" => "Voltage",
		  "Charge_A" => "Battery_current",
		  "Panel_V" => "Panel_voltage",
		  "Panel_W" => "Panel_power",
		  "total_kWh" => "total_kWh",
		  "today_kWh" => "today_kWh",
		  "today_max_kW" => "Max_pow_today",
		  "yesterday_kWh" => "Yesterday_kWh",
		  "yesterday_max_kW" => "Max_pow_yesterday",
		  "Nr_Days" => "Day"
		);
		$txtmapping = array(
		  "Status" => "Operation_state",
		  "TrackerStatus" => "Tracker_operation_mode",
		  "Off_reason" => "Off_reason",
		  "Current_error" => "Current_error",
		);
		
		foreach ($mapping as $key => $value ) {
			$aktuelleDaten["LR".$laderegler."_".$key] = $ergebnis[$value]; 
		}
		foreach ($txtmapping as $key => $value ) {
			$aktuelleDaten["LR".$laderegler."_".$key] = $ergebnis[$value]; 
		}
		
		if (array_key_exists('Wifi_RSSI', $ergebnis["ESP_Data"])) { // hängt von der Firmware-Version ab
			$funktionen->log_schreiben("Wifi_RSSI: ".$ergebnis["ESP_Data"]["Wifi_RSSI"]."db","   ",5);
		}
		
		$funktionen->log_schreiben("Watt: ".$aktuelleDaten["LR".$laderegler."_"."Panel_W"],"   ",8);
		
	} // evaluateVictronData

$aktuelleDaten = array();
$RemoteDaten = true;
$Device = "LR"; // ME = Smart Meter
$Version = "";
$Start = time();  // Timestamp festhalten

try{	

	// 6.2b Victron Laderegler Daten auslesen 
	$funktionen->log_schreiben( "Trace 6.2b - auslesen", "   ", 7 );
	$vi=1; 
	foreach ($Victron_IP as $Laderegler_IP) {
		$data = readWemosD1("Victron2MQTT".$vi, $Laderegler_IP);
		if ($data) { // LR auslesbar
			// 6.2b JSON Daten auswerten 
			$funktionen->log_schreiben( "Trace 6.2b - auswerten ", "   ", 7 );
			evaluateVictronData($data,$vi, $aktuelleDaten);
		} else {
			// throw new Exception("Konnte TCP-Connection zum Victron2MQTT".$vi." nicht öffnen. ");
		}
		$vi++;
	}

// 6.3b abgeleitete Daten berechnen

	$funktionen->log_schreiben( "Trace 6.3b - abgeleitete Daten berechnen", "   ", 7 );
	
// 6.4b Query für das Schreiben in die influxDB zusammenstellen
	
	$funktionen->log_schreiben( "Trace 6.4b - Query zusammenstellen", "   ", 7 );
	
	$zq = "";
	foreach($aktuelleDaten as $key => $value) {
		if (array_key_exists(substr($key,4),$txtmapping)) { //"LR".$laderegler."_".
			// Textfeld
			// $funktionen->log_schreiben($key." ist ein Textfeld","   ", 5);
			$zq .= ",".$key.'="'.$value.'"';
		} else {
			// numerisches Feld
			// $funktionen->log_schreiben($key." ist ein numerisches Feld","   ", 5);
			$zq .= ",".$key."=".$value;
		}
	}
	$zq = $Victron_Measurement." ".substr($zq,1)." ".$zentralerTimestamp."\n";
	//$funktionen->log_schreiben("zq: ".$zq,"--->",5);
	
	
	$aktuelleDaten["ZusatzQuery"] = $zq; 
	$funktionen->log_schreiben("Zentraler Timestamp: ".$zentralerTimestamp,"   ",8);
	$aktuelleDaten["zentralerTimestamp"] = $zentralerTimestamp;

	$FehlermeldungText = "";

	$aktuelleDaten["Regler"] = $Regler;
	$aktuelleDaten["Objekt"] = $Objekt;
	$aktuelleDaten["Firmware"] = "Victron2MQTT";
	//$aktuelleDaten["zentralerTimestamp"] = ($aktuelleDaten["zentralerTimestamp"]+10);

// 6.5b optionale Nachbearbeitung der Laderegler Daten
	
	$funktionen->log_schreiben( "Trace 6.5b - Nachbearbeitung", "   ", 7 );
	
	if ( file_exists ("/var/www/html/Victron2MQTT_math.php")) {
		include 'Victron2MQTT_math.php';  // Falls etwas neu berechnet werden muss.
	}
	$funktionen->log_schreiben(var_export($aktuelleDaten,1),"   ",8);
	
// 6.6b Smart-Meter Daten optional an den hauseigenen MQTT Broker übergeben
	
	$funktionen->log_schreiben( "Trace 6.6b - MQTT", "   ", 7 );
	
	if ($MQTT) {
		$funktionen->log_schreiben("MQTT Daten zum [ $MQTTBroker ] senden.","   ",1);
		require($Pfad."/mqtt_senden.php");
	}

// 6.7b Zeitpunkte definieren
	
	$funktionen->log_schreiben( "Trace 6.7b - Zeit", "   ", 7 );
	
	$aktuelleDaten["Timestamp"] = time();
	$aktuelleDaten["Monat"]     = date("n");
	$aktuelleDaten["Woche"]     = date("W");
	$aktuelleDaten["Wochentag"] = strftime("%A",time());
	$aktuelleDaten["Datum"]     = date("d.m.Y");
	$aktuelleDaten["Uhrzeit"]   = date("H:i:s");

// 6.8b Smart-Meter Daten in influxDB ablegen
	
	$funktionen->log_schreiben( "Trace 6.8b - Daten in InfluxDB", "   ", 7 );
	
	$aktuelleDaten["InfluxAdresse"] = $InfluxAdresse;
	$aktuelleDaten["InfluxPort"] = $InfluxPort;
	$aktuelleDaten["InfluxUser"] =  $InfluxUser;
	$aktuelleDaten["InfluxPassword"] = $InfluxPassword;
	$aktuelleDaten["InfluxDBName"] = $InfluxDBName;
	$aktuelleDaten["InfluxDaylight"] = $InfluxDaylight;
	$aktuelleDaten["InfluxDBLokal"] = $Victron_InfluxDB;
	$aktuelleDaten["InfluxSSL"] = $InfluxSSL;
	$aktuelleDaten["Demodaten"] = false;
	
	if ($InfluxDB_remote) {
		// Daten sollen in remote DB geschrieben werden
		if ($RemoteDaten) {
			$rc = $funktionen->influx_remote_test();
			if ($rc) {
				$rc = $funktionen->influx_remote($aktuelleDaten);
				if ($rc) {
					$RemoteDaten = false;
				}
			} else {
				$RemoteDaten = false;
			}
		}
		if ($InfluxDB_local) {
			// Daten sollen zusätzlich lokal abgelegt werden
			$rc = $funktionen->influx_local($aktuelleDaten);
		}
	} else {
		// Daten sollen nur lokal abgelegt werden
		$rc = $funktionen->influx_local($aktuelleDaten);
	}

	$funktionen->log_schreiben( "Ende Abschnitt 6 - Insel", "   ", 5 );
	
} catch(\Throwable $ex) {
	$USB1 = false;

	$funktionen->log_schreiben( "Socket==false. Kein Kontakt zum Victron2MQTT ".$Laderegler_IP, "XX ", 3 );
	$funktionen->log_schreiben( "Exit.... ", "XX ", 3 );
	for ($Ui = 1; $Ui <= count( $User_Key ); $Ui++) {
		$rc = $funktionen->send_cached_message( $API_Token[$Ui], $User_Key[$Ui], $Device."-Gerät Victron2MQTT- ".$Laderegler_IP." nicht erreichbar.".$errno.$errstr, 0, "", $Messengerdienst[$Ui], "YmdH" );
	}
}

Raspi 3B, Hybrid Must PV18-3024 VHM, Hoymiles HM-800 , Nachteinspeisung, Flex-BKW, AhoyDTU, Smart Meter DTSU666-H, DIY Akku 6,7 KWh, DalyBMS2MQTT, Victron2MQTT,Architektur, HomeMatic CCU. Autor: Solaranlage Do-It-Yourself

Antworten

Zurück zu „Regler, Wallboxen und Wechselrichter“