CUL mit IPS 4.0 auf Raspberry Pi3

Hallo,

ich versuche schon seit Tagen einen Busware CUL mit IPS 4.0 auf einen Raspberry Pi3 ans Laufen zu bekommen.
Wen ich den CUL an einem Windows PC über Virtuellen COM-Port und Hyperterminal anspreche bekomme ich auf die Befehle auch die zu erwartende Rückmeldung.

in IPS habe ich den CUL als Serial-I/O-Port eingerichtet (9600,8 Datenbits, 1 Stopbit), wenn ich nun einen Text-Befehl sende auf den ich eine Rückantwort bekommen muss, bleibt diese jedoch aus. Daher gehe ich davon aus, dass keine Kommunikation zum CUL aufgebaut werden kann. :confused:

Weiß hier jemand weiter?

Der CUL läuft auf einen anderen PI und Fhem ohne Probleme.
Habe vor die letzte Funktion (Somfy RTS Rolläden) die derzeit noch in Fhem läuft in IPS umzuziehen.
Mit den Lacrosse Temperatursensoren und dem Jeelink-Stick ging es mit einem kleinen Script ohne Probleme.

Chris

Hat sich erledigt. Musste das Event-Script von hierl etwas anpassen.

Es gibt auch ein IPS 4.0 Modul für Busware CUL/CUN/COC
Tommi

Hallo Tommi,

vielen Dank für den Hinweis. Wo finde ich das Modul?
Im Forum wurde ich leider nicht fündig.

Gruß Chris

Schau mal hier: Übersicht der PHP-Module

paresy

Hi, könntest du zu dem Thema ein bisschen mehr schreiben?
Das habe ich bis dato noch nicht gefunden, fände es aber seeeehr Interessant… (komme von FHEM)

danke und Gruß
Suner

Hallo Suner,

ich bin folgendermaßen vorgegangen:

  • Jeelink mit LaCrosse Sketch
  • in I/O-Instanzen als Serial Port angelegt (Baudrate: 57600 ,8, 1, N)
  • CutterInstanz rechtes Trennzeichen 0D 0A ; Hex
  • Register Variable angelegt welche das action-skript aufruft.
<?
<?

// Zuordnung hier eintragen

// IDs der Sensoren
    $ID_array=array(37 /*EG\Arbeiten\ID*/
    ,3 /*EG\Speisekammer\ID*/
    ,8 /*Aussen_Ws\ID*/
    ,59 /*UG\Bad\ID*/
    ,40 /*Garage\ID*/
    
	 										);
// Arrays mit ID, Temperatur, Luftfeuchtigkeit und Batteriestatus
	 $ID_variable_array=array(34421 /*[EG\Arbeiten\ID]*/ 
	 ,32324
    ,42858 /*[Aussen\Klimasensoren\ID]*/
    ,32856
    ,17410 /*[Garage\ID]*/
	 										);
	 $T_variable_array=array(39793 /*[EG\Arbeiten\Temperatur]*/
	 ,59585
	 ,47977 /*[Aussen\Klimasensoren\Temperatur]*/
	 ,59374
	 ,30470 /*[Garage\Temperatur]*/
	 										);
	 $H_variable_array=array(43464 /*[EG\Arbeiten\Luftfeuchtigkeit]*/
	 ,56477
	 ,38785 /*[Aussen\Klimasensoren\Luftfeuchtigkeit]*/
	 ,40426
	 ,39209 /*[Garage\Luftfeuchtigkeit]*/
      									);
	 $Batt_variable_array=array(33109 /*[EG\Arbeiten\Batterie Klimasensor]*/
	 ,20178
    ,51813 /*[Aussen\Klimasensoren\Batterie Klimasensor]*/
    ,14428
    ,24878 /*[Garage\Batterie Klimasensor]*/
                                 );
    
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'];


    // Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
    RegVar_SetBuffer($_IPS['INSTANCE'], $data);
}

    
// Format
  //
  // OK 9 56 1   4   156 37     ID = 56  T: 18.0  H: 37  no NewBatt
  // OK 9 49 1   4   182 54     ID = 49  T: 20.6  H: 54  no NewBatt
  // OK 9 55 129 4 192 56       ID = 55  T: 21.6  H: 56  WITH NewBatt
  // OK 9 ID XXX XXX XXX XXX
  // |  | |  |   |   |   |
  // |  | |  |   |   |   --- Humidity incl. WeakBatteryFlag
  // |  | |  |   |   |------ Temp * 10 + 1000 LSB
  // |  | |  |   |---------- Temp * 10 + 1000 MSB
  // |  | |  |-------------- Sensor type (1 or 2) +128 if NewBatteryFlag
  // |  | |----------------- Sensor ID
  // |  |------------------- fix "9"
  // |---------------------- fix "OK"
  

// Decodierung

# Temperature sensor - Format:
    #      0   1   2   3   4
    # -------------------------
    # OK 9 56  1   4   156 37     ID = 56  T: 18.0  H: 37  no NewBatt
    # OK 9 49  1   4   182 54     ID = 49  T: 20.6  H: 54  no NewBatt
    # OK 9 55  129 4   192 56     ID = 55  T: 21.6  H: 56  WITH NewBatt

    # OK 9 2   1   4 212 106       ID = 2   T: 23.6  H: -- Channel: 1
    # OK 9 2   130 4 225 125       ID = 2   T: 24.9  H: -- Channel: 2

    # OK 9 ID XXX XXX XXX XXX
    # |  | |  |   |   |   |
    # |  | |  |   |   |   --- Humidity incl. WeakBatteryFlag
    # |  | |  |   |   |------ Temp * 10 + 1000 LSB
    # |  | |  |   |---------- Temp * 10 + 1000 MSB
    # |  | |  |-------------- Sensor type (1 or 2) +128 if NewBatteryFlag
    # |  | |----------------- Sensor ID
    # |  |------------------- fix "9"
    # |---------------------- fix "OK"

	 $data = RegVar_GetBuffer(34355 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable]*/);

    $bytes = explode( ' ', $data);


   $addr = $bytes[2] ;
   
     if (in_array($addr, $ID_array))
  {
    $battery_new = ($bytes[3] & 0x80) >> 7;
    $battery_low = ($bytes[6] & 0x80) >> 7;
    $type = ($bytes[3] & 0x70) >> 4;
    $channel = $bytes[3] & 0x0F;
    $temperature = ($bytes[4]*256 + $bytes[5] - 1000)/10;
    $humidity = $bytes[6] & 0x7f;
 
  // Daten in Variable schreiben
    $key=array_search($addr, $ID_array);
    setvalue($ID_variable_array[$key],$addr);
    setvalue($Batt_variable_array[$key],$battery_low);
    setvalue($T_variable_array[$key],$temperature);
    setvalue($H_variable_array[$key],$humidity);
  }else
  {
   //Hier zukünftiges Skript für autocreate

  }
  
  // Wenn counter =0 Port schließen und LED ausschalten, sonst counter dekrement
  $count=GetValueInteger(43582 /*[Klimatisierung\Klimasensoren\Lacrosse\Counter]*/);
  if($count==0)
  {
  	SPRT_SendText(13147 /*[Jeelink]*/, "0a v");
   IPS_SetProperty(13147 /*[Jeelink]*/, "Open", false);
   IPS_ApplyChanges (13147 /*[Jeelink]*/);
  }else
  {
  $count=$count-1;
  SetValueInteger(43582 /*[Klimatisierung\Klimasensoren\Lacrosse\Counter]*/,$count);
  }
  
?>

Für jeden Sensor müssen die Variablen leider noch manuell angelegt werden. Wenn ich Zeit habe schreibe ich noch ein „autocreate“ Welches die Variable automatisch generiert. (siehe Platzhalter im Skript)

Weil die Sensoren für meine Anwendung die Daten zu oft senden, öffne ich den Serial Port nur alle 5min und empfange x Datensätze (bei mir aktuell Anzahl Sensoren x 3) bevor ich den Port wieder schließe.

Dazu ein Skript welches den Port alle 5 min öffnet und den Counter initialisiert.

<?
// Jellink startup
$AnzahlSens=6;
IPS_SetProperty(13147 /*[Jeelink]*/, "Open", true);
IPS_ApplyChanges (13147 /*[Jeelink]*/);
SetValueInteger(43582 /*[Klimatisierung\Klimasensoren\Lacrosse\Counter]*/, $AnzahlSens*3);

?>

Anbei noch ein Überblick

Ich hoffe es hilft Dir weiter.

Gruß Chris

Update:

Hab mich jetzt doch noch drangesetzt und das autocreate programmiert.

  • Jeelink mit LaCrosse Sketch
  • in I/O-Instanzen als Serial Port angelegt (Baudrate: 57600 ,8, 1, N)
  • CutterInstanz rechtes Trennzeichen 0D 0A ; Hex
  • Register Variable angelegen welche das regvar-skript aufruft.
<?
//Address-Arrays

$Addr_ID=14941 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\IDs]*/;
$Addr_ID_array=49869 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\ID_Variables]*/;
$Addr_T_array=14058 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\T_Variables]*/;
$Addr_H_array=25980 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\H_Variables]*/;
$Addr_Batt_array=42412 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\Batt_Variables]*/;

// Arrays einlesen

   $ID_array = array();
	$ID_array = unserialize(GetValue($Addr_ID));
	
	$ID_variable_array = array();
	$ID_variable_array = unserialize(GetValue($Addr_ID_array));
	
	$T_variable_array = array();
	$T_variable_array = unserialize(GetValue($Addr_T_array));
	
	$H_variable_array = array();
	$H_variable_array = unserialize(GetValue($Addr_H_array));
	
	$Batt_variable_array = array();
	$Batt_variable_array = unserialize(GetValue($Addr_Batt_array));

   
	
    
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'];


    // Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
    RegVar_SetBuffer($_IPS['INSTANCE'], $data);
}

    
// Format
  //
  // OK 9 56 1   4   156 37     ID = 56  T: 18.0  H: 37  no NewBatt
  // OK 9 49 1   4   182 54     ID = 49  T: 20.6  H: 54  no NewBatt
  // OK 9 55 129 4 192 56       ID = 55  T: 21.6  H: 56  WITH NewBatt
  // OK 9 ID XXX XXX XXX XXX
  // |  | |  |   |   |   |
  // |  | |  |   |   |   --- Humidity incl. WeakBatteryFlag
  // |  | |  |   |   |------ Temp * 10 + 1000 LSB
  // |  | |  |   |---------- Temp * 10 + 1000 MSB
  // |  | |  |-------------- Sensor type (1 or 2) +128 if NewBatteryFlag
  // |  | |----------------- Sensor ID
  // |  |------------------- fix "9"
  // |---------------------- fix "OK"
  

// Decodierung

# Temperature sensor - Format:
    #      0   1   2   3   4
    # -------------------------
    # OK 9 56  1   4   156 37     ID = 56  T: 18.0  H: 37  no NewBatt
    # OK 9 49  1   4   182 54     ID = 49  T: 20.6  H: 54  no NewBatt
    # OK 9 55  129 4   192 56     ID = 55  T: 21.6  H: 56  WITH NewBatt

    # OK 9 2   1   4 212 106       ID = 2   T: 23.6  H: -- Channel: 1
    # OK 9 2   130 4 225 125       ID = 2   T: 24.9  H: -- Channel: 2

    # OK 9 ID XXX XXX XXX XXX
    # |  | |  |   |   |   |
    # |  | |  |   |   |   --- Humidity incl. WeakBatteryFlag
    # |  | |  |   |   |------ Temp * 10 + 1000 LSB
    # |  | |  |   |---------- Temp * 10 + 1000 MSB
    # |  | |  |-------------- Sensor type (1 or 2) +128 if NewBatteryFlag
    # |  | |----------------- Sensor ID
    # |  |------------------- fix "9"
    # |---------------------- fix "OK"

	 $data = RegVar_GetBuffer(34355 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable]*/);

    $bytes = explode( ' ', $data);


    $addr = $bytes[2] ;
   if (strlen($addr)<=2 )
   {
    $battery_new = ($bytes[3] & 0x80) >> 7;
    $battery_low = ($bytes[6] & 0x80) >> 7;
    $type = ($bytes[3] & 0x70) >> 4;
    $channel = $bytes[3] & 0x0F;
    $temperature = ($bytes[4]*256 + $bytes[5] - 1000)/10;
    $humidity = $bytes[6] & 0x7f;
   }
   
   if (in_array($addr, $ID_array) and strlen($addr)<=2 )
  {
  
  // Daten in Variable schreiben
    $key=array_search($addr, $ID_array);
    setvalue($ID_variable_array[$key],$addr);
    setvalue($Batt_variable_array[$key],$battery_low);
    setvalue($T_variable_array[$key],$temperature);
    setvalue($H_variable_array[$key],$humidity);
  }elseif( strlen($addr)<=2)
  {
  
  $CatID = IPS_CreateCategory();       // Kategorie anlegen
  IPS_SetName($CatID,$addr); // Kategorie benennen
  IPS_SetParent($CatID,IPS_GetParent ( IPS_GetParent ( $_IPS['SELF']))); // Kategorie einsortieren unter dem Objekt mit der ID "12345"
  
  $ID_array[]=$addr;
  SetValue($Addr_ID,serialize($ID_array));
  
  $VarID_ID= IPS_CreateVariable(1);
  IPS_SetName($VarID_ID, "ID"); // Variable benennen
  IPS_SetParent($VarID_ID, $CatID ); // Variable einsortieren
  SetValue($VarID_ID, $addr);
  $ID_variable_array[]=$VarID_ID;
  SetValue($Addr_ID_array,serialize($ID_variable_array));
  
  $VarID_T= IPS_CreateVariable(2);
  IPS_SetName($VarID_T, "Temperatur"); // Variable benennen
  IPS_SetParent($VarID_T,  $CatID ); // Variable einsortieren
  IPS_SetVariableCustomProfile($VarID_T, "~Temperature");
  SetValue($VarID_T, $temperature);
  $T_variable_array[]=$VarID_T;
  SetValue($Addr_T_array,serialize($T_variable_array));
  
  $VarID_H= IPS_CreateVariable(2);
  IPS_SetName($VarID_H, "Luftfeuchtigkeit"); // Variable benennen
  IPS_SetParent($VarID_H,  $CatID ); // Variable einsortieren 
  IPS_SetVariableCustomProfile($VarID_H, "~Humidity.F");
  SetValue($VarID_H, $humidity);
  $H_variable_array[]=$VarID_H;
  SetValue($Addr_H_array,serialize($H_variable_array));
  
  $VarID_Batt= IPS_CreateVariable(0);
  IPS_SetName($VarID_Batt, "Batterie Klimasensor"); // Variable benennen
  IPS_SetParent($VarID_Batt,  $CatID ); // Variable einsortieren 
  IPS_SetVariableCustomProfile($VarID_Batt, "~Battery");
  SetValue($VarID_Batt, $battery_low);
  $Batt_variable_array[]=$VarID_Batt;
  SetValue($Addr_Batt_array,serialize($Batt_variable_array));
  }else{
  }
  
  // Wenn counter =0 Port schließen und LED ausschalten, sonst counter dekrement
  $count=GetValueInteger(43582 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\Counter]*/);
  if($count==0)
  {
  	SPRT_SendText(13147 /*[Jeelink]*/, "0a v");
   IPS_SetProperty(13147 /*[Jeelink]*/, "Open", false);
   IPS_ApplyChanges (13147 /*[Jeelink]*/);
  }else
  {
  $count=$count-1;
  SetValueInteger(43582 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\Counter]*/,$count);
  }
  
?>
  • Folgende Variablen unter der Register variablen anlegen

  • Alle Variablen IDs ausser Counter in regvar-skript unter Address-Arrays eintragen.

  • Startup skript wie im vorherigen Beitrag anlegen und die deine ID für den Counter (bei set value) und die ID für den Serial Port (bei Set property und applychanges) eintragen.

  • Jetzt sollte Pro empfangenem Sensor eine Kategorie (Name entspricht der Sensor ID oben im Bild ID 35) angelegt werden, welche die zugehörigen Variablen/Werte enthält. Der Inhalt der Kategorie kann jetzt beliebig im Projekt verschoben werden.

Gruß Chris

Ich habe mal den Jeelink für cuxd angepasst… das ist jetzt aber irgendwie etwas ungüsntig…
könntest du mir vll deinen Sketch zur Verfügung stellen?

gruß
Suner

hab einen Sketch gefunden der ganz gut aussieht;) werde mal rumprobieren.

Ich habe das Ganze jetzt mal ausprobiert.
Er hat auch was gemacht, sieht aber nicht so ganz richtig aus.

Vielleicht hast du ja, oder auch jemand anders eine Idee…
serial.PNG

Irgendwie habe ich die doofe Vermutung, dass nicht das Empfangen wird, was das Script erwartet… hatte vorhin den Stick mal an nem Windows mit nem Putty, da sahen die Empfangenen Daten eigentlich ganz gut aus…

zusätzliche kriege ich noch folgendes in der Ausgabe des Scriptes:


Notice:  Undefined offset: 2 in /var/lib/symcon/scripts/39508.ips.php on line 86

Notice:  Undefined offset: 3 in /var/lib/symcon/scripts/39508.ips.php on line 89

Notice:  Undefined offset: 6 in /var/lib/symcon/scripts/39508.ips.php on line 90

Notice:  Undefined offset: 3 in /var/lib/symcon/scripts/39508.ips.php on line 91

Notice:  Undefined offset: 3 in /var/lib/symcon/scripts/39508.ips.php on line 92

Notice:  Undefined offset: 4 in /var/lib/symcon/scripts/39508.ips.php on line 93

Notice:  Undefined offset: 5 in /var/lib/symcon/scripts/39508.ips.php on line 93

Notice:  Undefined offset: 6 in /var/lib/symcon/scripts/39508.ips.php on line 94

Habe das Skript mittlerweile etwas robuster und universeller gemacht. Es funktioniert jetzt auch mit Sensoren welche anstatt Temperatur und Luftfeuchte, zwei Temperaturen alternierend senden.

Für das neue Skript muss zusätzlich eine Variable für die Adressen der zweiten Temperatur angelegt werden.

Und am Anfang des Skripts die Variablen IDs eingetragen werden.

Hier das neue Skript:

<?
//Address-Arrays mit IDs der Variablen

$Addr_ID=14941 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\IDs]*/;
$Addr_ID_array=49869 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\ID_Variables]*/;
$Addr_T_array=14058 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\T_Variables]*/;
$Addr_T2_array=51339 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\T2_Variables]*/;
$Addr_H_array=25980 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\H_Variables]*/;
$Addr_Batt_array=42412 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\Batt_Variables]*/;
$Addr_counter=43582 /*[Klimatisierung\Klimasensoren\Lacrosse\Register Variable\Counter]*/ ;
$Addr_Jeelink=13147 /*[Jeelink]*/;

// Arrays einlesen

   $ID_array = array();
	$ID_array = unserialize(GetValue($Addr_ID));
	
	$ID_variable_array = array();
	$ID_variable_array = unserialize(GetValue($Addr_ID_array));
	
	$T_variable_array = array();
	$T_variable_array = unserialize(GetValue($Addr_T_array));
	
	$T2_variable_array = array();
	$T2_variable_array = unserialize(GetValue($Addr_T2_array));
	
	$H_variable_array = array();
	$H_variable_array = unserialize(GetValue($Addr_H_array));
	
	$Batt_variable_array = array();
	$Batt_variable_array = unserialize(GetValue($Addr_Batt_array));

   
	
    
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'];


    // Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
    RegVar_SetBuffer($_IPS['INSTANCE'], $data);
}

    
// Format
  //
  // OK 9 56 1   4   156 37     ID = 56  T: 18.0  H: 37  no NewBatt
  // OK 9 49 1   4   182 54     ID = 49  T: 20.6  H: 54  no NewBatt
  // OK 9 55 129 4 192 56       ID = 55  T: 21.6  H: 56  WITH NewBatt
  // OK 9 ID XXX XXX XXX XXX
  // |  | |  |   |   |   |
  // |  | |  |   |   |   --- Humidity incl. WeakBatteryFlag
  // |  | |  |   |   |------ Temp * 10 + 1000 LSB
  // |  | |  |   |---------- Temp * 10 + 1000 MSB
  // |  | |  |-------------- Sensor type (1 or 2) +128 if NewBatteryFlag
  // |  | |----------------- Sensor ID
  // |  |------------------- fix "9"
  // |---------------------- fix "OK"
  

// Decodierung

# Temperature sensor - Format:
    #      0   1   2   3   4
    # -------------------------
    # OK 9 56  1   4   156 37     ID = 56  T: 18.0  H: 37  no NewBatt
    # OK 9 49  1   4   182 54     ID = 49  T: 20.6  H: 54  no NewBatt
    # OK 9 55  129 4   192 56     ID = 55  T: 21.6  H: 56  WITH NewBatt

    # OK 9 2   1   4 212 106       ID = 2   T: 23.6  H: -- Channel: 1
    # OK 9 2   130 4 225 125       ID = 2   T: 24.9  H: -- Channel: 2

    # OK 9 ID XXX XXX XXX XXX
    # |  | |  |   |   |   |
    # |  | |  |   |   |   --- Humidity incl. WeakBatteryFlag
    # |  | |  |   |   |------ Temp * 10 + 1000 LSB
    # |  | |  |   |---------- Temp * 10 + 1000 MSB
    # |  | |  |-------------- Sensor type (1 or 2) +128 if NewBatteryFlag
    # |  | |----------------- Sensor ID
    # |  |------------------- fix "9"
    # |---------------------- fix "OK"

	 $data = RegVar_GetBuffer($_IPS['INSTANCE']);

    $bytes = explode( ' ', $data);

if ($bytes[0]=='OK' and count($bytes[0])<=2 )
{
    $addr = $bytes[2] ;
    $battery_new = ($bytes[3] & 0x80) >> 7;
    $battery_low = ($bytes[6] & 0x80) >> 7;
    $type = ($bytes[3] & 0x70) >> 4;
    $channel = $bytes[3] & 0x0F;
    $temperature = ($bytes[4]*256 + $bytes[5] - 1000)/10;
    $humidity = $bytes[6] & 0x7f;
   
   if (in_array($addr, $ID_array))
  {
  
  // Daten in Variable schreiben
    $key=array_search($addr, $ID_array);
    setvalue($ID_variable_array[$key],$addr);
    setvalue($Batt_variable_array[$key],$battery_low);
	 if($channel==1){
    setvalue($T_variable_array[$key],$temperature);
    }elseif($channel==2){
    setvalue($T2_variable_array[$key],$temperature);
    }
    if($humidity<100){
    setvalue($H_variable_array[$key],$humidity);
    }else{
    setvalue($H_variable_array[$key],999);
	 }
    
  }else
  {
  
  $CatID = IPS_CreateCategory();       // Kategorie anlegen
  IPS_SetName($CatID,$addr); // Kategorie benennen
  IPS_SetParent($CatID,IPS_GetParent ( IPS_GetParent ( $_IPS['SELF']))); // Kategorie einsortieren unter dem Objekt mit der ID "12345"
  
  $ID_array[]=$addr;
  SetValue($Addr_ID,serialize($ID_array));
  
  $VarID_ID= IPS_CreateVariable(1);
  IPS_SetName($VarID_ID, "ID"); // Variable benennen
  IPS_SetParent($VarID_ID, $CatID ); // Variable einsortieren
  SetValue($VarID_ID, $addr);
  $ID_variable_array[]=$VarID_ID;
  SetValue($Addr_ID_array,serialize($ID_variable_array));
  
  $VarID_T= IPS_CreateVariable(2);
  IPS_SetName($VarID_T, "Temperatur"); // Variable benennen
  IPS_SetParent($VarID_T,  $CatID ); // Variable einsortieren
  IPS_SetVariableCustomProfile($VarID_T, "~Temperature");
  SetValue($VarID_T, $temperature);
  $T_variable_array[]=$VarID_T;
  SetValue($Addr_T_array,serialize($T_variable_array));
  
  $VarID_T2= IPS_CreateVariable(2);
  IPS_SetName($VarID_T2, "Temperatur2"); // Variable benennen
  IPS_SetParent($VarID_T2,  $CatID ); // Variable einsortieren
  IPS_SetVariableCustomProfile($VarID_T2, "~Temperature");
  SetValue($VarID_T2, $temperature);
  $T2_variable_array[]=$VarID_T2;
  SetValue($Addr_T2_array,serialize($T2_variable_array));
  
  $VarID_H= IPS_CreateVariable(2);
  IPS_SetName($VarID_H, "Luftfeuchtigkeit"); // Variable benennen
  IPS_SetParent($VarID_H,  $CatID ); // Variable einsortieren 
  IPS_SetVariableCustomProfile($VarID_H, "~Humidity.F");
  SetValue($VarID_H, $humidity);
  $H_variable_array[]=$VarID_H;
  SetValue($Addr_H_array,serialize($H_variable_array));
  
  $VarID_Batt= IPS_CreateVariable(0);
  IPS_SetName($VarID_Batt, "Batterie Klimasensor"); // Variable benennen
  IPS_SetParent($VarID_Batt,  $CatID ); // Variable einsortieren 
  IPS_SetVariableCustomProfile($VarID_Batt, "~Battery");
  SetValue($VarID_Batt, $battery_low);
  $Batt_variable_array[]=$VarID_Batt;
  SetValue($Addr_Batt_array,serialize($Batt_variable_array));
  }
}
  
  // Wenn counter =0 Port schließen und LED ausschalten und Arrays ggf. aufräumen, sonst counter dekrement
  $count=GetValueInteger($Addr_counter);
  if($count==0)
  {
  	SPRT_SendText($Addr_Jeelink, "0a v");
   IPS_SetProperty($Addr_Jeelink, "Open", false);
   IPS_ApplyChanges ($Addr_Jeelink);
   
   //Arrays aufräumen
   
   for ($i = 0; $i <= count($ID_variable_array)-1; $i++) {
   if (IPS_VariableExists($ID_variable_array[$i])){
   }else{
   
   unset($ID_array[$i]);
   $ID_array = array_values($ID_array);
   SetValue($Addr_ID,serialize($ID_array));
   //print_r($ID_array);
   
   unset($ID_variable_array[$i]);
   $ID_variable_array = array_values($ID_variable_array);
   SetValue($Addr_ID_array,serialize($ID_variable_array));
   //print_r($ID_variable_array);
   
   unset($T_variable_array[$i]);
   $T_variable_array = array_values($T_variable_array);
   SetValue($Addr_T_array,serialize($T_variable_array));
   //print_r($T_variable_array);
   
   unset($T2_variable_array[$i]);
   $T2_variable_array = array_values($T2_variable_array);
   SetValue($Addr_T2_array,serialize($T2_variable_array));
   //print_r($T2_variable_array);
   
   unset($H_variable_array[$i]);
   $H_variable_array = array_values($H_variable_array);
   SetValue($Addr_H_array,serialize($H_variable_array));
   //print_r($H_variable_array);
   
   unset($Batt_variable_array[$i]);
   $Batt_variable_array = array_values($Batt_variable_array);
   SetValue($Addr_Batt_array,serialize($Batt_variable_array));
   //print_r($Batt_variable_array);
  
   }
   }
   
  }else
  {
  $count=$count-1;
  SetValueInteger($Addr_counter,$count);
  }
  
?>

Einstellung Jeelink:
Unbenannt.png
Einstellung Cutter:
Unbenannt1.png

Super,
Danke dir schon mal.
Ich werde es ausprobieren und dann noch mal ganz in Ruhe das Script durchgehen und dann versuchen zu lernen und zu verstehen :stuck_out_tongue:

JAWOLLO!!!
EIN TRAUM!!!

Danke dir :slight_smile:

:loveips::loveips::loveips:

Hallo Chris,

ziemlich am Anfang diese Threads hast du geschrieben, dass du deinen SOMFY/RTS nach IPS umziehen wolltest. Hat das schon geklappt?

Ich habe mein CUL zur Zeit an der CCU2 und möchte ihn auch direkt unter IPS (am Raspi) betreiben, um auf die letzten FS20- und FHT80B-GEräte zugreifen zu können. Aber da läuft auch noch die Steuerung meiner Symfy/RTS - Rolläden auf der CCU2 und CUL und die möchte ich ja auch weiterhin nutzen.
Ich bin ein Anfänger unter IPS und PHP ist mir ganz neu. Der Aufwand das von CCU2/Tcl nach IPS/PHP umzuziehen ist für mich enorm und ich fürchte, dass ich das nicht schaffen werde.

Deshalb wäre es ja toll wenn du das schon hinbekommen hättest und es hier mal vorstellen könntest :smiley:

viele Grüße
cervicor

Hallo Cervicor,

ja hab es geschafft Somfy RTS über einen CUL aus IPS zu steuern.
Ich versuche es so gut es geht zu beschreiben.

  1. CUL als seriellen Port anlegen (9600, Datenbits 8, Stopbit 1, keine Parität)
  2. Cutter instanz anlegen (hab aber gesehen dass ich keine Trennzeichen angegeben habe) kann man sich vermutlich sparen weil nur gesendet wird
  3. Register Variable anlegen und als Übergeordnete Instanz den Cutter angeben bzw. den seriellen Port direkt wenn kein Cutter erstellt wurde
  4. Unterhalb der Register Variablen ein Skript erstellen welches folgenden Inhalt hat (Ursprüngliche Quelle: http://www.tdressler.net/ipsymcon/cun_ips.html)
<?php
/**
* RegVar-Script für busware.de CUL/CUN receiver
* protocol decodes translated from FHEM project
* http://www.koeniglich.de/fhem/fhem.html
* testet with IPS 3.1 and CUN FW 1.46/COC FW 1.61 (ESA not tested)
* http://www.tdressler.net/ipsymcon
* V0.19 06.02.2015
* @package CUN
*/

//Regvar-Instance
$reg=55121 /*[CUL\Register Variable]*/;
#$reconnect=58270;

if (!IPS_InstanceExists($reg)) {
			print "Instance with ID $reg doesnt exists";
			return;
}
$inst=IPS_GetInstance($reg);
$ityp=$inst['ModuleInfo']['ModuleName'];
if ($ityp!="Register Variable") {
			print "Instance $reg is not a 'Register Variable' Instance";
			return;
}
//get message variable
$lmid=getVid('AuxMessage',$reg,3);
//load error variable
$errid=getVid('Errors',$reg,1);
$errors=GetValueInteger($errid);
setValue($errid,0);
//autocreate IPS Objects, set to false if you dont want this
$autocreate=true;

//logging
$logdir='../logs/';
$cullog=$logdir."cul.log";


//manual executed
if ($_IPS['SENDER'] == "Execute")
{
/*
	Start/Stop Parent,
	set Modus vis CUL_Status Event script capturing Status change
*/
   //Status variablen
	$versid=getVid('Version',$reg,3);
	$mid=getVid('Modus',$reg,3);
	//Parent=ClientSocket or ComPort
	$sid=IPS_GetParent($reg);
	if ($sid) {
	   $inst=IPS_GetInstance($sid);
	   $ityp=$inst['ModuleInfo']['ModuleName'];
	   if ($ityp=="Client Socket") {
			setValue($mid,"");
			setValue($versid,"");
			//stop
			CSCK_SetOpen($sid,false);
			IPS_ApplyChanges($sid);
			sleep(1);
			//start
			CSCK_SetOpen($sid,true);
			IPS_ApplyChanges($sid);
		}elseif($ityp=="Serial Port") {
			setValue($mid,"");
			setValue($versid,"");
			//stop
			ComPort_SetOpen($sid,false);
			IPS_ApplyChanges($sid);
			sleep(1);
			//start
			ComPort_SetOpen($sid,true);
			IPS_ApplyChanges($sid);
		}else{
		   print "Modultyp wrong";
		   return;
		}
		sleep(1);
		$modus=getValue($mid);
		print "Modus: $modus 
";
		$version=getValue($versid);
		print "Version: $version
\r";
   }else{
   	print "Parent not found";
   }
}
//register variable triggerd action
elseif ($_IPS['SENDER'] == "RegisterVariable")
{
  // bereits im Puffer der Instanz vorhandene Daten in $data kopieren
  $data  = RegVar_GetBuffer($reg);
  // neu empfangene Daten an $data anhängen
  $data .= $_IPS['VALUE'];


	//split lines
	$rows=preg_split("/
/",$data);
	//reset Regvar Buffer
	$data="";
	RegVar_SetBuffer($reg, "");

	foreach($rows as $line) {
//---------------EM1000-----------------------------------

		if (preg_match("/^E[0-9A-F]{18,20}\s*\$/",$line)) {
      //  E0101E2997805002F02
			$type=substr($line,2,1);
			$addr=substr($line,3,2);
			$addr_num=hexdec($addr);
			$catname='EM1010CUL';
			$sensorname='EM1010 Sensor';
			$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
			                  'Signal'=>array('type'=>1,'profile'=>''),
	                        'Last'=>array('type'=>1,'profile'=>'~UnixTimestamp'),
									'Total'=>array('type'=>2,'profile'=>'~Electricity'),
									'Actual'=>array('type'=>2,'profile'=>'~Power'),
									'Peak'=>array('type'=>2,'profile'=>'~Power'),
									'total_cnt'=>array('type'=>1,'profile'=>''),
									'basis_cnt'=>array('type'=>1,'profile'=>''),
									'cf_power'=>array('type'=>2,'profile'=>''),
									'cf_energy'=>array('type'=>2,'profile'=>''));
			$varids=get_ips_vars($addr,$vartypes,$catname,$sensorname);
			if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
			}
			$cf1=$varids['cf_power']['val'];
			$cf2=$varids['cf_energy']['val'];
			$basis_cnt=$varids['basis_cnt']['val'];
			$total_cnt_last=$varids['total_cnt']['val'];
			$last=$varids['Last']['val'];
			//ips_logmessage($catname,"1:$cf1,2:$cf2,B:$basis_cnt,T:$total_cnt_last,L:$last");

			/*
			Set corretion factor
			corr1 is the correction factor for power
			corr2 is the correction factor for energy
			*/
			$cfnew=(($cf1==0)||($cf2==0));
			if($addr_num >= 1 && $addr_num <= 4) {                // EMWZ: nRotation in 5 minutes
    				$cf1 = ($cf1 ? $cf1 : 150);					//Zählerkonstanzte U/kwh
    				$cf2 = ($cf2 ? $cf2 : 150);
    				$corr1=12/$cf1;
    				$corr2=1/$cf2;

	  		} elseif ($addr_num >= 5 && $addr_num <= 8) {          // EMEM
		   		$cf1 = ($cf1 ? $cf1 : 0.01);
    				$cf2 = ($cf2 ? $cf2 : 0.001);
    				$corr1=$cf1;
    				$corr2=$cf2;

	  		} elseif($addr_num >= 9 && $addr_num <= 12) {          // EMGZ: 0.01
   	 		$cf1 = ($cf1 ? $cf1 : 0.01);
    			$cf2 = ($cf2 ? $cf2 : 0.01);
    			$corr1=$cf1;
    			$corr2=$cf2;

	  	  } else {
			IPS_Logmessage($catname,"Wrong Address:$addr");
			setValue($errid,$errors+1);
			continue 2;
			return;
  		  }
			//store default factors
			if ($cfnew) {
				SetValue($varids['cf_power']['id'],$cf1);
				SetValue($varids['cf_energy']['id'],$cf2);
			}

/*
		Decode Packet
		description from CUL_EM.pm
	  Ettaacc111122223333
        tt:type 01=EM-1000s, 02=EM-100-EM, 03=1000GZ
        aa:address, depending on the type above 01:01-04, 02:05-08, 03:09-12
        cc:counter, will be incremented by one for each message
        1111: cumulated value
        2222: last value (Not set for type 2)
        3333: top value  (Not set for type 2)
    seqno    =  number of received datagram in sequence, runs from 2 to 255
  	 total_cnt=  total (cumulated) value in ticks as read from the device
  	 basis_cnt=  correction to total (cumulated) value in ticks to account for
               counter wraparounds
  	 total    =  total (cumulated) value in device units
  	 current  =  current value (average over latest 5 minutes) in device units
    peak     =  maximum value in device units
*/


			$seqno=hexdec(substr($line,5,2));
			//total value
			$total_cnt=hexdec(substr($line,9,2).substr($line,7,2));
			//counter overflow, max value 65535
			if($total_cnt< $total_cnt_last) {
      		$basis_cnt += 65536;
      		SetValue($varids['basis_cnt']['id'],$basis_cnt);
    		}
    		$total    = ($basis_cnt+$total_cnt)*$corr2;
    		SetValue($varids['total_cnt']['id'],$total_cnt);

      	//check time diff tp previous
   		$now=time();
			$tdiff=$now-$last;

			// peak and current (5min) value
			if ($type<>2) {
				$current_cnt=hexdec(substr($line,13,2).substr($line,11,2));
				$peak_cnt=hexdec(substr($line,17,2).substr($line,15,2));
				$current  = $current_cnt*$corr1;
    			$peak     = $peak_cnt*$corr1;
			}else{
		   	//calculate current as counter difference
				if ($total_cnt>=$total_cnt_last) {
					$current_cnt=$total_cnt-$total_cnt_last;
				}else{
			   	//add overflow
					$current_cnt=$total_cnt+65536-$total_cnt_last;
				}
         	//type 2 has no peak and current entry
				$current  = $current_cnt*$corr1;
				$peak=0;
				$peak_cnt=0;
			}

			//store in IPS
   		SetValue($varids['Total']['id'],$total);
   		SetValue($varids['Actual']['id'],$current);
   		SetValue($varids['Peak']['id'],$peak);
			SetValue($varids['Last']['id'],$now);

			//signal
			if ( strlen($line)>19) {
			   SetSignal($varids['Signal']['id'],substr($line,19,2));
			}
			//logging to IPS log
	 		$val = sprintf("SEQ: %d CNT: %d Basis: %d DIFF: %d TIME:$tdiff CUM: %0.3f  5MIN: %0.3f  PEAK: %d TOP: %0.3f",
                         $seqno, $total_cnt, $basis_cnt,$current_cnt,$total, $current,$peak_cnt, $peak);
 			$text= "Type $type Addr:$addr, $val";

   		//logging
  			IPS_Logmessage($catname,$text);


	}//if pregmatch
//-----------------------FS20
	elseif (preg_match("/^F[0-9A-F]{8,12}\s*\$/",$line)) {
 		//F1F1E013A4F
  			$hcode=substr($line,1,4);
 			$addr=substr($line,5,2);
 			$cde=substr($line,7,2);
			$id=hex2four($hcode.$addr);
			if (strlen($id)==12)$id=substr($id,0,4).' '.substr($id,4,4).' '.substr($id,8,4);
			$catname='FS20CUL';
			$sensorname='FS20 ';
			$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
									'Status'=>array('type'=>3,'profile'=>''),
									'Signal'=>array('type'=>1,'profile'=>'')
	                        );
			$varids=get_ips_vars($id,$vartypes,$catname,$sensorname);
			if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
			}
 			$fs20_codes = array(
 			//definitions taken from http://www.elv.de/downloads/faq/Zuordnung_interne_Programmbezeichnungen_zu_FS20_Befehlcodes.pdf
			  	"00" => "off",
  				"01" => "dim06%",
  				"02" => "dim12%",
  				"03" => "dim18%",
  				"04" => "dim25%",
  				"05" => "dim31%",
  				"06" => "dim37%",
  				"07" => "dim43%",
  				"08" => "dim50%",
  				"09" => "dim56%",
  				"0A" => "dim62%",
  				"0B" => "dim68%",
  				"0C" => "dim75%",
  				"0D" => "dim81%",
  				"0E" => "dim87%",
  				"0F" => "dim93%",
  				"10" => "dim100%/On",
  				"11" => "Dim to previous",		// Set to previous dim value (before switching it off)
  				"12" => "toggle",	// between off and previous dim val
  				"13" => "dimup",
  				"14" => "dimdown",
  				"15" => "dimupdown",
  				"16" => "set timer",
  				"17" => "nop",
  				"18" => "off-for-timer",
  				"19" => "on-for-timer than out",
  				"1A" => "on-old-for-timer than out",
  				"1B" => "reset",
  				"1C" => "ramp-on-time",      //time to reach the desired dim value on dimmers
  				"1D" => "ramp-off-time",     //time to reach the off state on dimmers
  				"1E" => "on-old-for-timer-prev", // old val for timer, then go to prev. state
  				"1F" => "on-100-for-timer-prev", // 100% for timer, then go to previous state
  				"20" => "Timer off",
  				"21" => "Dim Timer to 06%",
  				"22" => "Dim Timer to 12%",
  				"23" => "Dim Timer to 18%",
  				"24" => "Dim Timer to 25%",
  				"25" => "Dim Timer to 31%",
  				"26" => "Dim Timer to 37%",
  				"27" => "Dim Timer to 43%",
  				"28" => "Dim Timer to 50%",
  				"29" => "Dim Timer to 56%",
  				"2A" => "Dim Timer to 62%",
  				"2B" => "Dim Timer to 68%",
  				"2C" => "Dim Timer to 75%",
  				"2D" => "Dim Timer to 81%",
  				"2E" => "Dim Timer to 87%",
  				"2F" => "Dim Timer to 93%",
  				"30" => "Dim Timer to 100%/On",
  				"31" => "Dim Timer to previous",	// Set to previous dim value (before switching it off)
  				"32" => "toggle",	// between off and previous dim val
  				"33" => "Dim Timer up one level",
  				"34" => "Dim Timer down one level",
  				"35" => "updown one level, out after Timer ",
  				"36" => "set timer",
  				"37" => "nop",
  				"38" => "off-for-timer",
  				"39" => "on-for-timer than out",
  				"3A" => "on-to-old-for-timer than out",
  				"3B" => "reset",
  				"3C" => "ramp-on-time",      //time to reach the desired dim value on dimmers
  				"3D" => "ramp-off-time",     //time to reach the off state on dimmers
  				"3E" => "on-old-for-timer-prev", // old val for timer, then go to prev. state
  				"3F" => "on-100-for-timer-prev", // 100% for timer, then go to previous state
			);
  		if (isset($fs20_codes[$cde])) {
  		   $v =$fs20_codes[$cde];
  		}else {
		  $v = "unknown Code $cde" ;
		  setValue($errid,$errors+1);
		  IPS_Logmessage($catname,"Err:$errors ($v)");
		  continue ;
		}
		$varids=get_ips_vars($id,$vartypes,$catname,$sensorname);
		if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
		}
 			$dur = 0;
  		$cx = hexdec($cde);
  		if($cx & 0x20) {
    		$dur = hexdec(substr($line, 9, 2));
    		$i = ($dur & 0xf0) / 16;
    		$j = ($dur & 0xf);
    		$dur = pow(2,$i)*$j*0.25;
    		$cde = sprintf("%02x", $cx & ~0x20);
		}
  		if($dur) $v .= " DUR: $dur" ;
    		//signal
			if ( strlen($line)>11) {
			   SetSignal($varids['Signal']['id'],substr($line,11,2));
  		}else{
  			//signal
			if ( strlen($line)>9) {
			   SetSignal($varids['Signal']['id'],substr($line,9,2));
			}
		}


		$text= "Dev $id: $v($cde)";
		SetValue($varids['Status']['id'],$v);


		//logging
  		IPS_Logmessage($catname,$text);


 	} //if pregmatch
//------------------FHT----------------------------------
	elseif (preg_match("/^(T[0-9A-F]{8,12})\s*\$/",$line,$res)) {
	      //T4414B90106
 			//T0A4700BA00
 			//T500CFD8237

 			$varids=null;
			$res=$res[1];
 			$dev = substr($res, 1, 4);
  			$cde = substr($res, 5, 2);
	    if(strlen($res) <12 ) {
		  //TFK with signal
		   $dev = substr($res, 1, 6);
		   $cde = substr($res, 7, 2);
		   $val=$res;
 			$catname='FHTTFKCUL';
			$sensorname='FHTTFK ';
			$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
			                  'Signal'=>array('type'=>1,'profile'=>''),
					  'Window'=>array('type'=>3,'profile'=>''),
					  'Warnings'=>array('type'=>3,'profile'=>''),
					  'Status'=>array('type'=>3,'profile'=>''));
			$varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
			if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
			}

	       		$FHT_tfk_codes = array(
    			"02" => "Window:Closed",
    			"82" => "Window:Closed",
    			"01" => "Window:Open",
    			"81" => "Window:Open",
    			"0C" => "Sync:Syncing",
    			"91" => "Window:Open, Low Batt",
    			"11" => "Window:Open, Low Batt",
    			"92" => "Window:Closed, Low Batt",
    			"12" => "Window:Closed, Low Batt",
    			"0F" => "Test:Success");

		  switch ($cde) {

		     case "01":
		     case "81": $win="open";
				 SetValue($varids['Window']['id'],$win);
			         break;
		     case "02":
		     case "82": $win="closed";
				 SetValue($varids['Window']['id'],$win);
			         break;
		     case "11":
		     case "91": $win="open";
				 $warn="Low Batt";
			         SetValue($varids['Window']['id'],$win);
				 SetValue($varids['Warnings']['id'],$warn);
			         break;
		     case "12":
		     case "92": $win="closed";
			       $warn="Low Batt";
			       SetValue($varids['Window']['id'],$win);
				 SetValue($varids['Warnings']['id'],$warn);
			         break;
				default: break;
		  }
		  //signal
			if ( strlen($res)>9) {
			   SetSignal($varids['Signal']['id'],substr($res,9,2));
			}

		  $val="";
		  $cmd=isset($FHT_tfk_codes[$cde])?$FHT_tfk_codes[$cde]:"Unknown TFK:$cde";
		  SetValue($varids['Status']['id'],"$cmd");
		  $text="FHT TFK Dev $dev:";
		  $text.= " $cmd" ;


      //logging
  		IPS_Logmessage($catname,$text);

	    } else {
 			$catname='FHTCUL';
			$sensorname='FHT ';
			$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
			                  'HC'=>Array('type'=>3,'profile'=>''),
			                  'Signal'=>array('type'=>1,'profile'=>''),
									'Low'=>array('type'=>3,'profile'=>''),
                           'Position'=>array('type'=>3,'profile'=>''),
									'Warnings'=>array('type'=>3,'profile'=>''),
									'Soll'=>array('type'=>2,'profile'=>'~Temperature'),
									'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
									'Status'=>array('type'=>3,'profile'=>''));
			$varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
			if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
			}
			$FHT_codes = array(
  				"00" => "actuator",
  				"01" => "actuator1",
  				"02" => "actuator2",
  				"03" => "actuator3",
  				"04" => "actuator4",
  				"05" => "actuator5",
  				"06" => "actuator6",
  				"07" => "actuator7",
  				"08" => "actuator8",

  				"14" => "mon-from1",
  				"15" => "mon-to1",
  				"16" => "mon-from2",
  				"17" => "mon-to2",
  				"18" => "tue-from1",
  				"19" => "tue-to1",
  				"1A" => "tue-from2",
  				"1B" => "tue-to2",
  				"1C" => "wed-from1",
  				"1D" => "wed-to1",
  				"1E" => "wed-from2",
  				"1F" => "wed-to2",
  				"20" => "thu-from1",
  				"21" => "thu-to1",
  				"22" => "thu-from2",
  				"23" => "thu-to2",
  				"24" => "fri-from1",
  				"25" => "fri-to1",
  				"26" => "fri-from2",
  				"27" => "fri-to2",
  				"28" => "sat-from1",
  				"29" => "sat-to1",
  				"2A" => "sat-from2",
  				"2B" => "sat-to2",
  				"2C" => "sun-from1",
  				"2D" => "sun-to1",
  				"2E" => "sun-from2",
  				"2F" => "sun-to2",

			  	"3E" => "mode",
  				"3F" => "holiday1",		# Not verified
  				"40" => "holiday2",		# Not verified
  				"41" => "desired-temp",
  				"XX" => "measured-temp",		# sum of next. two, never really sent
  				"42" => "measured-low",
  				"43" => "measured-high",
  				"44" => "warnings",
  				"45" => "manu-temp",		# No clue what it does.

  				"4B" => "ack",
  				"53" => "can-xmit",
  				"54" => "can-rcv",

  				"60" => "year",
  				"61" => "month",
  				"62" => "day",
  				"63" => "hour",
  				"64" => "minute",
  				"65" => "report1",
  				"66" => "report2",
  				"69" => "ack2",

  				"7D" => "start-xmit",
  				"7E" => "end-xmit",

  				"82" => "day-temp",
  				"84" => "night-temp",
  				"85" => "lowtemp-offset",         # Alarm-Temp.-Differenz
  				"8A" => "windowopen-temp"

			);


			// additional warnings
			$FHT_warnings = array(
  				"battery"       => 1,
  				"lowtemp"       => 1,
  				"window"        => 1,
  				"windowsensor"  => 1,
			);

			$FHT_priority = array(
  				"desired-temp"=> 1,
  				"mode"	=> 2,
  				"report1"     => 3,
  				"report2"     => 3,
  				"holiday1"	=> 4,
  				"holiday2"	=> 5,
  				"day-temp"	=> 6,
  				"night-temp"	=> 7,
			);

			$FHT_c2m = array(0 => "auto", 1 => "manual", 2 => "holiday", 3 => "holiday_short");
			$hc=hexdec($dev);
			$house=sprintf("%02d %02d",($hc >>8), ($hc & 255));
			SetValue($varids['HC']['id'],"$house");
			$text="Dev: $dev (HC $house)";
    		if(strlen($line) > 9) $val = substr($line, 9, 2);


         //signal
			if ( strlen($line)>11) {
			   SetSignal($varids['Signal']['id'],substr($line,11,2));
			}
		  if(!$val || $cde == "65" || $cde == "66") {
    		// This is a confirmation message. We reformat it so that
    		$confirm = 1;
  			}

		  $val = hexdec($val);

		  $cmd = isset($FHT_codes[$cde])?$FHT_codes[$cde]:"";
 			if(!$cmd) {
    			$cmd= "(Unknown: $cde =>$val)";
    			$val="";
    			//continue;
    			setValue($errid,$errors+1);
    			goto fhtlog;
  			}

  			if( preg_match("/-from/",$cmd) || preg_match("/-to/",$cmd)) {
	    		$val = sprintf("%02d:%02d", $val/6, ($val%6)*10);

  			} elseif($cmd == "mode") {
    			if(isset($c2m[$val])) $val = $c2m[$val] ;

  			} elseif(preg_match("/.*-temp/",$cmd)) {
	 			$val=$val/2;
    			if ($cmd== "desired-temp") {
       			SetValue($varids['Soll']['id'],$val);
    			}
    			$val = sprintf("%.1f", $val);
  			} elseif($cmd == "lowtemp-offset") {
    			$val = sprintf("%d.0", $val);

  			} elseif(preg_match("/^actuator/",$cmd)) {
				$id=substr($line,6,1);
  				$sval = substr($line,7,2);
  				$fv = sprintf("%d%%", (integer)(100*$val/255+0.5));

       		if(preg_match("/[AB]0/i",$sval)) { $val = $fv; }   # sync in the summer
    			elseif(preg_match("/.0/",$sval)) { $val = "syncnow"; }
    			elseif(preg_match("/.1/",$sval)) { $val = "99%"; } # FHT set to 30.5, FHT80B=="ON"
    			elseif(preg_match("/.2/",$sval)) { $val = "0%"; }  # FHT set to  5.5
    			elseif(preg_match("/.6/",$sval)) { $val = "$fv"; }
    			elseif(preg_match("/.8/",$sval)) { $val = "offset: $fv"; }
    			elseif(preg_match("/.A/",$sval)) { $val = "lime-protection"; }
    			elseif(preg_match("/.C/",$sval)) { $val = sprintf("synctime: %d", int($val/2)-1); }
    			elseif(preg_match("/.E/",$sval)) { $val = "test"; }
    			elseif(preg_match("/.F/",$sval)) { $val = "pair"; }
    			else { $val = "unknown_$sval: $fv"; }

    			$pos=strpos($val,"%");
    			if (! ($pos===false)) {
					if ($id=="0") {
         			SetValue($varids['Position']['id'],$val);
         			}else{
         			   $pid==getVid('Position'.$id,IPS_GetParent($varids['ID']['id']));
							if (! $pid==false) {
				   			SetValue($pid,$val);
							}
						}
      		}


  			} elseif($cmd == "measured-low") {

    			SetValue($varids['Low']['id'],$val);
    			//continue;
    			goto fhtlog;

  			} elseif($cmd == "measured-high") {

   			// if(defined($varids['Low']['val'])) {
				$low=$varids['Low']['val'];
      		$off =  0;
      		$val = $val*256 + $low;
      		$val /= 10;
      		SetValue($varids['Temperatur']['id'],$val);
				$val = sprintf("%.1f (Celsius)", $val+$off);
      		$cmd = "measured-temp";


  		  } elseif($cmd == "warnings") {


    			# initialize values for additional warnings
    			# parse warnings
	    	     if($val & 1) {
   	   		$nVal  = "Battery low";
      			$nBattery = "low";
		     }
    		     if($val & 2) {
      			if($nVal) $nVal .= "; " ;
			   $nVal .= "Temperature too low";
			   $nLowTemp = "warn";
    			}
    			if($val &32) {
      			if($nVal) $nVal .= "; " ;
      			$nVal .= "Window open";
      			$nWindow = "open";
    			}
    			if($val &16) {
      			if($nVal) $nVal .= "; " ;
      			$nVal .= "Fault on window sensor";
      			$nSensor = "fault";
    			}

	    		# set default values or new values if they were changed
   	 		$valBattery = isset($nBattery)? $nBattery : "ok";
    			$valLowTemp = isset($nLowTemp)? $nLowTemp : "ok";
    			$valWindow  = isset($nWindow)? $nWindow : "closed";
    			$valSensor  = isset($nSensor)? $nSensor : "ok";
    			$val = isset($nVal)? $nVal : "none";

   	 		# set additional warnings and trigger notify

	    		$text.= " battery: $valBattery";
   	 		$text.= " lowtemp: $valLowTemp";
    			$text.= " window: $valWindow";
    			$text.= " windowsensor: $valSensor";
    			SetValue($varids['Warnings']['id'],"$val");
		     }


	    //finish
	    fhtlog:
  		if(substr($line,7,1) == "7") {        # Do not store FHZ acks.
	    	$cmd = "FHT:$cmd";
	   	$text.="
".$cmd;
  		} else {
    		//if($cmd == "measured-temp")
	 		$text.= " $cmd: $val" ;
	 		SetValue($varids['Status']['id'],"$cmd: $val");
  		}
	       //logging
  		IPS_Logmessage($catname,$text);

	 }//if strlen
   }//if preg

//---------------------Wetter(WS300)-----------------------------------------
 	elseif (preg_match("/^K[0-9A-F]{6,16}\s*\$/",$line)) {
 			//K11245265,K41815177F4
 			$tlist = array("0"=>"temp",
               "1"=>"temp/hum",
               "2"=>"rain",
               "3"=>"wind",
               "4"=>"temp/hum/press",
               "5"=>"brightness",
               "6"=>"pyro",
               "7"=>"temp/hum");
			$a=str_split($line);
			$len=strlen($line)-1; //last is cr
 			$firstbyte = hexdec($a[1]);
 			$typebyte=$a[2];
  			$cde = (string)($firstbyte&7);
  			$type = isset($tlist[$typebyte]) ? $tlist[$typebyte] : "unknown";
  			$typebyte=$typebyte & 7;
 			$varids=null;
 			$val="no data";


 			$catname='WSCUL';
			$sensorname='WS ';
			$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
			                  'Signal'=>array('type'=>1,'profile'=>''),
                           'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
                           'Humidity'=>array('type'=>1,'profile'=>'~Humidity')
								);
			$varids=get_ips_vars($cde,$vartypes,$catname,$sensorname);
			if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
			}
		if (($firstbyte&7)==7) {
		  if($typebyte == 0 && $len > 6) {           # temp
      			$sgn = ($firstbyte&8) ? -1 : 1;
      			$tmp = $sgn * ($a[6].$a[3].".".$a[4]);
      			$val = "T: $tmp";
      			$hum=0;
      			SetValue($varids['Temperatur']['id'],$tmp);
    				SetValue($varids['Humidity']['id'],$hum);

    		}

    		if($typebyte == 1 && $len > 8) {           # temp/hum
      		$sgn = ($firstbyte&8) ? -1 : 1;
      		$tmp = $sgn * ($a[6].$a[3].".".$a[4]);
      		//$hum = ($a[7].$a[8].".".$a[5]) ;
      		$hum = ($a[7].$a[8]) ;
      		$val = "T: $tmp  H: $hum";
      		$devtype = "PS50";
      		$family = "WS300";
      		SetValue($varids['Temperatur']['id'],$tmp);
	    		SetValue($varids['Humidity']['id'],$hum);
    		}
    		//signal
			if ( $len>9) {
			   SetSignal($varids['Signal']['id'],substr($line,19,2));

			}

  		}else{
    		if ($len < 12 ) {                 #  S300TH
      			$sgn = ($firstbyte&8) ? -1 : 1;
      			$tmp = $sgn * ($a[6].$a[3].".".$a[4]);
      			//$hum = ($a[7].$a[8].".".$a[5]);
               $hum = ($a[7].$a[8]) ;
					$val = "T: $tmp  H: $hum";
      			$devtype = "S300TH";
      			SetValue($varids['Temperatur']['id'],$tmp);
    				SetValue($varids['Humidity']['id'],$hum);
      			//signal
					if ( $len==10) {
					   SetSignal($varids['Signal']['id'],substr($line,9,2));

					}
    		} elseif($len > 13) {          # KS300/2

      		$c =  255;
      		$rain = sprintf("%0.1f", hexdec($a[14].$a[11].$a[12]) * $c / 1000);
      		$wnd  = sprintf("%0.1f", $a[9].$a[10].$a[7] );
      		$hum  = sprintf( "%02d", $a[8].$a[5]);
      		$tmp  = sprintf("%0.1f", ($a[6].$a[3].$a[4]),
                             (($a[1] & 0xC) ? -1 : 1));
      		$ir = ((hexdec($a[1]) & 2)) ? "yes" : "no";
				SetValue($varids['Temperatur']['id'],$tmp);
    				SetValue($varids['Humidity']['id'],$hum);
      		$val = "T: $tmp  H: $hum  W: $wnd  R: $rain  IR: $ir";
      	}
      	//signal
			if ( $len==15) {
			   SetSignal($varids['Signal']['id'],substr($line,15,2));
			}
      }
			$text="Dev $cde ($type): $val";
			IPS_Logmessage($catname,$text);

		}//if preg
//--------------------HMS-------------------------------------------------------
		elseif (preg_match("/^H[0-9A-F]{12,14}\s*\$/",$line)) {
 			//H37AE01240000
         $codes = array(
  				0 => "HMS100TF",
  				1 => "HMS100T",
  				2 => "HMS100WD",
  				3 => "RM100-2",
  				4 => "HMS100TFK", # Depending on the onboard jumper it is 4 or 5
  				5 => "HMS100TFK",
  				6 => "HMS100MG",
  				8 => "HMS100CO",
  				14 => "HMS100FIT"
			);

    		$type = hexdec(substr($line,6,1));
    		$stat = $type > 1 ? hexdec(substr($line,7,2)) : hexdec(substr($line,5,2));
    		$prf  = $type > 1 ? "02" : "05";
    		$bat  = $type > 1 ? hexdec(substr($line,5,1))+1 : 1;
    		$dev = substr($line,1,4);
    		$val = $type > 1 ?  "000000" : substr($line,7);
 			$catname='HMSCUL';
 			$sensorname='HMS ';
			//if (!isset($sensorname)) $sensorname='HMS ';
			switch ($type) {
			   case 0://TF
						$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
						         'Signal'=>array('type'=>1,'profile'=>''),
						         'Type'=>array('type'=>3,'profile'=>''),
                           'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
                           'Humidity'=>array('type'=>1,'profile'=>'~Humidity'),
                           'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
								);
								break;
			   case 1://T
						$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
						         'Signal'=>array('type'=>1,'profile'=>''),
						         'Type'=>array('type'=>3,'profile'=>''),
                           'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
                           'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
								);
								break;
			   case 4://TFK Switch1
			   case 5://TFK Switch2
			         $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
			                        'Signal'=>array('type'=>1,'profile'=>''),
			                        'Type'=>array('type'=>3,'profile'=>''),
                                 'Kontakt'=>array('type'=>0,'profile'=>'~Switch'),
                                 'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
								);
								break;

			   case 2://WD
			   case 3://RM100
  			   case 6://Gas MG
			   case 8://Gas CO
			   case 14://FIT
			         $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
			                           'Signal'=>array('type'=>1,'profile'=>''),
			                        'Type'=>array('type'=>3,'profile'=>''),
                                 'Alarm'=>array('type'=>0,'profile'=>'~Alert'),
                                 'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
								);
								break;

			   default://type not known
                     	IPS_LogMessage($catname,"Unknown type: $type");
                     	setValue($errid,$errors+1);
								continue 2;
			}
			$varids=null;
			$varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
			if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
			}

			SetValue($varids['Battery']['id'],($bat==1));
			if (! ($varids['Type']['val']) == $codes[$type]) {
				SetValue($varids['Type']['id'],$codes[$type]);
			}
			switch($type) {
			   case 0: //TF
			   # Codierung <t1><t0><f0><t2><f2><f1>
						$hum=(Integer)(substr($val, 4, 2).substr($val, 2, 1))/10;
							SetValue($varids['Humidity']['id'],$hum);
				case 1://T
				      $tmp=(substr($val, 3, 1).substr($val, 0, 2))/10;
				      if (($stat & 128)>0) $tmp=-$tmp;
						SetValue($varids['Temperatur']['id'],$tmp);
						break;
				case 2:
				case 3:
				case 6:
				case 8:
				case 14: SetValue($varids['Alarm']['id'],($stat>0));
							 break;
				case 4:
				case 5: SetValue($varids['Kontakt']['id'],($stat>0));
							 break;
				default:
				   IPS_LogMessage($catname,"Type $type for Dev $HA not known");
				   break;
			}
			//signal
			if ( strlen($line)>13) {
				SetSignal($varids['Signal']['id'],substr($line,13,2));
			}
         $text="Dev $dev ($type:".$codes[$type]."): Stat:$stat, Bat: $bat Val: $val";
			IPS_Logmessage($catname,$text);

		}//if preg

		//--------------------ESA-------------------------------------------------------
		elseif (preg_match("/^S[0-9A-F]{32,34}\s*\$/",$line)) {
  # definitions taken from FHEM 64_ESA2000.pm
  # S6E003D011E00037650001102C1DA07D01D
  # S 6E 003D 011E 00037650 0011 02C1DA 07D0 1D
  #              1           2           3
  # 0 12 3456 7890 12345678 9012 345678 9012 34
  # seqno        =  number of received datagram in sequence mod 128(repeated if seqno/128 >0)
  # code         =  device code
  # type           = type of sensor: 011E: ESA1000-WZ, ...
  # total_cnt    =  total (cumulated) value in ticks as read from the device
  # current_cnt  =  current value (average over latest 5 minutes) in device units
  # timestamp    =  current time from start of device in 10 sec units
  # ticks        =  ticks per kWh setup in ESA1000WS (depends on the meter)
         $codelist = array(
  				"003D" => "ESA1000-S0",
  				"0055" => "ESA1000-S0",
  				"44C7" => "ESA2000_LED",
  				"0178" => "ESA2000_LED",
  				"0595" => "ESA1000GAS",
  				"01FA" => "ESA2000_LED"
			);
		 $tlist=array("011E"=>"ESA1000-WZ");

    		$seqno= hexdec(substr($line,1,2))%128;
    		$code = substr($line,3,4);
    		$type = substr($line,7,4);
			$dev=$code."-".$type;
    		$total_cnt=hexdec(substr($line,11,8));
    		$current_cnt=hexdec(substr($line,19,4));
    		$timestamp=hexdec(substr($line,23,6));
    		$ticks=hexdec(substr($line,29,4));
 			$catname='ESACUL';
 			$sensorname = isset($codelist[$code]) ? $codelist[$code] : "ESA ";
 			$varids=null;
			$vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
			                  'Signal'=>array('type'=>1,'profile'=>''),
                           	   'total'=>array('type'=>1,'profile'=>''),
                               'current'=>array('type'=>1,'profile'=>''),
                               'ticks'=>array('type'=>1,'profile'=>'')
								);
			$varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
			if (is_null($varids)) {
			   //no vars available, maybe autocreate disabled
				continue;
			}
			SetValue($varids['total']['id'],$total_cnt);
			SetValue($varids['current']['id'],$current_cnt);
			SetValue($varids['ticks']['id'],$ticks);
 			//signal
			if ( strlen($line)>32) {
				SetSignal($varids['Signal']['id'],substr($line,33,2));
			}
         $text="Dev $dev : Tot:$total_cnt, Cur: $current_cnt Ticks: $ticks";
			IPS_Logmessage($catname,$text);


		}//if preg

		#-----------aux/unknown/unimplemented cul/cun/coc message------
		elseif (! preg_match("/^\s*$/",$line)) {
		   IPS_Logmessage('CUL','MSG:'.$line);
		  	setValue($lmid,$line);
      	//--------------------OneWire---------------------------------------------
			if (preg_match("/^R:[0-9A-F]{16}\s*\$/",$line)) {
         	IPS_Logmessage('CUL','OneWire Device:'.substr($line,2));
			}
			elseif (preg_match("/^D:\s*([0-9]+)\s*\$/",$line,$res)) {
       	  IPS_Logmessage('CUL','OneWire detected Devices:'.$res[1]);
			}
			elseif (preg_match("/^\s*(ON|OFF)\s*\$/",$line,$res)) {
         	IPS_Logmessage('CUL','OneWire HMS Emulation:'.$res[1]);
			}
			elseif (preg_match("/^Y\w[0-9A-F]{1,16}\s*\$/",$line,$res)) {
         	IPS_Logmessage('CUL','Somfy Emulation');
			}
			
			//------ Init messages --------------
			elseif(preg_match("/^(V\s*[0-9\.]+)\s*CSM.*/",$line,$res)) {
			   IPS_Logmessage('CUL','Version:'.$res[1]);
         }
			elseif(preg_match("/^[0-9]{2}\s+[0-9]{3}/",$line,$res)) {
			   IPS_Logmessage('CUL','Modus:'.substr($line,2));
			//--------- Error -------------
			}else {
			   $errors=$errors+1;
				IPS_Logmessage('CUL','Err:'.$errors.' MSG:'.$line);
				setValue($errid,$errors);
		  		if ($errors>10) {
		  		   //to many errors, reset COC
		  		   if ($reconnect && IPS_ScriptExists($reconnect)) {
					  IPS_RunScript($reconnect);
					}
		  		}//errors
			}//preg others
		}//preg
	}//foreach
}//if  sender

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

/**
* IPS Variablen handler
* creates variables as needed
* returns assoc. Array with IPS Variable ID and Value
* @param integer Sensor Address
* @param array Array with Variable Names, Types and Profiles
* @param string Sensor Group Master Categorie Name
* @param string Sensor default name, will be extended with $addr
*/
function get_ips_vars($addr,$vartypes,$cat,$sens) {

 	$varids=null;

	 $master=@IPS_GetObjectIDByName($cat,0);
	//no master cat, create new
	 if (!$master) {
   	$master=IPS_CreateCategory();
   	IPS_SetName($master,$cat);
   	IPS_SetParent($master,0);
		if ($master>0) {
	   	IPS_LogMessage('CUL', "Master category created, ID=$master
");
   	}else{
			IPS_LogMessage('CUL', "Can't create Master Category
");
			return null;
		}
 	}

  $id=0;
  if ($master>0) {
  //get chilren sensors
   $Sensors=IPS_GetChildrenIDs($master);
   foreach($Sensors as $sid) {
   	$name=IPS_GetName($sid);
      //print "$sid:".$name."
";
		//get vars for each sensor
		$vars=IPS_GetChildrenIDs($sid);
      foreach($vars as $vid) {
       $obj=IPS_GetObject($vid);
         $vname=$obj['ObjectName'];
         $typ=$obj['ObjectType'];
         if ($typ==2) { //Variable
         	//if ID, here is the address
         	if ($vname="ID") {
         		$i=GetValue($vid);
         		//go out if matches, $id returns the sensor categorie id
         		if ($i===$addr) {
         	   	$id=$sid;
         	   	break;
         		}
         	}
         }
      }
      if ($id>0) break;
   }
	if ($id==0) {
		//Sensor with address $addr not found in IPS
		if ($GLOBALS['autocreate']==false) {
			//autocreate disable, ignore new device
			return null;
		}
		//create new sensor
	   $id=ips_createCategory();
	   ips_setName($id,$sens.' '.$addr);
	   ips_setParent($id,$master);
		//creates all needed variables for the new sensor
		foreach (array_keys($vartypes) as $name) {
	      $typ=$vartypes[$name]['type'];
         $profile=$vartypes[$name]['profile'];
			$vid=IPS_CreateVariable($typ);
			ips_setname($vid,$name);
			ips_setParent($vid,$id);
         IPS_SetVariableCustomProfile($vid,$profile);
			//preload variables
			SetValue($vid,0);
         $varids[$name]['id']=$vid;
         $varids[$name]['val']=0;
         //Store address in $ID for next time
         if ($name=='ID') {
	         SetValue($vid,$addr);
   	      $varids[$name]['val']=$addr;
			}
		}
	}else{
	   //found matching cat, collect ids and vals for this sensor
	   $vars=IPS_GetChildrenIDs($id);
      foreach($vars as $vid) {
         $obj=IPS_GetObject($vid);
         $name=$obj['ObjectName'];
         $typ=$obj['ObjectType'];
         if ($typ==2) { //Variable
         	$val=GetValue($vid);
         	$varids[$name]['id']=$vid;
         	$varids[$name]['val']=$val;
         }

      }

	}
	//returns IDs and Values of this Sensor, Name is Key
	return $varids;
	}
}
//#############################
//
/**
* converting CUL Hex IDs into ELV-4-Ids
* translated from 10_fs20
* @param string $v Hex-Value
* @returns string ELV-ID
*/
function hex2four($v){
  $r = "";
  foreach  (str_split($v) as $x) {
    $r .= sprintf("%d%d", (hexdec($x)/4)+1, (hexdec($x)%4)+1);
  }
  return $r;
}

//#############################
/**
* do simple logging
* @param string $logfile Filename for logfile
* @param string $text
* @returns void
*/

function logge($logfile,$text) {
	if (strlen($logfile)>0) {
		$log=fopen($logfile,"a+");
		if ($log) {
	   	$d=date("r");
			fwrite($log,"$d $text");
 			fflush($log);
			fclose($log);
		}
	}
}
/**
* Get ID by name if exists, else create
* @Param String Name
* @param integer Parent-ID
* @param integer Variable Typ (0..3)
* @return integer ID
*/
function getVid($name,$par,$typ) {
	$vid = @IPS_GetVariableIDByName($name, $par);
	if ($vid === false) {
		$vid=IPS_CreateVariable($typ);
		ips_setname($vid,$name);
		ips_setParent($vid,$par);
		setValue($vid,'');
	}
	return $vid;
}
/**
* set signal strange (in dB)
* @Param Integer ID Signal Variable
* @param String Hex-Byte
*/

function setSignal($sid,$hex) {
	$rssi=hexdec($hex);
   if ($rssi>=128)  {
		$rssi=(($rssi-256)/2)-74;
	} else {
		$rssi=($rssi/2)-74;
	}
	$rssi=intval($rssi);
	//IPS_Logmessage('CUL',"Signal: $rssi ($hex) Id $sid");
   setValue($sid,$rssi);
}

?>
  1. ID der Registervariablen im Skript unter "$reg="eintragen und das Skript in der RegVar als Ziel auswählen.
  2. Startup-skript anlegen und bei Kerninstanzen/Events bei Start-Skript eintragen (Wenn schon eine Startskript für eine andere Funktion angelegt ist, einfach den Code mit in die Datei einfügen. Im Code wieder die richtige ID der Regvar eintragen.
<?



 /**
* CUN/CUL StatusEvent Script,
* Add to EventHandler Instance as startup script(or include there) and
* add as Script for Status Events
*
* testet with IPS 3.1 and CUN FW 1.46/COC FW 1.61 (ESA not tested)
* http://www.tdressler.net/ipsymcon
* V0.8 06.03.2015
* @package CUN
*/

//Regvar-Instance
$reg=55121 /*[CUL\Register Variable]*/;


//activate 1wire HMS emulation for temperature sensors

if (!IPS_InstanceExists($reg)) {
			IPS_LogMessage("CUL", "Instance with ID $reg doesnt exists");
			return;
}
$inst=IPS_GetInstance($reg);
$ityp=$inst['ModuleInfo']['ModuleName'];
if ($ityp!="Register Variable") {
			IPS_LogMessage("CUL", "Instance $reg is not a 'Register Variable' Instance");
			return;
}
//check origin of request
switch ($_IPS['SENDER']) {
	case "Startup": //executed on startup
	                  IPS_LogMessage("CUL","Set CUL Modus onStartup");
	                  set_modus();
						 	break;
	case "Execute": //Manual start
	                  IPS_LogMessage("CUL","Set CUL Modus manually");
							set_modus();
						 	break;
	case "StatusEvent": //execute only if status change to aktiv
	                     $status=$_IPS['STATUS'];
	                     IPS_LogMessage("CUL","Status:".$_IPS['STATUSTEXT']." (".$status.")");
								if ($status==102) set_modus();
	                     break;
	case "RunScript":
	                  IPS_LogMessage("CUL","Set CUL Modus by Script");
	                  $vers=set_modus();
	                  print $vers;
						 	break;
	default:
   			IPS_LogMessage("CUL", "Unknown Sender ".$_IPS['SENDER']);
   			print "Unknown Sender ".$_IPS['SENDER'];
   			break;
}
return;
/**
* set CUN/CUL to modus X21
* (report known messages incl. signal data)
*/
function set_modus() { //aktiv
	global $reg;
	global $ow_use_hms;
	//get message variable
	$lmid=getVid('AuxMessage',$reg);
	//Status variablen
	$versid=getVid('Version',$reg);
	$mid=getVid('Modus',$reg);
   //Modus abfragen
 	RegVar_SendText($reg,"X
");
   IPS_Sleep(200);
	$modus=substr(getValue($lmid),0,2);
	setValue($mid,$modus);
	if ($modus<>"21") {
	//CUL/CUN Modus setzen
		RegVar_SendText($reg,"X21
");
		IPS_Sleep(500);
		//Modus abfragen
		RegVar_SendText($reg,"X
");
		IPS_Sleep(500);
		$modus=substr(getValue($lmid),0,2);
		setValue($mid,$modus);
		//log action
		if ($modus=="21") {
		   IPS_LogMessage("CUL","CUL Modus set successfully");
		}else{
		   IPS_LogMessage("CUL","Set CUL Modus failed");
		}

	}else{
	   IPS_LogMessage("CUL","CUL Modus already set");
	}
	//Version abfragen
	RegVar_SendText($reg,"V
");
   IPS_Sleep(500);
	$version=getValue($lmid);
	setValue($versid,$version);
	setValue($lmid,"");
	return $version;
}


function init_onewire() {
  	global $reg;
	//get message variable
	$lmid=getVid('AuxMessage',$reg);
   //$devid=getVid('OneWireDevices',$reg);
	#read OW-IDs
	IPS_Sleep(1000);
   RegVar_SendText($reg,"Of
");
   IPS_Sleep(2000);
   RegVar_SendText($reg,"OHo
");
   IPS_Sleep(2000);
   $res=substr(getValue($lmid),0,2);
   if ($res<>"ON") {
      RegVar_SendText($reg,"OHo
");
   	IPS_Sleep(1500);
   	$res=substr(getValue($lmid),0,2);
   }
   if ($res=="ON") {
      #set 180s intervall
      RegVar_SendText($reg,"OHt180
");
   	IPS_Sleep(1500);
   	$res=getValue($lmid);
   	IPS_LogMessage("CUL", "Set Timer OW 180s:$res");
   }else{
      IPS_LogMessage("CUL","Onewire: Failed to set HMS modus($res)");
   }
   setValue($lmid,"");
}

/**
* Get ID by name if exists, else create
* @Param String Name
* @param integer Parent-ID
* @return integer ID
*/
function getVid($name,$par) {
	$vid = @IPS_GetVariableIDByName($name, $par);
	if ($vid === false) {
		$vid=IPS_CreateVariable(3);
		ips_setname($vid,$name);
		ips_setParent($vid,$par);
		setValue($vid,'');
	}
	return $vid;
}



?>
  1. Sende-Skript anlegen auch hier wieder die richtige ID der Regvar eintragen. Der Rest der Parameter kann so bleiben.
<?

############Somfy_send_skript#################################

/*
Y<func>
Somfy RTS/Simu Hz (R) mode. <func> is one of:
t<dez>
Sets the time in us (microseconds) for a single symbol
Typical values are: 1200-1300
Default: 1240 (According to the patent it should be 1208, but this works better)
r<dez>
Sets the number of repetitions of a Somfy RTS frame. If the receiver is far away from the sender, increasing this number may help reception.
Default: 6
s = Send out a Somfy command. <hex> is a hex string of the following form: KKC0RRRRAAAAAA
KK - Encryption key														   A4290434060000
C - Command (1 = My, 2 = Up, 4 = Down, 8 = Prog)
0 - Checksum (set to 0, is calculated automatically)
RRRR - Rolling code
AAAAAA - Address (= remote channel)
*/


#######Parameter#####

$reg=55121 /*[CUL\Register Variable]*/;
$symbolwidth = 1240;    # Default Somfy frame symbol width
$repetition = 8;	# Default Somfy frame repeat counter
$somfy_updateFreq = 3;	# Interval for State update
#$CUL433_Adr= ; #Adresse des CUL433
$command=$_IPS['Direction'];#C - Command (1 = My, 2 = Up, 4 = Down, 8 = Prog)
$ID_Key=$_IPS['ID_Key'];
$enckey=$_IPS['Key'];#KK - Encryption key
$ID_Rolling_Code=$_IPS['ID_Rolling_Code'];
$rollingcode=$_IPS['Rolling_Code'];#RRRR - Rolling code
$Adress=$_IPS['Adress'];#AAAAAA - Address (= remote channel)

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

	## Set symbol length	--> Init

	$message = "t" . $symbolwidth;
#   RegVar_SendText($reg,"Y".$message."
");

	## Set frame repetition --> Init

	$message = "r" . $repetition;
#	RegVar_SendText($reg,"Y".$message."
");

	    switch($command)
	{
		case 0:
		$command=1;
		break;

		case 1:
		$command=2;
		break;

		case 2:
		$command=4;
		break;
	}

	# message looks like this
	# Ys_key_ctrl_cks_rollcode_a0_a1_a2
	# Ys ad 20 0ae3 a2 98 42
   $Swapped_Adress=$Adress[4].$Adress[5].$Adress[2].$Adress[3].$Adress[0].$Adress[1];
   #print_r($Swapped_Adress."
");
	## Gen Message
	$message = "s". $enckey.$command.'0'.$rollingcode.$Adress;
	#print_r($message."
");

	## Send Message
	RegVar_SendText($reg,"Y".$message."
");

	# increment encryption key and rolling code
   $enc_key_increment      = hexdec( $enckey );
	$rolling_code_increment = hexdec( $rollingcode );
	$new_enc_key = sprintf( "%02X", ( ++$enc_key_increment & hexdec("AF") ) );
	$new_rolling_code = sprintf( "%04X", ( ++$rolling_code_increment ) );

	# update the readings, but do not generate an event
   SetValue ( $ID_Key, $new_enc_key );
   SetValue ( $ID_Rolling_Code, $new_rolling_code );




?>