Hallo Community,
nach vielen Wochen probierens, viel Hoffnung und Enttäuschung und wieder Hoffnung ist er jetzt endlich da: Der RS232 <-> eBus Adapter, der Empfangen und Senden kann.
An dieser Stelle meinen herzlichen Dank an Helmut hier aus dem Forum, der unermüdlich mit mir als eBus Nutzer (Weishaupt Thermo Condens WTC-15), aber elektronischem Laien Pakete ausgetauscht, Platinen erstellt, umgelötet und zurückgesandt hat.
Einen Start in die eBus Telegrammwelt in IPS gibt es hier.
Vor einigen Monaten haben Horst und ich schon mal an der Auswertung des Protokolls mittels IPS gearbeitet. An dieser Stelle auch an Horst nochmals mein herzlicher Dank für das spontane Annehmen des Challenges (Für ihn war es dann natürlich keiner, das ging „Ratz-Fatz“). Der Code wurde mittlerweile um zwei eBus Services erweitert und sieht so aus:
<?php
if ($IPS_SENDER == 'RegisterVariable')
{
$data = RegVar_GetBuffer($IPS_INSTANCE);
$data .= $IPS_VALUE;
if (strpos($data, chr(hexdec('AA'))) !== false)
{
$datasets = explode(chr(hexdec('AA')), $data);
for ($i = 0; $i < count($datasets) - 1; $i++)
{
$dataset = $datasets[$i];
if (strlen($dataset) >= 6 && ord($dataset[4]) <= 16 && strlen($dataset) >= 6 + ord($dataset[4]))
{
$telegram = array(
'QQ' => ord($dataset[0]),
'ZZ' => ord($dataset[1]),
'DH' => ord($dataset[2]),
'DU' => ord($dataset[3]),
'NN' => ord($dataset[4]),
'DATA' => substr($dataset, 5, ord($dataset[4])),
'CRC' => ord($dataset[5 + ord($dataset[4])])
);
if (strlen($dataset) > (6 + ord($dataset[4])) && (ord($dataset[6 + ord($dataset[4])]) == 255 || ord($dataset[6 + ord($dataset[4])]) == 0))
{
$telegram['ACK'] = ord($dataset[6 + ord($dataset[4])]) == 0;
}
parseTelegram($telegram);
}
}
$data = $datasets[count($datasets) - 1];
}
RegVar_SetBuffer($IPS_INSTANCE, $data);
}
function strToHex ($str)
{
$result = '';
for ($i = 0; $i < strlen($str); $i++)
{
$result .= strtoupper(((strlen(dechex(ord($str[$i]))) < 2) ? '0' : '').dechex(ord($str[$i]))).' ';
}
return $result;
}
function parseTelegram ($telegram)
{
//print_r($telegram);
//--------------------------------------------------- Service 0507 Start -------------------------------------------------------------------------
if ($telegram['DH'] == 0x05 && $telegram['DU'] == 0x07)
{
$service = "0507";
setvalue (21450 /*[Heizung\eBus\Services\Last Read Service]*/,$service);
switch (ord($telegram['DATA'][0]))
{
case 0x00: $meldung0 = 'Brenner ausschalten'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0x01: $meldung0 = 'Keine Aktion'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0x55: $meldung0 = 'Brauchwasserbereitung'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0xAA: $meldung0 = 'Heizbetrieb'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0xCC: $meldung0 = 'Emissionskontrolle'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0xDD: $meldung0 = 'TÜV-Funktion'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0xEe: $meldung0 = 'Reglerstop-Funktion'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0x66: $meldung0 = 'Brauchwasserbereitung bei Reglerstop'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0xBB: $meldung0 = 'Brauchwasserbereitung bei Heizbetrieb'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
case 0x44: $meldung0 = 'Reglerstop-Funktion stufiger Betrieb'; setvalue(40821 /*[Heizung\eBus\Services\0507\Status Wärmeanforderung]*/,$meldung0); break;
}
switch (ord($telegram['DATA'][1]))
{
case 0x00: $meldung1 = 'Keine Aktion'; setvalue (20586 /*[Heizung\eBus\Services\0507\Status Verbraucher]*/, $meldung1); break;
case 0x01: $meldung1 = 'Ausschalten Kesselpumpe'; setvalue (20586 /*[Heizung\eBus\Services\0507\Status Verbraucher]*/, $meldung1); break;
case 0x02: $meldung1 = 'Einschalten Kesselpumpe'; setvalue (20586 /*[Heizung\eBus\Services\0507\Status Verbraucher]*/, $meldung1); break;
case 0x03: $meldung1 = 'Ausschalten variabler Verbraucher'; setvalue (20586 /*[Heizung\eBus\Services\0507\Status Verbraucher]*/, $meldung1); break;
case 0x04: $meldung1 = 'Einschalten variabler Verbraucher'; setvalue (20586 /*[Heizung\eBus\Services\0507\Status Verbraucher]*/, $meldung1); break;
}
$Kesselsollwert_Temp = decodeDATA2c($telegram['DATA'][3].$telegram['DATA'][2]);
SetValue(32429 /*[Heizung\eBus\Services\0507\Kessel Sollwert Temperatur]*/ , $Kesselsollwert_Temp);
$Kesselsollwert_Druck = decodeDATA2b($telegram['DATA'][5].$telegram['DATA'][4]);
if ($Kesselsollwert_Druck == -128) { //abfangen Ersatzwert
$Kesselsollwert_Druck = "Ersatzwert";
}
SetValue(32845 /*[Heizung\eBus\Services\0507\Kessel Sollwert Druck]*/ , $Kesselsollwert_Druck);
if (ord($telegram['DATA'][6]) == 0xff) //abfangen Ersatzwert
{
$stellgrad = 'Ersatzwert';
}
else
{
$stellgrad = ord($telegram['DATA'][7])/2;
}
setvalue(32642 /*[Heizung\eBus\Services\0507\Stellgrad]*/, $stellgrad);
$brauchwassersolltemp = ord($telegram['DATA'][7])/2;
setvalue (12110 /*[Heizung\eBus\Services\0507\Brauchwasser Sollwert Temperatur]*/, $brauchwassersolltemp);
}
// ------------------------------------------------------------------------ Service 0507 Ende -----------------------------------------------------------------
// ------------------------------------------------------------------------ Service 0700 Start ---------------------------------------------------------------
if ($telegram['DH'] == 0x07 && $telegram['DU'] == 0x00)
{
$service = "0700";
setvalue (21450 /*[Heizung\eBus\Services\Last Read Service]*/,$service);
$Heizungsaussentemp = decodeDATA2b ($telegram['DATA'][1].$telegram['DATA'][0]);
setvalue (44308 /*[Heizung\eBus\Services\0700\Aussentemperatur Heizungsfühler]*/, $Heizungsaussentemp);
}
//--------------------------------------------------------------------------- Service 0700 Ende---------------------------------------------
// ------------------------------------------------------------------------- Service 5014 start ------------------------------------------------
if ($telegram['DH'] == 0x50 && $telegram['DU'] == 0x14)
{
$service = "5014";
setvalue (21450 /*[Heizung\eBus\Services\Last Read Service]*/,$service);
$Waermeanforderung = decodeDATA2b ($telegram['DATA'][2].$telegram['DATA'][3]);
$temp_messpunkt = decodeDATA2b ($telegram['DATA'][4].$telegram['DATA'][5]);
setvalue (57840 /*[Heizung\eBus\Services\5014\Raumtemperatur FB]*/, $temp_messpunkt);
setvalue (13325 /*[Heizung\eBus\Services\5014\Wärmeanforderung]*/, $Waermeanforderung);
}
//--------------------------------------------------------------------------- Service 5014 Ende -----------------------------------------
// ab hier funktionen
}
function decodeDATA2b ($data) //data[0] = high, data[1]=low
{
$result = false;
if ((ord($data[0]) & 0x80) == 0x80)//high byte muss 0x80 sein
{
$result = - (((~ ord($data[0])) & 0x000000ff) + ((((~ ord($data[1])) & 0x000000ff) + 1) / 256));
}
else
{
$result = (ord($data[0]))+ (ord($data[1])/256) ; // High Byte plus (Low Byte / 256)
}
return $result;
}
function decodeDATA2c ($data)
{
$result = false;
if ((ord($data[0]) & 0x80) == 0x80)
{
$result = - ((((~ ord($data[0])) & 0x000000ff) * 16) + (((~ ord($data[1])) & 0x000000f0) >> 4) + ((((~ ord($data[1])) & 0x0000000f) + 1) / 16));
}
else
{
$result = (ord($data[0]) * 16) + ((ord($data[1]) & 0xf0) >> 4) + ((ord($data[1]) & 0x0f) / 16);
}
return $result;
}
?>
In diesem Skript werden die Services 0507, 0700, und 5014 ausgewertet (Siehe Bild). Die Daten kommen per RegisterVariable ins Skript. Die o.g. Services sind nicht Herstellerspezifisch, d.h. die Datenbytes und Typen sind offengelegt, und werden vor allem ohne einen zu sendenden „Trigger“ Befehl zyklisch über den Bus versand.
Im eBus Protokoll gibt es aber auch Telegramme die nur auf Anforderung versand werden. Ein solcher Service ist 0902. Dieser liegt im nicht veröffentlichten Teil des eBus Protokolls. Durch Vergleichen der Daten auf dem Bus und in meiner Weishaupt Software ist es mir gelungen einige Bytes zu entschlüsseln.
Gelesenes Paket Request Teil Nutzdatenteil Auswertung
FF 35 09 02 03 [b]05 00 02 [/b]55 00 02 D2 00 70 00 [b]05 00 02[/b] D2 =210 21 Grad Normal Solltemp
FF 35 09 02 03 08 00 02 AB 00 02 8C 00 FF 00 08 00 02 8C = 140 14 Grad Absenk Solltemp
FF 35 09 02 03 14 0A 02 0C 00 02 50 00 D6 00 14 0A 02 50 = 80 8 Grad Raumfrostschutz
FF 35 09 02 03 16 01 02 0F 00 02 B4 00 B0 00 16 01 02 B4 = 180 18 Grad Sommer/Winter Umschalttemp
FF 35 09 02 03 0E 01 02 44 00 02 5A 00 62 00 0E 01 02 5A =90 Steilheit 9,0
FF 35 09 02 03 13 00 02 DA 00 02 EA 01 3E 00 13 00 02 EA 01 = 234 1 Sollte lt Reihenfolge Warmwasser Soll = 49,0 Grad sein
FF 35 09 02 03 33 01 02 2C 00 02 90 01 14 00 33 01 02 90 01 = 144 1 Sollte lt Reihenfolge Warmwasser Min = 40,0 Grad sein
Und jetzt wird es spannend, weil genau jetzt braucht man einen Adapter, der auch senden kann:
Mit dem Skript
<?
$instance = 28634 /*[Serial Port eBus]*/;
function hex2str($hex)
{
$str="";
for($i=0;$i<strlen($hex);$i+=2)
{
$str.=chr(hexdec(substr($hex,$i,2)));
}
return $str;
}
// *** Groß- bzw. Kleinschreibung ist nicht relevant ***
$data = hex2str("FF350902031601020F00");
COMPort_SendText ($instance, $data);
?>
sende ich das Request Telefgramm
FF 35 09 02 03 16 01 02 0F 00
auf den Bus, als Antwort erhalte ich dann:
FF 35 09 02 03 16 01 02 0F 00 00 02 B4 00 B0
Das 0xB4 entspricht dezimal 180, das sind 18,0 Grad Sommer/Winter Umschalt-Temperatur bei meiner Heizung.
Somit müsste eBus jetzt hardware- und softwaretechnisch komplett mittels IPS auslesbar und „für mutige“ die Anlagen auch parametrierbar sein, vorausgesetzt die Telegramme sind entschlüsselt.
Weitere info’s gibt es auch im eBus Wiki hier. Auch hier wird versucht weitere Telegramme, auch für Vaillant und Solarsteuerungen zu entschlüsseln.