Helios KWL EC 300 PRO

Versuch es mal so:


case "\x01\x11\x20\x35": // Zuluft Temperatur
	$Zuluft=substr($data,4,1);// Temperatur ausfiltern
	$ZuluftTemp = ord($Zuluft); // Chr in Dezimal umwandeln
	$Status = floatval($Temperatur[$ZuluftTemp]);
	$Status1 = GetValue(26273); // aktuelle Temperatur auslesen
	if ($Status <> $Status1) // Temperatur nur bei änderung schreiben
	SetValue(26273, $Status);
break;

Das Skript funktioniert auch, und man spart sich noch die Dummy Variable.

Jedoch kann ich nur einige Bits auslesen und die Lüfterstufe klappt garnicht.

tja so kann ich dir nicht helfen…
einmal funktioniert der Script nicht dann kannst nichts auslesen, Poste alles was du gemacht hast (Scripte, Variablen, Splitter…)

Es geht doch nur so:

case "\x01\x11\x20\x35": // Zuluft Temperatur
	$Zuluft=substr($data,4,1);// Temperatur ausfiltern
	$ZuluftTemp = ord($Zuluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$ZuluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(17327 /*[Schnittstellen\KWL\KWL Temp Zuluft\Zuluft innen]*/); // aktuelle Temperatur auslesen
	if ($Status <> $Status1) // Temperatur nur bei änderung schreiben
	SetValue(26273 /*[Schnittstellen\KWL\KWL Temp Zuluft\Zuluft innen]*/, $Status);
break;

Obwohl das Skript anfängt zu funktionieren, gibt es folgende Meldungen. Es sind komischerweise immer die Dummy Module der Booleans…

09.05.2016 13:48:20*| Register Variable*| <br />
<b>Warning</b>:  Variable #22662 existiert nicht in <b>/var/lib/symcon/scripts/41100.ips.php</b> on line <b>202</b><br />
<br />
<b>Warning</b>:  Variable #35477 existiert nicht in <b>/var/lib/symcon/scripts/41100.ips.php</b> on line <b>228</b><br />
<br />
<b>Warning</b>:  Variable #44606 existiert nicht in <b>/var/lib/symcon/scripts/41100.ips.php</b> on line <b>239</b><br />
<br />
<b>Warning</b>:  Variable #34710 existiert nicht in <b>/var/lib/symcon/scripts/41100.ips.php</b> on line <b>250</b><br />
<br />
<b>Warning</b>:  Variable #22398 existiert nicht in <b>/var/lib/symcon/scripts/41100.ips.php</b> on line <b>261</b><br />
<br />
<b>Warning</b>:  Variable #58948 existiert nicht in <b>/var/lib/symcon/scripts/41100.ips.php</b> on line <b>267</b><br />
<?

$ID_Betrieb = 57584 /*[Schnittstellen\KWL\KWL Betrieb\Betrieb]*/;
//$CO2_Status = 20745 /*[Objekt #20745 existiert nicht]*/;
//$Luftfeuchte_Status = 36528 /*[Objekt #36528 existiert nicht]*/;
$Heizung_Status = 38671 /*[Schnittstellen\KWL\KWL Heizung Status\Heizung Status]*/;
$Filter_Status = 54659 /*[Schnittstellen\KWL\KWL Filterwechsel\Filterwechsel]*/;
$Heizung_Indikator = 24032 /*[Schnittstellen\KWL\KWL Heating indikator\Heizung indicator]*/;
$Fehler_Indikator = 15349 /*[Objekt #15349 existiert nicht]*/;
$Service = 26131 /*[Schnittstellen\KWL\KWL Service\Service]*/;


$ID_Luefterstufe = 51581 /*[Objekt #51581 existiert nicht]*/;
$ID_Aussenluft =25558 /*[Schnittstellen\KWL
icht benötigt\KWL Abluft Status\Aussenluft Status]*/;
$ID_Fortluft =39025 /*[Schnittstellen\KWL
icht benötigt\KWL Fortluft Status\Fortluft Status]*/;
$ID_Abluft =26336 /*[Schnittstellen\KWL
icht benötigt\KWL Lüfterstufe Status\Lüfterstufe Status]*/;
$ID_Zuluft =46208 /*[Schnittstellen\KWL
icht benötigt\KWL Zuluft Status\Zuluft Status]*/;

$ID_Temp = 53257 /*[Schnittstellen\KWL\Speicher]*/;

// Tabelle zur Temperatur Umrechnung
$Temperatur = array(
"-74", "-70", "-66", "-62", "-59", "-56", "-54", "-52", "-50", "-48", "-47",
"-46", "-44", "-43", "-42", "-41", "-40", "-39", "-38", "-37", "-36", "-35",
"-34", "-33", "-33", "-32", "-31", "-30", "-30", "-29", "-28", "-28", "-27",
"-27", "-26", "-25", "-25", "-24", "-24", "-23", "-23", "-22", "-22", "-21",
"-21", "-20", "-20", "-19", "-19", "-19", "-18", "-18", "-17", "-17", "-16",
"-16", "-16", "-15", "-15", "-14", "-14", "-14", "-13", "-13", "-12", "-12",
"-12", "-11", "-11", "-11", "-10", "-10", "-9", "-9", "-9", "-8", "-8", "-8",
"-7", "-7", "-7", "-6", "-6", "-6", "-5", "-5", "-5", "-4", "-4", "-4", "-3",
"-3", "-3", "-2", "-2", "-2", "-1", "-1", "-1", "-1", "0", "0", "0", "1", "1",
"1", "2", "2", "2", "3", "3", "3", "4", "4", "4", "5", "5", "5", "5", "6", "6",
"6", "7", "7", "7", "8", "8", "8", "9", "9", "9", "10", "10.3", "10.6", "11", "11.3",
"11.6", "12.0", "12.3", "12.6", "13.0", "13.3", "13.6", "14.0", "14.3", "14.6", "15.0", "15.3", "15.6",
"16.0", "16.3", "16.6", "17.3", "17.6", "18.0", "18.3", "18.6", "19.0", "19.3", "19.6", "20.0", "20.5",
"21.0", "21.3", "21.6", "22.0", "22.3", "22.6", "23.0", "23.5", "24.0", "24.3", "24.6", "25.0", "25.5",
"26.0", "26.5", "27.0", "27.3", "27.6", "28.0", "28.5", "29.0", "29.5", "30.0", "30.5", "31.0", "31.5",
"32.0", "32.5", "33.0", "33.5", "34.0", "34.5", "35.0", "35.5", "36.0", "36.5", "37.0", "37.5", "38.0",
"38.5", "39", "40.0", "40.5", "41.0", "41.5", "42", "43.0", "43.5", "44", "45", "45", "46",
"47", "48", "48", "49", "50", "51", "52", "53", "53", "54", "55", "56", "57",
"59", "60", "61", "62", "63", "65", "66", "68", "69", "71", "73", "75", "77",
"79", "81", "82", "86", "90", "93", "97", "100", "100", "100", "100", "100",
"100", "100", "100", "100");

// wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
if ($_IPS['SENDER'] == "RegisterVariable")
{
    // 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'];

// Befehle zum Regeln der Lüfterstufe
#Stufe1 | "\01\x11\x10\x29\x01\x4C"
#Stufe2 | "\01\x11\x10\x29\x03\x4E"
#Stufe3 | "\01\x11\x10\x29\x07\x52"
#Stufe4 | "\01\x11\x10\x29\x0F\x5A"
#Stufe5 | "\01\x11\x10\x29\x1F\x6A"
#Stufe6 | "\01\x11\x10\x29\x3F\x8A"
#Stufe7 | "\01\x11\x10\x29\x7F\xCA"
#Stufe8 | "\01\x11\x10\x29\xFF\x4A"

// Lüfterstufe Status auslesen

$Funktion=substr($data,0,6);// Funktion ausfiltern

switch($Funktion)
{
case "\x01\x11\x10\x29\x01\x4C": // Lüfterstufe 1
SetValue($ID_Luefterstufe , 1);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 1)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 1);
}

break;
case "\x01\x11\x10\x29\x03\x4E": // Lüfterstufe 2
SetValue($ID_Luefterstufe , 2);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 2)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 2);
}
break;
case "\x01\x11\x10\x29\x07\x52": // Lüfterstufe 3
SetValue($ID_Luefterstufe , 3);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 3)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 3);
}
break;
case "\x01\x11\x10\x29\x0F\x5A": // Lüfterstufe 4
SetValue($ID_Luefterstufe , 4);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 4)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 4);
}
break;
case "\x01\x11\x10\x29\x1F\x6A": // Lüfterstufe 5
SetValue($ID_Luefterstufe , 5);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 5)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 5);
}
break;
case "\x01\x11\x10\x29\x3F\x8A": // Lüfterstufe 6
SetValue($ID_Luefterstufe , 6);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 6)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 6);
}
break;
case "\x01\x11\x10\x29\x7F\xCA": // Lüfterstufe 7
SetValue($ID_Luefterstufe , 7);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 7)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 7);
}
break;
case "\x01\x11\x10\x29\xFF\x4A": // Lüfterstufe 8
SetValue($ID_Luefterstufe , 8);
$Stufe = GetValue (54152 /*[Schnittstellen\KWL\KWL Lüfterstufe]*/);
if ($Stufe <> 8)
{
SetValue(51581 /*[Objekt #51581 existiert nicht]*/, 8);
}
break;
}

##############
#KWL schreibt zu allen Zuluft Temperatur 35
#01 11 20 35 9E 05

#KWL schreibt zu allen Abluft Temperatur 34
#01 11 20 34 A0 06

#KWL schreibt zu allen Fortluft Temperatur 33
#01 11 20 33 8E F3

#KWL schreibt zu allen Außenluft Temperatur 32
#01 11 20 32 87 EB

#return;
// Temperaturen auslesen

$Funktion1=substr($data,0,4);// Funktion ausfiltern

switch($Funktion1)
{
case "\x01\x11\x20\x35": // Zuluft Temperatur
	$Zuluft=substr($data,4,1);// Temperatur ausfiltern
	$ZuluftTemp = ord($Zuluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$ZuluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(17327 /*[Schnittstellen\KWL\KWL Temp Zuluft]*/); // aktuelle Temperatur auslesen
	if ($Status <> $Status1) // Temperatur nur bei änderung schreiben
	SetValue(26273 /*[Schnittstellen\KWL\KWL Temp Zuluft\Temp Zuluft innen]*/, $Status);
break;

case "\x01\x11\x20\x34": // Abluft Temperatur
	$Abluft=substr($data,4,1);// Temperatur ausfiltern
	$AbluftTemp = ord($Abluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$AbluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(59104 /*[Schnittstellen\KWL\KWL Temp Abluft]*/); //
	if ($Status <> $Status1)
	SetValue(47538 /*[Schnittstellen\KWL\KWL Temp Abluft\Abluft innen]*/, $Status);
break;

case "\x01\x11\x20\x33": // Fortluft Temperatur
	$Fortluft=substr($data,4,1);// Temperatur ausfiltern
	$FortluftTemp = ord($Fortluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$FortluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(55503 /*[Schnittstellen\KWL\KWL Temp Fortluft]*/); //
	if ($Status <> $Status1)
	SetValue(45899 /*[Schnittstellen\KWL\KWL Temp Fortluft\Fortluft aussen]*/, $Status);
break;

case "\x01\x11\x20\x32": // Außenluft Temperatur
	$Aussenluft=substr($data,4,1);// Temperatur ausfiltern
	$AussenluftTemp = ord($Aussenluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$AussenluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(24148 /*[Schnittstellen\KWL\KWL Temp Aussenluft]*/); //
	if ($Status <> $Status1)
	SetValue(21161 /*[Schnittstellen\KWL\KWL Temp Aussenluft\Aussenluft]*/, $Status);
break;

case "\x01\x11\x21\xA3": // Anlagen Status
	$Status=substr($data,4,1);// Status ausfiltern
	$StatusDez = ord($Status);

if (getBitState($StatusDez, 0))  // KWL Betriebsstatus an Bit0 auslesen
	{
   if (getValue(22662 /*[Schnittstellen\KWL\KWL Betrieb]*/) == false)
	SetValue(57584 /*[Schnittstellen\KWL\KWL Betrieb\Betrieb]*/, true);
	}
	else
	{
   if (getValue(22662 /*[Schnittstellen\KWL\KWL Betrieb]*/) == true)
	SetValue(57584 /*[Schnittstellen\KWL\KWL Betrieb\Betrieb]*/, false);
	}

#if (getBitState($StatusDez, 1))  // KWL CO2 adjust state an Bit1 auslesen
    #SetValueBoolean($CO2_Status , true);
  #else
    #SetValueBoolean($CO2_Status,false);

#if (getBitState($StatusDez, 2))  // KWL %RH adjust state an Bit2 auslesen
    #SetValueBoolean($Luftfeuchte_Status , true);
  #else
    #SetValueBoolean($Luftfeuchte_Status,false);

if (getBitState($StatusDez, 3))  // KWL Heating state an Bit3 auslesen
	{
   if (getValue(35477 /*[Schnittstellen\KWL\KWL Heizung Status]*/) == false)
 	SetValue(38671 /*[Schnittstellen\KWL\KWL Heizung Status\Heizung Status]*/, true);
	}
	else
	{
	if (getValue(35477 /*[Schnittstellen\KWL\KWL Heizung Status]*/) == true)
 	SetValue(38671 /*[Schnittstellen\KWL\KWL Heizung Status\Heizung Status]*/, false);
}

if (getBitState($StatusDez, 4))  // KWL Filterguard indicator an Bit4 auslesen
	{
	if (getValue(44606 /*[Schnittstellen\KWL\KWL Filterwechsel]*/) == false)
 	SetValue(54659 /*[Schnittstellen\KWL\KWL Filterwechsel\Filterwechsel]*/, true);
	}
  	else
	{
   if (getValue(44606 /*[Schnittstellen\KWL\KWL Filterwechsel]*/) == true)
 	SetValue(54659 /*[Schnittstellen\KWL\KWL Filterwechsel\Filterwechsel]*/, false);
	}

if (getBitState($StatusDez, 5))  // KWL Heating indicator an Bit5 auslesen
	{
   if (getValue(34710 /*[Schnittstellen\KWL\KWL Heating indikator]*/) == false)
 	SetValue(24032 /*[Schnittstellen\KWL\KWL Heating indikator\Heizung indicator]*/, true);
	}
  	else
	{
   if (getValue(34710 /*[Schnittstellen\KWL\KWL Heating indikator]*/) == true)
 	SetValue(24032 /*[Schnittstellen\KWL\KWL Heating indikator\Heizung indicator]*/, false);
	}

if (getBitState($StatusDez, 6))  // KWL Fault indicator an Bit6 auslesen
	{
   if (getValue(22398 /*[Schnittstellen\KWL\KWL Fehler indikator]*/) == false)
 	SetValue(15439 /*[Schnittstellen\KWL\KWL Fehler indikator\Fehler Indicator]*/, true);
	}
	else
	{
   if (getValue(22398 /*[Schnittstellen\KWL\KWL Fehler indikator]*/) == true)
 	SetValue(15439 /*[Schnittstellen\KWL\KWL Fehler indikator\Fehler Indicator]*/, false);
	}

if (getBitState($StatusDez, 7))  // KWL Service reminder an Bit7 auslesen
	{
	if (getValue(58948 /*[Schnittstellen\KWL\KWL Service]*/) == false)
 	SetValue(26131 /*[Schnittstellen\KWL\KWL Service\Service]*/, true);
	}
	else
	{
   if (getValue(58948 /*[Schnittstellen\KWL\KWL Service]*/) == true)
 	SetValue(26131 /*[Schnittstellen\KWL\KWL Service\Service]*/, false);
	}
break;

}


}

  function getBitState($Value, $BitNo)
  {
    return (($Value & pow(2, $BitNo)) != 0);
  }

?>


Capture6.JPG

Danke für deine Hilfe

du versuchst eine Variable zu beschreiben die es nicht gibt! "SetValue(51581 /[Objekt #51581 existiert nicht]/, 1); "
nächster Fehler du versuchst das Dummy Modul zu beschreiben ID: 54152 das geht auch nicht

mach mal so:


case "\x01\x11\x10\x29\x01\x4C": // Lüfterstufe 1 
  SetValue($ID_Luefterstufe , 1); 
  $Stufe = GetValue (44368); 
  if ($Stufe <> 1) 
  { 
  SetValue(44368, 1); 
  } 
break; 

EIB und Dummy Modul mit Variablen ist nicht das selbe, du musst das Script natürlich an deine Verhältnisse anpassen

So, habe es nun doch noch hinbekommen, dank eurer Hilfe :smiley:

Hier mein modifiziertes Skript zum Lesen der Variablen:


<?

$ID_Betrieb = 57584 /*[Schnittstellen\Vallox KWL\Betrieb]*/;
$CO2_Status = 49064 /*[Schnittstellen\Vallox KWL\CO2 Status]*/;
$Luftfeuchte_Status = 26466 /*[Schnittstellen\Vallox KWL\Luftfeuchte Status]*/;
$Heizung_Status = 38671 /*[Schnittstellen\Vallox KWL\Heizung Status]*/;
$Filter_Status = 54659 /*[Schnittstellen\Vallox KWL\Filterwechsel]*/;
$Heizung_Indikator = 24032 /*[Schnittstellen\Vallox KWL\Heizung indicator]*/;
$Fehler_Indikator = 15439 /*[Schnittstellen\Vallox KWL\Fehler Indicator]*/;
$Service = 26131 /*[Schnittstellen\Vallox KWL\Service]*/;

$ID_Luefterstufe = 50869 /*[Schnittstellen\Vallox KWL\Lüfterstufe IST]*/;
$ID_Aussenluft =25558 /*[Schnittstellen\Vallox KWL
icht benötigt\KWL Abluft Status\Aussenluft Status]*/;
$ID_Fortluft =39025 /*[Schnittstellen\Vallox KWL
icht benötigt\KWL Fortluft Status\Fortluft Status]*/;
$ID_Abluft =26336 /*[Schnittstellen\Vallox KWL
icht benötigt\KWL Lüfterstufe Status\Lüfterstufe Status]*/;
$ID_Zuluft =46208 /*[Schnittstellen\Vallox KWL
icht benötigt\KWL Zuluft Status\Zuluft Status]*/;

$ID_Temp = 53257 /*[Schnittstellen\Vallox KWL\Speicher]*/;

// Tabelle zur Temperatur Umrechnung
$Temperatur = array(
"-74", "-70", "-66", "-62", "-59", "-56", "-54", "-52", "-50", "-48", "-47",
"-46", "-44", "-43", "-42", "-41", "-40", "-39", "-38", "-37", "-36", "-35",
"-34", "-33", "-33", "-32", "-31", "-30", "-30", "-29", "-28", "-28", "-27",
"-27", "-26", "-25", "-25", "-24", "-24", "-23", "-23", "-22", "-22", "-21",
"-21", "-20", "-20", "-19", "-19", "-19", "-18", "-18", "-17", "-17", "-16",
"-16", "-16", "-15", "-15", "-14", "-14", "-14", "-13", "-13", "-12", "-12",
"-12", "-11", "-11", "-11", "-10", "-10", "-9", "-9", "-9", "-8", "-8", "-8",
"-7", "-7", "-7", "-6", "-6", "-6", "-5", "-5", "-5", "-4", "-4", "-4", "-3",
"-3", "-3", "-2", "-2", "-2", "-1", "-1", "-1", "-1", "0", "0", "0", "1", "1",
"1", "2", "2", "2", "3", "3", "3", "4", "4", "4", "5", "5", "5", "5", "6", "6",
"6", "7", "7", "7", "8", "8", "8", "9", "9", "9", "10", "10.3", "10.6", "11", "11.3",
"11.6", "12.0", "12.3", "12.6", "13.0", "13.3", "13.6", "14.0", "14.3", "14.6", "15.0", "15.3", "15.6",
"16.0", "16.3", "16.6", "17.3", "17.6", "18.0", "18.3", "18.6", "19.0", "19.3", "19.6", "20.0", "20.5",
"21.0", "21.3", "21.6", "22.0", "22.3", "22.6", "23.0", "23.5", "24.0", "24.3", "24.6", "25.0", "25.5",
"26.0", "26.5", "27.0", "27.3", "27.6", "28.0", "28.5", "29.0", "29.5", "30.0", "30.5", "31.0", "31.5",
"32.0", "32.5", "33.0", "33.5", "34.0", "34.5", "35.0", "35.5", "36.0", "36.5", "37.0", "37.5", "38.0",
"38.5", "39", "40.0", "40.5", "41.0", "41.5", "42", "43.0", "43.5", "44", "45", "45", "46",
"47", "48", "48", "49", "50", "51", "52", "53", "53", "54", "55", "56", "57",
"59", "60", "61", "62", "63", "65", "66", "68", "69", "71", "73", "75", "77",
"79", "81", "82", "86", "90", "93", "97", "100", "100", "100", "100", "100",
"100", "100", "100", "100");

// wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
if ($_IPS['SENDER'] == "RegisterVariable")
{
    // 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'];

// Befehle zum Regeln der Lüfterstufe
#Stufe1 | "\01\x11\x10\x29\x01\x4C"
#Stufe2 | "\01\x11\x10\x29\x03\x4E"
#Stufe3 | "\01\x11\x10\x29\x07\x52"
#Stufe4 | "\01\x11\x10\x29\x0F\x5A"
#Stufe5 | "\01\x11\x10\x29\x1F\x6A"
#Stufe6 | "\01\x11\x10\x29\x3F\x8A"
#Stufe7 | "\01\x11\x10\x29\x7F\xCA"
#Stufe8 | "\01\x11\x10\x29\xFF\x4A"

// Lüfterstufe Status auslesen

$Funktion=substr($data,0,5);// Funktion ausfiltern

switch($Funktion)
{
case "\x01\x11\x21\x29\x01": // Lüfterstufe 1
 SetValue($ID_Luefterstufe, 1);
break;
case "\x01\x11\x21\x29\x03": // Lüfterstufe 2
  SetValue($ID_Luefterstufe, 2);
break;
case "\x01\x11\x21\x29\x07": // Lüfterstufe 3
  SetValue($ID_Luefterstufe, 3);
break;
case "\x01\x11\x21\x29\x0F": // Lüfterstufe 4
  SetValue($ID_Luefterstufe, 4);
break;
case "\x01\x11\x21\x29\x1F": // Lüfterstufe 5
  SetValue($ID_Luefterstufe, 5);
break;
case "\x01\x11\x21\x29\x3F": // Lüfterstufe 6
  SetValue($ID_Luefterstufe, 6);
break;
case "\x01\x11\x21\x29\x7F": // Lüfterstufe 7
  SetValue($ID_Luefterstufe, 7);
break;
case "\x01\x11\x21\x29\xFF": // Lüfterstufe 8
  SetValue($ID_Luefterstufe, 8);
break;
}

##############
#KWL schreibt zu allen Zuluft Temperatur 35
#01 11 20 35 9E 05

#KWL schreibt zu allen Abluft Temperatur 34
#01 11 20 34 A0 06

#KWL schreibt zu allen Fortluft Temperatur 33
#01 11 20 33 8E F3

#KWL schreibt zu allen Außenluft Temperatur 32
#01 11 20 32 87 EB

#return;
// Temperaturen auslesen

$Funktion1=substr($data,0,4);// Funktion ausfiltern
switch($Funktion1)
{
case "\x01\x11\x20\x35": // Zuluft Temperatur in die Wohnung

	$Zuluft=substr($data,4,1);// Temperatur ausfiltern
	$ZuluftTemp = ord($Zuluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$ZuluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(53497 /*[Schnittstellen\Vallox KWL\KWL Temp Zuluft]*/); // aktuelle Temperatur auslesen
	if ($Status <> $Status1) // Temperatur nur bei änderung schreiben
	SetValue(26273 /*[Schnittstellen\Vallox KWL\KWL Temp Zuluft\Temp Zuluft in die Wohnung]*/, $Status);
break;

case "\x01\x11\x20\x34": // Abluft Temperatur aus der Wohnung
	$Abluft=substr($data,4,1);// Temperatur ausfiltern
	$AbluftTemp = ord($Abluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$AbluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(19274 /*[Schnittstellen\Vallox KWL\KWL Temp Abluft]*/); //
	if ($Status <> $Status1)
	SetValue(47538 /*[Schnittstellen\Vallox KWL\KWL Temp Abluft\Abluft aus der Wohnung]*/, $Status);
break;

case "\x01\x11\x20\x33": // Fortluft Temperatur nach draussen
	$Fortluft=substr($data,4,1);// Temperatur ausfiltern
	$FortluftTemp = ord($Fortluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$FortluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(45564 /*[Schnittstellen\Vallox KWL\KWL Temp Fortluft]*/); //
	if ($Status <> $Status1)
	SetValue(45899 /*[Schnittstellen\Vallox KWL\KWL Temp Fortluft\Fortluft nach draussen]*/, $Status);
break;

case "\x01\x11\x20\x32": // Außenluft Temperatur zum Gerät
	$Aussenluft=substr($data,4,1);// Temperatur ausfiltern
	$AussenluftTemp = ord($Aussenluft); // Chr in Dezimal umwandeln
	SetValue($ID_Temp , $Temperatur[$AussenluftTemp]);
	$Status = GetValue($ID_Temp); //
	$Status1 = GetValue(30834 /*[Schnittstellen\Vallox KWL\KWL Temp Aussenluft]*/); //
	if ($Status <> $Status1)
	SetValue(21161 /*[Schnittstellen\Vallox KWL\KWL Temp Aussenluft\Aussenluft zum Gerät]*/, $Status);
break;

case "\x01\x11\x21\xA3": // Anlagen Status
	$Status=substr($data,4,1);// Status ausfiltern
	$StatusDez = ord($Status);

if (getBitState($StatusDez, 0))  // KWL Betriebsstatus an Bit0 auslesen
    SetValueBoolean($ID_Betrieb , true);
  else
    SetValueBoolean($ID_Betrieb , false);

if (getBitState($StatusDez, 1))  // KWL CO2 adjust state an Bit1 auslesen
    SetValueBoolean($CO2_Status , true);
  else
    SetValueBoolean($CO2_Status , false);

if (getBitState($StatusDez, 2))  // KWL %RH adjust state an Bit2 auslesen
    SetValueBoolean($Luftfeuchte_Status , true);
  else
    SetValueBoolean($Luftfeuchte_Status , false);

if (getBitState($StatusDez, 3))  // KWL Heating state an Bit3 auslesen
    SetValueBoolean($Heizung_Status , true);
  else
    SetValueBoolean($Heizung_Status , false);

if (getBitState($StatusDez, 4))  // KWL Filterguard indicator an Bit4 auslesen
    SetValueBoolean($Filter_Status , true);
  else
    SetValueBoolean($Filter_Status , false);

if (getBitState($StatusDez, 5))  // KWL Heating indicator an Bit5 auslesen
    SetValueBoolean($Heizung_Indikator , true);
  else
    SetValueBoolean($Heizung_Indikator , false);

if (getBitState($StatusDez, 6))  // KWL Fault indicator an Bit6 auslesen
    SetValueBoolean($Fehler_Indikator , true);
  else
    SetValueBoolean($Fehler_Indikator , false);

if (getBitState($StatusDez, 7))  // KWL Service reminder an Bit7 auslesen
    SetValueBoolean($Service , true);
  else
    SetValueBoolean($Service , false);
    
break;

}


}

  function getBitState($Value, $BitNo)
  {
    return (($Value & pow(2, $BitNo)) != 0);
  }

?>

und hier das zum Schreiben der Lüfterstufe:

<?

#####################################################
# Lüfterstufe Senden
#####################################################

$id_Helios = 23053 /*[Serial Port KWL]*/;

if(['SENDER'] == "WebFront");
	{
   	switch($_IPS['VALUE'])
    	{
    		case 1: // Lüfterstufe 1
    			SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 1);
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\x01\x7A\x01\x2F\x10\x29\x01\x6A\x01\x2F\x11\x29\x01\x6B\x6B");
 		   break;
    		case 2: // Lüfterstufe 2
    		   SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 2);
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\x03\x6D\x01\x2F\x10\x29\x03\x6D\x01\x2F\x11\x29\x03\x6D\x6D");
			break;
			case 3: // Lüfterstufe 3
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\x07\x80\x01\x2F\x10\x29\x07\x70\x01\x2F\x11\x29\x07\x71\x71");
    		   SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 3);
				break;
			case 4: // Lüfterstufe 4
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\x0F\x88\x01\x2F\x10\x29\x0F\x78\x01\x2F\x44\x4A\x7A\x38\x38");
    		   SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 4);
			break;
			case 5: // Lüfterstufe 5
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\x1F\x98\x01\x2F\x10\x29\x1F\x88\x01\x2F\x11\x29\x1F\x89\x89");
    		   SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 5);
			break;
			case 6: // Lüfterstufe 6
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\x3F\xB8\x01\x2F\x10\x29\x3F\xA8\x01\x2F\x11\x29\x3F\xA9\xA9");
    		   SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 6);
			break;
			case 7: // Lüfterstufe 7
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\x7F\xF8\x01\x2F\x10\x29\x7F\xE8\x01\x2F\x11\x29\x7F\xE9\xE9");
    		   SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 7);
			break;
			case 8:  // Lüfterstufe 8
				SPRT_SendText(23053 /*[Serial Port KWL]*/,"\x01\x2F\x20\x29\xFF\x78\x01\x2F\x10\x29\xFF\x68\x01\x2F\x11\x29\xFF\x69\x69");
    		   SetValue(46728 /*[Schnittstellen\Vallox KWL\Lüfterstufe SOLL]*/, 8);
			break;
    }
}
?>

Schön das es jetzt funktioniert, die Einarbeitung dauert halt ein Wenig…

Die Fragen gehen jedoch weiter :o

Ich versuche nun gerade das Skript zu erweitern um mehr Informationen aus der KWL zu bekommen.

Wenn ich dieses Python Skript

#!/usr/bin/env python
#########################################################################
# Copyright 2014 Marcel Tiews marcel.tiews@gmail.com
#########################################################################
# Helios-Plugin for SmartHome.py. http://mknx.github.io/smarthome/
#
# This plugin is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This plugin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this plugin. If not, see <http://www.gnu.org/licenses/>.
#########################################################################

import sys
import serial
import logging
import socket
import threading
import struct
import time
import datetime
import array

logger = logging.getLogger("")

# Some "Constants" - previous definitions (thanks to Johannes and Marcel)
#CONST_BUSMEMBER__MAINBOARD     = 0x11
#CONST_BUSMEMBER__SLAVEBOARDS   = 0x10
#CONST_BUSMEMBER__CONTROLBOARDS = 0x20
#CONST_BUSMEMBER__ME            = 0x2F


# Broadcast addresses - no way to address slave boards in the units directly (according to Vallox)
CONST_BUS_ALL_MAINBOARDS   = 0x10
CONST_BUS_ALL_REMOTES      = 0x20

# Individual addresses
CONST_BUS_MAINBOARD1       = 0x11 # 1st of max 15 ventilation units (mainboards 1-F)
CONST_BUS_REMOTE1          = 0x21 # 1st of max 15 remote controls (remotes 1-F, default jumper = 1)
CONST_BUS_LON              = 0x28 # default for LON bus module (just for information --> expensive)
CONST_BUS_ME               = 0x2F # stealth mode - we are behaving like a regular remote control

CONST_MAP_VARIABLES_TO_ID = {
        "outside_temp"    : {"varid" : 0x32, 'type': 'temperature',  'bitposition': -1, 'read': True, 'write': False },
        "exhaust_temp"    : {"varid" : 0x33, 'type': 'temperature',  'bitposition': -1, 'read': True, 'write': False },
        "inside_temp"     : {"varid" : 0x34, 'type': 'temperature',  'bitposition': -1, 'read': True, 'write': False },
        "incoming_temp"   : {"varid" : 0x35, 'type': 'temperature',  'bitposition': -1, 'read': True, 'write': False },
        "bypass_temp"     : {"varid" : 0xAF, 'type': 'temperature',  'bitposition': -1, 'read': True, 'write': True  },
        "fanspeed"        : {"varid" : 0x29, 'type': 'fanspeed',     'bitposition': -1, 'read': True, 'write': True  },
        "max_fanspeed"    : {"varid" : 0xA5, 'type': 'fanspeed',     'bitposition': -1, 'read': True, 'write': True  },
        "min_fanspeed"    : {"varid" : 0xA9, 'type': 'fanspeed',     'bitposition': -1, 'read': True, 'write': True  },
        "power_state"     : {"varid" : 0xA3, 'type': 'bit',          'bitposition':  0, 'read': True, 'write': True  },
        "bypass_disabled" : {"varid" : 0xA3, 'type': 'bit',          'bitposition':  3, 'read': True, 'write': True  },
        "clean_filter"    : {"varid" : 0xAB, 'type': 'dec',          'bitposition': -1, 'read': True, 'write': True  },
        "boost_setting"   : {"varid" : 0xAA, 'type': 'bit',          'bitposition':  5, 'read': True, 'write': True  },
	"boost_on"        : {"varid" : 0x71, 'type': 'bit',          'bitposition':  5, 'read': True, 'write': True  },
	"boost_status"    : {"varid" : 0x71, 'type': 'bit',          'bitposition':  6, 'read': True, 'write': False },
        "damper"          : {"varid" : 0x08, 'type': 'bit',          'bitposition':  1, 'read': True, 'write': True  },
	"boost_remaining" : {"varid" : 0x79, 'type': 'dec',          'bitposition': -1, 'read': True, 'write': False },
        "fan_in_on_off"   : {"varid" : 0x08, 'type': 'bit',          'bitposition':  3, 'read': True, 'write': True  },
        "fan_in_percent"  : {"varid" : 0xB0, 'type': 'dec',          'bitposition': -1, 'read': True, 'write': True  },        
        "fan_out_on_off"  : {"varid" : 0x08, 'type': 'bit',          'bitposition':  5, 'read': True, 'write': True  },
        "fan_out_percent" : {"varid" : 0xB1, 'type': 'dec',          'bitposition': -1, 'read': True, 'write': True  },   
        "device_error"    : {"varid" : 0x36, 'type': 'dec',          'bitposition': -1, 'read': True, 'write': False }
    }
CONST_TEMPERATURE = array.array('i', [
                                -74,-70,-66,-62,-59,-56,-54,-52,-50,-48,-47,-46,-44,-43,-42,-41,-40,-39,-38,-37,-36,
                                -35,-34,-33,-33,-32,-31,-30,-30,-29,-28,-28,-27,-27,-26,-25,-25,-24,-24,-23,-23,-22,
                                -22,-21,-21,-20,-20,-19,-19,-19,-18,-18,-17,-17,-16,-16,-16,-15,-15,-14,-14,-14,-13,
                                -13,-12,-12,-12,-11,-11,-11,-10,-10,-9,-9,-9,-8,-8,-8,-7,-7,-7,-6,-6,-6,-5,-5,-5,-4,
                                -4,-4,-3,-3,-3,-2,-2,-2,-1,-1,-1,-1,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,5,6,6,6,7,7,
                                7,8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14,15,15,15,16,16,16,17,17,
                                18,18,18,19,19,19,20,20,21,21,21,22,22,22,23,23,24,24,24,25,25,26,26,27,27,27,28,28,
                                29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,40,40,41,41,42,43,43,
                                44,45,45,46,47,48,48,49,50,51,52,53,53,54,55,56,57,59,60,61,62,63,65,66,68,69,71,73,
                                75,77,79,81,82,86,90,93,97,100,100,100,100,100,100,100,100,100])


class HeliosException(Exception):
    pass


class HeliosBase():

    def __init__(self, tty='/dev/ttyUSB0'):
        self._tty = tty
        self._is_connected = False
        self._port = False
        self._lock = threading.Lock()
     
    def connect(self):
        if self._is_connected and self._port:
            return True
            
        try:
            logger.debug("Helios: Connecting...")
            self._port = serial.Serial(
                self._tty, 
                baudrate=9600, 
                bytesize=serial.EIGHTBITS, 
                parity=serial.PARITY_NONE, 
                stopbits=serial.STOPBITS_ONE, 
                timeout=1)
            self._is_connected = True
            return True
        except:
            logger.error("Helios: Could not open {0}.".format(self._tty))
            return False
        
    def disconnect(self):
        if self._is_connected and self._port:
            logger.debug("HeliosBase: Disconnecting...")
            self._port.close()
            self._is_connected = False
            
    def _createTelegram(self, sender, receiver, function, value):
        telegram = [1,sender,receiver,function,value,0]
        telegram[5] = self._calculateCRC(telegram)
        return telegram
        
    def _waitForSilence(self):
        # Modbus RTU only allows one master (client which controls communication).
        # So lets try to wait a bit and jump in when nobody's speaking.
        # Modbus defines a waittime of 3,5 Characters between telegrams:
        # (1/9600baud * (1 Start bit + 8 Data bits + 1 Parity bit + 1 Stop bit) 
        # => about 4ms
        # Lets go with 7ms!  ;O)
        
        gotSlot = False
        backupTimeout = self._port.timeout
        end = time.time() + 3
        self._port.timeout = 0.07
        while end > time.time():
            chars = self._port.read(1)
            # nothing received so we got a slot of silence...hopefully
            if len(chars) == 0:
                gotSlot = True
                break
        self._port.timeout = backupTimeout
        return gotSlot    

    def _sendTelegram(self, telegram):
        if not self._is_connected:
            return False
        
        logger.debug("Helios: Sending telegram '{0}'".format(self._telegramToString(telegram)))
        self._port.write(bytearray(telegram))
        return True
            
    def _readTelegram(self, sender, receiver, datapoint):
        # sometimes a lot of garbage is received...so lets get a bit robust
        # and read a bit of this junk and see whether we are getting something
        # useful out of it!
        # How long does it take until something useful is received???
        timeout = time.time() + 1
        telegram = [0,0,0,0,0,0]
        while self._is_connected and timeout > time.time():
            char = self._port.read(1)
            if(len(char) > 0):
                byte = bytearray(char)[0]
                telegram.pop(0)
                telegram.append(byte)
                # Telegrams always start with a 0x01, is the CRC valid?, ...
                if (telegram[0] == 0x01 and 
                    telegram[1] == sender and 
                    telegram[2] == receiver and 
                    telegram[3] == datapoint and 
                    telegram[5] == self._calculateCRC(telegram)):
                    logger.debug("Telegram received '{0}'".format(self._telegramToString(telegram)))
                    return telegram[4]
        return None
    
    def _calculateCRC(self, telegram):
        sum = 0
        for c in telegram[:-1]:
            sum = sum + c
        return sum % 256
    
    def _telegramToString(self, telegram):
        str = ""
        for c in telegram:
            # str = str + hex(c) + " "     0x01 was showing as 0x1, 0x1A was showing as 0x1a
            str = str + '0x%0*X' % (2,c) + " "
        str = str[:-1] # remove trailing space
        return str
                            
    def _convertFromRawValue(self, varname, rawvalue):
        value = None
        vardef = CONST_MAP_VARIABLES_TO_ID[varname]
        
        if vardef["type"] == "temperature":
            value = CONST_TEMPERATURE[rawvalue]
        elif vardef["type"] == "fanspeed":
            if rawvalue == 0x01:
                value = 1
            elif rawvalue == 0x03: 
                value = 2
            elif rawvalue == 0x07: 
                value = 3
            elif rawvalue == 0x0F: 
                value = 4
            elif rawvalue == 0x1F: 
                value = 5
            elif rawvalue == 0x3F: 
                value = 6
            elif rawvalue == 0x7F: 
                value = 7
            elif rawvalue == 0xFF: 
                value = 8
            else:
                value = None
        elif vardef["type"] == "bit":
            value = rawvalue >> vardef["bitposition"] & 0x01
        elif vardef["type"] == "dec": #  decimal value
            value = rawvalue
                   
        return value        

    def _convertFromValue(self, varname, value, prevvalue):
        rawvalue = None
        vardef = CONST_MAP_VARIABLES_TO_ID[varname]
        
        if vardef['type'] == "temperature":
            rawvalue = CONST_TEMPERATURE.index(int(value))
        elif vardef["type"] == "fanspeed":
            value = int(value)
            if value == 1:
                rawvalue = 0x01
            elif value == 2: 
                rawvalue = 0x03
            elif value == 3: 
                rawvalue = 0x07
            elif value == 4: 
                rawvalue = 0x0F
            elif value == 5: 
                rawvalue = 0x1F
            elif value == 6: 
                rawvalue = 0x3F
            elif value == 7: 
                rawvalue = 0x7F
            elif value == 8: 
                rawvalue = 0xFF
            else:
                rawvalue = None
        elif vardef["type"] == "bit":
            # for bits we have to keep the other bits of the byte (previous value)
            if value in (True,1,"true","True","1","On","on"):
                rawvalue = prevvalue | (1 << vardef["bitposition"])
            else:
                rawvalue = prevvalue & ~(1 << vardef["bitposition"])
        elif vardef["type"] == "dec": #  decimal value
            rawvalue = int(value)
            
        return rawvalue        
        
    def writeValue(self,varname, value):
        if CONST_MAP_VARIABLES_TO_ID[varname]["write"] != True:
            logger.error("Helios: Variable {0} may not be written!".format(varname))
            return False 
        success = False
        
        self._lock.acquire()
        try:
            # if we have got to write a single bit, we need the current (byte) value to
            # reproduce the other bits...
            if CONST_MAP_VARIABLES_TO_ID[varname]["type"] == "bit":
                currentval = None
                if self._waitForSilence():
                    # Send poll request
                    telegram = self._createTelegram(
                        CONST_BUS_ME,
                        CONST_BUS_MAINBOARD1, 
                        0, 
                        CONST_MAP_VARIABLES_TO_ID[varname]["varid"]
                    )
                    self._sendTelegram(telegram)
                    # Read response
                    currentval = self._readTelegram(
                        CONST_BUS_MAINBOARD1, 
                        CONST_BUS_ME, 
                        CONST_MAP_VARIABLES_TO_ID[varname]["varid"]
                    )
                if currentval == None:
                    logger.error("Helios: Sending value to ventilation system failed. Can not read current variable value '{0}'."
                        .format(varname))
                    return False
                rawvalue = self._convertFromValue(varname, value, currentval)
            else:    
                rawvalue = self._convertFromValue(varname, value, None)
                
            # send the new value    
            if self._waitForSilence():
                if rawvalue != None:

                    # Broadcasting value to all remote control boards
                    telegram = self._createTelegram(
                        CONST_BUS_ME,
                        CONST_BUS_ALL_REMOTES, 
                        CONST_MAP_VARIABLES_TO_ID[varname]["varid"], 
                        rawvalue
                    )
                    self._sendTelegram(telegram)
                    
                    # Broadcasting value to all mainboards
                    telegram = self._createTelegram(
                        CONST_BUS_ME,
                        CONST_BUS_ALL_MAINBOARDS, 
                        CONST_MAP_VARIABLES_TO_ID[varname]["varid"], 
                        rawvalue
                    )
                    self._sendTelegram(telegram)

                    # Writing value to 1st mainboard
                    telegram = self._createTelegram(
                        CONST_BUS_ME,
                        CONST_BUS_MAINBOARD1, 
                        CONST_MAP_VARIABLES_TO_ID[varname]["varid"], 
                        rawvalue 
                    )
                    self._sendTelegram(telegram)
                    
                    # Send checksum a second time
                    self._sendTelegram([telegram[5]])

##################### Special treatment to switch the remote controls on again:
                    if CONST_MAP_VARIABLES_TO_ID[varname]["varid"] == 0xA3 and CONST_MAP_VARIABLES_TO_ID[varname]["bitposition"] == 0:
                        logger.debug("On/off command - special treatment for the remote controls")                    
                        telegram = self._createTelegram(
                            CONST_BUS_ME,
                            CONST_BUS_ALL_REMOTES, 
                            CONST_MAP_VARIABLES_TO_ID[varname]["varid"], 
                            rawvalue 
                        )
                        self._sendTelegram(telegram)

                        telegram = self._createTelegram(
                            CONST_BUS_ME,
                            CONST_BUS_REMOTE1, 
                            CONST_MAP_VARIABLES_TO_ID[varname]["varid"], 
                            rawvalue 
                        )
                        self._sendTelegram(telegram)

                        self._sendTelegram([telegram[5]])
####################


                    success = True
                    
                else:
                    logger.error("Helios: Sending value to ventilation system failed. Can not convert value '{0}' for variable '{1}'."
                        .format(value,varname))
                    success = False
            else:
                logger.error("Helios: Sending value to ventilation system failed. No free slot for sending telegrams available.")
                success = False
        except Exception as e:
                logger.error("Helios: Exception in writeValue() occurred: {0}".format(e))
        finally:
            self._lock.release()
   
        return success
            
    def readValue(self,varname):
        if CONST_MAP_VARIABLES_TO_ID[varname]["read"] != True:
            logger.error("Variable {0} may not be read!".format(varname))
            return False
        value = None
        
        self._lock.acquire()
        try:
            logger.debug("Helios: Reading value: {0}".format(varname)) 
            if self._waitForSilence():
                # Send poll request
                telegram = self._createTelegram(
                    CONST_BUS_ME,
                    CONST_BUS_MAINBOARD1, 
                    0, 
                    CONST_MAP_VARIABLES_TO_ID[varname]["varid"]
                )
                self._sendTelegram(telegram)
                # Read response
                value = self._readTelegram(
                    CONST_BUS_MAINBOARD1, 
                    CONST_BUS_ME, 
                    CONST_MAP_VARIABLES_TO_ID[varname]["varid"]
                )
                if value is not None:
                    raw_value = value
                    value = self._convertFromRawValue(varname,value)
                    logger.debug("Value for {0} ({1}) received: {2}|{3}|{4} --> converted = {5}"
                        .format(varname, '0x%0*X' % (2, CONST_MAP_VARIABLES_TO_ID[varname]["varid"]),
                        '0x%0*X' % (2,raw_value), "{0:08b}".format(raw_value), raw_value, value)
                    ) 
                else:
                    logger.error("Helios: No valid value for '{0}' from ventilation system received."
                        .format(varname)
                    ) 
            else:
                logger.warn("Helios: Reading value from ventilation system failed. No free slot to send poll request available.")
        except Exception as e:
                logger.error("Helios: Exception in readValue() occurred: {0}".format(e))
        finally:
            self._lock.release()
   
        return value

    
class Helios(HeliosBase): 
    _items = {}
    
    def __init__(self, smarthome, tty, cycle=300):
        HeliosBase.__init__(self, tty)
        self._sh = smarthome
        self._cycle = int(cycle)
        self._alive = False
        
    def run(self):
        self.connect()
        self._alive = True
        self._sh.scheduler.add('Helios', self._update, cycle=self._cycle)

    def stop(self):
        self.disconnect()
        self._alive = False

    def parse_item(self, item):
        if 'helios_var' in item.conf:
            varname = item.conf['helios_var']
            if varname in CONST_MAP_VARIABLES_TO_ID.keys():
                self._items[varname] = item
                return self.update_item
            else:
                logger.warn("Helios: Ignoring unknown variable '{0}'".format(varname))
        
    def update_item(self, item, caller=None, source=None, dest=None):
        if caller != 'Helios':
            self.writeValue(item.conf['helios_var'], item()) 
        
    def _update(self):
        logger.debug("Helios: Updating values")
        for var in self._items.keys():
            val = self.readValue(var)
            if val != None:
                self._items[var](val,"Helios")

   
def main():
    import argparse 
    
    parser = argparse.ArgumentParser(
    description="Helios ventilation system commandline interface.",
    epilog="Without arguments all readable values using default tty will be retrieved.",
    argument_default=argparse.SUPPRESS)
    parser.add_argument("-t", "--tty", dest="port", default="/dev/ttyUSB0", help="Serial device to use")
    parser.add_argument("-r", "--read", dest="read_var", help="Read variables from ventilation system")
    parser.add_argument("-w", "--write", dest="write_var", help="Write variable to ventilation system")
    parser.add_argument("-v", "--value", dest="value", help="Value to write (required with option -v)")
    parser.add_argument("-d", "--debug", dest="enable_debug", action="store_true", help="Prints debug statements.")
    args = vars(parser.parse_args())
 
    if "write_var" in args.keys() and "value" not in args.keys():
        parser.print_usage()
        return

    logger.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    if "enable_debug" in args.keys():
        ch.setLevel(logging.DEBUG)
    else:
        ch.setLevel(logging.INFO)
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    ch.setFormatter(formatter)
    logger.addHandler(ch)

    try:
        helios = HeliosBase(args["port"])
        helios.connect()
        if not helios._is_connected:
            raise Exception("Not connected")
        
        if "read_var" in args.keys():
            print("{0} = {1}".format(args["read_var"],helios.readValue(args["read_var"])))
        elif "write_var" in args.keys():
            helios.writeValue(args["write_var"],args["value"])
        else:
            for var in CONST_MAP_VARIABLES_TO_ID.keys():
                print("{0} = {1}".format(var,helios.readValue(var)))
    except Exception as e:
        print("Exception: {0}".format(e))
        return 1
    finally:
        if helios:
            helios.disconnect()

if __name__ == "__main__":
    sys.exit(main())        

auf meinem PI ausführe erhalte ich folgende Daten zurück:

bypass_disabled = 0
max_fanspeed = 8
inside_temp = 20
fan_out_percent = 100
incoming_temp = 15
boost_setting = 1
boost_remaining = 0
min_fanspeed = 1
fan_out_on_off = 0
outside_temp = 14
fan_in_percent = 100
clean_filter = 0
fan_in_on_off = 0
bypass_temp = 12
power_state = 1
exhaust_temp = 21
fanspeed = 1
damper = 1
device_error = 0
boost_status = 0
boost_on = 0

Ich möchte zum Beispiel den Fan In Status, den Fan Out Status und die Bypass Klappe (damper) abfragen.
Was mich wundert, dass wie im Python Skript beschrieben im Register \x08 diese Informationen sein soll, wenn ich jedoch im Debug für den Serial Port als auch für den Cutter kein Register 08 erkennen kann.

So sieht aktuell mein Skript aus:

<?

$ID_Betrieb = 57584 /*[Schnittstellen\Vallox KWL\Betrieb]*/;
$CO2_Status = 49064 /*[Schnittstellen\Vallox KWL\CO2 Status]*/;
$Luftfeuchte_Status = 26466 /*[Schnittstellen\Vallox KWL\Luftfeuchte Status]*/;
$Heizung_Status = 38671 /*[Schnittstellen\Vallox KWL\Sommer-Winterbetrieb]*/;
$Filter_Status = 54659 /*[Schnittstellen\Vallox KWL\Filterwechsel]*/;
$Heizung_Indikator = 24032 /*[Schnittstellen\Vallox KWL\Heizung indicator]*/;
$Fehler_Indikator = 15439 /*[Schnittstellen\Vallox KWL\Fehler Indicator]*/;
$Service = 26131 /*[Schnittstellen\Vallox KWL\Service]*/;
$Boost_on = 30876 /*[Schnittstellen\Vallox KWL\Boost on]*/;
$Boost_Status = 40442 /*[Schnittstellen\Vallox KWL\Boost Status]*/;
$Fan_In_On = 56190 /*[Schnittstellen\Vallox KWL\kwl test\Fan In]*/;
$Fan_Out_On = 48667 /*[Schnittstellen\Vallox KWL\kwl test\Fan Out]*/;
$Klappe = 46617 /*[Schnittstellen\Vallox KWL\kwl test\Bypass Klappe]*/;

$ID_Luefterstufe = 50869 /*[Schnittstellen\Vallox KWL\Lüfterstufe IST]*/;
$ID_Aussenluft =25558 /*[Objekt #25558 existiert nicht]*/;
$ID_Fortluft =39025 /*[Objekt #39025 existiert nicht]*/;
$ID_Abluft =26336 /*[Objekt #26336 existiert nicht]*/;
$ID_Zuluft =46208 /*[Objekt #46208 existiert nicht]*/;

$ID_Temp = 53257 /*[Schnittstellen\Vallox KWL\Speicher]*/;

// Tabelle zur Temperatur Umrechnung
$Temperatur = array(
"-74", "-70", "-66", "-62", "-59", "-56", "-54", "-52", "-50", "-48", "-47",
"-46", "-44", "-43", "-42", "-41", "-40", "-39", "-38", "-37", "-36", "-35",
"-34", "-33", "-33", "-32", "-31", "-30", "-30", "-29", "-28", "-28", "-27",
"-27", "-26", "-25", "-25", "-24", "-24", "-23", "-23", "-22", "-22", "-21",
"-21", "-20", "-20", "-19", "-19", "-19", "-18", "-18", "-17", "-17", "-16",
"-16", "-16", "-15", "-15", "-14", "-14", "-14", "-13", "-13", "-12", "-12",
"-12", "-11", "-11", "-11", "-10", "-10", "-9", "-9", "-9", "-8", "-8", "-8",
"-7", "-7", "-7", "-6", "-6", "-6", "-5", "-5", "-5", "-4", "-4", "-4", "-3",
"-3", "-3", "-2", "-2", "-2", "-1", "-1", "-1", "-1", "0", "0", "0", "1", "1",
"1", "2", "2", "2", "3", "3", "3", "4", "4", "4", "5", "5", "5", "5", "6", "6",
"6", "7", "7", "7", "8", "8", "8", "9", "9", "9", "10", "10.3", "10.6", "11", "11.3",
"11.6", "12.0", "12.3", "12.6", "13.0", "13.3", "13.6", "14.0", "14.3", "14.6", "15.0", "15.3", "15.6",
"16.0", "16.3", "16.6", "17.3", "17.6", "18.0", "18.3", "18.6", "19.0", "19.3", "19.6", "20.0", "20.5",
"21.0", "21.3", "21.6", "22.0", "22.3", "22.6", "23.0", "23.5", "24.0", "24.3", "24.6", "25.0", "25.5",
"26.0", "26.5", "27.0", "27.3", "27.6", "28.0", "28.5", "29.0", "29.5", "30.0", "30.5", "31.0", "31.5",
"32.0", "32.5", "33.0", "33.5", "34.0", "34.5", "35.0", "35.5", "36.0", "36.5", "37.0", "37.5", "38.0",
"38.5", "39", "40.0", "40.5", "41.0", "41.5", "42", "43.0", "43.5", "44", "45", "45", "46",
"47", "48", "48", "49", "50", "51", "52", "53", "53", "54", "55", "56", "57",
"59", "60", "61", "62", "63", "65", "66", "68", "69", "71", "73", "75", "77",
"79", "81", "82", "86", "90", "93", "97", "100", "100", "100", "100", "100",
"100", "100", "100", "100");

// wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
if ($_IPS['SENDER'] == "RegisterVariable")
{
    // 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'];

// Lüfterstufe Status auslesen

$Funktion=substr($data,0,5);// Funktion ausfiltern

switch($Funktion)
{
case "\x01\x11\x21\x29\x01": // Lüfterstufe 1
 SetValue($ID_Luefterstufe, 1);
break;
case "\x01\x11\x21\x29\x03": // Lüfterstufe 2
  SetValue($ID_Luefterstufe, 2);
break;
case "\x01\x11\x21\x29\x07": // Lüfterstufe 3
  SetValue($ID_Luefterstufe, 3);
break;
case "\x01\x11\x21\x29\x0F": // Lüfterstufe 4
  SetValue($ID_Luefterstufe, 4);
break;
case "\x01\x11\x21\x29\x1F": // Lüfterstufe 5
  SetValue($ID_Luefterstufe, 5);
break;
case "\x01\x11\x21\x29\x3F": // Lüfterstufe 6
  SetValue($ID_Luefterstufe, 6);
break;
case "\x01\x11\x21\x29\x7F": // Lüfterstufe 7
  SetValue($ID_Luefterstufe, 7);
break;
case "\x01\x11\x21\x29\xFF": // Lüfterstufe 8
  SetValue($ID_Luefterstufe, 8);
break;
}

// Temperaturen auslesen

$Funktion1=substr($data,0,4);// Funktion ausfiltern
switch($Funktion1)
{
case "\x01\x11\x20\xAF": // Bypass Temperatur
    $Bypass=substr($data,4,1);// Temperatur ausfiltern
    $BypassTemp = ord($Bypass); // Chr in Dezimal umwandeln
    SetValue(11639 /*[Schnittstellen\Vallox KWL\Bypass Temperatur]*/ , $Temperatur[$BypassTemp]);
break;

case "\x01\x11\x20\x35": // Zuluft Temperatur in die Wohnung
    $Zuluft=substr($data,4,1);// Temperatur ausfiltern
    $ZuluftTemp = ord($Zuluft); // Chr in Dezimal umwandeln
    SetValue(26273 /*[Schnittstellen\Vallox KWL\Temp Zuluft in die Wohnung]*/ , $Temperatur[$ZuluftTemp]);
break;

case "\x01\x11\x20\x34": // Abluft Temperatur aus der Wohnung
    $Abluft=substr($data,4,1);// Temperatur ausfiltern
    $AbluftTemp = ord($Abluft); // Chr in Dezimal umwandeln
    SetValue(47538 /*[Schnittstellen\Vallox KWL\Temp Abluft aus der Wohnung]*/ , $Temperatur[$AbluftTemp]);
break;

case "\x01\x11\x20\x33": // Fortluft Temperatur nach draussen
    $Fortluft=substr($data,4,1);// Temperatur ausfiltern
    $FortluftTemp = ord($Fortluft); // Chr in Dezimal umwandeln
    SetValue(45899 /*[Schnittstellen\Vallox KWL\Temp Fortluft nach draussen]*/ , $Temperatur[$FortluftTemp]);
break;

case "\x01\x11\x20\x32": // Außenluft Temperatur zum Gerät
    $Aussenluft=substr($data,4,1);// Temperatur ausfiltern
    $AussenluftTemp = ord($Aussenluft); // Chr in Dezimal umwandeln
    SetValue(21161 /*[Schnittstellen\Vallox KWL\Temp Aussenluft zum Gerät]*/ , $Temperatur[$AussenluftTemp]);
break;

case "\x01\x11\x21\xA3": // Anlagen Status
    $Status=substr($data,4,1);// Status ausfiltern
    $StatusDez = ord($Status);

if (getBitState($StatusDez, 0))  // KWL Betriebsstatus an Bit0 auslesen
    SetValueBoolean($ID_Betrieb , true);
  else
    SetValueBoolean($ID_Betrieb , false);

if (getBitState($StatusDez, 1))  // KWL CO2 adjust state an Bit1 auslesen
    SetValueBoolean($CO2_Status , true);
  else
    SetValueBoolean($CO2_Status , false);

if (getBitState($StatusDez, 2))  // KWL %RH adjust state an Bit2 auslesen
    SetValueBoolean($Luftfeuchte_Status , true);
  else
    SetValueBoolean($Luftfeuchte_Status , false);

if (getBitState($StatusDez, 3))  // KWL Heating state an Bit3 auslesen
    SetValueBoolean($Heizung_Status , true);
  else
    SetValueBoolean($Heizung_Status , false);

if (getBitState($StatusDez, 4))  // KWL Filterguard indicator an Bit4 auslesen
    SetValueBoolean($Filter_Status , true);
  else
    SetValueBoolean($Filter_Status , false);

if (getBitState($StatusDez, 5))  // KWL Heating indicator an Bit5 auslesen
    SetValueBoolean($Heizung_Indikator , true);
  else
    SetValueBoolean($Heizung_Indikator , false);

if (getBitState($StatusDez, 6))  // KWL Fault indicator an Bit6 auslesen
    SetValueBoolean($Fehler_Indikator , true);
  else
    SetValueBoolean($Fehler_Indikator , false);

if (getBitState($StatusDez, 7))  // KWL Service reminder an Bit7 auslesen
    SetValueBoolean($Service , true);
  else
    SetValueBoolean($Service , false);

break;

case "\x01\x11\x21\x71": // Anlagen Status
    $Status=substr($data,4,1);// Status ausfiltern
    $StatusDez = ord($Status);

if (getBitState($StatusDez, 5))  // KWL Boost On an Bit5 auslesen
    SetValueBoolean($Boost_on , true);
  else
    SetValueBoolean($Boost_on , false);

if (getBitState($StatusDez, 6))  // KWL Boost Status an Bit6 auslesen
    SetValueBoolean($Boost_Status , true);
  else
    SetValueBoolean($Boost_Status , false);

break;

case "\x01\x11\x21\x08": // Anlagen Status
    $Status=substr($data,4,1);// Status ausfiltern
    $StatusDez = ord($Status);

if (getBitState($StatusDez, 1))  // KWL Damper Position an Bit1 auslesen
    SetValueBoolean($Klappe , true);
  else
    SetValueBoolean($Klappe , false);

if (getBitState($StatusDez, 3))  // KWL Fan In an Bit3 auslesen
    SetValueBoolean($Fan_In_On , true);
  else
    SetValueBoolean($Fan_In_On , false);

if (getBitState($StatusDez, 5))  // KWL Fan Out an Bit5 auslesen
    SetValueBoolean($Fan_Out_On , true);
  else
    SetValueBoolean($Fan_Out_On , false);

break;

}


}

  function getBitState($Value, $BitNo)
  {
    return (($Value & pow(2, $BitNo)) != 0);
  }

?>

Wo hab ich wieder mal den Denkfehler?

Hallo,

in der Modbus-Doku von Helios wird teilweise auf weitere Tabellen verwiesen. Diese fehlen aber irrtümlicherweise noch in der Doku.

Vorab deshalb hier die Infos zur Status-Variable 01306

RegStr.BtSystemPar.u32StateFlags Variable - v01306
Bit Status Nr. Maske (hex) Fehlerbeschreibung
0 0000 0000 0000 0000 0000 0000 0000 0001 1 0x00000001 1 = SYSTEM fertig initialisiert (Anzeige im BT bis dahin: SYSTEM BOOTING)
1 0000 0000 0000 0000 0000 0000 0000 0010 2 0x00000002 1 = SYSTEM Softwareupdate aktiv (Anzeige im BT bis dahin: SYSTEM LOADING)
2 0000 0000 0000 0000 0000 0000 0000 0100 3 0x00000004 1 = Firmwareupdate wird aktiviert
3 0000 0000 0000 0000 0000 0000 0000 1000 4 0x00000008 1 = INBA ist aktiv
4 0000 0000 0000 0000 0000 0000 0001 0000 5 0x00000010 1 = Partybetrieb
5 0000 0000 0000 0000 0000 0000 0010 0000 6 0x00000020 1 = Ruhebetrieb
6 0000 0000 0000 0000 0000 0000 0100 0000 7 0x00000040 1 = Urlaubsbetrieb
7 0000 0000 0000 0000 0000 0000 1000 0000 8 0x00000080 1 = VHZ ist auf BASIS-Modul konfiguriert
8 0000 0000 0000 0000 0000 0001 0000 0000 9 0x00000100 1 = VHZ ist auf ErwModul konfiguriert
9 0000 0000 0000 0000 0000 0010 0000 0000 10 0x00000200 1 = ErwModul VHZ aktiv (z.B. BT-Anzeige: Menüpunkt VHZ einblenden)
10 0000 0000 0000 0000 0000 0100 0000 0000 11 0x00000400 1 = VHZ konfiguriert
11 0000 0000 0000 0000 0000 1000 0000 0000 12 0x00000800 VHZ: Heizungstyp (0 = Elektrisch / 1 = Sole (Erde oder Luft)
12 0000 0000 0000 0000 0001 0000 0000 0000 13 0x00001000 1 = NHZ konfiguriert (Temperaturprofil eingestellt ungl. HEIZUNG_AUS)
13 0000 0000 0000 0000 0010 0000 0000 0000 14 0x00002000 1 = ErwModul NHZ aktiv (z.B. BT-Anzeige: Menüpunkt NHZ einblenden)
14 0000 0000 0000 0000 0100 0000 0000 0000 15 0x00004000 1 = NHZ aktiv (Regelung, Fehler, identisch mit „Nachheizung.Ein“)
15 0000 0000 0000 0000 1000 0000 0000 0000 16 0x00008000 NHZ: Heizungstyp (0 = Elektrisch / 1 = Warmwasser)
16 0000 0000 0000 0001 0000 0000 0000 0000 17 0x00010000 1 = CO2 Regelung ein
17 0000 0000 0000 0010 0000 0000 0000 0000 18 0x00020000 1 = Humi Regelung ein
18 0000 0000 0000 0100 0000 0000 0000 0000 19 0x00040000 1 = VOC Regelung ein
19 0000 0000 0000 1000 0000 0000 0000 0000 20 0x00080000 - frei -
20 0000 0000 0001 0000 0000 0000 0000 0000 21 0x00100000 1 = min. ein Externer Kontakt angeschlossen (EM oder ES)
21 0000 0000 0010 0000 0000 0000 0000 0000 22 0x00200000 1 = Externe Kontaktfunktion AKTIV
22 0000 0000 0100 0000 0000 0000 0000 0000 23 0x00400000 1 = Externen Zugriff zulassen
23 0000 0000 1000 0000 0000 0000 0000 0000 24 0x00800000 1 = Externer Zugriff aktiv
24 0000 0001 0000 0000 0000 0000 0000 0000 25 0x01000000 1 = Defrost Wärmetauscher
25 0000 0010 0000 0000 0000 0000 0000 0000 26 0x02000000 1 = Defrost Warmwasserregister
26 0000 0100 0000 0000 0000 0000 0000 0000 27 0x04000000 1 = Filterwechsel fällig
27 0000 1000 0000 0000 0000 0000 0000 0000 28 0x08000000 1 = Konfig_1 (DIBT) / 0 = Konfig_2 (PHI)
28 0001 0000 0000 0000 0000 0000 0000 0000 29 0x10000000 1 = BEC-U1 über Web deaktiviert (reine Anzeigefunktion)
29 0010 0000 0000 0000 0000 0000 0000 0000 30 0x20000000 1 = Bedienteil sperren
30 0100 0000 0000 0000 0000 0000 0000 0000 31 0x40000000 1 = Master Password required (Wird gesetzt wenn 3 mal falsches pw eingegeben wurde)
31 1000 0000 0000 0000 0000 0000 0000 0000 32 0x80000000 1 = Anzeige der Lüfterstufe in %

Hallo,
bin noch blutiger Anfänger und habe das Python Script von jensmaehn mal probiert. Hat super geklappt und ich möchte nun das Script aus einem anderen Python Progrämmchen aufrufen um einzelne Werte abzufragen oder zu setzen. Leider schaff ich das nur wenn ich das Script in der Shell aufrufe.
Kann mir jemand helfen wie ich das auch aus einem eigenen Script schaffe? Bzw. was ich an dem Python Skript ändern muss?
Möchte letztendlich selbst ein Skript schreiben das bspw. in Abhängigkeit anderer Messwerte (Feuchte, Uhrzeuit, Temperatur…) die Lüfterstufe verändert.
Vielen Dank!

Ab sofort steht ein IP-Symcon Modul zur Einbindung einer Helios KWL mit easyControls Steuerung zur Verfügung :slight_smile:

[b][Modul] Helios (KWL mit easyControls Steuerung)[/b]

Viele Grüße,
Chris

Hallo PhilippS,
mir wurde die Helios KWL 300W ET als Ersatz für meine defekt Helios EC 300 pro empfohlen. Jetzt suche ich mir die Finger wund nach der Antwort auf eine Frage, die Du als Besitzer hoffentlich leicht beantworten kannst:

Wo ist in der Helios KWL 300W ET die Steuerungselektronik verbaut?

In meinem bisherigen Gerät war dies hinter dem Wärmetauscher, was leider zu einigen Problemen geführt hat (Wasseransammlungen). Deshalb würdest Du mir mit der Antwort sehr helfen.

Danke, Daniel

Hallo Daniel,

die Steuerung ist immernoch hinter dem Wärmetauscher, du musst die Abdeckung hinter dem Wärmetauscher abmachen dann siehst du es

1 „Gefällt mir“

Vielen Dank! Ich kenne das Procedere dann schon von Vorgänger-Gerät. Leider hat sich da immer Wasser angesammelt…