Allgemeine Frage: Objekt-ID vs. Klartext bzw. Arbeitstitel

Hi,

in IPSymcon V2 werden ja Objekt-Funktionen und Methoden offenbar grundsätzlich mit der Objekt-ID angesprochen statt mit einem Objekt-Namen.

Da ich ziemlich schwach bin, was die Erinnerung von Zahlenreihen anbetrifft, und man den Objekten im Objektbaum ja leider keine Systematik beibringen kann, muss man (ich zumindest) sich eine Methodik überlegen, wie man sich selbst Referenzen schaffen kann.

In anderen Programmiersprachen habe ich mir eine stringente Syntax alsi „Alias“ angewöhnt, z.B. „FS20_A_EZ-01“ heisst: „Erster FS20 Aktor Esszimmer“ Diese „Programmierer-definierte Alias-Notation“ ist dort nochmals vom Klartext-Namen im Objektbaum abgekoppelt.

Ich werde mehrere IPS parallel in verschiedenen Gebäuden benutzen und will dabei einige der Funktionen (z.B. „Ambiences“) überall verwenden. Deshalb würde ich gerne Code und Objekt-IDs komplett enkoppeln.

Wie macht ihr das in IPS, um die Lesbarkeit (auch, was das Objekt anbetrifft, das gerade gesteuert wird) des Code zu gewährleisten?

Mein Ziel wäre es, Zeilen wie:

FS20_SwitchMode(16569 /[FS20-Aktor-KH-01-1431 [UP Decke]]/,$val);

gegen

FS20_SwitchMode( [getID( {FS20_A_EZ01} ) ] ,$val);

zu ersetzen. [ und { habe ich nur als Arbeits-Syntax benutzt um zu zeigen, dass da irgendwie eine Funktion oder etwas ähnliches kommen muss.

Man kann doch auch den Namen verwenden:

SetValueInteger(„Status Toaster“, 2);

auf jeden Fall i$n der V2.

Hi sokkederheld

In der V2 sind die Funktionen SetValueXXX(… und GetValueXXX(… nur noch aus Gründen der Abwärtskompatibilität vorhanden. Lt. Handbuch sollten sie nicht mehr verwendet werden, ich gehe auch davon aus, das Paresy sie irgendwann entgültig „entsorgen“ wird.

Es sollten nur noch die Funktionen SetValue(… und GetValue(… verwendung finden, zumindestens in neuen bzw. überarbeiteten Skripten.

Ich für meinen Teil nutze zur leichteren Anpassung der Skripte die php-defines, die ich am Anfang im Skript stehen habe. Somit kann ich bei wechselnden Instanz-ID’s die Skripte leicht anpassen und der Quelltext ist leichter lesbar, da in den IPS-Befehlen quasi Namen verwendung finden.


define("Status", 12345, true);
define("Sensor", 54321, true);

if (GetValue(Sensor) == true) {             // <-- Hier steht dann sozusagen ein Klartextname
  SetValue(Status, "Eingeschaltet");
} else {
  SetValue(Status, "Ausgeschaltet");
}

@Sokkerheld:
Also, dann habe ich das falsch verstanden (ich war bisher davon ausgegangen, dass V2 den Zugriff via Namen gerade NICHT MEHR unterstützt - es gibt ja dazu auch keine Doku --> z.B. http://www.ipsymcon.de/downloads/ips2manual/FS20_SwitchDuration.html).:confused:

Aber das ändert auch grundsätzlich (für mich) nichts an der gewünschten Alias-Thematik.

Ich will „Allgemeinen Code“ schreiben und daher referenziert - am allerlibsten in einem ganz separaten „Array“, das aber irgendwo gespeichert sein soll - auf die konkreten Sender- und Aktoren-Funktionen zugreifen. Denn:

Namen und ID’s können sich über die Zeit hinweg und vor allem von System zu System ändern. Kapselt man nun die Scripte und Funktionen so, dass Referenzen übergeben werden, kann die rufende Instanz ganz separat agieren und vor allem ist die Anpassung von System zu System nur an einer einzigen Stelle - der Referenz - vorzunehmen.

Ein Beispiel:

Ich denke daran, eine „intelligente“ Abwesenheits-Simulation zu codieren. Diese „Funktion“ kann sicher der eine oder andere brauchen. Allerdings hat jeder andere Bezeichnungen und der eine will 5 Geräte, der nächste 10 Geräte in diese Simulation einbeziehen.

Parameter wäre also z.B. ein Array der teilnehmenden Objekte und ggf. ein paar weitere Parameter JE Objekt, z.B. die relative Häufigkeit (Gang öfters an-aus als Wohnzimmer).

Um dann nicht die Teilnehmer und deren Parameter im Script selbst anpassen zu müssen, wäre solch eine Referenz gut.

@bruns8234:

So in etwa stelle ich mir das vor. Nur würde ich die Definition gerne „zentral“ sehen.

In Deiner Lösung musst Du, wenn ich das richtig verstehe, in JEDEM Script Änderungen vornehmen, wenn sich bestimmte ID’s ändern (z.B. weil man mal versehentlich ein Objekt löscht und neu anlegt oder wenn man eine Reihe von Scripte auf einer anderen IPS laufen lassen will.

Noch wilder wird es, wenn man IPS von Drittsystemen aus befehligen will. Denn dann braucht man eine Konsistenz über alle Systeme hinweg.

Wenn man mit Aliassen arbeitet und lokaler Referenz, ist dieses Problem ebenfalls vom Tisch.

Vielleicht kann Kollege Steiner da mal einen Hinweis geben, er macht ja doch sehr umfangreiche Projekte mit dem System und dürfte vor ähnlichen Herausforderungen stehen, wenn er nicht jedesmal einen riesen Aufwand treiben will.

Hmm, Handbuch… ich kenne leider bisher nur diese unvollständige Hilfedatei und da längst nicht alles da drin steht, suche ich mir die Syntax meistens anhand von Beispielen im Forum zusammen. Mit allen Macken der jeweiligen „Vorbilder“ :wink:

Aber GetValueString ist doch eigentlich nur die typisierte Version des polymorphen GetValue? Also intern wird es doch ohnehin eine mehrfach überladene Funktion sein.

Naja, ich werde dann in Zukunft auch GetValue und SetValue einsetzen, aber dafür, die typisierten Versionen dieser Befehle einzustampfen spräche eigentlich… nichts, oder? Welchen Vorteil brächte das? Und wäre dieser es wert, dass etliche Leute ihre Skripte ändern müssen?

Hallo jwka,

das von Thorsten (bruns8234) vorgestellte Verfahren ist für Deine Zwecke doch bestens geeignet. Er hat es des besseren Verständnisses wegen eben etwas einfacher dargestellt.

Es hindert Dich doch niemand daran, die „define“-Liste in ein eigenes Skript zu verlagern und dieses dann in alle anderen Skripte per „include“ einzubinden. Dann hast Du alle IDs und Namen, wie von Dir gefordert, zentral in einem einzigen Skript. Bei Änderungen muss nur dieses eine Skript angefasst werden.

Statt „define“ kannst Du in diesem Skript natürlich auch ein Array-Konstrukt verwenden oder auch eine Datenbank. Es gibt jede Menge Möglichkeiten.

Gruß
HJH

@HJH
Danke, das zeigt mir wenigstens, dass ich nicht völlig auf dem Holzweg bin.

Trotzdem einfach nochmals die Frage in die „große Runde“:

Hat jemand da schon eine Systematik entwickelt oder gibt es in PHP / IPS sowas wie einen „Standard“ zur Herangehensweise?

Ich halte viel davon, bereits erfundene Räder zu nutzen und die Zeit anders zu investieren, denn ein neues Rad zu erfinden.

Grüße
jwka

SetValue/GetValue sind nur neue Funktionen. Die alten GetValueBoolean… werden nicht verschwinden. Es wird nur nicht mehr Empfohlen die Namen zu verwenden, sondern nur noch die IDs. Es wird früher oder später Warnings dafür geben, wenn man die Funktion mit dem Namen aufruft.

Dann zum Thema. Dein Ansatz bietet für dein Einsatzgebiet wahrscheinlich das passende. Trotzdem will ich auch mal ein Problem darstellen.

Beispiel:
FS20_A_EZ01

FS20 als System kann sich ja auch ändern. Ist also ein ungünstiges Prefix.
01 sagt soviel aus wie 12345 als ID und damit ist dein System für einen externen noch weniger aussagend als wenn dort die ID stehen würde + dem Auto-Kommentar von IP-Symcon.

Ich löse das Problem wie folgt:
Stelle wir uns vor, wir hätten eine Flurlicht steuerung, die auf alles Etagen gleich ist. Wir brauchen sie also z.B. 3x.

Wir könnten jetzt also 3x das Skript per Copy&Paste in das Skript tun, was für die meisten auch OK ist. Wer jetzt aber Redundanz vermeiden will und/oder ein System zum CodeReusing zwischen Projekten braucht, kann das relevante Skript ja auslagern.

So erstellen wir ein schönes Skript „Lichtsteuerung (xComfort, Flur, Bewegungsmelder, Helligkeitsregelung)“.

In diesen steht dann z.B.:


if(!$IPS_VALUE) { //Wenn keine Bewegung - siehe Handbuch für Spezialvariable
 MXC_SwitchMode($lampenID, false);
} else {
 if(!GetValueBoolean($istTag)) { //Nur nach Sonnenuntergang
  if((time() > strtotime("22:30")) || (time() < strtotime("06:00"))) {
   MXC_DimSet($lampenID, 15);
  } else {
   MXC_DimSet($lampenID, 50);
  }
 }
}

Dann brauchen wir noch ein Skript für jeden Flur.


//Trigger durch Bewegungsmelder Variable!

//Eindeutige Geräte-ID
$lampenID = 53013 /*[Erdgeschoss\Flur\Deckenlampe]*/;
//Tag/Nacht Variable
$istTag = 31753 /*[IstTag]*/;

includeScript(12345 /*[Szenarien\Lichtsteuerung (xComfort, Flur, Bewegungsmelder, Helligkeitsregelung)]*/

//Copy&Paste aus der Skript-Library
function includeScript($scriptID)
{ $s = IPS_GetScript($scriptID);
 include($s['ScriptFile']);
}  

Wir können uns also „Funktionsvorlagen“ erstellen und diese dann nur noch mit den nötigen IDs füttern. In diesen Skripten sind dann die IDs, zu denen IP-Symcon immer vollständige und aussagekräftige Namen erstellt. (Sofern man seinen Baum vernünftig erstellt)

Wenn man es will/braucht, kann man das Szenario auch für FS20 anpassen und dynamisch anhand der übergebenen InstanzID die richtige Funktion aufrufen. Soweit will ich es aber hier nicht treiben.

Ich würde also keine kryptischen Namen vergeben, sondern klare und beschreibende Namen und diese in den Baum einordnen. Nach dem Prinzip Etage\Zimmer\Gerät. Die Namen der Status Variablen würde ich, sofern nicht unbedingt benötigt, garnicht anfassen.

Wenn ihr die IDs nutzt, nimmt euch IPS die Arbeit ab, wenn sich ein Name ändert, da die Kommentare im Skripteditor automatisch aktualisiert werden bei jedem öffnen des Skriptes!

paresy

@Paresy
Jetzt kommen wir zur richtigen Diskussion. Prima, danke!

Vorab: Ich stelle vielleicht Fragen, die noch ein paar Schritte weit weg sind von meinem jetzigen Newbee-KnowHow …

Mein Beispiel mit „FS20_A_EZ01“ war willkürlich nicht so tief angegeben wie ich es beabsichtige, zu fahren (wie Dein Vorschlag mit Stockwerk/Zimmer/Verwendung). Allerdings habe ich am Ende trotzdem eine zweistellige Zahl vorgesehen, weil eben manche Aktoren nach meiner erfahrung über die Lebenszeit u.U. eben NICHT so ganz eindeutig zugewiesen sind, so kann sich z.B. die Position einer Lampe beim Umbau durchaus von „Decke“ zu „Wand“ ändern oder aus zwei Aktoren dann doch nur einer werden.

Mit meine „Notation“ bin ich auch noch nicht ganz a jour. Ich überlege, ob ich tiefe Arrays machen soll, oder bestimmte Infos in die einzelnen Array-Werte mit einbringe. So war das z.B. mit FS20 gemeint.

Und dass die „01“ dann ebensowenig Aussagekräftig ist wie eine „10382“, da bin ich mit Dir absolut nicht einer Meinung, weil ja die Buchstaben weiter vorne den Bereich schon sehr genau eingrenzen und die Ziffern eines Raums sicher nicht in Kraut schiessen werden. Zusätzlich kann eine gewisse Systematik auch bei der Ziffer eingesetzt werden kann, z.B. 0x für Licht, 1x für Steckdosen etc. Damit kann man sich im Zeitpunkt der Erstellung eines Scriptes sehr viel leichter merken, dass die Steckdose „in der Ecke beim Klavier“ die xxx_EZ13 ist.

Auch später, wenn eine andere Person etwas nachvollziehen will, kann sie oft schon an den ersten „Identifiern“ aufhören zu lesen, weil z.B. nur Lichtelemente gesucht werden.

Ich hatte ja auch schon angeregt, eine Möglichkeit zu schaffen, ein Stück weit „gewillkürte“ IDs im Objektbaum vergeben zu können, um eben dieser Problematik ein bischen entgegen zu kommen. Dass dann eine Konsitenzprüfung nötig wird, ist klar.

Und zum Problem:
Nicht übersehen: Ich würde natürlich die Namen und Aliasse selbst ebenfalls nur als Inhalte von Arrays halten. Die Variablennamen in meinen Scripten (bzw. die referenz zu Arrayinhalten) sind dann wieder universeller und konkrete Aufrufe von Einheiten (FS10, Moeller etc.) würde ich ebenfall gerne kapseln. So kann später z.B. durch ändern eines Eintrags im „Bestands-Array“ sowohl die Methode als auch die Einheit geändert werden. Heute wird ein Licht mittels FS20 geschaltet, morgen mit einer KNX Komponente. Die Logik bleibt dieselbe, lediglich an meiner Bestandsmatrix muss ich Einträge ändern.

Nun eine (vielleicht blöde) Frage (als PHP newbee) zu meinem „Bestands-Array“:

Nach Erfahrung von geübten PHP Programmierern: Ist es sinnvoller ein „tiefes“ Array zu benutzen oder in einer Position einen String zu verwenden, den man dann mit String-Operationen (strtok) auseinander nimmt.

Also: Ist der Zugriff auf A [y] [z] schneller oder ist strtok(Strtok( (A ;"");"")?

Und weiter:

Wie unterscheidet sich (Laufzeitgeschwindigkeit) ein Array (per include in ein Script „geholt“) von dem Zugriff auf in „HilfsObjekten“ des Objektbaums abgelegten Werten? (Wobei da ja wieder das Problem mit der „anonymen“ ID auftritt).

Danke