Grundsätzliche Fragen zur Modulerstellung

Der Name ist gleichzeitig die Variable.
Da du aber " anstatt ’ benutzt, will PHP da einen Wert eintragen.

Michael

Und du willst $id nutzt :slight_smile:

paresy

Stimmt, das hier $this->InstanceID ist auch Quark.
Einfach $id dafür nutzen.
Also so:
=> ‚I2GDMR_Set_Intensity($id, $Slider);‘
Michael

…wie müsste das also jetzt „im ganzen Satz“ aussehen??:confused:

Joachim

Jetzt erkennbar ?
Michael

…so sieht es ganz gut aus!:slight_smile:

		$arrayActions[] = array("type" => "Button", "label" => "On", "onClick" => 'I2GDMR_Set_Status($id, true);');
			$arrayActions[] = array("type" => "Button", "label" => "Off", "onClick" => 'I2GDMR_Set_Status($id, false);');
			$arrayActions[] = array("type" => "Button", "label" => "Toggle", "onClick" => 'I2GDMR_Toggle_Status($id);');
			$arrayActions[] = array("type" => "Label", "label" => "Dimmen");
			$arrayActions[] = array("type" => "HorizontalSlider", "name" => "Slider", "minimum" => 0,  "maximum" => 255, "onChange" => 'I2GDMR_Set_Intensity($id, $Slider);');

Joachim

…noch mal etwas ganz anderes:
Ich bin mit meinem Test-IPS von einem Raspberry Pi 1 auf einen aktuellen Raspberry Pi 3 umgezogen - ein Unterschied wie Tag und Nacht!
Die Module sind in wenigen Sekunden auf den aktuellen Stand gebracht, insbesondere die Reaktionszeit beim GPIO-Input hat sich dramatisch verkürzt. Hätte nie gedacht, dass dieses so einen Unterschied macht.

Joachim

Hallo Leute,

das ist noch so etas, da hätte ich gerne mal eine „professionelle“ Lösung.
Wie man in dem Log-Ausschnitt erkennt werden nach einem Update zunächst die Childinstanzen erstellt, die Fehlerzeilen die dort aufgezeigt werden, sind die wo im ApplYChanges ein „SendToParent“ aufgerufen wird. Das muss ja scheitern weil man wie im Log sichtbar die IO-Instanz als letztes erstellt wird. Muss ja auch irgendeine Reihenfolge geben…

Was mich dann aber doch mal interessiert:
Wie könnte ich den Fehler abfangen? Wie kann ich also vor dem SendToParent prüfen, ob die Instanz schon existiert?

Joachim

Einfach abfragen ob die Instanz verfügar ist ?


    /**
     * Prüft den Parent auf vorhandensein und Status.
     * 
     * @access protected
     * @return bool True wenn Parent vorhanden und in Status 102, sonst immer false.
     */
    protected function HasActiveParent()
    {
        $instance = @IPS_GetInstance($this->InstanceID);
        if ($instance['ConnectionID'] > 0)
        {
            $parent = IPS_GetInstance($instance['ConnectionID']);
            if ($parent['InstanceStatus'] == 102)
                return true;
        }
        return false;
    }

Michael

Hallo Michael,

vielen Dank für die Funktion!

Irgendetwas mache ich aber noch verkehrt, der Log-Auszug sieht leider immer noch so aus.
So frage ich jetzt Deine Funktion im ApplyChange ab:

If ((IPS_GetKernelRunlevel() == 10103) AND ($this->HasActiveParent() == true)) {

Da das mit protected nicht funktionierte habe ich es so angepasst:

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;
    	}  

Wo hängt es?:confused:

Joachim

…jemand eine Idee, warum dieses so nicht funktioniert?

Der Ansatz ist doch eigentlich klasse. Kann es sein, dass in der Phase des Updates noch „Altdaten“ vorhanden sind, die den „Schutzmechanismus“ aushebeln?

Joachim

Ich muss gestehen, ich wollte das auch noch mal explizit testen.
Ich vermute jetzt nur, es liegt hier:
$Parent = IPS_GetInstance
Vielleicht so?


private function HasActiveParent()
{
$Instance = @IPS_GetInstance($this->InstanceID);
if ($Instance['ConnectionID'] > 0)
{
$Parent = @IPS_GetInstance($Instance);
if (is_array($Parent)
if ($Parent['InstanceStatus'] == 102)
return true;
}
return false;
}

Michael
PS: ungetestet am Handy getippt

Ich verwende dafür diesen Satz an Funktionen in meiner Basisklasse. Grundsätzlich muss man schon ein wenig planen, welche Methoden und Eigenschaften man in welchem Objekt-Zustand nutzen kann. Bei einem Modulupdate dürfte da noch ziemlich wenig vorhanden sein, auch wenn KR_READY gesetzt ist.



 /**
     * Check if a parent is active
     * @param $id integer InstanceID
     * @return bool
     */
    protected function HasActiveParent($id = 0)
    {
        if ($id == 0) $id = $this->InstanceID;
        $parent = $this->GetParent($id);
        if ($parent > 0) {
            $status = $this->GetInstanceStatus($parent);
            if ($status == self::ST_AKTIV) {
                return true;
            } else {
                //IPS_SetInstanceStatus($id, self::ST_NOPARENT);
                $this->debug(__FUNCTION__, "Parent not active for Instance #" . $id);
                return false;
            }
        }
        $this->debug(__FUNCTION__, "No Parent for Instance #" . $id);
        return false;
    }
 //------------------------------------------------------------------------------
    /**
     * Check if a parent for Instance $id exists
     * @param $id integer InstanceID
     * @return integer
     */
    protected function GetParent($id = 0)
    {
        $parent = 0;
        if ($id == 0) $id = $this->InstanceID;
        if (IPS_InstanceExists($id)) {
            $instance = IPS_GetInstance($id);
            $parent = $instance['ConnectionID'];
        } else {
            $this->debug(__FUNCTION__, "Instance #$id doesn't exists");
        }
        return $parent;
    }
//------------------------------------------------------------------------------
    /**
     * Retrieve instance status
     * @param int $id
     * @return mixed
     */
    protected function GetInstanceStatus($id = 0)
    {
        if ($id == 0) $id = $this->InstanceID;
        $inst = IPS_GetInstance($id);
        return $inst['InstanceStatus'];
    }

Tommi

Hallo Tommi,

was verbirgt sich denn hinter „self::ST_AKTIV“?

Joachim

102
Michael

…leider produziert das die gleiche Fehlermeldung:

19.04.2017 19:26:52*| InstanceManager*| <br />
<b>Warning</b>:  Cannot find interface for instance #45344 in <b>/var/lib/symcon/modules/GeCoS-Modules/GeCoS_16In/module.php</b> on line <b>78</b><br />
<br />
<b>Warning</b>:  Cannot find interface for instance #45344 in <b>/var/lib/symcon/modules/GeCoS-Modules/GeCoS_16In/module.php</b> on line <b>151</b><br />
<br />
<b>Warning</b>:  Cannot find interface for instance #45344 in <b>/var/lib/symcon/modules/GeCoS-Modules/GeCoS_16In/module.php</b> on line <b>155</b><br />
<br />
<b>Warning</b>:  Cannot find interface for instance #45344 in <b>/var/lib/symcon/modules/GeCoS-Modules/GeCoS_16In/module.php</b> on line <b>141</b><br />

Die Zeilennummern sind jeweils diejenigen die das „SendToParent“ enthalten.

Irgendwie „schleicht“ sich der Code an dem

If ((IPS_GetKernelRunlevel() == 10103) AND ($this->HasActiveParent() == true)) {

vorbei…:eek:

Ist doch irgendwie komisch…

Joachim

Nur mal ein paar Überlegungunen:
Woher kommt die Parent Instance-ID, wenn der Parent erst im Anschluss erzeugt wird? Wäre es nicht sinnvoll bei Update die Verknüpfung aufzuheben wenn ich weiss, das sie neú angelegt wird? Kann es sein, das die GUID für #45344 nicht mehr existiert?

Tommi

Geht ja nicht weil du nicht weißt wie sie wieder korrekt verbunden werden, wenn es mehrere Instanzen pro Typ gibt.

Mir ist die Meldung auch schon länger nicht mehr aufgefallen.
Ich versuche gerade zu verstehen was bei mir anders ist.

Mal eben getestet… alle Instanzen werden ‚rot‘. Somit erstmal alle in Fehler.
Laut Log wird irgendeine Instanz zuerst neu übernommen.
Und die wirft keine Fehler…und macht auch kein SendDataToParent, also springt vorher raus.

Dafür bekomme ich beim entladen die gleichen Fehelr wie zu IPS3.4 Zeiten:

19.04.2017 21:08:11*| InstanceManager*| Referenzzähler >1 (=2) für Instanz #34944

Michael

Hallo Michael,

irgendeine Idee warum es bei mir nicht hinhaut?
Hier mal in anstrakter Form (gekürzt) das ApplyChanges:

        public function ApplyChanges() 
        {
            	// Diese Zeile nicht löschen
            	parent::ApplyChanges();
            	//Connect to available splitter or create a new one
	    	$this->ConnectParent("{5F50D0FC-0DBB-4364-B0A3-C900040C5C35}");
		
                //Status-Variablen anlegen
		
		
		If ((IPS_GetKernelRunlevel() == 10103) AND ($this->HasActiveParent() == true)) {
			//ReceiveData-Filter setzen
			
			$Filter = '((.*"Function":"get_used_i2c".*|.*"InstanceID":'.$this->InstanceID.'.*)|(.*"Function":"status".*|.*"Function":"interrupt".*))';
			$this->SetReceiveDataFilter($Filter);
			
$this->SendDataToParent(json_encode(Array("DataID"=> "{47113C57-29FE-4A60-9D0E-840022883B89}", "Function" => "set_used_i2c", "DeviceAddress" => $this->ReadPropertyInteger("DeviceAddress"), "DeviceBus" => $this->ReadPropertyInteger("DeviceBus"), "InstanceID" => $this->InstanceID)));
			If ($this->ReadPropertyBoolean("Open") == true) {				
				// Setup
				$this->Setup();
				$this->GetInput();
				$this->SetStatus(102);
			}
			else {
				$this->SetStatus(104);
			}	
		}
	}

Wieso wird die „Sperre“ übersprungen?

Joachim

Nachtrag: Könnte das $this->ConnectParent("{5F50D0FC-0DBB-4364-B0A3-C900040C5C35}"); an dieser Stelle ein Problem sein?

ConnectParent ist bestimmt auch ein Problem und darf nur im Create ausgeführt werden.
Doku: ConnectParent — IP-Symcon :: Automatisierungssoftware
Michael