Abfrage & Steuerung von Viessmann Heizungen

HI Coyote,

sorry für die Nachfrage, aber bist Du mit der Implementierung des 300er Protokoll weitergekommen, die Abfragen mit den KW Protokoll laufen Dank Deiner Arbeit zwar, allerdings nicht wirklich stabil. Würde jede Art von der 300er Implementierung begrüßen, leider auch mit dem Statement bedingt durch meine Fähigkeiten nicht wirklich beitragen zu können, außer Feedback zu geben und als Tester gerne mitzuarbeiten.

Grüße
Spechtl

Ich komme sehr gut mit dieser Beschreibung zurecht.

Zum testen habe ich das genommen.

Habe versucht mal ein Testscript an eine Registervariable zu hängen und das 300er Protokoll auszutesten. Bin nicht weitergekommen. Hat jmd. schon ein php-Testscript zum Laufen gebracht?

Ich kann via php den Bus in den 300er Modus versetzen und auch wieder zurück. Ich kann dann einen Befehl zum Auslesen (z.B. Geräteart) schicken - es kommt aber nichts zurück.

Mit dem Tool zum Testen von oben kann ich auch auslesen … das ist aber nicht php …

Gruss, hcp

Hallo hcp,

ich bin selber noch in der Findungsphase. :wink:
Ich kann dir nur sagen was ich bis jetzt gemacht habe.

  1. Ich habe mir den USB-Optolink aus dem ersten Post bestellt.
  2. Den USB-Optolink habe ich in den PC eingesteckt.
    Danach hat sich das Teil selbstständig installiert mit einem USB - Serial Port Umsetzer.
    Da brauchte ich nichts für zu tun.
  3. Diesen Umsetzer habe ich so eingestellt.

  1. Danach habe ich in IPS einen Serial Port angelegt und so eingestellt.

  1. An diesem Serial Port habe ich eine Register Variable gehängt.
  2. An der Register-Variable habe ich ein Script gehängt.

  1. In IPS eine String Variable anlegen die da heißt Receive o.ä.
  2. In dem Script das die Register Variable aufruft steht das hier.

// neu empfangene Daten ablegen
$data = $_IPS['VALUE'];
 // Daten ausgeben
SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, $data);

Erster Test:
In deiner Receive Variablen sollte nun über die Com-Schnittstelle das hier kommen

Schritt_4.png

Die Uhrzeit sollte sich alle 2-3 Sekunden aktualisieren.

Dieser Strich den Du in der Variablen siehst ist das Ascii-Zeichen für „0x05 Hex“ der sogenannte Viessmann-Ping.

Wenn Du so weit bist geht es weiter!!! :slight_smile:

Das klappt bei mir auch. Kann dann auch den Bus in den 300er Modus setzen indem ich 0x16 0x00 0x00 gleich nach einem 0x05 Empfang sende. Bekomme dann auch wie erwartet die 0x06 als Antwort. Wenn ich danach aber etwas sende bekomme ich keine vernünftige Antwort … da hänge ich …

Das ist klar. Die Antwort kommt in mehreren häppchen.

Bei mir sieht das Empangsscript so aus:


<?
/*=============================================================
ViessmannOut - Martin Heinzel - 05.02.2013
Version: 0.1

Beschreibung:
Dieses Script wird von der Registervariablen gestartet.
Hier wird der Empfang der Daten gehändelt und in eine
Empfangsvariablen abgelegt.


Änderungen
----------

tt.mm.jjjj von Version x.x -> y.y

Beschreibung:

================================================================*/

// Variablen Deklaration --------------------------------------

// ID's
//--------------
$ID_Connect_Done  					=  38994 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Connect_Done]*/;
$SID_ViessmannEmpfangen          =  33859 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\ViesmannEmpfangen]*/;

// Variablen
//--------------
$Connect    		=  GetValueBoolean(47954 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Connect]*/);
$Receive_lenght   =  GetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/);

// Konstanten
//--------------


//-------------------------------------------------------------

require IPS_GetKernelDir()."scripts\\ViessmannVariablen.ips.php";

//--------------------------- Main ----------------------------

// wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
if ($_IPS['SENDER'] == "RegisterVariable")
{
	// kontrolle der empfangenen Daten auf den Viessmann "PING"
	if($_IPS['VALUE'] == VIESS_PING)
	{

	    // neu empfangene Daten ablegen
	    $data = $_IPS['VALUE'];
	    // Inhalt des Puffer der RegisterVariable-Instanz löschen
	    RegVar_SetBuffer($_IPS['INSTANCE'], "");
		 // Daten ausgeben
       SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, $data);
		 // Verbindung zu Viessmann ist abgebaut
		 SetValueBoolean($ID_Connect_Done, false);
		 // TimeOut Zeit zurücksetzen
		IPS_SetScriptTimer($SID_ViessmannEmpfangen , 0);
		// Wenn verbunden werden soll dann
		if($Connect)
		{
		   // verbinden
			COMPort_SendText(43855 /*[Viessmann]*/, IPS_CONNECT );
		}

	}
	else
	{

		if(substr($_IPS['VALUE'], 0, 1) == VIESS_CONNECTED)
		{
			// Verbindung zu Viessmann ist aufgebaut
			SetValueBoolean($ID_Connect_Done, true);
			// Inhalt des Puffer der RegisterVariable-Instanz löschen
		   RegVar_SetBuffer($_IPS['INSTANCE'], "");
		}

	    // bereits im Puffer der Instanz vorhandene Daten in $data kopieren
	    $data  = RegVar_GetBuffer($_IPS['INSTANCE']);
	    // neu empfangene Daten an $data anhängen
	    $data .= $_IPS['VALUE'];
     	 // Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
    	RegVar_SetBuffer($_IPS['INSTANCE'], $data);

      if(strlen($data) == $Receive_lenght or $Receive_lenght == 0)
		{
			 // ausgeben der Daten
   	    SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, $data);
		}
	}
}

//------------------------- Main ENDE --------------------------
?>

Das ist das Script ViessmannVariablen.ips.php


<?
/*=============================================================
Script - ViessmannVariablen - 03.02.2013
Version: 0.1

Beschreibung:
In diesem Script werden die Viessmann - Konstaten definiert.

Änderungen
----------

tt.mm.jjjj von Version x.x -> y.y

Beschreibung:

================================================================*/

// Variablen Deklaration --------------------------------------

// Konstanten
//--------------
// Empfangen
define( "VIESS_PING",             						chr(0x05));
define( "VIESS_COMERR",           						chr(0x15));
define( "VIESS_CONNECTED",        						chr(0x06));

// Senden
define( "IPS_CONNECT",          							chr(0x16).chr(0x00).chr(0x00));
define( "IPS_DISCONNECT",       							chr(0x04));

// Senden Telegramme
define( "IPS_Temp_Aussen_ACT",             			chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x55).chr(0x25). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0x82));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

define( "IPS_Temp_Kessel_ACT",         				chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x08).chr(0x10). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0x20));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

define( "IPS_Temp_Kessel_SET",         				chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x55).chr(0x5A). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0xB7));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

define( "IPS_Temp_Speicher_ACT",        				chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x08).chr(0x12). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0x22));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

define( "IPS_Temp_Speicher_SET",        				chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x63).chr(0x00). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0x6B));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

define( "IPS_Temp_Vorlauf_ACT",          				chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x29).chr(0x00). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0x31));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

define( "IPS_Temp_Vorlauf_SET",          				chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x25).chr(0x44). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0x71));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

define( "IPS_Temp_Ruecklauf_ACT",      				chr(0x41). 				// Telegramm Start-Byte
																	chr(0x05). 				// Länge der Nutzdaten
																	chr(0x00). 				// 00 = Anfrage, 01 = Antwort, 03 = Fehler
																	chr(0x01). 				// 01 = ReadData, 02 = WriteData, 07 = Function Call
																	chr(0x08).chr(0x08). // 2 byte Adresse der Daten oder Prozedur
																	chr(0x02). 				// Anzahl der Bytes, die in der Antwort erwartet werden
																	chr(0x18));				// Prüfsumme = Summe der Werte ab dem 2 Byte (ohne 41)

//-------------------------------------------------------------
?>

Skript läuft und empfängt die Pings. Was kommt als nächstes?

Hab nun gestern meinen Adapter in Betrieb genommen.
Habe beide Scriptvarianten ausprobiert und verwende nun die Scripts aus dem ersten Post.
Damit habe ich problemlos die Abfrage von Werten hinbekommen.
Meine Anlage ist eine VPlusHO1 (20C8).
Mache mich dann mal an das Logging von Daten und die ersten Einstellungen.
Falls es updates gibt oder ich helfen kann, laßt es mich wissen.

Gruß Thomas

Hi Schablone,

bin Deiner Anregung gefolgt und versuche auf diesen Weg das Protokoll meiner Abfrage umzustellen. Habe mich an Deine Instruktionen gehalten, aber nachdem das alles für mich immer noch ein großes Rätsel darstellt, bin ich wohl auf Deine Hilfe in Form von den weiteren Schritten angewiesen.

Danke
Spechtl

Ich bin noch bei einer IBN in Holland (Bergen). Wenn ich es schaffe, werde ich am Wochenende das, was ich bis jetzt habe einstellen. Ich bin aber selber noch nicht ganz fertig!

Nur zur Info:

Als nächstes wird das Online-Bit gesetzt. Dann geht das Vissmann Out Script nach dem nächsten Ping auf „Verbinden“. Danach Geht die Vissmann auf 06 hex.

Dann ist die Vissmann bereit Anfragen zu beantwortet.

Die Anfragen die ich für meine Heizung senden kann, stehen in den Konstanten die ich bereits gepostet habe.

Gesendet von meinem GT-I9100 mit Tapatalk 2

Hallo Spechtel,

wie versprochen meine Scripte:

Das Senden Script:


<?
/*=============================================================
ViessmannSenden - Martin Heinzel - 05.02.2013
Version: 0.1

Beschreibung:
Mit diesem Script werden Daten gesendet


Änderungen
----------

tt.mm.jjjj von Version x.x -> y.y

Beschreibung:

================================================================*/

// Variablen Deklaration --------------------------------------

// ID's
//--------------
$ID_Connect             					=  47954 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Connect]*/;
$ID_Connect_Done  							=  38994 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Connect_Done]*/;
$ID_Token                              =  24085 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Token]*/;

// Variablen
//--------------
$Connect_Done           					=  GetValueBoolean($ID_Connect_Done);
$Connect                					=  GetValueBoolean($ID_Connect);
$Token                                 =  GetValueInteger($ID_Token);

// Konstanten
//--------------


//-------------------------------------------------------------

require IPS_GetKernelDir()."scripts\\ViessmannVariablen.ips.php";

//--------------------------- Main ----------------------------

// Verbindung zu Viessmann herstellen
if(!$Connect_Done and !$Connect)
{
	SetValueBoolean($ID_Connect, true);
}

// Verbindung zu Viessmann OK
if($Connect_Done)
{

	Switch($Token)
	{
	//#########  Temperaturen ##################
	case 1:
		// abfragen der Aussentemperatur
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
 		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Aussen_ACT );
		break;

	case 2:
		// abfragen der Kesseltemperatur ACT
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Kessel_ACT );
		break;

	case 3:
		// abfragen der Kesseltemperatur SET
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Kessel_SET );
		break;

	case 4:
		// abfragen der Speichertemperatur ACT
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Speicher_ACT );
		break;

	case 5:
		// abfragen der Speichertemperatur SET
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Speicher_SET );
		break;

	case 6:
		// abfragen der Vorlauftemperatur ACT
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Vorlauf_ACT );
		break;

	case 7:
		// abfragen der Vorlauftemperatur SET
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Vorlauf_SET );
		break;

	case 8:
		// abfragen der Rücklauftemperatur ACT
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Temp_Ruecklauf_ACT );
		break;

	case 9:
		// abfragen der Betriebsart ACT
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 11);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Betriebsart_ACT );
		break;

	case 10:
		// abfragen der Brennerstarts ACT
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 13);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Brenner_Starts_ACT );
		break;

	case 11:
		// abfragen der Brenner Stunden ACT
		SetValueString(39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/, "");
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 13);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_Brenner_Stunden_ACT );
		break;

	case 12:
		// Verbindung zu Viessmann abbauen
		SetValueBoolean($ID_Connect, false);
		SetValueInteger(21524 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_lenght]*/, 0);
		SetValueInteger($ID_Token, 0);
		COMPort_SendText(43855 /*[Viessmann]*/, IPS_DISCONNECT );
		//IPS_SetScriptTimer($_IPS['SELF'], 30);
	}
}

//------------------------- Main ENDE --------------------------

?>

Das Empfangen Script:


<?
/*=============================================================
ViessmannEmpfangen - Martin Heinzel - 05.02.2013
Version: 0.1

Beschreibung:
Dieses Script wertet die Empfangenen Daten der Viessmann aus.


Änderungen
----------

tt.mm.jjjj von Version x.x -> y.y

Beschreibung:

================================================================*/

// Variablen Deklaration --------------------------------------

// ID's
//--------------
$ID_Receive          						=  39800 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive]*/;
$ID_Connect     					         =  47954 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Connect]*/;
$ID_Connect_Done  							=  38994 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Connect_Done]*/;
$ID_Token                              =  24085 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Token]*/;
$ID_TimeOutCounter                     =  17928 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\TimeOutCounter]*/;
$ID_CommFaultCounter                   =  34278 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\CommFaultCounter]*/;
$ID_TimeOut                            =  38680 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\TimeOut]*/;
$SID_ViessmannSenden              		=  25080 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\ViessmannSenden]*/;
$ID_Temp_Aussen_ACT				         =  40248 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Aussen_ACT]*/;
$ID_Temp_Kessel_ACT				         =  30466 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Kessel_ACT]*/;
$ID_Temp_Kessel_SET				         =  12619 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Kessel_SET]*/;
$ID_Temp_Speicher_ACT				      =  27117 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Speicher_ACT]*/;
$ID_Temp_Speicher_SET				      =  22278 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Speicher_SET]*/;
$ID_Temp_Vorlauf_ACT			            =  48976 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Vorlauf_ACT]*/;
$ID_Temp_Vorlauf_SET			            =  35626 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Vorlauf_SET]*/;
$ID_Temp_Ruecklauf_ACT				      =  43689 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Temp_Ruecklauf_ACT]*/;
$ID_Betriebsart_ACT                    =  50731 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Betriebsart_ACT]*/;
$ID_Brennerstarts_ACT                  =  40380 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Brennerstarts_ACT]*/;
$ID_Brenner_Stunden_ACT                =  42523 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\Receive_Data\Brenner_Stunden_ACT]*/;

// Variablen
//--------------
$Receive 										=  GetValueString($ID_Receive);
$Connect_Done           					=  GetValueBoolean($ID_Connect_Done);
$Connect                					=  GetValueBoolean($ID_Connect);
$Token                                 =  GetValueInteger($ID_Token);
$Receive_Byte        						=  array();
$TimeOutCounter                     	=  GetValueInteger($ID_TimeOutCounter);
$CommFaultCounter                   	=  GetValueInteger($ID_CommFaultCounter);

// Konstanten
//--------------


//-------------------------------------------------------------

//--------------------------- Main ----------------------------

// Byteweise einlesen der Daten
for ($i = 0; $i < strlen($Receive); $i++)
{
	// wandeln der einzelnen Zeichen von String in Hex
	$Receive_Byte[$i] =  dechex(ord(substr($Receive ,$i)));
	//echo $Receive_Byte[$i]. "
";
}

// Wenn die Checksumme OK ist
if(checksum($Receive_Byte) == $Receive_Byte[strlen($Receive)-1])
{

   //zurücksetzen des TimeOut Counters
	SetValueInteger($ID_TimeOutCounter, 0);
	//rücksetzen des TimeOut Flag
	SetValueBoolean($ID_TimeOut, false);

	Switch($Token)
	{
	//#########  Temperaturen ##################
	case 1:
		// Auslesen der Aussentemperatur
		ViesmannTemp($Receive_Byte, $ID_Temp_Aussen_ACT);
		SetValueInteger($ID_Token, 2);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 2:
		// Auslesen der Kesseltemperatur ACT
		ViesmannTemp($Receive_Byte, $ID_Temp_Kessel_ACT);
		SetValueInteger($ID_Token, 3);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 3:
		// Auslesen der Kesseltemperatur SET
		ViesmannTemp($Receive_Byte, $ID_Temp_Kessel_SET);
		SetValueInteger($ID_Token, 4);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 4:
		// Auslesen der Speichertemperatur ACT
		ViesmannTemp($Receive_Byte, $ID_Temp_Speicher_ACT);
		SetValueInteger($ID_Token, 5);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 5:
		// Auslesen der Speichertemperatur SET
		ViesmannTemp($Receive_Byte, $ID_Temp_Speicher_SET);
		SetValueInteger($ID_Token, 6);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 6:
		// Auslesen der Vorlauftemperatur ACT
		ViesmannTemp($Receive_Byte, $ID_Temp_Vorlauf_ACT);
		SetValueInteger($ID_Token, 7);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 7:
		// Auslesen der Vorlauftemperatur SET
		ViesmannTemp($Receive_Byte, $ID_Temp_Vorlauf_SET);
		SetValueInteger($ID_Token, 8);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 8:
		// Auslesen der Rücklauftemperatur ACT
		ViesmannTemp($Receive_Byte, $ID_Temp_Ruecklauf_ACT);
		SetValueInteger($ID_Token, 9);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 9:
		// Auslesen der Betriebsart ACT
		Switch($Receive_Byte[8])
		{
			case 0:
			SetValueString($ID_Betriebsart_ACT, "Aus");
			break;

			case 1:
			SetValueString($ID_Betriebsart_ACT, "Warmwasser");
			break;

			case 2:
			SetValueString($ID_Betriebsart_ACT, "Warmwasser + Heizen");
		}
		SetValueInteger($ID_Token, 10);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 10:
		ViesmannCount($Receive_Byte, $ID_Brennerstarts_ACT);
		SetValueInteger($ID_Token, 11);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
		break;

	case 11:
		$Count_HEX 	= $Receive_Byte[11].$Receive_Byte[10].$Receive_Byte[9].$Receive_Byte[8];
		$Counter 	= hexdec($Count_HEX)/3600;
		SetValueInteger($ID_Brenner_Stunden_ACT, (int)$Counter);
		SetValueInteger($ID_Token, 12);
		IPS_SetScriptTimer($_IPS['SELF'], 5);
	}
}

// Wenn die Verbindung zu Viessmann herstellt ist
if($Connect_Done and $Connect and ($Token == 0))
{
	//Erste Abfrage starten
	SetValueInteger($ID_Token, 1);
	IPS_SetScriptTimer($_IPS['SELF'], 5);
	IPS_SetScriptTimer($SID_ViessmannSenden, 0);
}

// TimeOut
if($_IPS['SENDER'] == "TimerEvent")
{

	//Erhöhen des TimeOut
	if($TimeOutCounter <= 2)
	{
      $TimeOutCounter   += 1;
		SetValueInteger($ID_TimeOutCounter, $TimeOutCounter);
		IPS_RunScript(25080 /*[Schäferweg\Dachgeschoss\Heizungsraum\Viessmann Heizung\ViessmannSenden]*/);
	}
	else
	{
	   //zurücksetzen des TimeOut Counters
		SetValueInteger($ID_TimeOutCounter, 0);
		//erhöhen des gesamten Fault counters
		$CommFaultCounter += 1;
		SetValueInteger($ID_CommFaultCounter, $CommFaultCounter);
		//setzen des TimeOut Flag
		SetValueBoolean($ID_TimeOut, true);
		//erhöhen des Token
		if($Token <= 12)
		{
		   $Token   += 1;
		   SetValueInteger($ID_Token , $Token);
		}
		else
		{
			// Verbindung zu Viessmann beenden
			SetValueBoolean($ID_Connect_Done, false);
		}
	}
}

//------------------------- Main ENDE --------------------------

//------------------------ Funktionen -------------------------

/**
 * Returns the calculated checksum.
 *
 * @param  Byte_array $Receive_Byte Array of the received Bytes
 * @return Calculated checksum in hex
 */
function checksum($Receive_Byte)
{

	// Prüfen der Lämge
	$Receive_lenght      =     count($Receive_Byte);
	// initialisieren der Checksumme
	$checksum            =  0;

	// Aufaddieren der Byte's
	for ($i = 2; $i < $Receive_lenght-1; $i++)
	{
		$checksum			+=	hexdec($Receive_Byte[$i]);
  	}

	// wandeln in hex und ausgeben der ersten beiden Zeichen
  	$checksum_hex        = substr(dechex($checksum), -2);
  	//if(substr($checksum_hex, 0) == 0)
  	//{
	//  	$checksum_hex     = substr(dechex($checksum), -1);
	//}
	return $checksum_hex;
}

function ViesmannTemp($Receive_Byte, $ID)
{
	$Temp_HEX = $Receive_Byte[9].$Receive_Byte[8];
	$Temperatur = hexdec($Temp_HEX)/10.0;
	SetValueFloat($ID, $Temperatur);
}

function ViesmannCount($Receive_Byte, $ID)
{
	$Count_HEX 	= $Receive_Byte[11].$Receive_Byte[10].$Receive_Byte[9].$Receive_Byte[8];
	$Counter 	= hexdec($Count_HEX);
	SetValueInteger($ID, $Counter);
}

//--------------------- Funktionen ENDE ------------------------

?>

Das sind noch keine fertigen Scripte!!

Es sind nur Beispiele wie man Sendet und Empfängt.

Anbei auch die aktuelle Version meiner Scripte inkl. einer XML für die 20C8.
Basieren immer noch auf der Version von coyote aus dem ersten Post.
Habe bei der Behandlung von Count noch was geändert, damit die Betriebsstunden richtig übergeben werden.
Ebenso hatte ich öfter Viessmann_Ping (0x05) statt Werten in meinen Variablen und werfe die nun weg.
Damit lese ich alle 5 min Betriebswerte aus (im Script Viessmann_Send).
Zum Schreiben von Werten bin ich noch nicht gekommen.

mfg
Thomas

Viessmann.zip (5.96 KB)

Also ich nutze auch die Version aus dem ersten Post. Hatte auch ähnliche Probleme wie Thomas.
Bei mir läuft das Script in 4 Anlagen.

Guten Morgen!!

Ich habe ein paar Fragen zu meiner Viessmann Model „Vitodens 300-W“.

Ich arbeite am 300er Protokoll.
Meine Gerätekennung ist die „20CB“.

Ich habe nicht die richtige Adresse für den Warmwasser-Sollwert.
Ich benutze die „chr(0x63).chr(0x00)“ und bekomme immer nur einen Wert von 5°C.
Hat da jemand eine andere Adresse?

Die Zirkulationspumpe (Adresse chr(0x65).chr(0x15)) ist mir nicht ganz klar.
a. Ist das die Externe Pumpe für Warmwasser oder die Heizungs(Heizkreise)pumpe?
b. Stimmt meine Adresse chr(0x65).chr(0x15)?

Für eure Hilfe besten Dank!!

Das Skript läuft bei mir prima und ich würde das gerne als Basis nehmen um weiterzubauen. Das Empfangsskript triggert alle 5 sec und hört damit nicht mehr auf. Sollte das nicht stoppen nachdem alle Daten einmal abgefragt wurden?

Gruss, hcp

Hallo hcp,

die Vissmann sendet alle 2-3 Sekunden einen Vissmann-Ping.
Ich bin selber noch nicht wesentlich weiter mit dem Scrip.
Mir fehlen noch einige Datenpunkte in der Steuerung. Siehe Post über dir.
Ich bin momentan auf Teneriffa. Nächste Woche bin ich wieder zu Hause.

Hallo Schablone,

Deine Skripte für das 300er Protokoll sehen gefallen mir recht gut. Bevor ich anfange sie für mich zu adaptieren wollte ich mal nachhören ob Du mit den Skripten weitergekommen bist,

Danke und Grüsse,

Martin

Hallo Martin,

Besten Dank.

Nein bin ich nicht. Ich bin beruflich immer noch unter Dampf.
Des weiteren fehlen mir immer noch ein paar Datenpunkte (siehe oben).

Das Prinzip ist aber klar. Wenn ich nachher alles zusammen habe, möchte ich jede Minute(als Beispiel)
alle Datenpunkte per „Token ring“ abfragen.

Wenn nur einer meine Frage beantworten könnte!! :o

Ich finde den verdammten Datenpunkt nicht.

Moin zusammen,

also eine korrekte Datenpunktliste zu bekommen ist unglaublich schwierig, selbst mit einigen Kontakte direkt bei Viessmann rücken die diese Liste nicht heraus. Die einzige Chance wäre wirklich die Originalsoftware von Viessmann mit einem Optolinkadpater einzusetzen und dazwischen einen Sniffer zu stecken der das Protokoll mitplottet.

Ich habe mir bei http://openv.wikispaces.com jede Menge Adressen rausgesucht und per Trail & Error Werte rausgesucht. Ich habe bei uns drei Anlagen per LON verbunden wie auch ein Modem für die Fernüberwachung. Das gibt mir die Möglichkeit eine Adresse auszuprobieren und am Modem bzw. an der Viessmann HP die Werte zu kontrollieren. Ich habe versucht über ein Optolink auf alle Anlagen zuzugreifen. Scheinbart geht das aber nicht. Also gibt es bei mir 3 Optolinkadapter die über ein Lan/USB Device an meinen virtuellen Server angebunden werden. Ich nutze das Script aus dem ersten Post mit einigen Modifikationen. Kann ich gerne mal posten! Wie auch meine funktionierende XML für verschiedene Anlagen.

Gruß Bastian

Hallo Bastian,

Genau so mache ich das auch.

Das wäre echt lieb von Dir! :slight_smile: