Skript zur Wertübergabe an KNX

Hallo zusammen,

habe mich auf Grund eines Umbaus etc. ein Jahr lange nicht mehr mit Symcon befasst… und möchte nun wieder einsteigen.

Ich nutze Symcon vorerst als Schnittstelle zu unseren Saugrobotern und HomeConnect, etc.
Die Visu läuft über eine entsprechende KNX Visu.

Nun hab ich mir überlegt ob ich mir das ganze etwas „intelligent“ machen kann.

Mein Gedankenansatz wäre z.B. ein. Skript das ich unter einer Variable einordne die ich auf den KNX Bus übertragen möchte.

Praktisch wäre dann wenn ich im Skript nur noch eine Gruppenadresse und den DPT Typ angeben müsste, so das man das Skript einfach immer wieder verwenden kann.

Diverse ID‘s etc. kann ich ja mit GetParent ermitteln, mir fehlt jedoch der Ansatz für das Gruppenadresse Thema, hat jemand einen Lösungsansatz?

Denke ich zu kompliziert? :joy:

Grüße,
Adrian

Ja.
Lege die entsprechenden KNX Instanzen z.b. über den dazugehörigen KNX Konfigurator an.
Die dadurch entstehenden Statusvariablen kannst du dann z.b. über Ereignisse, Ablaufpläne oder Scripte schalten.
Michael

So funktioniert KNX in IPS leider nicht, du benötigst pro GA zwingend eine Instanz mit fester GA und festem Datentyp.

Ja, das dachte ich mir schon das es nicht anders klappt.
Im Prinzip wollte ich das ganze nur etwas vereinfachen, wie macht ihr das so in der Praxis ?

Ich nehme jetzt einfach mal mein Beispiel: Saugroboter, hier möchte ich div. Statusmeldungen an den KNX Bus übertragen und vom KNX Bus z.B Start & Dock sowie die Saugleistung einstellen.

Packt ihr das alles irgendwie in ein Script?
Oder gar mit Ablaufplänen / Ereignissen ?

Bei mir gibt es dafür das ‚KNX zu Symcon Script‘

Ein Auszug aus dem Script (der ggf. nicht läuft, weil ich was übersehen habe):

$data =   array(
   // boolean Statusvariable Shelly, Merros, Homematic => KNX Instanz ID
                56719 =>  36384,
                51811               => 39530,
                31820       => 40735,
                37776     => 51810,
//                14854     => 55841,

);
$knx_instanz = IPS_GetParent($_IPS['VARIABLE']);

if(in_array($knx_instanz,$data)){
   // Simple Boolean
    $id = array_search($knx_instanz, $data);
    RequestAction($id, $_IPS['VALUE']);
}else{
   // andere Datentypen
    switch($knx_instanz){
        case 21402:
            RequestAction(20832, 1);
        break;

case 50803:
            $i=0;
          while(GetValueInteger(28599) != 0 ){
                // Dimmen
                if($_IPS['VALUE']){ 
                    DAVRT_Z3_Volume(24351, "UP"); // heller/lauter
                    //IPS_LogMessage("knx->symcon", "Wohnung lauter ".$i++);
                }else{  
                    DAVRT_Z3_Volume(24351, "DOWN"); // Dunkler / leiser
                    //IPS_LogMessage("knx->symcon", "Wohnung leiser ".$i++);
                }
                ips_sleep(200);
            }
            break;

Hallo Tobias,

dein Skript sieht glaube ich danach aus was ich eigentlich wollte, aber ich verstehe es irgendwie nicht ganz :frowning:

Mir stellte sich im Prinzip die Frage ob ich wirklich für jede Variable die ich auf den KNX Übertragen möchte, oder anders herum jeweils ein eigenes Skript anlegen sollte?

Oder ein Skript pro „Gerät“ wie z.B. ein Skript Symcon → KNX für alle Variablen des Saugroboters, und ein Skript für die Steuerung ( KNX → Symcon ) für alle Variablen die ich aus KNX heraus ansteuern möchte.

In meinem Beispiel ist es jetzt ein Script je Richtung. Hier für ALLE Geräte von KNX zu Symcon. Im Script wird entsprechend entschieden, über welche Instanz die Werte kommen und unterschiedliche Dinge ausgeführt.

Woran genau hapert es?

Mir fehlt der richtige Ansatz dafür…
Ich möchte folgendes vom Roboter an den KNX übermitteln:

Fehlermeldung
Zustand ( Reinigt/Lädt )
Batteriezustand

Und folgendes vom KNX zu Symcon

Steuerung: Start, Pause, Dock
Nasswischen Ja/Nein
Saugleistung,
Etc.

Das sind ja jetzt viele verschiedene Werte, bool, String, Int.

Hier fehlt mir der Ansatz wie ich das so komprimiert darstellen kann wie in deinem Beispiel.

Auch die Lesbarkeit eines Scriptes ist wertvoll, deshalb muss es nicht zwingend so kompakt sein. Meine Scripte sind eher auf Verständlichkeit getrimmt und enthalten oft viel mehr Kommentarzeilen als Codezeilen.

Ich würde ein Script für Saugroboter-> KNX und ein zweites für die Gegenrichtung anlegen. Getriggert wird das Script dann durch ausgelöstete Ereignisse (Wertänderung jeder der betreffenden Variablen).

Pro GA benötigst du eine KNX-Instanz, aber die kann man ja trotzdem alle in einem Script (pro Richtung) abarbeiten.

Ich hab jetzt mal in dem Falle für die Waschmaschine ein Skript gebaut, würde mich über eure Meinung dazu freuen.
Konnte es noch nicht testen, sollte aber funktionieren, sieht jedoch etwas „umständlich“ aus?

<?php

//Definition der Variablen die von Symcon zu KNX übertragen werden:

$betriebsStatus = (15194);
$laufzeit = (21531);
$tuerStatus = (47940);

//Definition der KNX Gruppenadressen die von Symcon beschrieben werden:

$knx_betriebsStatus = (15466);
$knx_laufzeit  = (44691);
$knx_tuerStatus = (12879);


if ($_IPS['VARIABLE'] == $betriebsStatus)
{
    RequestAction($knx_betriebsStatus, $betriebStatus);
}

if ($_IPS['VARIABLE'] == $laufzeit)
{
    RequestAction($knx_laufzeit, $laufzeit);
}

if ($_IPS['VARIABLE'] == $tuerStatus)
{
    RequestAction($knx_tuerStatus, $tuerStatus);
}

Grüße,
Adrian

  1. Das Script hat ein paar Schönheitsfehler. So werden IF-Bedingungen ausgeführt, die nie mehr wahr werden können. Dies ist nicht sonderlich effizient. Else-if bzw. sog. switch Statements wären hier praktischer. ABER für die grundlegende Funktion wäre das egal.

$_IPS['VARIABLE'] abzufragen abzuprüfen, ist grundsätzlcih gut.
Der WERT ist dann aber $_IPS['VALUE'], du würdest hier Richtung KNX grundsätzlich die Symcon Variablen-ID senden, anstatt des Werts.

Ich würde das Script, um nicht zuviel zu ändern, etwa so schreiben.

if ($_IPS['VARIABLE'] == 15194 /*betriebsStatus*/)
{
    RequestAction(15466 /*knx_betriebsStatus*/, $_IPS['VALUE']);
}
elseif ($_IPS['VARIABLE'] == 21531 /*laufzeit*/)
{
    RequestAction(44691 /*knx_laufzeit*/, $_IPS['VALUE']);
}
elseif ($_IPS['VARIABLE'] == 47940 /*tuerStatus*/)
{
    RequestAction(12879 /*knx_tuerStatus*/, $_IPS['VALUE']);
}

Hintergrund: ICH komme sehr schnell durcheinander, wenn die Variablen-ID irgendwo separat definiert ist und es macht das Ändern/Ausprobieren etwas leichter. Wenn man die Scripte dann später super universell weiter nutzen möchte, kann man die Variablen immernoch vorab definieren.

Hallo Tobias,

danke für den Denkanstoß :slight_smile:
Ich erinnere mich, Switch Statements habe ich früher öfters verwendet, ich habe das Skript mal umgebaut, musste jedoch noch ein paar Rechenaufgaben einbauen für die Laufzeit.

Um das ganze etwas transparenter zu machen im Meldungsfenster, wollte ich gerne eine Log Message mit dem jeweiligen Status erzeugen, allerdings komme ich mit meinem Skript wohl nicht an den Inhalt der Variable, oder habe den falschen Ansatz.

Was sagst du sonst zum neuen Aufbau?


switch ($_IPS['VARIABLE'])
{

    case 15194;
        RequestAction(15466, $_IPS['VALUE']);
        IPS_LogMessage('Waschmaschine', 'Der Betriebsstatus'.$_IPS['VALUE'],'wurde an den KNX-Bus übertragen' );
        break;

    case 47940;
        if ($_IPS['VALUE'] == "Offen")
            {
                RequestAction(31378,true);
            }
            elseif ($_IPS['VALUE'] == "Geschlossen")
                {
                    RequestAction(31378,false);
                }
        break;


    case 21531;
        RequestAction(44691, timeConversion($_IPS['VALUE']));
        break;
}



//Hilfsfunktionen 

function timeConversion($sekunden) //Umrechnung der Zeit von Sekunden auf Stunden:Miunten:Sekunden

    {
		$std  = floor($sekunden / 3600 % 24);
		$min  = floor($sekunden / 60 % 60);
		$sek  = floor($sekunden % 60);
		return (sprintf("%02u:%02u:%02u",$std,$min,$sek));
	}

Ist es denn erforderlich den Auslöser des Scriptaufrufs zu ermitteln?

Man könnte doch einfach alle Gerätevariablen übertragen sobald sich irgendeine geändert hat, sind doch nur eine Handvoll. So oft wird das Script vermutlich nicht getriggert dass man sich den Bus zumüllt?

Hier ist ein Komma reingeraten (ich habe es mal in ** eingeschlossen), wo ein Punkt stehen sollte. Vielleicht klemmt die Methode schon deshalb bei dir?