Die Liste für den Splitter kann ich mir immer direkt aus den Instanzen generieren, da ich ja auch nur diese übergeben muss, da hast du recht, die anderen kann ich ja eh noch nicht ansteuern bzw. die Daten auswerten.
Allerdings in der Liste für’n Konfigurator müssten halt auch die angezeigt werden, die noch keine Instanzen haben. Das wäre ja dann blöd, da man beim Öffnen vom Konfigurator/Aktualisieren der Liste einige Sekunden warten muss.
Und? Wann musst du Mal an den Konfigurator?
Sonst öffnen und auf suchen klicken, schließen und neu öffnen.
Letztes nur so lange bis die Listen wirklich dynamisch in IPS sind
So wie z.b. bei OneWire oder Homematic.
Michael
Okay, ich fange erstmal an, das wird sowieso Arbeit ohne Ende Ich hab noch nichtmal die Kommunikation/WaitForResponse richtig am laufen. Alles Neuland für mich, danke!
Aber nochmal um das klar zu stellen: Wenn ich z.B. den Gerätecode aus einer Instanz abfrage oder irgend ne Variable wissen will, darf ich die nicht direkt auslesen, sondern muss das alles über den Datenaustausch lösen? Gibts dazu irgendwo schon einfache Beispiele?
Nein gibt es so nicht.
Du wirst aber nicht drum herum kommen direkt deine Childs zu ermitteln und direkt den Gerätecode auszulesen.
Der Datenaustausch zu den Childs hat keinen Rückkanal.
Wobei ich nicht wüsste warum du eine Variable auslesen willst. Ist mit noch kein Anwendungsfall untergeommen und würde ich persönlich auch vermeiden wollen.
Michael
Ja, und den auch den Code im Splitter beim SendDataToChildren mit übergeben.
So das deine Devices aus der Property einen ReceiveFilter setzen um auch nur ihre Daten zu erhalten und keine Fremden.
Michael
Ich hab hierzu nochmal eine Frage: Wenn der Datenaustausch zu den Childs keinen Rückkanal hat, kann ich die Gerätecodes doch nur mit IPS_GetProperty bekommen, oder liege ich da falsch?
Genau so, aber das braucht nur der Konfigurator damit er einen Abgleich zwischen vorhandenen Geräten und vorhandenen Instanzen machen kann. Und das auch nur wenn die Konfig geöffnet wird (GetKonfigurationForm)
Der Splitter braucht diese Info ja nicht, er sendet einfach weiter.
Michael
Doch der Splitter brauch die auch leider für den Initprozess. Ich wollte die Liste dann in einem Buffer im Splitter halten. Hole ich mir die für den Konfigurator dann aus dem Splitter oder auch über GetProperty?
Sorry, habe das mit einem anderen Thread verwechselt und Mal nachgelesen.
Ja wie in Post 15 & 16 geschrieben.
Ja mit IPS_GetProperty.
Habe aber noch mal überlegt ob ein Buffer sinnvoll ist um die Liste zu cachen.
Weil du ja Einträge entfernen (IM_DELETE) und hinzufügen (IM_CREATE) und ändern (IM_CHANGESETTINGS) beachten musst, ist es vielleicht einfacher immer die ganze Liste neu zu generieren.
Diese Liste von Instanzen musst du ja auch bei der Registrierung der Nachrichten in IPS übergeben.
Wobei IM_CREATE eher blöd ist, da es ja noch keine zu registrierende ObjektID gibt.
Also stattdessen eher FM_CONNECT und FM_DISCONNECT auf den Splitter registrieren um zu erfahren ob eine Geräte-Instanz verbunden / getrennt wurde. Und IM_CHANGESETTINGS mit der jeweiligen Geräte-Instanz registrieren um eine Änderung der Property zu erfahren.
wenn das Property nicht geändert werden kann, dann brauche ich IM_CHANGESETTINGS aber nicht oder? Der DuoFern Code der Geräte kann nicht verändert werden nur der vom Gateway. Hm wo ist jetzt der Unterschied von FM_CONNECT und DM_CONNECT? Gibt es da ne Doku oder nen Beispiel von? Finde da nicht so richtig was. Habe jetzt DM_CONNECT/DM_DISCONNECT angemeldet um zu schauen, ob der Parent sich ändert.
Offiziell in der Doku ist es FM und nicht DM.
Gemeint ist das gleiche. Nachrichten IP-Symcon :: Automatisierungssoftware
Beispiele was in den Data ankommt von MessageSink gibt es nicht.
Aber den Property muss der User ändern können, oder soll er etwa beim Austausch eines Gerätes eine neue Instanz anlegen und alle seine Scripte überarbeiten, Links neu erstellen und Ereignisse anpassen?
Ah okay Ich habe bei deinen Modulen auch eine Liste gefunden, die ist aber nicht mit Doku identisch. Sollte ich vielleicht mal eine aktuelle Liste aus der Dokus erstellen, oder ist die Doku unvollständig?
Du würdest die Geräteliste also garnicht buffern, sondern jedes mal bei FM_CONNECT/FM_DISCONNECT mit IPS_GetChildrenIDs($this->InstanceID) alle Kinder ermitteln und dann mit IPS_GetProperty ( $childId, „deviceCode“ ); die Gerätecodes auslesen und das Array dann an Init($deviceCodeList) übergeben?
Weißt du wie FM_CONNECT/FM_DISCONNECT genau funktioniert? Muss ich das noch auf den Kindern anmelden, oder reicht die eigene InstanzID? Beim Parent habe ich es nicht angemeldet und bekomme trotzdem die Nachrichten.
Wenn der Benutzer den Gerätecode vom Device ändern kann, müsste ich aber IM_CHANGESETTINGS auf allen Kindern welche einen Gerätecode haben anmelden/abmelden, um eine Änderung mitzubekommen, richtig? Ich hoffe, ich bekomme dann in $Data mit, welche Property geändert wurde.
/**
* Updates children data, buffers child instance ids and register/unregister msgs
*
* @return int parent instance id
*/
private function UpdateChildrenData() {
$oldChildrenIds = $this->ChildrenInstanceIDs;
$childrenIds = @IPS_GetChildrenIDs ( $this->InstanceID );
// no children changes
if ($childrenIds == $oldChildrenIds) {
return $childrenIds;
}
// unregister messagesat old children
foreach ( array_diff ( $oldChildrenIds, $childrenIds ) as $oldChildId ) {
// child has no duo fern code property
if (@IPS_GetProperty ( $oldChildId, "duoFernCode" ) === false) {
continue;
}
// unregister messages
if ($oldChildId > 0) {
$this->UnregisterMessage ( $oldChildId, IM_CHANGESETTINGS );
}
}
// register messages at new children
foreach ( array_diff ( $childrenIds, $oldChildrenIds ) as $childId ) {
// child has no duo fern code property
if (@IPS_GetProperty ( $childId, "duoFernCode" ) === false) {
continue;
}
// register messages
if ($childId > 0) {
$this->RegisterMessage ( $childId, IM_CHANGESETTINGS );
}
}
$this->ChildrenInstanceIDs = $childrenIds;
return $childrenIds;
}
/**
* Handles registered messages
* Will be called when receiving a registered msg
*
* @param int $TimeStamp
* @param int $SenderID
* @param string $Message
* @param array $Data
*/
public function MessageSink($TimeStamp, $SenderID, $Message, $Data) {
switch ($Message) {
case IPS_KERNELMESSAGE :
if ($Data [0] == KR_READY)
$this->ApplyChanges ();
break;
case FM_CONNECT :
case FM_DISCONNECT :
$this->ForceRefresh ();
$this->UpdateChildrenData();
break;
case IM_CHANGESTATUS :
if (($SenderID == @IPS_GetInstance ( $this->InstanceID ) ['ConnectionID']) and ($Data [0] == IS_ACTIVE)) {
$this->ForceRefresh ();
}
break;
}
}
Macht das so Sinn, oder bin ich da auf dem Holzweg?
MessageSink mußt du wohl noch etwas ändern, was genau mußt du mal testen.
public function MessageSink($TimeStamp, $SenderID, $Message, $Data) {
switch ($Message) {
case IPS_KERNELMESSAGE :
if ($Data [0] == KR_READY)
$this->ApplyChanges ();
break;
case FM_CONNECT :
case FM_DISCONNECT :
$this->ForceRefresh ();
// $this->UpdateChildrenData(); Würde ich in ApplyChanges verlagern, welches ja über ForceRefresh ausgeführt wird.
// Zumal hier ja auch der Parent der Sender sein kann, wenn dein Splitter vom Parent getrennt / verbunden wird.
// Somit macht es schon sinn die Liste neu zu holen und an den Parent neu zu übertragen.
break;
case IM_CHANGESTATUS :
if (($SenderID == @IPS_GetInstance ( $this->InstanceID ) ['ConnectionID']) and ($Data [0] == IS_ACTIVE)) {
$this->ForceRefresh ();
}
break;
case IM_CHANGESETTINGS:
// Hier dann die Childes verarbeiten. !
// Vermutlich am einfachsten wieder über ForceRefresh / Applychanges ?
// Vorsicht dass du ja nicht die Childes umkonfigurierst aus dem Splitter, sonst Endlosschleife !
break;
}
}
danke, aber deine Methode schließt den Konfigurator nicht aus. Reicht es nicht einfach zu testen ob es das Property duoFernCode gibt? So kann ich Konfigurator und ParentIO recht einfach ausschließen. Oder muss ich zwingend auf ConnectionID prüfen?
Ja, musst du.
Was wenn jemand (OK unwahrscheinlich aber möglich) zwei Sticks mit zwei Splittern in Betrieb hat ?
Immerhin kann man ja mit USB over LAN auch mehrere Liegenschaften in seinem IPS haben.
Ich prüfe gar nicht ob der Property existiert, da ich über die GUID ja nur meine Child-Geräte mit diesem Property habe (Parent und Konfigurator haben eh andere GUIDs).
Was wolltest du den machen?
Alle Instanzen in IPS durchgehen?
Das wäre etwas übertrieben, zumal es ja auch viel mehr Rechenleistung benötigt.
Das mit den Code war nicht auf (d)einen Konfigurator bezogen, sondern das ich diese Anforderung von dir schon Mal selbst umgesetzt habe. Und in meinem Fall war es ein Konfigurator.
Michael