LightManager Air

Hi,
bevor ich vor einem Jahr mit IPS anfing hatte (habe noch) einen Lightmanager Air. Die Szenen lassen sich sehr leicht aus IPS aufrufen mit:


file_get_contents("http://<IP des LM>/control?scene=1);

So wird Szene 1 gestartet das wäre das selbe als wenn man mit einer Harmony L001 an den LM schicken würde.

Es ist also kinderleicht. Ich habe ein Script geschrieben mit dem es kinderleichter wird:-)

Das Script:


<?php
// Die ganzen Idents werden benutzt damit nicht jeder Aufruf erneut alles anlegt

// IP vom LeightManager Air
$IP = '192.168.178.49';

// Lege Stringvariable für Konfiguration an falls noch nicht vorhanden
$ConfigID = IPS_GetObjectIDByIdent("Config", $_IPS['SELF']);
if ($ConfigID == false){
    $ConfigID = IPS_CreateVariable(3);
    IPS_SetName($ConfigID, "Config"); // Variable benennen
    IPS_SetParent($ConfigID, $_IPS['SELF']); 
    IPS_SetIdent($ConfigID, "Config"); 
}
// Lese Konfiguration aus LM
if (file_exists('http://'.$IP.'/config.xml')){
    $file = implode(gzfile('http://'.$IP.'/config.xml'));
}
else{
// Lese Konfiguration aus Variable
    $file = GetValue($ConfigID);
}

// Konfiguration in Variable speichern
SetValue($ConfigID, $file);

// Konfiguration ist eine XML Datei
$xml = simplexml_load_string($file);

// XML -> Json
$json = json_encode($xml);

// Jason -> Array
$array = json_decode($json,TRUE);

// Für Debug-Zwecke
//var_dump($xml);
//return;

// Anlegen einer neuen Kategorie mit dem Namen "Szenen" falls nocht nicht vorhanden
$CatID = IPS_GetObjectIDByIdent("Szenen", $_IPS['SELF']);
if ($CatID == false){
    $CatID = IPS_CreateCategory();              // Kategorie anlegen
    IPS_SetName($CatID, "Szenen");              // Kategorie benennen
    IPS_SetParent($CatID, $_IPS['SELF']);       // Kategorie einsortieren unter dem Objekt
    IPS_SetIdent($CatID, "Szenen");
}

// Alle Szenen als Scripte anlegen wenn noch nicht vorhanden
$i1 = 0;
while ($xml->lightscenes->scene[$i1]){
    $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->lightscenes->scene[$i1]->name);
    $ScriptID = IPS_GetObjectIDByIdent($ident, $CatID);
    if ($ScriptID == false){
        $ScriptID = IPS_CreateScript(0);        // Script erzeugen
        IPS_SetParent($ScriptID, $CatID);       // Script einsortieren unter dem Objekt
        IPS_SetName($ScriptID, (string) $xml->lightscenes->scene[$i1]->name);       // Script bennenen
        IPS_SetIdent($ScriptID, $ident);
    }
// Script zusammenbasteln ist einfach nur "http://<IP vn LM>/control?scene=x"
    $content = "<?\rfile_get_contents('http://".$IP."/control?".(string) $xml->lightscenes->scene[$i1]->param."');\r?>";
    IPS_SetScriptContent($ScriptID, $content);
    $i1++;
}

// Anlegen einer neuen Kategorie mit dem Namen "Zonen" falls nocht nicht vorhanden
// Zonen enthalten die einzelnen Kommandos der Geräte aus den Szenen
$CatID = IPS_GetObjectIDByIdent("Zonen", $_IPS['SELF']);
if ($CatID == false){
    $CatID = IPS_CreateCategory();              // Kategorie anlegen
    IPS_SetName($CatID, "Zonen");               // Kategorie benennen
    IPS_SetParent($CatID, $_IPS['SELF']);       // Kategorie einsortieren unter dem Objekt
    IPS_SetIdent($CatID, "Zonen");
}
$i1 = 0;

// Anlegen einer neuen Kategorie mit dem Zonen-Name falls nocht nicht vorhanden
while ($xml->zone[$i1]){
    $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->zone[$i1]->zonename);
    $ZoneID = IPS_GetObjectIDByIdent($ident, $CatID);
    if ($ZoneID == false){
        $ZoneID = IPS_CreateCategory();
        IPS_SetName($ZoneID, (string) $xml->zone[$i1]->zonename); // Variable benennen
        IPS_SetParent($ZoneID, $CatID); 
        IPS_SetIdent($ZoneID, $ident);
    }
    $i2 = 0;
// Anlegen einer neuen Kategorie mit dem Aktuator-Name falls nocht nicht vorhanden
    while ($xml->zone[$i1]->actuators->actuator[$i2]){
        $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->zone[$i1]->actuators->actuator[$i2]->name);
        $ActuatorsID = IPS_GetObjectIDByIdent($ident, $ZoneID);
        if ($ActuatorsID == false){
            $ActuatorsID = IPS_CreateCategory();
            IPS_SetName($ActuatorsID, (string) $xml->zone[$i1]->actuators->actuator[$i2]->name); // Variable benennen
            IPS_SetParent($ActuatorsID, $ZoneID); 
            IPS_SetIdent($ActuatorsID, $ident);
        }
        $i3 = 0;
// Anlegen eines neuen Scripts mit dem Kommando-Name falls nocht nicht vorhanden
        while ($xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]){
            $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]->name);
            $ScriptID = IPS_GetObjectIDByIdent($ident, $ActuatorsID );
            if ($ScriptID == false){
                $ScriptID = IPS_CreateScript(0);
                IPS_SetName($ScriptID, (string) $xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]->name); // Variable benennen
                IPS_SetParent($ScriptID, $ActuatorsID ); 
                IPS_SetIdent($ScriptID, $ident);
            }
// Script zusammenbasteln ist einfach nur "http://<IP vn LM>/control?" und der Parameter aus dem XML
            $content = "<?\rfile_get_contents('http://".$IP."/control?".(string) $xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]->param."');\r?>";
            IPS_SetScriptContent($ScriptID, $content);
            $i3++;
        }
        $i2++;
    }
    $i1++;
}
?>

liest die aktuelle Konfiguration vom LM aus. Im Script muss nur die IP vom LM eingetragen werden und dann gestartet werden.

Das Script legt die aktuelle Konfiguration vom LM in der Variablen „Config“ ab um bei Fehlersuche hilfreich zu sein. Es werden 2 Kategorien „Szenen“ und „Zonen“ angelegt. In „Szenen“ liegen Scripte mit den Szenen-Namen die die jeweilige Szene starten. „Zonen“ enthält auch die Szenen aber darin sind alle Aktoren mit Scripten abgespeichert. Für das Web-Front empfiehlt es sich direkt die LM-Web-Seite als externe Seite einzurichten.

Vielleicht hilft es ja jemanden.

Ralf

Vielen Dank für das Skript. Die Idee ist super und ich würde meinen LMAIR gerne in IPS einbinden.
Nach Austausch der IP des LMAIR erhalte ich jedoch nach Ausführung des Skripts folgende Fehlermeldung:

Warning:  Objekt mit Ident Config wurde nicht gefunden in /var/lib/symcon/scripts/21301.ips.php on line 8

Warning:  Objekt mit Ident Szenen wurde nicht gefunden in /var/lib/symcon/scripts/21301.ips.php on line 41

Notice:  Trying to get property 'lightscenes' of non-object in /var/lib/symcon/scripts/21301.ips.php on line 51

Notice:  Trying to get property 'scene' of non-object in /var/lib/symcon/scripts/21301.ips.php on line 51

Notice:  Trying to access array offset on value of type null in /var/lib/symcon/scripts/21301.ips.php on line 51

Warning:  Objekt mit Ident Zonen wurde nicht gefunden in /var/lib/symcon/scripts/21301.ips.php on line 68

Notice:  Trying to get property 'zone' of non-object in /var/lib/symcon/scripts/21301.ips.php on line 78

Notice:  Trying to access array offset on value of type null in /var/lib/symcon/scripts/21301.ips.php on line 78
 writing your code here

Kannst du mir hier weiterhelfen?
Viele Grüße
marvus

Moin Marvus,
ich habe es bei mir mal getestet und es lief auch nicht. Ich habe das Script mal etwas geändert. Versuch dieses Script mal.

<?php
// Die ganzen Idents werden benutzt damit nicht jeder Aufruf erneut alles anlegt

// IP vom LeightManager Air
$IP = '192.168.178.49';

// Lege Stringvariable für Konfiguration an falls noch nicht vorhanden
$ConfigID = @IPS_GetObjectIDByIdent("Config", $_IPS['SELF']);
if ($ConfigID == false){
    $ConfigID = IPS_CreateVariable(3);
    IPS_SetName($ConfigID, "Config"); // Variable benennen
    IPS_SetParent($ConfigID, $_IPS['SELF']); 
    IPS_SetIdent($ConfigID, "Config"); 
}
// Lese Konfiguration aus LM
$file = @gzfile('http://'.$IP.'/config.xml');
if ($file != false){
    $config = implode($file);
}
else{
// Lese Konfiguration aus Variable
    $config = GetValue($ConfigID);
}

if ($config == ''){
    IPS_LogMessage("LM Air", "Konfiguration oder LM Air nicht gefunden "); 
}

// Konfiguration in Variable speichern
SetValue($ConfigID, $config);

// Konfiguration ist eine XML Datei
$xml = simplexml_load_string($config);

// XML -> Json
$json = json_encode($xml);

// Jason -> Array
$array = json_decode($json,TRUE);

// für Debug Zwecke
//var_dump($array);
//return;

// Anlegen einer neuen Kategorie mit dem Namen "Szenen" falls nocht nicht vorhanden
$CatID = @IPS_GetObjectIDByIdent("Szenen", $_IPS['SELF']);
if ($CatID == false){
    $CatID = IPS_CreateCategory();              // Kategorie anlegen
    IPS_SetName($CatID, "Szenen");              // Kategorie benennen
    IPS_SetParent($CatID, $_IPS['SELF']);       // Kategorie einsortieren unter dem Objekt
    IPS_SetIdent($CatID, "Szenen");
}

// Alle Szenen als Scripte anlegen wenn noch nicht vorhanden
$i1 = 0;
while ($xml->lightscenes->scene[$i1]){
    $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->lightscenes->scene[$i1]->name);
    $ScriptID = @IPS_GetObjectIDByIdent($ident, $CatID);
    if ($ScriptID == false){
        $ScriptID = IPS_CreateScript(0);        // Script erzeugen
        IPS_SetParent($ScriptID, $CatID);       // Script einsortieren unter dem Objekt
        IPS_SetName($ScriptID, (string) $xml->lightscenes->scene[$i1]->name);       // Script bennenen
        IPS_SetIdent($ScriptID, $ident);
    }
// Script zusammenbasteln ist einfach nur "http://<IP vn LM>/control?scene=x"
    $content = "<?\rfile_get_contents('http://".$IP."/control?".(string) $xml->lightscenes->scene[$i1]->param."');\r?>";
    IPS_SetScriptContent($ScriptID, $content);
    $i1++;
}

// Anlegen einer neuen Kategorie mit dem Namen "Zonen" falls nocht nicht vorhanden
// Zonen enthalten die einzelnen Kommandos der Geräte aus den Szenen
$CatID = @IPS_GetObjectIDByIdent("Zonen", $_IPS['SELF']);
if ($CatID == false){
    $CatID = IPS_CreateCategory();              // Kategorie anlegen
    IPS_SetName($CatID, "Zonen");               // Kategorie benennen
    IPS_SetParent($CatID, $_IPS['SELF']);       // Kategorie einsortieren unter dem Objekt
    IPS_SetIdent($CatID, "Zonen");
}
$i1 = 0;

// Anlegen einer neuen Kategorie mit dem Zonen-Name falls nocht nicht vorhanden
while ($xml->zone[$i1]){
    $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->zone[$i1]->zonename);
    $ZoneID = @IPS_GetObjectIDByIdent($ident, $CatID);
    if ($ZoneID == false){
        $ZoneID = IPS_CreateCategory();
        IPS_SetName($ZoneID, (string) $xml->zone[$i1]->zonename); // Variable benennen
        IPS_SetParent($ZoneID, $CatID); 
        IPS_SetIdent($ZoneID, $ident);
    }
    $i2 = 0;
// Anlegen einer neuen Kategorie mit dem Aktuator-Name falls nocht nicht vorhanden
    while ($xml->zone[$i1]->actuators->actuator[$i2]){
        $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->zone[$i1]->actuators->actuator[$i2]->name);
        $ActuatorsID = @IPS_GetObjectIDByIdent($ident, $ZoneID);
        if ($ActuatorsID == false){
            $ActuatorsID = IPS_CreateCategory();
            IPS_SetName($ActuatorsID, (string) $xml->zone[$i1]->actuators->actuator[$i2]->name); // Variable benennen
            IPS_SetParent($ActuatorsID, $ZoneID); 
            IPS_SetIdent($ActuatorsID, $ident);
        }
        $i3 = 0;
// Anlegen eines neuen Scripts mit dem Kommando-Name falls nocht nicht vorhanden
        while ($xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]){
            $ident = preg_replace("/[^0-9a-zA-Z]/", "", (string) $xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]->name);
            $ScriptID = @IPS_GetObjectIDByIdent($ident, $ActuatorsID );
            if ($ScriptID == false){
                $ScriptID = IPS_CreateScript(0);
                IPS_SetName($ScriptID, (string) $xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]->name); // Variable benennen
                IPS_SetParent($ScriptID, $ActuatorsID ); 
                IPS_SetIdent($ScriptID, $ident);
            }
// Script zusammenbasteln ist einfach nur "http://<IP vn LM>/control?" und der Parameter aus dem XML
            $content = "<?\rfile_get_contents('http://".$IP."/control?".(string) $xml->zone[$i1]->actuators->actuator[$i2]->commandlist->command[$i3]->param."');\r?>";
            IPS_SetScriptContent($ScriptID, $content);
            $i3++;
        }
        $i2++;
    }
    $i1++;
}
?>

Ach ja falls die Konfiguration nicht gelesen werden kann steht es im Logfile von IPS.

Ralf

Hallo Ralf,
vielen Dank. Ich hatte es erst jetzt gesehen. Normalerweise bekomme ich immer eine Mail.

Das Skript funktioniert jetzt und liest alles aus. Perfekt :ok_hand:t2:
Vielen Dank.

Der LMAIR unterstützt ab sofort das Schwimmbadthermometer TFA 30.3066.01. Ich spiele mit dem Gedanken mir das Ding anzuschaffen.
Gibt es auch eine Möglichkeit über den LMAIR das Thermometer als Variable in IPS zu bekommen?

Viele Grüße
marvus

Hi,
freut mich. Ob man so an Sensor-Werte kommt kann ich (noch) nicht sagen.

Ralf

Hallo zusammen,
mit dem von Ralf geposteten Skript können Befehle an den Lmair geschickt werden. Gibt es auch eine Möglichkeit über den Lightmanager einen Befehl an IPS zu schicken? Zum Beispiel um eine Boolean zu schalten, mit dem ich einen Ablaufplan auslösen kann?

Viele Grüße
marvus

192.168.178.2:3777/hook/Lightmanager?cmd=pause-aus

Das ist dann ein Webhook und Du musst noch die entsprechende Routine zur Auswertung programmieren.

Ralf

Hallo Ralf,
danke für den ersten Schritt. Ich habe nun im LMAIR ein Webhook angelegt:
192.168.2.138:3777/hook/Lightmanager?cmd=runter

Anschließend habe ich im Webhook folgendes angelegt:
Hook: /hook/runter
Skript: „Ein leeres Skript angelegt“

Aber was muss in das leere Skript rein?
Verstehe ich es richtig, dass wenn in dem noch leeren Skript eine Änderung passiert, ich auf diese Änderung mit einem Ablaufplan als Auslöser reagieren kann?

Mein Ziel ist es die Rolladen zu schließen.
P.S. Der LMAIR kann seit kurzem auch Shellys, aber das funktioniert noch nicht zuverlässig. Daher meine Idee, einen Befehl an meine Skripte in IPS zu schicken, die die Rolladen schließen. So umgehe ich das immer mal wiederkehrende Anlegen des Roku Emulators.

Moin,
In das wehook Script kommt z.b.

$kommando = $_GET['cmd'];
switch ($kommando){
    case "close":
        $SetPayload['state'] = 'CLOSE';
        $SetPayloadJSON = json_encode($SetPayload, JSON_UNESCAPED_SLASHES);
        Z2M_Command(41484, 'set', $SetPayloadJSON);
        break;
}

In den switches kommt jetzt deine Reaktion rein. Als Trigger für den Ablaufplan müsstest du noch eine variable anlegen und im Switch dann setzen.

Btw für roku benutze ich mittlerweile ein docker roku2mqtt. Ist stabil und wird von allen meinen Hubs erkannt.

Ralf

Danke,
ich bekomme es aber noch nicht hin, da mich meine fehlenden Kenntnisse nicht über den Tellerrand hinausschauen lassen :wink:


2

Bist du so nett und erklärst mir noch, was ich wo austauschen muss?
An der roku2mqtt Lösung wäre ich aufgrund meiner Synology auch interessiert. Welchen Docker hast du genau in Verwendung und hast du hier auch eine Anleitung? :smiley:

Einen schönen Restsonntag noch :smiling_face:

Moin,
lege dir eine Boolean Variable an und merke dir die Objekt-ID dann:

$kommando = $_GET['cmd'];
$Variable = Objekt-ID der Variablen;
switch ($kommando){
    case "true":
        SetValue($Variable, true);
        break;
    case "false":
        SetValue($Variable, false);
        break;
}

wenn Du jetzt das cmd „true“ (ohne Anführungszeichen) schickst wird die Variable auf true gesetzt und Du kannst deinen Ablaufplan auf Aktualisierung triggern lassen. Ich habe true und false ins Beispiel geschrieben damiit Du sehen kannst das noch mehr damit geht.

Ralf

1 „Gefällt mir“

Hallo Ralf, irgendwo hängt es noch. Bei der Test Boolean tut sich nichts und sie bleibt auf „false“.
Den „webhook“ habe ich auch angepasst auf „/hook/Lightmanager?cmd=true“

Woran könnte es noch liegen?

<?php

$kommando = $_GET['cmd'];
$Variable = 42339;
switch ($kommando){
    case "true":
        SetValue($Variable, true);
        break;
    case "false":
        SetValue($Variable, false);
        break;
}

Hier erhalte ich beim manuellen Ausführen des Skripts den Fehler:
Notice: Undefined index: cmd in /var/lib/symcon/scripts/51709.ips.php on line 3

Hilft das weiter?

Es muss per webhook aufgerufen werden dann kommt cmd. Schick Mal true vom Lightmanager.

Ralf

Hallo Ralf, das geht ebenfalls nicht. Daher mein Versuch mal manuell auszulösen. Aber gut, das habe ich jetzt verstanden, dass es so auf keinen Fall geht. Ich habe noch einmal alles per Screenshot protokolliert. Kannst du bitte noch einmal genau drüberschauen, ob die irgendwo ein Fehler auffällt?

Liebe Grüße

4

Der Hook darf nur /hook/lightmanager heißen. Dann acht Mal auf die aktualisierungzeit der boolean.

Hallo Ralf,
es funktioniert jetzt und das Rollo fährt nach Aktualisierung der Boolean herunter! :slightly_smiling_face:

Wie sieht es aber jetzt mit einem zweiten Befehl aus, wenn ich z.B. das Rollo wieder hochfahren möchte?
Ich lege im LMAIR eine neue Szene an und setze gemäß deinem Foto oben die Geräte ID „2“ (Taste 1). Jetzt habe ich unter „Konfiguration“ der Taste 1 einen neuen Webhook angelegt und den cmd Befehl in „hoch“ geändert:

„192.168.2.226:3777/hook/Lightmanager?cmd=hoch

Nun aktualisert sich das Skript, das bereits beim Herunterfahren und im Webhook zuvor angelegt wurde, sprich das selbe Skript, wie beim Herunterfahren. Wie schaffe ich es denn dem Ablaufplan oder einer zweiten Boolean in IPS beizubringen, die Befehle „hoch“, „runter“, „stop“ und „auf Position fahren“ zu trennen?

Moin,
Schön das es einen Fortschritt gab.

Wenn du die Switch um deine Befehle erweiterst kannst du eine beliebige Anzahl von Kommandos hinzufügen. Kompliziert wie bisher oder du schreibst hinter den entsprechenden Kommandos gleich die Befehle um dein Rollo zu steuern. Also statt SetValue z.b. ein RequestAction…

Ralf

Ralf Biedermann

Hallo Ralf,
vielen Dank, das war der entscheidene letzte Tipp. Ich steuere jetzt alle Befehle direkt per RequestAction. Die Shellys reagieren blitzschnell. Danke für die ausführliche Hilfestellung.

Falls du mal in der nächsten Zeit viel Zeit hast, würde ich mich zusätzlich noch über die kleinschrittige Erklärung für die Roku2Mqtt Lösung auf der Synology freuen. Ich habe da die letzten Tage parallel ein wenig mit herumexperimentiert, aber kam mit den Ports und Einstellungen nicht zurecht. Zudem, wie ich den Docker mit IPS in Verbindung bringe. Ist nicht eilig, da ich jetzt erstmal eine schnelle und funktionierende Alternative habe, aber ich bin natürlich immer an anderen Möglichkeiten interessiert.

Besten Dank
Marvin