Fehlermeldungen nach 6.0 Update

Hallo,

mein System unter Ubuntu 20.04 hat sich im Linux Stable Kanal die Version 6 Installiert, nun hagelt es Fehler und das System ist nicht mehr Nutzbar…

Das war beim Update von 4.4 auf 5.0 sowie 5.5 schon so und auch jetzt Funktionieren Kern Komponenten die Symcon selbst bereitstellt nach dem Update nicht mehr!?

15.08.2021, 10:15:15 | TimerPool            | Energiezaehler (Strom) (UpdateTimer): 
Fatal error: Uncaught Error: Call to undefined function EZS_Update() in /-:1
Stack trace:
#0 {main}
  thrown in /- on line 1

oder die Homematic Integration:

15.08.2021, 10:21:02 | TimerPool            | HomeMatic RF Interface Splitter (ReadRFInterfaces): 
Fatal error: Uncaught Error: Call to undefined function HM_ReadRFInterfaces() in /-:1
Stack trace:
#0 {main}
  thrown in /- on line 1

Die Unifi Anbindung geht auch nicht mehr:

15.08.2021, 11:46:00 | TimerPool            | UniFi RRF (UpdatePresence): 
Fatal error: Uncaught Error: Call to undefined function Unifi_UpdatePresence() in /-:1
Stack trace:
#0 {main}
  thrown in /- on line 1

Auch Telegram nun nicht mehr:

15.08.2021, 11:45:00 | TimerPool            | TelegramMessenger Octobot (GetUpdates): 
Fatal error: Uncaught Error: Call to undefined function Telegram_GetUpdates() in /-:1
Stack trace:
#0 {main}
  thrown in /- on line 1

und von der alten MQTT Client Integration ganz zu schweigen:

15.08.2021, 10:21:20 | TimerPool            | MQTT Client (MQTTC_Ping): 
Fatal error: Uncaught Error: Call to undefined function MQTTC_Ping() in /-:1
Stack trace:
#0 {main}
  thrown in /- on line 1

Ich habe nun alle Module aus dem Modul Store sogar durch diesen „Erneut Installieren“ lassen, hat aber keine Änderung gebracht.

Ich wollte mir neben meinem 4.4 Live System die neue Version Parallel hochziehen und dann Umschalten aber all die Arbeit in die neue Version ist nun durch das Update wieder hinfällig.

Auch das beim Update keine Warnung kommt, oder zumindest eine Prüfung stattfindet die die Kompatibilität der Instalation mit der neuen Version Überprüft, und dann ein Update so lange unterbindet bis alle Anforderungen erfüllt sind.
Auch vor dem Update Automatisch ein Backup zu erstellen wie es jede Professionelle Software macht und dann einen Weg Zurück anbietet sollte doch kein Problem sein!

Es tut mir leid das ich mich hier wieder mit einem Negativen Kommentar Melde nur ist mir das leider nicht Möglich bei dem erneut Vermurksten Update.

Magst du mal ins Logfile schauen was da für Fehler kommen? Die Module nutzten definitiv mehr Leute und soweit ich weiß laufen die auch problemlos mit der 6.0.

Ich habe den Titel auch angepasst - wir halten hier Dinge sachlich und lösungsorientiert :wink:

paresy

PS: Mein heißer Tipp wäre, dass du eine globale autoload definiert hast und dort ggf. set_time_limit nutzt.

Danke fürs Anpassen des Thread Titels.

Ja ich habe in der __autoload.php ein Include meiner Erweiterungen, aber dort werden aber keine PHP.INI Werte verändert.

Das Log hat seit 10:10 505.123 Zeilen und in 16.529 Steht das Wort „error“

Im Log steht beim Starten dieser Fehler

Warning: Script #18282 does not exist in /var/lib/symcon/scripts/__autoload.php on line 2

Notice: Trying to access array offset on value of type bool in /var/lib/symcon/scripts/__autoload.php on line 2

Warning: include_once(/var/lib/symcon/scripts): failed to open stream: Success in /var/lib/symcon/scripts/__autoload.php on line 5

Warning: include_once(): Failed opening '/var/lib/symcon/scripts/' for inclusion (include_path='.:/var/lib/symcon/scripts') in /var/lib/symcon/scripts/__autoload.php on line 5
{"Update":{}}

die __autoload.php beinhaltet dies:

<?
$fX = IPS_GetKernelDir()."scripts".DIRECTORY_SEPARATOR.IPS_GetScript(18282 /*[Programme\Global\master_include]*/ )["ScriptFile"];

if(file_exists($fX)) {
    include_once($fX);
}
?>

$fX beinhaltet wenn ich es in einem Script Ausführe dies:

/var/lib/symcon/scripts/18282.ips.php

Und die Datei gibt es und die in diesem Include Enthaltenen Funktionen funktionieren trotz des Fehlers beim starten.

Das erklärt definitiv den Fehler und warum er nur bei dir auftritt. Beim Initialisieren der PHP Module dürfen keine Fehler durch die autoinclude Datei erzeugt werden (ansonsten werden diese als false positives gewertet, dass das PHP Modul defekt ist)

Ich kann mir nur noch nicht erklären, warum IPS_GetScript der Meinung sein sollte dass dieses Skript nicht existiert - wohingegen nach dem Start das Skript dann korrekt gefunden wird.

Magst du mal in die autoinclude den Pfad hart kodieren und schauen, ob dies das Problem erstmal löst?

paresy

Das Master Include in der __autoload.php hat dann weitere Dateien eingebunden, auch bei diesen musste ich die Pfade Absolut Hartkodiert angeben.

Warum kann ich die Scripte nicht mit eine Schleife über eine Kategorie alle dynamisch laden?

foreach(IPS_GETCHILDRENIDS(IPS_GetParent($_IPS['SELF'])) as $key){
      include_once(IPS_GetScript($key)["ScriptFile"]);
}

Kannst du schon.
Aber dein Script wird auch schon eingebunden bevor Symcon komplett gestartet ist.
Das muss auch so sein, da sonst die PHP-Module nicht zum Start geladen werden.
Du kannst dein Script ab absichern indem du prüfst ob Symcon schon gestartet ist.
https://www.symcon.de/service/dokumentation/befehlsreferenz/programminformationen/ips-getkernelrunlevel/
Michael

Vielen Dank @Nall-chan !

Du könntest Alternativ auch IPS_ScriptExists einbauen und dein IPS_GetScript($key)[„ScriptFile“] durch ein IPS_GetScriptFile($key) optimieren :slight_smile:

paresy

Nun habe ich im master Include welches vom __autoload.php Aufgerufen wird, Versucht darauf zu warten das der Kernel State Ready ist bevor ich die anderen Includes lade.

Aber scheinbar wird die __autoinclude.php vor einigen anderen System Prozessen wie das Reaggregieren der Variablen ausgeführt und so wird der Status des Kernels nie auf Ready kommen.

Hier das Script:

$try = 0;
$started = false;

print "Current run Level: ".IPS_GetKernelRunlevel()."\n";

while (!$started){
    if(IPS_GetKernelRunlevel() == 10103){
        print " > System already started, continue\n";
        $started = true;
    }
    $try++;
    if ($try > 150){
        print " > Timeout reached, break!\n";
        break;
    }
    print ".";
    sleep(1);
}

if ($started){
    foreach(IPS_GETCHILDRENIDS(IPS_GetParent($_IPS['SELF'])) as $key){
        if (($key != $_IPS['SELF']) and (substr(IPS_GetName($key),0, 7) == "include") and (IPS_GetObject($key)['ObjectType'] == 3)){
            include_once(IPS_GetScriptFile($key));
            print " > include_once(".IPS_GetKernelDir()."scripts".DIRECTORY_SEPARATOR.IPS_GetScriptFile($key).");\n";
        }
    }
} else {
    print " # Not started!";
}

Wie kann ich das trotzdem hinbekommen?

Das wird so nicht funktionieren. Aktuell blockierst du einfach alles während IP-Symcon startet. Während des Starts werden für die PHP Module sehr viel Skripte gestartet, um die Module zu initialisieren. Dort ist der Zustand auch korrekterweise nicht KR_READY.

Hast du es mit IPS_ScriptExists ausprobiert wie ich vorgeschlagen hatte? Das sollte wesentlich einfacher sein und keine Nebenwirkungen haben. Deine Includes werden geladen, sobald diese im System registriert sind. Und in den Skripten, welche davor laufen bei der Initialisierung, sollte diese eher nicht benötigt werden. Damit kannst du dir dann auch den Objekttyp check im if sparen.

paresy

Hallo @paresy

Wie meinst du könnte mir IPS_ScriptExists hier helfen?

Magst du mal testen ob das überhaupt geht wie von mir vorgeschlagen?

foreach(IPS_GetChildrenIDs(IPS_GetParent($_IPS['SELF'])) as $id){
    if(IPS_ScriptExists($id)) {
          include_once(IPS_GetScriptFile($id));
    }
}

Insgesamt finde ich dein Konstrukt, welches dynamisch je nach SELF die Skripte lädt sehr abenteuerlich und definitiv nichts, was wir in unseren Test-Szenarien vorsehen. Nur als Info am Rande, dass dies in Zukunft gerne mal wieder Probleme machen kann/wird.

paresy

Hallo @paresy

wie kann ich sonst eigene Funktionen Systemweit laden ohne ein Modul zu bauen?

Ich sehe keinen Unterschied von IPS_ScriptExists zu der PHP Funktion file_exists die ich schon probiert habe und welche auch true zurückgibt unt trotzdem werden die Includes nicht geladen weilzu dem Zeitpunkt wo __autoload.php ausgeführt wird noch nicht mal alle IPS Funktionen geladen sind und deshalb meine Schleifen nicht Funktionieren können.

Gibt es keine Möglichkeit direkt nach dem laden aller IPS Funktionen noch eigene Zusätzlich zu laden, das war ja mal der Ursprüngliche Zweck der __autoload.php oder?

Ich glaub du verstehst das Konzept von der__autoload.php nicht. Diese wird immer geladen. Bei jedem Request. Da ist keinerlei „Persistenz“ sondern das ist ein Overhead den du für jede Ausführung hast. Der kostet dich jedes Mal wertvolle CPU-Zyklen :wink:

Diese Aussage passt leider nicht zu den Logs und Fehlermeldungen die du uns bisher geliefert hast.

Dafür ist die __autoload.php schon korrekt. Aber dein Konstrukt welches auf Basis von $_IPS['SELF'] unterschiedliche PHP Dateien lädt (=wild und unterschiedlich je nach Skript) halte ich für sehr irreführend.

Hast du meinen Code-Schnippsel probiert? Und wenn ja → Gibt es Fehler? Wenn ja → Welche genau?

paresy

Übrigens gibt es einen riesen Unterschied. Schau dir mal deine Fehlermeldungen genau an. Das IPS_GetScript liefert die erste Fehlermeldung, womit das Kind bereits in den Brunnen gefallen ist. Dann greift das file_exists, welches true liefert, weil unter Linux jeder Ordner ebenfalls eine gültige Datei darstellt. Deswegen evaluiert /var/lib/symcon/scripts/ zu true und dann fliegt dir das include_once um die Ohren, weil kein Dateiname dahinter kommt.

paresy

Hallo @paresy

Die Fehler sind sobald ich keine Absoluten Statischen Pfade zu den Scripts habe immer die gleichen wie ganz oben Beschrieben.

Das „Konstrukt“ ist nichts besonderes, ich habe alle Funktionen in mehrere Scripte die ich je nach typ führe in einem „Ordner“ (Kategorie) abgelegt, die __autoload.php läd all diese scripte mit den darin enthaltenen Funktionen und somit kann ich diese genau wie die IPS Internen überall verwenden.

Neu ist mir das dies bei jedem Request gemacht wird und nicht nur beim Starten den Funktionsumfang von meiner IPS Installation erweitert, aber nachvollziehbar da jede Änderung in einem per include Integrierten Script sofort systemweit verfügbar ist.

Zurück zu meiner Frage, wie kann ich sonst meine Funktionen in IPS Integrieren ohne eigenes Modul?

Die autoinclude ist der einzige Weg es so zu erreichen wie du es haben willst.

Jetzt zurück zu meiner Frage: Hast du es ausprobiert :wink:

paresy

Einfach alle Deine Funktionen/Konstanten in die __autoload.php packen. Fertig.
Dann stehen Sie dir in jedem Script zur Verfügung.

1 „Gefällt mir“

Probier das auch mal. Ersetze die 12345 durch deine globals ID der Kategorie.

if(IPS_CategoryExists(12345)) {
  foreach(IPS_GetChildrenIDs(12345) as $id){
    if(IPS_ScriptExists($id)) {
          include_once(IPS_GetScriptFile($id));
    }
  }
}

paresy

Nebenbei… Das ist auch keine Lösung. Da ein Modul nur ein ‚Bauplan‘ für eine Instanz ist. Somit hast du keine globalen Funktionen, sondern nur Funktionen für diese Instanz(en) für welche das Modul der Bauplan ist.
Michael

1 „Gefällt mir“