VBus Protokoll und Resol Solarregler

Bei mir ist vor 2 Wochen die Solaranlage in Betrieb gegangen. Ich hatte meinen Klemptner nach einem Regler mit „Schnittstelle“ gefragt und er hat mir den Resol BS+ angeboten. Dieser hat eine „VBUS“ Schnittstelle. Da das Protokoll vom Hersteller frei zugänglich ist und auch ein LAN bzw. ein USB Adapter angeboten wird, habe ich mich auch dafür entschieden. Das Protokoll ist zum Beispiel hier abrufbar.
Ich habe mich für die USB Variante entschieden. (Diesen habe ich nach einiger Zeit durch einen RS485 -> RS232 Adapter ersetzt.

  1. Da er ohne ein weiteres Netzteil auskommt.
  2. Stellt dieser nach der Treiberinstallation einen virtuellen Com Port zur Verfügung.
  3. Die VBus Leitung kann bis zu 50m lang sein und da mein Server im Keller neben dem Heizungsraum ist , war das kein Problem.
    Also hab ich in IPS eine Com Port Instanz erstellt, geöffnet und schon waren im Debug Fenster die Daten zu sehen. Der Regler sendet im Sekundentakt die Betriebswerte. Da die „Datenflut“ mir aber zu groß ist, wird der Port per Script alle 30 sekunden nur kurz geöffnet.

Der Port wird dann, nach Erhalt eines Datensatzes, durch das Auswertscript wieder geschlossen.

Das Protokoll hat so seine Spezialitäten. Es kann auf einem Bus logischerweise nur einen Master geben. Dieser ist immer der Regler. Damit ist mit einem PC Adapter auch nur 1 Regler abrufbar. Mehr ist im Normalfall auch nicht nötig.
Um die einzelnen Datensätze zu syncronisieren gibt es ein Syncronisationsbyte (AAh). Wenn dieses Byte gesendet wird beginnt eine neuer Datensatz. Dies ist das einzigste Byte in dem das Bit7 (hier MSB genannt) „1“ sein darf. Bei allen anderen Bytes wird dieses Bit entfernt und in einem extra Byte übertragen (Septett gennant). Deswegen muß man etwas Aufwand betreiben , nach erhalt eines Datensatzes, die Bytes wieder zusammenzusetzen um die richtigen Werte zu erhalten.
So aber nun zum wichtigen. Wie bekomme man die Daten nach IPS.

  1. „Serial Port“ Instanz erstellen

  2. Cutter Instanz erstellen
    Einstellungen siehe Bild.
    Übergeordnete Instanz - der eben angelegte Com Port


    Warum den Cutter?
    Da die seriellen Daten nicht in einem Rutsch kommen und auch durch das Syncronisationsbyte immer ein definierter Start- und Endpunkt da ist, lassen sich mit dem Cutter, die Daten ideal zusammen führen und dann in einem Zug an die Registervariable übergeben.
    Damit wären wir beim nächsten Punkt.

  3. Registervariable erstellen
    Übergeordnete Instanz - der eben angelegte Cutter

  4. Zielscript: das unten folgende

  5. Variablen werden durch das Script selbst angelegt

Ich habe versucht vieles zu kommentieren, damit auch andere was damit anfangen können. Wenn doch noch Fragen sind, können diese in diesem Tread gestellt werden.
Auch habe ich die Überprüfung der Checksumme mit hineingenommen, da bei mir ca.3-4 mal am Tag „wirre“ Datensätze ankommen und ansonsten dann falsche Werte in die Variablen geschrieben werden. Macht sich dann nicht schön in den Diagrammen.

Schönes Wochenende noch
Attain

COM.png

Hallo an alle,

durch die Diskussion mit honk0504, in diesem Thread, habe ich das Script komplett neu überarbeitet. Dank an Ihn für den Beta Test.
Vorraussetzung ist IPS-Version ab 2.7

-neu: Automatisches Anlegen aller im Datensatz übergebenen Variablen, unter einem Dummy Modul.
-neu: Variablen werden über einen eindeutigen IDENT angesprochen.
-neu: Unterstützung aller RESOL-Regler.
-neu: Bekannte Variablenprofile werden ausgewählt.
-fix: Negative Werte werden richtig berrechnet.

  • … uvm.

Aufgebaut habe ich das Script auf einer XML Datei die in der RESOL Service Center Software enthalten ist.
Diese Software kann auf der Resol Seite kostenlos heruntergeladen werden.
LINK

EDIT 01.05.2020

Ich habe das Script nochmalig überarbeitet.
-neu: IPS Version muss mindestens 2.7 statt 2.5 sein
-neu: Automatisches Erstellen von I/O Instance, Cutter, RegisterVariable (Installer)
-neu: Einstellbarer ScriptTimer
-neu: TCP oder RS232 Schnittstelle
-neu: Unterstützte BitSize 31 und 32
-neu: Variablen Info wird mit „Common Usage“ beschrieben
-neu: Englische Variablennamen per Option auswählbar

Installation:

  1. die angehängte ZIP Datei entpacken und die enthaltenen XML Datei ins Script Verzeichnis kopieren.
  2. das Script anlegen
  3. Inhalt hineinkopieren
  4. Konfiguration anpassen
  5. Einmalig manuell ausführen, nur dann werden alle nötigen Instanzen angelegt
  6. Fertig
<?
/*
WICHTIG !! Zur Verarbeitung ist die Datei "VBusSpecificationResol.xml" im Scripts  Verzeichnis nötig !!
WICHTIG !! mindestens IPS_Version 2.7 ist notwendig!!

Dieses Script dient zum Empfang von Daten über den "V-Bus".
Die Daten werden entsprechend ihrer Bedeutung aufbereitet und in IPS Variablen abgelegt.
Die Variablennamen können umbennant werden, müssen aber unter dem angelegtem Dummymodul bleiben.
Bekannte Formate bekommen automatisch ein Variablenprofil, alle anderen müssen manuell eines zugewiesen bekommen.

Protokollinformationen sind unter : http://goo.gl/HP6ZY zu finden.
Weitere Infos : http://groups.google.com/group/resol-vbus/

Copyright (c) 		2010-2020 Attain
Link				http://www.ip-symcon.de/forum/f23/vbus-protokoll-resol-solarregler-11700/
Version				1.2.2
Datum				13.05.2020

Changelog:
V1.0	01.10.2010
		first release

V1.1	11.02.2012
		auslesen der spezifischen reglerdaten aus der XML Datei
		automatisches Variablen erstellen, per Ident angesprochen
		Dummy Modul wird erstellt
		Automatisches Anlegen von Varprofilen

V1.2	01.05.2020
		IPS Version muss mindestens 2.7 statt 2.5 sein
		Automatisches Erstellen von I/O Instance, Cutter, RegisterVariable(Installer)
		TCP oder RS232 Schnittstelle
		Unterstützte BitSize 31 und 32
		Variablen Info wird mit "Common Usage" beschrieben
		Englische Variablennamen per Option auswählbar
V1.2.1	03.05.2020
		fix Varprofil Zuordnung
V1.2.2	13.05.2020
		fix Varprofil Sonderzeichen

ToDo	PHP Modul erstellen
+----------------------------------------------------------------------+
| This library is free software; you can redistribute it and/or        |
| modify it under the terms of the GNU Lesser General Public           |
| License as published by the Free Software Foundation; either         |
| version 2.1 of the License, or (at your option) any later version.   |
+----------------------------------------------------------------------+
*/
########## Konfigurationsteil #####################
$debug		= false;				// zur Fehlersuche auf TRUE setzen
$socket		= "TCP";				// Art des Adapter, TCP oder RS232
$timer		= 0;					// Abstand in sekunden, in der Daten empfangen werden sollen  | 0 = Timer deaktiviert, Port bleibt immer offen, Alle Daten werden verarbeitet 
$language	= 0;					// Variablennamen | 0 = Deutsch | 1 = English

//nur TCP
$ip_address	= "192.168.123.110";	// IP Adresse des LAN Adapter
$ip_port	= 7053;					// Kommunikationsport
$passwort	= "vbus";				// passwort zur Abfrage der Daten mit dem LAN Adapter, standart: vbus

// nur RS232
$com_port	= "COM4";				// Serieller Port

########## Installer ###########################
if		($socket == "TCP") $IOid = ATN_GetInstanceIDbyIdent("{3CFF0FD9-E306-41DB-9B5A-9D06D38576C3}","RESOL_IO");
elseif	($socket == "RS232") $IOid = ATN_GetInstanceIDbyIdent("{3CFF0FD9-E306-41DB-9B5A-9D06D38576C3}","RESOL_IO");
else	IPS_LogMessage("RESOL-VBUS-SCRIPT ".$_IPS['SELF'], $socket . " ist keine gültige Schnittstelle");

if ($_IPS['SENDER'] == "Execute")
{
	if (IPS_GetKernelVersion()<2.7)
	{
		IPS_LogMessage("RESOL-VBUS-SCRIPT ".$_IPS['SELF'], "Script ist erst ab Version 2.7 lauffähig");
		return;
	}
	if ($socket == "TCP")
	{
		if (!$IOid) // client socket instance does not exist -> create
		{
			$IOid = IPS_CreateInstance("{3CFF0FD9-E306-41DB-9B5A-9D06D38576C3}");
			IPS_SetIdent($IOid,"RESOL_IO");
			IPS_SetName($IOid,"Client Socket (Resol)");
		}
		IPS_SetConfiguration($IOid,'{"Open":true,"Host":"' . $ip_address . '","Port":'. $ip_port . '}');
		IPS_ApplyChanges($IOid); 
		CSCK_SendText($IOid,"PASS " . $passwort . CHR(13));
		CSCK_SendText($IOid,"DATA".CHR(13));
	}
	elseif($socket == "RS232")
	{
		if (!$IOid) // serial instance does not exist -> create
		{
			$IOid = IPS_CreateInstance("{6DC3D946-0D31-450F-A8C6-C42DB8D7D4F1}");
			IPS_SetIdent($IOid,"RESOL_IO");
			IPS_SetName($IOid,"Serial Port (Resol)");
		}
		IPS_SetConfiguration($IOid,'{"Open":true,"Port":"' . $com_port . '","BaudRate":"9600","DataBits":"8","StopBits":"1","Parity":"None"}');
		IPS_ApplyChanges($IOid); 
	}

	// Cutter
	$Cutterid = ATN_GetInstanceIDbyIdent("{AC6C6E74-C797-40B3-BA82-F135D941D1A2}","RESOL_CUTTER");
	if (!$Cutterid) // nicht vorhanden, anlegen
	{
		$Cutterid = IPS_CreateInstance("{AC6C6E74-C797-40B3-BA82-F135D941D1A2}");
		IPS_SetName($Cutterid,"Cutter (Resol)");
		IPS_SetIdent($Cutterid,"RESOL_CUTTER");
	}
	IPS_SetConfiguration($Cutterid,'{"ParseType":0,"LeftCutChar":"AA 10","LeftCutCharAsHex":true,"RightCutChar":"AA","RightCutCharAsHex":true,"DeleteCutChars":false,"InputLength":0,"SyncChar":"","SyncCharAsHex":false,"Timeout":1000}');
	If (IPS_GetInstance($Cutterid)['ConnectionID'] != $IOid)
	{
		@IPS_DisconnectInstance ($Cutterid);
		IPS_ApplyChanges($Cutterid);
	} 
	@IPS_ConnectInstance($Cutterid, $IOid);
	IPS_ApplyChanges($Cutterid);

	// Register Variable 
	$Registerid = ATN_GetInstanceIDbyIdent("{F3855B3C-7CD6-47CA-97AB-E66D346C037F}","RESOL_REGISTER_VARIABLE");
	if(!$Registerid) // nicht vorhanden, anlegen
	{
		$Registerid = IPS_CreateInstance("{F3855B3C-7CD6-47CA-97AB-E66D346C037F}");
		IPS_SetName($Registerid,"RegisterVariable (Resol)");
		IPS_SetIdent($Registerid,"RESOL_REGISTER_VARIABLE");
		IPS_SetParent($Registerid,$_IPS['SELF']);
	}
	IPS_SetConfiguration($Registerid,'{"RXObjectID":' . $_IPS['SELF'] . '}');
	If (IPS_GetInstance($Registerid)['ConnectionID'] != $Cutterid) 
	{
		@IPS_DisconnectInstance ($Registerid);
		IPS_ApplyChanges($Registerid);
	}
	@IPS_ConnectInstance($Registerid, $Cutterid);
	IPS_ApplyChanges($Registerid);

	IPS_SetScriptTimer($_IPS['SELF'],$timer);

return;
} // End Execute

################ Timer #############################
if ($_IPS['SENDER'] == "TimerEvent")
{
	if (!IPS_GetProperty($IOid,"Open"))  // Port geschlossen ?
	{
		IPS_SetProperty($IOid,"Open",true); // Datenport einschalten
		IPS_ApplyChanges($IOid); 
	}
	if ($socket == "TCP")
	{
		CSCK_SendText($IOid,"PASS " . $passwort . CHR(13));
		CSCK_SendText($IOid,"DATA".CHR(13));
	}
	return;
}

################ Datenempfang #####################################
if ($_IPS['SENDER'] == "RegisterVariable")
{
	########## Definition von Konstanten ##############
	define('ANZAHL_FRAMES', ord($_IPS['VALUE']{6}));
	define('HEADER_CHECKSUMME', ord($_IPS['VALUE']{7}));
	define('REGLER_TYP', "0x" . dechex(ord($_IPS['VALUE']{2})) . dechex(ord($_IPS['VALUE']{1} )));
	define('SCRIPT_KENNUNG', 'V-Bus-Script ID : ' . $_IPS['SELF']);
	define('XML_DATEI', 'VBusSpecificationResol.xml');
	if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,REGLER_TYP);
	############ Scriptteil ###########################
	$cs = 16;       // durch den Cutter wird das erste Byte (0x10 Hex) abgeschnitten, hier wird der Wert wieder dazu genommen
	for ($i=00; $i<=06; $i++)
	{
		$cs += ord($_IPS['VALUE']{$i}); //Headerbytes zur Checksumme zusammenaddieren
	}
	$cs = ~$cs;	//Checksumme invertieren
	$cs &= 127;	//MSB aus Checksumme entfernen
	if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,"Berrechnete Checksumme Header: $cs , Empfangene Checksumme: " . HEADER_CHECKSUMME);
	if ( $cs == HEADER_CHECKSUMME)  // Checksumme ok?
	{
		if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,"HeaderChecksumme OK!");
		$byte_array = array();
		$k = 0; // array Index
		if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,"Anzahl der ermittelten Frames: " . ANZAHL_FRAMES);
		for ($i=01; $i<=ANZAHL_FRAMES; $i++) // Schleife für alle Datenframes
		{
			$cs = 0;
			$septet = ord($_IPS['VALUE']{$i * 6 + 6});
			for ($j=00; $j<=03; $j++)
			{  // es sind immer 4 Bytes in einem Frame
				$payload_byte = ord($_IPS['VALUE']{$i * 6 + 2 + $j});
				$byte_array[$k] = $payload_byte + 128 * (($septet >> $j) & 1); //das komplette Datenbyte aus dem Byte und dem Teil des Septet zusammenfügen
				$k++; //Array Index erhöhen
				$cs += $payload_byte;// Bytes zur Checksumme addieren
			} // End payload Byte Schleife
			$cs += $septet; // septet dazuaddieren
			$cs = ~$cs; //Checksumme invertieren
			$cs &= 127; //MSB aus Checksumme entfernen
			if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,"Berrechnete Checksumme Frame $i: $cs , Empfangene Checksumme: ".ord($_IPS['VALUE']{$i * 6 + 7}));
			if ($cs != ord($_IPS['VALUE']{$i * 6 + 7})) // Checksumme Frame not ok?
			{
				IPS_LogMessage(SCRIPT_KENNUNG,"Checksummenfehler im Frame $i >> ermittelte Summe: $cs empfangene Summe: ".ord($_IPS['VALUE']{$i * 6 + 7}));
				return;
			}
		} // end for frameschleife
	}
	else  // Checksumme Head not ok
	{
		IPS_LogMessage(SCRIPT_KENNUNG,"Checksummenfehler Header >>Checksumme berrechnet: $cs Checksumme soll: ".ord($_IPS['VALUE']{7}));
		return;
	}	// end else
	if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,print_r($byte_array));

	########################################################################

	if (file_exists(XML_DATEI))
	{
		$xml = simplexml_load_file(XML_DATEI);
	//	print_r($xml);

		### Regler Typ in der XML Datei suchen ###
		foreach($xml->device as $master)
		{
			if ($master->address == REGLER_TYP)
			{
				$regler_name = (string)$master->name;
				if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,$regler_name);
				break; // end foreach
			} // end if
		} //end foreach
		if (!isset($regler_name))
		{
			IPS_LogMessage(SCRIPT_KENNUNG,REGLER_TYP . " wurde nicht in der XML Datei gefunden!");
		}
		### dummy instance ### ggf. anlegen ###
		$parentobject = IPS_GetObject($_IPS['SELF']);
		$parentID = $parentobject['ParentID'];
		if (IPS_GetObject($parentID)['ObjectType'] !== 1)
		{
			$parentID = IPS_CreateInstance("{485D0419-BE97-4548-AA9C-C083EB82E61E}");
			IPS_SetParent($parentID, $parentobject['ParentID']);
			IPS_SetParent($_IPS['SELF'], $parentID);
			IPS_SetHidden($_IPS['SELF'], true);
			IPS_SetName  ($parentID, $regler_name);
			IPS_SetIcon  ($parentID, "Sun");
		}

		### Regler
		foreach($xml->packet as $master)
		{
			if ($master->source == REGLER_TYP) // passenden Regler in der Datei gefunden
			{
				//print_r($master);
				foreach($master->field as $field)
				{
					$field_name = (string)($field->name[$language]); // 0 = deutsch 1 = englisch
					$field_info = (string)$field['commonUsage'][0];
					$field_unit = (string)$field->unit;
					$field_bit_size = (int)$field->bitSize;
					$var_profil = "";
					if ($field_bit_size  == 1)
					{
						$var_type = 0; // 0 ^ bool
					}
					elseif ((float)$field->factor < 1 && (float)$field->factor > 0)
					{
						$var_type = 2; // ^ float
					}
					else // kein factor oder factor >= 1
					{
						$var_type = 1; // ^ integer
					}
					if (isset($field->field->offset)) // es gibt mehrere unterwerte
					{
						$var_value = 0;
						foreach($field->field as $child_field)
						{
							$field_offset =   (int)$child_field->offset;
							$field_factor = (float)$child_field->factor;
							$var_value += ($byte_array[$field_offset] + 256 * $byte_array[$field_offset+1])* $field_factor;
						}
					}
					else // nur 1 unterwert
					{
						$field_offset = (int)$field->offset;
						if (isset($field->factor))
						{
							$field_factor = (float)$field->factor;
						}
						else // wenn kein factor angegeben ist
						{
							$field_factor = 1;
						}
						switch ($field_bit_size)
						{
							case 32:
								$var_value  = $byte_array[$field_offset] + (2**8) * $byte_array[$field_offset+1] + (2**16) * $byte_array[$field_offset+2] + (2**24) * $byte_array[$field_offset+3];
								$var_value *= $field_factor;
							break;
							case 31:
								$var_value  = $byte_array[$field_offset] + (2**8) * $byte_array[$field_offset+1] + (2**16) * $byte_array[$field_offset+2] + (2**24) * $byte_array[$field_offset+3];
								$var_value -= ((2**32)*($var_value >> 31)); // wenn bit 31 == true , Wert ist negativ
								$var_value *= $field_factor;
							break;
							case 16:
								$var_value  = $byte_array[$field_offset] + (2**8) * $byte_array[$field_offset+1];
								$var_value *= $field_factor;
							break;
							case 15:
								$var_value  = $byte_array[$field_offset] + 2**8 * $byte_array[$field_offset+1];
								$var_value -= ((2**16)*($var_value >> 15)); // wenn bit 15 == true , Wert ist negativ
								$var_value *= $field_factor;
							break;
							case 8:
								$var_value = $byte_array[$field_offset];
							break;
							case 7:  
								$var_value = $byte_array[$field_offset];
								$var_value -= ((2**8)*($var_value >> 7)); // wenn bit 7 == true , Wert ist negativ
							break;
							case 1:
								$field_bit = $field->bitPos;
								$var_value = (($byte_array[$field_offset] >> $field_bit) & 1);
								$var_profil = "~Switch";
							break;
						} // END Switch
					} //end else
					if ((string)$field->format == "t") // Systemzeit
					{
						$var_value = mktime(0,$var_value,0);
						$var_profil = "~UnixTimestamp";
					}
					if ((string) $field_unit == " °C") // Temperaturen
					{
						$var_profil = "~Temperature";

					}
					if ($field_unit == " %") // Drehzahlen
					{
						$var_profil = "~Intensity.100";
					}
					if ($debug) echo "|" .$var_profil . "|" . $field_unit . "|
";
					if ($var_profil == "" && $field_unit != "") {$var_profil = ATN_CreateVariableProfile($var_type, $field_unit, $field_bit_size);}
					$var_ident = REGLER_TYP . $field_offset . (string)$field->bitPos;  // eindeutigen IDENT erzeugen
					$position = (int) $field_offset . (string)$field->bitPos;
					if ($debug) IPS_LogMessage(SCRIPT_KENNUNG,$field_name . " " . $field_offset . " ".$var_value . " ".$field_unit);
					$var_id = CreateVariableByName($parentID, $field_name, $var_type, $var_ident, $var_profil, $position, $field_info);
					if (GetValue($var_id) != $var_value) SetValue($var_id,$var_value); // Wert in Variable abspeichern. Nur neue.
				}
			break; //foreach beenden
			} // end if
		} //end foreach
	} //end if
	else
	{
		IPS_LogMessage(SCRIPT_KENNUNG,'Konnte Datei ' . XML_DATEI . ' nicht laden.');
	}
	if ($timer) // nur wenn timer aktiv, port schliessen
	{
		IPS_SetProperty($IOid, "Open", false); // Datenport ausschalten
		IPS_ApplyChanges($IOid);
	}
}
// Geguttenbergt by paresy
function CreateVariableByName($id, $name, $type, $ident, $profile = "", $position = 0, $info = "")
	{
		$vid = @IPS_GetObjectIDByIdent ($ident, $id);
		if($vid === false)
		{
			$vid = IPS_CreateVariable($type);
			IPS_SetParent($vid, $id);
			IPS_SetName($vid, $name);
			IPS_SetIdent($vid, $ident);
			IPS_SetPosition($vid, $position);
			IPS_SetInfo($vid, $info);
			if($profile !== "") IPS_SetVariableCustomProfile($vid, $profile);
		}
		return $vid;
	}

function ATN_GetInstanceIDbyIdent($guid,$ident) // check if instance already exist
{
	$Instance = IPS_GetInstanceListByModuleID($guid);
	foreach ($Instance as $IOid)
	{
		$object = IPS_GetObject($IOid);
		if ($object['ObjectIdent'] == $ident)
		{
			return ($IOid); // found instance with ident 
		}
	}
	return(false); //instance does not exist
}

function ATN_CreateVariableProfile($var_type, $field_unit, $field_bit_size)
{
	$Maximalwert = 2** (int)$field_bit_size;
	$profil_name = "Resol" . $field_unit;
	// keine Sonderzeichen im Var-Profilname zulässig
	$profil_name = preg_replace ( '/[^a-z0-9]/i', '_', $profil_name );
	if (!@IPS_GetVariableProfile($profil_name))
	{
		IPS_CreateVariableProfile($profil_name, $var_type);
		IPS_SetVariableProfileText($profil_name, "", $field_unit);
		IPS_SetVariableProfileValues ($profil_name, 0, $Maximalwert, 1);
	}
	return $profil_name;
}
?>

EDIT 11.05.2020
XML Datei war fehlerhaft - erneuert

Gruß und Danke
Attain

VBusSpecificationResol.zip (28.4 KB)

Hallo miteinander

Ich habe das Resol Script gefunden und habe die sehr gute Anleitung befolgt.
Damit wäre mein Resol Regler eingebunden gewesen.

Beim erstenmal hat das Script dann auch den Regler gefunden und alle Variablen angelegt. Befüllt wurden die Variablen allerdings nicht.
Stattdessen schreibt es ins Log.

<br />
<b>Notice</b>: Undefined variable: var_value in <b>C:\IP-Symcon\scripts\30973.ips.php</b> on line <b>203</b><br />
<br />

Die Variablen scheinen einen falschen Typ zu haben.

Zum VBusSpecificationResol.xml muss ich sagen. Meinen Regler habe ich darin nicht gefunden, im Protokoll im Web allerdings schon. Damit habe ich dann das xml erweitert.

Was habe ich nicht beachtet. Der Cutter scheint richtig zu arbeiten der Liefert regelmässig dieselbe Menge Daten.

Leider verstehe ich das Script nicht und weiss nicht so richtig wo suchen.
Kann mir da jemand helfen?

grüsse
Tschewie

VBusSpecificationResol.xml (58 KB)

Hallo Tschewie,

die Erweiterungen in der XML Datei passen nicht.

  	&lt;name&gt;Pump speed R1&lt;/name&gt;
  	&lt;bitSize&gt;1&lt;/bitSize&gt;
  	&lt;factor&gt;1&lt;/factor&gt;

bitSize 1 bedeutet ein bool wert, aber eine Drehzahl ist ein Integer Wert.

Wo hast du die XML Werte her?
Ich schau mir das morgen mal genauer an.

Gruß
Attain

Edit:
Die Fehlermeldung kommt davon:

<bitSize>2</bitSize>

Das gibt es so nicht im Script.
Morgen mehr…

Hallo Attain

Die Zusätzlichen xml Einträge sind aus dem Dokument
http://goo.gl/HP6ZY Seite 72. Ohne diese legt er nicht mal die Variablen an.
Bei den anderen Reglern sind die %Werte auch als 1 Bitsize definiert. Was eigentlich komisch ist.
Der Logeintrag Undefined variable: kommt auch 8X vor. Die ersten 8(Sensoren) wahrscheinlich korrekt, ab dann stimmt es nicht mehr.

gruess
tschewie

Hallo Tschewie,

nein, die in dem Dokument angegebenen „Size“ sind Bytes. Im XML werden aber „Bits“ verwendet. Da ich den Regler in den XML Dokumenten nicht gefunden habe, habe ich die Datei manuell einmal angepasst.
Bitte diese Datei ersetzen. Alle Variablen nochmal löschen. Dann sollte es klappen.

Gruß
Attain

VBusSpecificationResol.xml (58.1 KB)

Hallo Attain

Cool es funktioniert.
Das mit den bits und bytes im xml habe ich nicht gewusst.
Die Werte sind sogar pausible.
Nun öffne ich den Port wahrscheinlich alle halbe stunde und schliesse in dann wieder um die Datenmenge im Griff zu haben.

Mein lanadapter initialiere ich
//socket oeffnen
CSCK_SetOpen(10423 /[Resol Socket]/ , true);
IPS_ApplyChanges(10423 /[Resol Socket]/ );

RegVar_SendText(10117 /*[Diverses\Resol\Register Variable]*/,'PASS ****');

sleep(1);
RegVar_SendText(10117 /[Diverses\Resol\Register Variable]/,‚DATA‘);

und es funktioniert.

:smiley:

gruss
Tschewie

Hallo Leute,

ich hole den Thread mal aus der versenkung - da ich mit dem Gedanken spiele mir eine Server mit Win 8 zu basteln, darauf IPS laufen zu lassen und meine RESOL Steuerung damit zu verbinden.

Frage 1: Läuft das angegeben script reibungslos?

Frage 2: Die Steuerung/Busleitung der RESOL wird ja laufend Messwerte übertragen und IPS diese dann speichern/verarbeiten. Heißt das, dass der Server immer unter Last läuft? Sprich geht der dann nie in den Ruhestand?
Denke dass das den Stromverbrauch ziemlich in die Höhe treiben wird ofer?

Gruß
Virus

Hallo

zur Frage 1: ja. Der Thread ist erschreckend kurz.

zur Frage 2: Der Regler sendet, wenn man nichts dagegen unternimmt, seine Werte einmal pro Sekunde.
Das Script speichert nur Werte in Variablen, die sich geändert haben. Dadurch wird der Schreibzugriff reduziert.
Ich persönlich öffne die Schnittstelle am PC einmal pro Minute und wenn ein Datensatz empfangen wurde, schließe ich diesen wieder. Aber auch ohne diese Maßnahme läuft mein 500 MHz /512MB RAM Singlecore „Server“ noch im unterem Auslastungsbereich.

Gruß
Attain

Hallo Attain,

ich habe auch versucht dein Script mit meinem DeltaSol BX Plus zum laufen zu bekommen, aber leider legt er mir nur 8 Variablen an die dann aber nie mit Werten gefüllt werden.
Kannst du dir diese Problem erklären? Und mir helfen es zu lösen?

Gruß
MaBu

Hallo Mabu,

entschuldige das ich erst jetzt reagiere. Ändere mal folgende Zeile im Schript ab

define('XML_DATEI', 'VBusSpecificationResol.xml'); 

in

define('XML_DATEI', 'VBusSpecificationResolDeltaSolBXPlus.xml')

und füge folgende Datei in das scripts Verzeichnis ein.VBusSpecificationResolDeltaSolBXPlus.txt (8.76 KB)
Da kein XML Dateien mehr hochgeladen werden können, mußt Du die Datei noch in .xml umbenennen.

Hallo Attain,

ich habe Deine Anleitung befolgt. Leider erkennt er den Solarregler nicht. Es wird ein unbekanntes Gerät angelegt. Angeblich ist der baugleich mit dem Resol DeltaSol M. Kannst Du mir evtl. weiterhelfen?

Ich habe schon die VBusSpecificationCitrin.xml aus der Resol Software verwendet und den PHP Code angepasst.

Noch eine kleine Frage. Wo muss das Script für das zeitliche Öffnen des Ports hin?

Schöne Grüße

SchlierfCH

Nachtrag

Alle Fragen geklärt. Hab bei der Kontrolle gemerkt, dass ich beim Cutter nicht auf setzen geklickt haben.

Hallo,

kopier das Script nochmal, setze bitte

$debug = true;

dann mußte Du unter „Meldungen“ folgendes in etwa haben:

29.05.2014 21:00:36.355 |     0 | CUSTOM  | V-Bus-Script ID : 36101 | 0x4221

Die Nummer (bei mir 0x4221) brauch ich.

Gruß
Attain

Hallo Attain,

danke für die Antwort. Das Ganze läuft mittlerweile problemlos. Ich habe den Cutter nicht richtig erstellt.
Trotzdem Danke :wink:

Eine Frage noch. Wohin kommt dieses Script?

<?
$ID = 33876 /[Resol]/; // ID des Com Port’s
COMPort_SetOpen($ID,true);
IPS_ApplyChanges($ID);
?>

Ich habe es momentan bei den I/O Instanzen zum entsprechenden Port eingefügt. Allerdings stelle ich keine Unterbrechung des Ports fest.

Gruß

SchlierfCH

einfach ganz an das Ende des Resolscripts das selbe eintragen, nur mit ComPort_SetOpen($ID.false)
:

$ID = 33876 /*[Resol]*/; // ID des Com Port's
COMPort_SetOpen($ID,false);
IPS_ApplyChanges($ID);

Damit wird nach Durchlauf des Scripts der Com Port deaktiviert.

Gruß

Hallo Attain,

zuerst einmal Danke für das tolle Script. Bei mir läuft es soweit einwandfrei. Ich probiere nun schon seit einer Weile die Bestriebstunden von meinen Drehzahl Relais auszulesen, was aber leider nicht klapt. Wenn ich die VBusSpecificationResolDeltaSolBXPlus.xml entsprechend bearbeite wird die Variable zwar angelegt aber nicht beschrieben. Vieleicht ist es auch nicht möglich, da ich sie mit dem Service Center auch nicht auswählen kann. Ich besitze einen RESOL BX Plus.

Vieleicht kann mir ja jemand einen Tip geben wie und ob man das lösen kann.

Danke schon mal dafür.

Gruß Torsten

Nachtrag: WMZ funktioniert auch nicht, obwohl ich in der xml WMZ auf true gesetzt habe.

Nachtrag: WMZ habe ich gelößt! Zum einen hatte ich leider die Vor- und Rücklauf sensoren vertauscht und in der xml musste ich Bytesize von 31 auf 16 ändern, seit dem funktioniert es.

Leider bin ich mit den Betriebsstunden nicht weitergekommen. Hilfe also weiterhin erwünscht :slight_smile:

Gruß und Danke
Torsten

Hallo, ich bin neu hier und wollte auch meinen Cosmo Multi 2 (0x7821) einbauen in IPS.
Daten kommen an aber er legt mit dem Script keine Variablen an.

Hat einer eine Info für mich ?

In der .xml hab ich meine Regelung nachgetragen.

In den Debug Informationen steht immer: Parameter type of Message does not match in /usr/share/symcon/scripts/51462.ips.php on line 93
Ich kann dort aber keinen Fehler entdecken.

Gruß
yodaeichen

Habs hinbekommen. Es lag an der fehlenden Reglereinstellung in vBusSpecification.
Hat nur lange gedauert bis ich drauf gekommen bin.