[gelöst] Code-Länge im DOIF limitiert?

Begonnen von spi3845, 05 Juli 2025, 08:44:11

Vorheriges Thema - Nächstes Thema

spi3845

Hallo zusammen,

ich habe einen umfangreichen Regler für eine Warmwasserzirkulation als DOIF (Perl-Modus) erstellt. Der ist inzwischen lang und ich stoße an eine Grenze, an der ich keinen zusätzlichen Code einfügen kann - im Editor wird Klick auf den Button "modify ..." nicht akzeptiert. Kürze ich den Code, geht es wieder. Aktuell hat der Code 3.501 Zeichen.

Ich könnte Teile des Codes in andere DOIFs auslagern, aber darunter leidet die Lesbarkeit und ich muss dann eine Event-Steuerung zwischen den unterschiedlichen DOIFs über z. B. userReadings realisieren. Alle DOIFs zusammen würden öfters aufgerufen als der einzelne, da ich viele Abfragen nach aktuellen Status in dem einen DOIF über [?device:reading] realisiere - im anderen Fall müsste ich dann [device:reading] machen, was die DOIFs insgesamt öfters ausführt.

Was ist hier das beste Vorgehen eurer Meinung?
Auslagern in andere DOIFs?
Oder gibt es eine Möglichkeit, die erlaubte Codelänge zu erhöhen?

Viele Grüße,
spi

Damian

Ich benutze den codemirror und bin bisher an keine Begrenzungen gestoßen. Meine Definition ist z. B. 7800 Zeichen lang.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

passibe

Benutzt du einen reverse proxy? Schau mal beim Klick auf modify in die Entwicklertools bzw. dort die Konsole, ob da nicht der HTTP status code 414 zurückgegeben wird. Ich hatte das Problem auch und habe deshalb in meiner nginx.conf large_client_header_buffers gesetzt:

http {
    [...]
    # Prevent 414 for long FHEM code
    large_client_header_buffers 4 16k;
    [...]
}
(Geht laut doku wohl auch im server-Level, aber da funktioniert das bei mir nicht. Funktioniert nur unter http. Keine Ahnung wieso, ist mir aber auch ein bisschen egal.)

Bei Apache geht das wohl mit LimitRequestLine, siehe hier: https://stackoverflow.com/a/2891598

Guybrush

unabhängig von deiner anfrage wäre es sauberer (und übersichtlicher) nur den reinen logik code im doif zu belassen und die ausführenden teile in funktionen der 99_myUtils.pm zu packen

spi3845

Zitat von: passibe am 05 Juli 2025, 12:32:15Benutzt du einen reverse proxy? ...

Ah, guter Punkt. Ich nutze einen Reverse Proxy. Ich teste mal, ob es beim direkten Zugriff anders aussieht.

spi3845

Zitat von: Guybrush am 05 Juli 2025, 13:15:42unabhängig von deiner anfrage wäre es sauberer (und übersichtlicher) nur den reinen logik code im doif zu belassen und die ausführenden teile in funktionen der 99_myUtils.pm zu packen
Das hatte ich auch überlegt, ist aber unübersichtlich, weil die Hauptbestandteile if-Abfragen sind. Die auszulagern als Funktionen ist schwierig.

betateilchen

Zitat von: spi3845 am 05 Juli 2025, 13:52:41Das hatte ich auch überlegt, ist aber unübersichtlich, weil die Hauptbestandteile if-Abfragen sind. Die auszulagern als Funktionen ist schwierig.

Alternativ könntest Du auch darüber nachdenken, ob DOIF in diesem Fall tatsächlich die "beste" Lösung ist, Deine Anforderung umzusetzen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

spi3845

Zitat von: betateilchen am 05 Juli 2025, 14:11:36
Zitat von: spi3845 am 05 Juli 2025, 13:52:41Das hatte ich auch überlegt, ist aber unübersichtlich, weil die Hauptbestandteile if-Abfragen sind. Die auszulagern als Funktionen ist schwierig.

Alternativ könntest Du auch darüber nachdenken, ob DOIF in diesem Fall tatsächlich die "beste" Lösung ist, Deine Anforderung umzusetzen.
Was wären denn gute Alternativen? Mehrere notifies oder doifs habe ich getestet, aber das macht das ganze komplex und unubersichtlich.

passibe

#8
Jetzt schau doch erstmal, ob da 414 zurückkommt bzw. stell die erlaubte URI-Länge hoch.

Wenn du happy mit deiner Lösung bist, wieso etwas ändern? Lass es dir nicht vermiesen, lös lieber erstmal dein ursprüngliches Problem.

Zumal 3500 Zeichen jetzt auch nicht wirklich viel sind. Das sind vermutlich grade mal 100 Zeilen Code, wenn nicht sogar weniger. Ob das wirklich dermaßen vorteilhaft ist, wenn man dann an einer Stelle noch 30 Zeilen hat und an der anderen 70, wage ich mal zu bezweifeln. Wenn es länger ist, von mir aus, aber hier ...

Guybrush

man kann auch den gesamten Inhalt eines doif in einer funktion auslagern und $name + $event an diese übergeben.. ist dann sogar leserlicher, wenn man eine IDE wie notpad++ o.ä. dann noch nutzt.

spi3845

Zitat von: passibe am 05 Juli 2025, 17:39:38Jetzt schau doch erstmal, ob da 414 zurückkommt bzw. stell die erlaubte URI-Länge hoch.

Wenn du happy mit deiner Lösung bist, wieso etwas ändern? Lass es dir nicht vermiesen, lös lieber erstmal dein ursprüngliches Problem.

Zumal 3500 Zeichen jetzt auch nicht wirklich viel sind. Das sind vermutlich grade mal 100 Zeilen Code, wenn nicht sogar weniger. Ob das wirklich dermaßen vorteilhaft ist, wenn man dann an einer Stelle noch 30 Zeilen hat und an der anderen 70, wage ich mal zu bezweifeln. Wenn es länger ist, von mir aus, aber hier ...
Da haste völlig recht...
Beim direkten Zugriff auf fhem habe ich die Zeichenbeschränkung nicht, es liegt also am Reverse Proxy.

Die Änderung
http {
    [...]
    # Prevent 414 for long FHEM code
    large_client_header_buffers 4 16k;
    [...]
}
hat bei mir nicht geholfen. Nutzt Du Websockets über den Reverse Proxy? Ich bekomme bei großem Inhalt einfach nur ein ERR_CONNECTION_CLOSED.

spi3845

Ich bin über diese beiden Parameter gestolpert:
http2_max_field_size 64k;
http2_max_header_size 64k;

Ich habe sie in meine nginx site-config eingetragen im entsprechenden server-Block für fhem und es hat geklappt. Damit läuft's. Vielen Dank für den urspünglichen Fingerzeig auf den Reverse Proxy. Den hatte ich in der Zwischenzeit schon komplett vergessen...

passibe

Ah sorry, ich hatte vergessen, dass da bei mir ein zweiter Proxy davor hängt (wegen SSO), deshalb wird der Proxy unmittelbar vor FHEM über http1.1 und nicht über h2 aufgerufen. Könnte sein, dass mir deshalb large_client_header_buffers reicht. (Kurioserweise musste ich bei dem "edge" Proxy nichts dazu einstellen.)

Aber schön, dass du es gelöst hast!

betateilchen

Zitat von: spi3845 am 05 Juli 2025, 15:45:52Was wären denn gute Alternativen? Mehrere notifies oder doifs habe ich getestet, aber das macht das ganze komplex und unubersichtlich.

Das kann man nicht pauschal beantworten, wenn man die zu lösende Aufgabe nicht kennt.

Aber meine Erfahrung in solchen Fällen ist, dass bei solchen Code-Mengen die Aufgabenstellung in der Regel nicht klar genug formuliert und weit genug abstrahiert wurde, um sie schlank und übersichtlich zu lösen.

Ursache dafür ist normalerweise die Vorgehensweise von Anwendern, den Code so zu "formulieren" wie sie die Bedingungen im Kopf haben und mündlich formulieren würden. Da ein Computer viel einfacher arbeitet, gibt es in der Regel immer Potenzial, den Code in diesem Punkt zu optimieren.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!