…ich möchte zu dem Thema noch ein Beispiel hinzufügen:
Der Nutzer hat die Möglichkeit, einen I²C-Multiplexer-Typ auszuwählen. Dabei wird
[PHP$this->RegisterPropertyInteger(„MUX“, 0);]
auf einen größeren Wert als 0 gesetzt. Das tatsächliche Vorhandensein bzw. die korrekte Funktionsweise kann ich prüfen, jedoch bei Mißerfolg den Wert aus dem Code heraus nicht wieder auf 0 zurücksetzen.
In der Praxis muss ich also nicht immer wieder nur prüfen, ob ein Multiplexer nur "wunschgemäß" vorhanden ist, sondern ob er auch tatsächlich vorhanden ist.
Ich würde es mir demnach wünschen, dass ich die RegisterProperty auch ganz "offiziell" aus dem Code heraus manipulieren kann...;)
Joachim
??
Habe ich nicht verstanden. Willst du jetzt eine Eigenschaft deregistrieren, oder was meinst du mit manipulieren?
Du kannst den Wert dich mit IPS_SetProperty auf 0 setzen, nur musst du aufpassen dass es keine Endlosschleife gibt durch das anschließende ApplyChanges.
Wenn du es eh prüfen musst (wie?, Wann ?) kannst du dir das nicht einfach in einem Buffer merken?
Michael
deregistrieren möchte ich es definitiv nicht, nur auf einen den Tatsachen entsprechenden Stand setzen. Hier würde das bedeuten: Wird der angegebene MUX nicht gefunden, wird der Wert wieder auf 0 gesetzt.
Weil du nach IPS_SetProperty immer ein ApplyChanges ausführen musst.
Und was machst du in dieser Methode?
Prüfen ob Mux gültig und neu setzen, übernehmen.
Und prüfen neusetzen und übernehmen…
Usw…
Also aufpassen
Michael
…werde ich mich mal mit beschäftigen - insbesondere mit der potentiellen Gefahr… Danke!
In diesem Zusammenhang noch eine andere Frage:
Wie kann ich prüfen, ob eine im Konfigurationsformular eine Änderung stattgefunden hat und insbesondere wie der vorherige Wert war?
Beispiel:
Im Create():
$this->RegisterPropertyInteger("Test", -1);
Im Konfigurationsformular kann dieser Wert verändert werden.
Ich könnte den aktuellen Wert vielleicht so „sichern“:
$OldValue = $this->ReadPropertyInteger("Test");
Und im ApplyChanges() mit
If ($OldValue <>$this->ReadPropertyInteger("Test")) {
An den alten Wert kommst du nicht.
Einfach den Aktuellen Wert im ApplyChanges in einem Buffer schreiben.
Und dann im ApplyChanges den Buffer (also alter Wert) mit dem neuen aus Readproperty vergleichen.
Beim Systemstart etwas tricky, da musst du einmalig den Aktuellen Wert in den Buffer schreiben (MessageSink auf Kernelstarted).
Und im ApplyChanges aufpassen das du erst prüfst ob auch der Kernel KR_Ready ist, bevor du den alt neu Vergleich machst.
obwohl ich nun insbesondere durch diesen Thread und die immer wieder „tapferen“ Helfer schon eine Menge gelernt hab bleiben zwei grundsätzliche Fragestellungen bisher ungelöst…
30.11.2017 19:55:48*| TimerPool*| Warte auf Beendigung des Timer-Threads…
public function Destroy()
{
parent::Destroy();
$this->SetTimerInterval("RunningTime_1", 0);
$this->SetTimerInterval("RunningTime_2", 0);
}
Trotz des Tipps in allen Modulen die vielleicht laufenden Timer im Destroy auf 0 zu setzen, kam es nun schon zwei Mal wieder bei Updates (und davon mache im Test einige) zu diesem Phänomen.
Gibt es hierzu noch weitere Maßnahmen um dieses auszuschließen oder zumindest (weiter) zu reduzieren?
30.11.2017 19:55:22*| InstanceManager*| Could not create instance interface:
Warning: Kann für die Instanz #21969 das Interface nicht finden in /var/lib/symcon/modules/SymconModules/IPS2GPIO_Vaillant/module.php on line 174
Quasi bei jedem Update wird für quasi jedes Child bemägelt, dass es die SendToParent-Funktion nicht ausführen kann. In der jeweils genannten Zeile befindet sich der erste Verbindungsversuch.
Auf Vorschlag in diesem Thread testen ich das vorher jedoch mit:
private function HasActiveParent()
{
$Instance = @IPS_GetInstance($this->InstanceID);
if ($Instance['ConnectionID'] > 0)
{
$Parent = IPS_GetInstance($Instance['ConnectionID']);
if ($Parent['InstanceStatus'] == 102)
return true;
}
return false;
}
Offenbar - so mein Verdacht - ist die ConnectionID noch gesetzt, obwohl sich auch dieses während des Update-Prozesses nicht wirklich erreichbar ist?
Vielleicht gibt es ja doch noch einen Tipp um hier und/oder dort noch eine nachhaltige Verbesserung zu erreichen?
Zu 2) bist du sicher dass es nicht umgekehrt ist ? Also von den Parent zum Child mit SendDataToChildren ?
Oder weil noch Daten im IO ankommen?
Kann mich nicht mehr entsinnen diese Meldungen bei meinen Modulen zu sehen.
Kann mich aber auch täuschen.
Nur weil ich es gerade gebraucht habe. Hier meine Funktion für HasActiveParent. Es prüft die ganze Kette und gibt zurück, wenn eine der Instanzen nicht Aktiv (102) ist. (Ab 5.0 wegen der IS_ACTIVE Konstante)
private function HasActiveParent()
{
$isActive = function($id) use (&$isActive) {
$i = IPS_GetInstance($id);
if ($i['ConnectionID'] == 0)
return true;
$p = IPS_GetInstance($i['ConnectionID']);
if ($p['InstanceStatus'] != IS_ACTIVE)
return false;
return $isActive($i['ConnectionID']);
};
return $isActive($this->InstanceID);
}
Mir stellt sich immer die Frage…
Sollte mein Splitter auch inactive als Status haben wenn der IO inactive ist?
Oder lasse ich den Status immer auf Active (Error jetzt Mal nicht betrachten)?
Prüfen will ich die Instanzen bis zum IO gar nicht; wenn ein Splitter in Fehler steht dann wird halt ein Fehler geworfen.
Eigentlich reicht mir da also das oberste Element, sofern es einen IO ist.
Oder spricht da etwas dagegen?
Michael