Grundsätzliche Fragen zur Modulerstellung

…habe es mal rausgenommen - war im Create und ApplyChanges…aber doppelt hält ja nicht immer besser…:wink:

Der Fehler ist aber leider geblieben…:mad:

Joachim

Im Gegenteil du verbindest die Instanz dann immer neu, auch wenn der User sie gerade getrennt hat :slight_smile:
Michael

@Paresy: Hast Du nicht noch eine Idee für mich?[emoji6]

Joachim

Ich verstehe das Problem immer noch nicht? Welche Sperre? Hast du mit SendDebug dir mal ausgeben lassen, wie die einzelnen Ergebnisse des if() sind?

paresy

Hallo Paresy,

es geht ja um die Fehlermeldung wie im Screenshot im Beitrag 208

Die entstehen ja, weil der Splitter beim Update noch nicht erstellt wurde, die schon erstellten Device-Instanzen per SendToParent versuchen Kontakt aufzunehmen.

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 />

In den genannten Zeilen steht jeweils ein SendToParent.

zum „Schutz“ davor habe ich im ApplyChanges ein

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

Da danach erst die SendToParent kommen gehe ich davon aus, dass beide Teile der Abfrage mit „true“ bestätigt werden, kann das gerne aber noch mal prüfen.

Joachim

…so, habe das jetzt zum Test mal so gemacht:

IPS_LogMessage("GeCoS 16In", "IPS-RunLevel: ".IPS_GetKernelRunlevel() );
		IPS_LogMessage("GeCoS 16In", "HasActiveParent: ".$this->HasActiveParent() );
		
		If ((IPS_GetKernelRunlevel() == 10103) AND ($this->HasActiveParent() == true)) {
			
			IPS_LogMessage("GeCoS 16In", "IPS-RunLevel: ".IPS_GetKernelRunlevel() );
			IPS_LogMessage("GeCoS 16In", "HasActiveParent: ".$this->HasActiveParent() );

Wie aus dem Log-Ausschnitt ersichtlich wird sowohl vor als auch nach der If-Abfrage beides mit true bestätigt, da es sich um ein Update handelt ist das für den Kernel-Status auch nachvollziehbar. Der IO wird im Log ersichtlich erst am Ende erstellt, trotzdem bestätigt „HasActiveParent“ das diese da wäre. Das SendToParent läuft aber trotzdem ins Leere…

Joachim

Hier noch mal die Funktion "HasActiveParent von Tommi:

/**
	* 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 == 102) {
                		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'];
    	}	  

…das Thema der letzten Postings konnte noch nicht geklärt werden. Komisch ist aber, dass es manchmal offensichtlich funktioniert - manchmal auch nicht…:confused:

Aber mal etwas anderes:
Wenn ich SelectColor verwende, auf welchen Variablentyp muss das gesichert werden? Auf RegisterPropertyInteger oder auf RegisterPropertyString?

Joachim

…um es noch mal etwas zu verdeutlichen:
In public function Create()

$this->RegisterPropertyInteger("ColorTemperatur_1", 0xA9F5F2);

In public function GetConfigurationForm()

$arrayElements[] = array("type" => "SelectColor", "name" => "ColorTemperatur_1", "caption" => "Farbe");

In public function ApplyChanges()

IPS_SetEventScheduleAction($EventID, $ActionID, $Name,$this->ReadPropertyInteger("ColorTemperatur_1"), $Script);

…führt aber aus irgendeinem Grund nicht dazu, dass die zugeordneten Farben im Wochenplan sich ändern…:confused:

Joachim

Oder anderes herum: kann ich mit IPS_SetEventScheduleAction($EventID, $ActionID, $Name, $Color, $Script); überhaupt einen schon bestehenden Wochenplan in der Farbgebung ändern?

Das solle problemlos gehen. Hast du den Befehl mal außerhalb deines Modul getestet?

paresy

Hallo Paresy,

wenn das Modul initialisiert wird, werden ja zunächst einmal die „Standardfarben“ aus der RegisterProberty gesetzt, wenn die Farben dann im Konfigurationsformular geändert werden, wird ja erneut das ApplyChanges durchlaufen wobei ja für $EventID und $ActionID keine neuen Werte gegeben werden - lediglich der Farbwert ändert sich.
Ich befürchte daher, dass es bei der „Neuinitialisierung“ einmal hinhaut, weil das Event ja neu ist, jedoch der Farbwert im Nachhinein nicht mehr angepasst werden kann…

Joachim

…auch wenn das andere noch nicht geklärt ist:

Gibt es die Möglichkeit „global“ Variablen im PHP-Modul zu definieren oder ist die SetBuffer/GetBuffer der dafür vorgesehene „Ersatz“?

Joachim

Da ist der aktuell „beste“ Ansatz. Eine andere Möglichkeit gibt es bisher nicht.

paresy

…manchmal bekomme ich folgende Fehlermeldung:

09.08.2017 17:19:17 | KernelMT | InstanzManager: Fehler bei Instanz #12799 , Meldung IM_CHANGESTATUS: Array
(
    [0] => 102
)

Wodurch wird diese ausgelöst?

Joachim

Irgendein Print_r in deinem MessageSink.
In deinem Fall wenn eine Instanz aktiv wird, welche du überwachst (102).
Vermutlich hast du da noch irgendwo eine Debug Ausgabe in deinem Modul.

Michael

Oder beim IPS Start, dann sind noch nicht alle Instanzen da ;).

…vielen Dank erst einmal für die Antworten.

Dass einzige was überhaupt in die von Michael angesprochene Richtung geht wäre:

$this->SendDebug("MessageSink", "Message from SenderID ".$SenderID." with Message ".$Message."
 Data: ".print_r($Data), 0);

ist aber ein „SendDebug“ und passt auch sonst textlich nicht…:confused:

Joachim

print_r($Data);

Das geht in die Standardausgabe !

Du hast da etwas vergessen:

print_r($Data,true);

Dann geht der Output in den Rückgabewert.

SendDebug mit
habe ich aber auch noch nicht gesehen :smiley:

Eventuell solltest du einfach mal SendDebug überschreiben um damit auch Objekte und Array auszugeben.
Irgendwo hatte ich da mal ein Beispiel gepostet.
Gefunden :slight_smile:
z.B.
$this->SendDebug(‚MessageSink Sender‘, $SenderID,0);
$this->SendDebug(‚MessageSink Data‘, $Data,0);

Erzeugt dann so etwas:
$this->SendDebug(‚Event‘, $MyArray,0);
Zwischenablage14.png


    /**
     * Ergänzt SendDebug um Möglichkeit Objekte und Array auszugeben.
     *
     * @access protected
     * @param string $Message Nachricht für Data.
     * @param mixed $Data Daten für die Ausgabe.
     * @return int $Format Ausgabeformat für Strings.
     */
    protected function SendDebug($Message, $Data, $Format)
    {

        if (is_object($Data))
        {
            foreach ($Data as $Key => $DebugData)
            {

                $this->SendDebug($Message . ":" . $Key, $DebugData, 0);
            }
        }
        else if (is_array($Data))
        {
            foreach ($Data as $Key => $DebugData)
            {
                $this->SendDebug($Message . ":" . $Key, $DebugData, 0);
            }
        }
        else if (is_bool($Data))
        {
            parent::SendDebug($Message, ($Data ? 'true' : 'false'), 0);
        }
        else
        {
            parent::SendDebug($Message, (string) $Data, $Format);
        }
    }

Michael

Hallo Michael,

hatte mich selbst etwas gewundert aber nicht als Fehlerquelle gesehen, habe es jetzt ganz rausgenommen, trotzdem vielen Dank für Dein Beispiel.

Noch mal zu einem anderen Thema:
Was passiert im Hintergrund im IPS, wenn ich ein Modul-Update durchführe?

Manchmal wirkt es so, als wenn mitten in irgendwelchen laufenden Prozessen des „Alt-Moduls“ das „Neu-Modul“ einfach ersetzt wird, was - wenn es so wäre - bei komplexen Prozessen eben zu Funktionsstörungen führen könnte.

Kann ich das „Alt-Modul“ irgendwie darauf vorbereiten, dass ein „Neu-Modul“ kommt und es in einen „deaktivierten“ Zustand bringen?

Joachim

Kurze Antwort:
Ja, das kann passieren, sogar soweit dass gerne Mal die __generated von IPS zerschossen wird.
Und nein, kannst du nicht ändern.
Michael

…aus der Praxis mal ein Beispiel, warum es gut wäre die Probertys auch aus dem Modul heraus ändern zu können:
Aktuell versuche ich einen I²C-Sensor zu implementieren, der diverse Einstellungsmöglichkeiten bietet, dieses ist über verschiedene Probertys gelöst die im Konfigurationsformular geändert werden können und bei „Übernehmen“ an den Sensor gesendet werden - so weit, so gut.

Nun bietet dieser Sensor auch die Möglichkeit, alle diese getätigten Einstellung über einen Befehl wieder auf „Default“ zu setzen, was ja aber auch bedeuten würde, dass die Einstellung in den Probertys nicht mit denen im Sensor selbst übereinstimmen - hier wäre es dann hilfreich, wenn diese eben auch aus dem Modul selbst gesetzt werden könnten…

Joachim