Benötige Hilfe bei JSON Decoder Skript

Hallo,
ich möchte meine WLED’s mit JSON ansprechen. Dabei bin ich auch recht weit gekommen, scheitere aber an einem Punkt mangels Erfahrung. Das Auslesen der WLED’s ergab folgende Baumstruktur:


Die Variablen unter „state“ kann ich mit folgendem Skript beschreiben:

<?php

// WLED send JSON
// z.B. WSC_SendMessage(12345, '{"on":true}');

$WSClientID = 40592; //ID anpassen
$VariableID = $_IPS['VARIABLE'];
$Ident = IPS_GetObject($VariableID)['ObjectIdent'];
$value = $_IPS['VALUE'];
$send = json_encode(array($Ident => $value));

WSC_SendMessage($WSClientID, $send);

Die direkt unter „seg“ liegenden Variablen mit diesem Skript:

<?php

// WLED send JSON
// z.B. WSC_SendMessage(12345, '{"on":true}'); oder {"on":true,"bri":255}; oder {"seg":[{"col":[[0,255,200]]}]};

$WSClientID = 40592; //ID anpassen
$VariableID = $_IPS['VARIABLE'];
$Ident = IPS_GetObject($VariableID)['ObjectIdent'];
$value = $_IPS['VALUE'];
$send = json_encode(array(
    "seg" => array(
    $Ident => $value),
     ),
);

WSC_SendMessage($WSClientID, $send);

Am nächsten Unterpunkt scheitere ich dann jedoch. Ich möchte auch die Variablen unter „col“ beschreiben. Also z.B. col/Index_0 Variable Index_0 oder eben col/Index_1 Variable Index_3

Kann mir da bitte jemand auf die Sprünge helfen?

Gruß
Marc

Hallo Marc,

die Farbwerte müssen alle zusammen gesendet werden (Rot, Grün und Blau).
Ich habe mein Skript so erweitert, dass es eigentlich mit den am meisten benötigten Werten funktionieren sollte. Es ist aber noch nicht vollkommen.

du kannst es bei den Variablen als Action Script eintragen, nur die Variablen unter „ccnf“ und „nl“ und „info“ habe ich noch nicht abgefragt.

<?php

// WLED send JSON
// z.B. WSC_SendMessage(23978, '{"on":true}');

$WSClientID = 23978; //ID anpassen
$send = "";
$VariableID = $_IPS['VARIABLE'];
$value = $_IPS['VALUE'];

$Ident = IPS_GetObject($VariableID)['ObjectIdent'];
$ParentID = IPS_GetParent($VariableID);
$ParentIdent = IPS_GetObject($ParentID)['ObjectIdent'];
$Parent2ID = IPS_GetParent($ParentID);
$Parent2Ident = IPS_GetObject($Parent2ID)['ObjectIdent'];

switch($ParentIdent){
    case "state":
        $send = array($Ident => $value);
    break;
    case "ccnf": //anpassen
    case "nl": //anpassen
    case "udpn": //anpassen
    case "seg": //hier gibt es nichts zum Schalten
    break;
    default:
        switch($Parent2Ident){
            case "seg":
                $id = GetValue(IPS_GetObjectIDByIdent("id", $ParentID));
                $seg = array(
                        'id' => $id,
                        $Ident => $value
                        
                    );
                $send = array($Parent2Ident => array($seg), 'v' => true);
            break;
            case "col":
                switch($Ident){
                    case "Index_0":
                        $r = $value;
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_2", $ParentID));
                    break;
                    case "Index_1":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = $value;
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_2", $ParentID));
                    break;
                    case "Index_2":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = $value;
                    break;
                }
//                echo $r." - ".$g." - ".$b;
                $id = GetValue(IPS_GetObjectIDByIdent("id", IPS_GetParent($Parent2ID)));
                $Parent4Ident = IPS_GetObject(IPS_GetParent(IPS_GetParent($Parent2ID)))['ObjectIdent'];
                switch($ParentIdent){
                    case "Index_0":
                        $col = array(
                            'id' => $id,
                            'col' => array(
                                array($r, $g, $b)
                                )
                        );
                    break;
                    case "Index_1":
                        $col = array(
                            'col' => array(
                                array(),
                                array($r, $g, $b),
                                array()
                                )
                        );
                    break;
                    case "Index_2":
                        $col = array(
                            'col' => array(
                                array(),
                                array(),
                                array($r, $g, $b)
                                )
                        );
                    break;
                }
                $send = array($Parent4Ident => array($col), 'v' => true);
            break;
        }
}
if($send != ""){
    WSC_SendMessage($WSClientID, json_encode($send));
}

Vielleicht kann auch einer der Moderatoren den Beitrag zum passenden WLED-Thread verschieben.

Gruß
Rainer

Hallo Rainer,

vielen Dank, bis hier hin. Das Skript funktioniert zum großen Teil. Jedoch habe ich schon ein Problem. Bei der Farbeinstellung „col“ gibt es ja nicht nur die Farben RGB, sondern auch W, welche sich hinter dem Index_3 verbirgt. Da laufe ich dann auf einen Fehler. Leider habe ich das Skript noch nicht so ganz verstanden, dass ich mir das selber erarbeiten könnte.
Magst du da bitte mal schauen, was da fehlt?

Gruß
Marc

Hallo Rainer,

ich habe es mir soeben selbst erarbeitet und hoffe, dass es richtig ist. Zumindest funktioniert es und ich laufe auf keinen Fehler. Hier der Auszug aus dem Skript mit den entsprechenden Befehlszeilen:

            case "col":
                switch($Ident){
                    case "Index_0":
                        $r = $value;
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_2", $ParentID));
                        $w = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                    break;
                    case "Index_1":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = $value;
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_2", $ParentID));
                        $w = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                    break;
                    case "Index_2":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = $value;
                        $w = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                     case "Index_3":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                        $w = $value;
                    break;
                }
//                echo $r." - ".$g." - ".$b." - ".$w;
                $id = GetValue(IPS_GetObjectIDByIdent("id", IPS_GetParent($Parent2ID)));
                $Parent4Ident = IPS_GetObject(IPS_GetParent(IPS_GetParent($Parent2ID)))['ObjectIdent'];
                switch($ParentIdent){
                    case "Index_0":
                        $col = array(
                            'id' => $id,
                            'col' => array(
                                array($r, $g, $b, $w)
                                )
                        );
                    break;
                    case "Index_1":
                        $col = array(
                            'col' => array(
                                array(),
                                array($r, $g, $b, $w),
                                array()
                                )
                        );
                    break;
                    case "Index_2":
                        $col = array(
                            'col' => array(
                                array(),
                                array(),
                                array($r, $g, $b, $w)
                                )
                        );
                    break;
                }

Gruß
Marc

Hallo Marc,
so hätte ich das auch gelöst :+1:
Da ich nur RGB Stripes habe, fehlt mir der 4. Wert.
in der WLED JSON API steht „col“

Each color is an array of 3 or 4 bytes, which represent an RGB(W) color.

Und unter „info>leds“ gibt es eine Variable „rgbw“. Die sollte bei dir dann auf true stehen (bei mir auf false). Daran kann man unterscheiden, ob du 3 oder 4 Werte für die Farbe brauchst.
Das kann man bei der Erstellung des Arrays dann berücksichtigen, wenn man unterschiedliche Stripes im Einsatz hat.

Schöner wäre hier aber auch eine separate Farb-Variable, an der man die Farbe erkennt und aus der dann das Array erzeugt wird. Mit den 3 bzw. 4 Werten lässt sich im WebFront die Farbe auch nicht gut darstellen. Aber zur einfachen Bedienung reicht es erstmal.

Gruß
Rainer

Hallo,

ich bin auch gerade dabei WLED bie mir zu installieren, habt ihr eure Scripte mittlerweile fertiggestellt und würdet ihr diese teilen?
das würde mir einiges an Arbeit sparen :slight_smile:
Tom

Woran scheitert es denn? Oder anders gefragt, wie weit bist du denn schon?
Gruß
Marc

bekomme den Status aber möchte auch ansteuern können.
ehrlich gesagt hab ich moch nicht näher damit beschäftigt, hatte bisher die Einbindung über MQTT aber bei der sound reactive firmware ist MQTT deaktiviert und ich muss die Ansteuerung über JSON machen.

Also, ich versuche es mal, bin aber auch kein großer Experte:
Als Erstes erstellst du eine I/O Instanz „WebSocket“ Client. In diese trägst du dann unter URL folgendes ein: ws://DeineIP/ws
Danach erstellst du in einer Kategorie deiner Wahl eine „JSON Decoder“ Instanz. Dann öffnest du die Instanz und gehst oben auf „Gateway ändern“. Dort suchst du dir deinen WebSocket Client aus. Der automatisch erstellte Http-Client kann gelöscht werden.
In dem Ordner, wo sich auch der JSON-Decoder befindet legst du folgendes Skript ab:

<?php

// WLED send JSON
// z.B. WSC_SendMessage(12345, '{"on":true}');

$WSClientID = 31430; //ID anpassen
$send = "";
$VariableID = $_IPS['VARIABLE'];
$value = $_IPS['VALUE'];

$Ident = IPS_GetObject($VariableID)['ObjectIdent'];
$ParentID = IPS_GetParent($VariableID);
$ParentIdent = IPS_GetObject($ParentID)['ObjectIdent'];
$Parent2ID = IPS_GetParent($ParentID);
$Parent2Ident = IPS_GetObject($Parent2ID)['ObjectIdent'];


switch($ParentIdent){
    case "state":
        $send = array($Ident => $value);
    break;
    case "ccnf": //anpassen
    case "nl":
        $send = array("nl" => array($Ident => $value));
    break;
    case "udpn":  
        $send = array("udpn" => array($Ident => $value));
    break;
    default:
        switch($Parent2Ident){
            case "seg":
                $id = GetValue(IPS_GetObjectIDByIdent("id", $ParentID));
                $seg = array(
                        'id' => $id,
                        $Ident => $value
                        
                    );
                $send = array($Parent2Ident => array($seg), 'v' => true);
            break;
            case "col":
                switch($Ident){
                    case "Index_0":
                        $r = $value;
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_2", $ParentID));
                        $w = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                    break;
                    case "Index_1":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = $value;
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_2", $ParentID));
                        $w = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                    break;
                    case "Index_2":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = $value;
                        $w = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                     case "Index_3":
                        $r = GetValue(IPS_GetObjectIDByIdent("Index_0", $ParentID));
                        $g = GetValue(IPS_GetObjectIDByIdent("Index_1", $ParentID));
                        $b = GetValue(IPS_GetObjectIDByIdent("Index_3", $ParentID));
                        $w = $value;
                    break;
                }
//                echo $r." - ".$g." - ".$b." - ".$w;
                $id = GetValue(IPS_GetObjectIDByIdent("id", IPS_GetParent($Parent2ID)));
                $Parent4Ident = IPS_GetObject(IPS_GetParent(IPS_GetParent($Parent2ID)))['ObjectIdent'];
                switch($ParentIdent){
                    case "Index_0":
                        $col = array(
                            'id' => $id,
                            'col' => array(
                                array($r, $g, $b, $w)
                                )
                        );
                    break;
                    case "Index_1":
                        $col = array(
                            'col' => array(
                                array(),
                                array($r, $g, $b, $w),
                                array()
                                )
                        );
                    break;
                    case "Index_2":
                        $col = array(
                            'col' => array(
                                array(),
                                array(),
                                array($r, $g, $b, $w)
                                )
                        );
                    break;
                }
                $send = array($Parent4Ident => array($col), 'v' => true);
            break;
        }
}
if($send != ""){
    WSC_SendMessage($WSClientID, json_encode($send));
}

In Zeile 6 trägst du dann noch die ID vom WebSocket Client ein und führst das Skript manuell aus. Dazu muss die WLED aber online sein, also der WebSocket muss auf „aktiv“ stehen.
Danach sollten im JSON Decoder die ganzen Variablen stehen.

Ich habe die alle mal händisch umbenannt und teilweise auch mit eigenen Profilen versehen, da mir die Kürzel nicht immer etwas sagen und ich mir das auch nicht merken kann. Ich weiß aber nicht, wie ich das veröffentlichen könnte. Da fehlt’s mir dann etwas.

Falls du da mehr wissen willst, was welches Kürzel bedeutet, kannst du dich ja mal melden. Ich habe das aber auch rausgefunden, indem ich im WebUI der WLED Änderungen gemacht habe und bei Symcon auf den Zeitstempel geschaut habe, wo sich wie und was geändert hat. Ich habe in den Profilen auch alle Farben und Szenen eingetragen.

Du bist mein Held, vielen Dank!
das hat mir eine menge Arbeit gespart, ich kann schon was schalten…

Falls du, oder ein anderer, mir sagen kann, wie ich die angepassten JSON Decoder Variablennamen und die jeweiligen Profile weitergeben kann, würde ich auch da versuchen zu helfen.

Wenn ich das Skript manuell ausführe, meckert er:

Warning: Undefined array key "VARIABLE" in /var/lib/symcon/scripts/57136.ips.php on line 8

Warning: Undefined array key "VALUE" in /var/lib/symcon/scripts/57136.ips.php on line 9

Die Warnung ist nachvollziehbar, es müsste über ein Ereignis ausgelöst werden. Hier stehe ich auf dem Schlauch. Wie oder womit löse ich das Skript aus?
Oder habe ich einen Denkfehler? Denn der JSON-Decoder bleibt leer.

Mit dem Script werden im ersten Anlauf, welcher manuell ausgeführt wird, erst einmal nur die Variablen angelegt. Danach steht das Script bei allen Variablen in den Profil- und Aktionseinstellungen als „Eigene Aktion“ eingetragen. Um nun Werte zu ändern, wie z.B. „on“, „pl“ oder „ps“, müssen die Variablen selbst angesprochen werden. Das Script selber muss nicht mehr aktiv ausgeführt werden, das es automatisch durch Ändern der Variablen geschieht.
Gruß
Marc

Was heißt manuell ausführen? Wahrscheinlich nicht, einfach das Skript ausführen, oder? Denn es müssen ja Werte für „VARIABLE“ und „VALUE“ übergeben werden.

Rechte Maustaste und Ausführen.