Neue Homematic-Devices aus CCU automatisch erstellen

Wer eine CCU nutzt und auch Probleme mit den abgeschnittenen Strings aus der eingebauten XML-API hat, kann mit nachfolgenden Skript unter Zuhilfename des XMLAPI-Patch von Homematic Inside neue Devices (bzw. Kanäle) automatisch anlegen lassen.

Das Skript unterstützt Wired und Radio Devices. Neue Geräte werden unter der Kategorie „new Homematic Devices“ angelegt, darunter wird ein Ordner des Raums, der dem Device (bzw. genau gesagt dem Kanal) zugewiesen wurde, angelegt. Darunter wird noch ein Ordner mit dem Geräte-Namen angelegt, worin die einzelnen Kanäle zu finden sind.

Bereits vorhandene Kanäle werden automatisch übersprungen.

Wichtig ist, die $ccu_address mit der IP-Adresse der CCU zu belegen.

Viel Spaß damit,
Martin

<?
/*
********************************************************************************
Create instances for new Homematic Devices from CCU device

Attention! It is necessary to have the XMLPatch-API installed (from
              Homematic Inside

Creator: friendly
Version: 1.0
********************************************************************************
*/

$ccu_address          = 'http://<<IP of CCU>>';   // Protocol and IP address of CCU
$category_new_devices = 'new Homematic Devices';  // Category root folder for new devices
$category_dummy_room  = 'no room';                // Category folder if room is not set
$logdir               = IPS_GetKernelDir().'/logs/';
$logfile
     = $logdir."hm_create_instances.log";

// nothing has to be changed below
// *****************************************************************************

$device_file          = $logdir."HM_devicelist.xml";
$room_file            = $logdir."HM_roomlist.xml";

// store reply from CCU for logging
$deviceList = getXmlApiList($ccu_address."/config/xmlapi/devicelist.cgi", $device_file);
$roomList   = getXmlApiList($ccu_address."/config/xmlapi/roomlist.cgi", $room_file);


// check every device from devicelist
foreach($deviceList as $attrib) {
  $HM_name      = utf8_decode($attrib['name']);
  $HM_address   = $attrib['address'];
  $HM_interface = $attrib['interface'];

  // interate over all channels of device
  foreach ($attrib as $channel) {
     $HM_channel_name    = utf8_decode($channel['name']);
    $HM_channel_address = $channel['address'];
    $HM_channel_ise_id  = (integer)$channel['ise_id'];
    $HM_found = FALSE;
    
    // check if channel is already configured in IP-Symcon
    foreach ( IPS_GetInstanceListByModuleID("{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}") as $id ){
      $curr_address = HM_GetAddress($id);
        if($HM_channel_address == $curr_address){
           $HM_found = TRUE;
           $HM_instance = $id;
        }
     }
     
     // search room for channel
     $HM_room = $category_dummy_room;
     foreach ($roomList as $currRoom){
        $currRoomName = utf8_decode($currRoom['name']);
        foreach ($currRoom as $roomChannel){
            $roomChannel_ise_id =  (integer)$roomChannel['ise_id'];
            if($HM_channel_ise_id == $roomChannel_ise_id){
                $HM_room =  $currRoomName;
            }
        }
     }

     // create channel instance if address not exists
     if($HM_found == FALSE){
        // get folder (category) hierarchy ( Category / Room / Device )
        $category = GetCategoryIDByName(0, $category_new_devices);
        $room     = GetCategoryIDByName($category, $HM_room);
        $device   = GetCategoryIDByName($room, $HM_name);

        // Create instance
        $HM_instance = IPS_CreateInstance("{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}");
      IPS_SetParent($HM_instance,$device);
      IPS_SetName($HM_instance, $HM_channel_name);
      HM_SetAddress($HM_instance,(string)$HM_channel_address);
        if($HM_interface == 'BidCos-RF'){
          $protocol = 0;
        }
        else{
          $protocol = 1;
        };
      HM_SetProtocol($HM_instance,$protocol);
      HM_SetEmulateStatus($HM_instance,true);
        // apply changes
        IPS_ApplyChanges($HM_instance);
     }

     // log channel attributes
     logEntry ("Device: ".$HM_name." - ".$HM_interface." - Channel: ".
       $HM_channel_name." (room: ".$HM_room.") - address: ".$HM_channel_address.
        " - IPS instance: ".$HM_instance." - new created: ".
        ($HM_found ? "no" : "yes")."
");
  }
}
function GetCategoryIDByName($ParentID, $name){
    global $IPS_SELF;
   $InstanzID = @IPS_GetCategoryIDByName($name, $ParentID);
    if($InstanzID === false){
        $InstanzID = IPS_CreateCategory();
        IPS_SetParent($InstanzID, $ParentID);
        IPS_SetName($InstanzID, $name);
        IPS_SetInfo($InstanzID, "this variable was created by script #$IPS_SELF");
    }
    return $InstanzID;
}

function logEntry($text) {
    global $logfile;
    if (strlen($logfile)>0) {
        $log=fopen($logfile,"a+");
        if ($log) {
           $d=date("r");
            fwrite($log,"$d $text");
             fflush($log);
            fclose($log);
        }
    }
}

function getXmlApiList($url, $file){
   logEntry("Get config from: ".$url."
");
   $xml = @file_get_contents($url);
   if((strpos($http_response_header[0], "200") === false)){
      logEntry("Error getting devices.
");
     return "";
   }
    // save Contents
   file_put_contents( $file, $xml );
   logEntry("Config written to ".$file."
");
   return simplexml_load_string($xml);
}
?>

Hallo.

Ausgesprochen hilfreich!

Danke.

Huhu,
leider wird das Script bei mir als ‚fehlerhaft‘ Markiert ohne dabei einen Fehler zu Protokollieren :expressionless:

//Sven

Hi Sven,

ich habs zwar selbst noch nicht probiert, aber hast du den Patch auf der CCU installiert?:

Natürlich habe ich den Patch gleich mal Installiert… auch getestet :slight_smile: Ist ja ganz nett um mal die HM Komponenten zu Zählen :slight_smile:
//Sven

Hast Du geprüft, ob evtl. die maximale Zeit für php-Skripts (in der php.ini) überschritten wird? Das könnte unter „Meldungen“ protokolliert werden. Die CCU ist ja relativ gemächlich in der Antwort, so dass dies schnell der Fall sein könnte. Falls es darin liegt, bitte entweder die Zeit hochstellen (IP-Symcon Dienst muss dann neu gestartet werden) oder die beiden Dateien per Hand füllen und dann im Skript direkt daraus lesen (über simplexml_load_file).

Grüße,
Martin

Huhu,
und vielen Dank für den Tipp…
Nun bekomme ich den Fehler:

Warning: Invalid argument supplied for foreach() in [Systemscripte\HM Add new Devices] on line 33

Liegt das vieleicht daran, dass ich wired Komponenten einsetze?
Manuell über den Browser klappt die Abfrage der XML Datei. Manuell Import habe ich allerdings noch nicht versucht.

//Sven

Hallo Sven,

bekommst irgendwelche Meldungen im hm_create_instances.log und sind die Files HM_devicelist.xml und HM_roomlist.xml (jeweils im logs-Ordner) vernünftig gefüllt?

Bei mir sind wired und radio Komponenten parallel im Einsatz und das Einlesen war problemlos möglich!

Ich bekomme genau den Fehler von Sven. Hat jemand rausgekriegt was da das Problem ist?

Danke

gros_ibou