Hauptmenü

FHEM und 99_myUtils

Begonnen von Dodo0815, 28 Januar 2016, 15:27:03

Vorheriges Thema - Nächstes Thema

Dodo0815

Hallo,

Ich bin zwar kein blutiger Anfänger im Bezug auf FHEM, aber es gibt ein Problem mit dem 99_myUtils.

Ich zeige euch am besten einmal meinen Aufruf in meinen 99_myUtils:
fhem('define ' . $name . '_Notifier notify ' . $name . ' { Rename($EVENT, $EVTPART0, $EVTPART1, $NAME, $TYPE) }');

$name ist eine übergebene Variable an die Funktion, die den fhem Befehl absetzt.
"Rename(..)" ist eine weitere Funktion in meinen Utils.

$EVENT, $EVTPART0, etc sind euch sicher bekannt..

Ziel dieser Funktion ist es, einen Notifier zu definieren, der die Funktion Rename aufruft, und Informationen wie das Event, den Namen und dessen Typ mitgibt.
Das hat auch immer funktioniert, bis FHEM 5.7 kam.

bei Version 5.6 hat mir exakt dieser Aufruf folgenden Notifier generiert:
HM_37BFBF { Rename($EVENT, $EVTPART0, $EVTPART1, $NAME, $TYPE) }
(Diese Zeile steht im Notifier unter "DEF".

Das passt so. Funktion Rename wird aufgerufen mit den erforderlichen Daten.


Aber seit 5.7 erstellt er mir folgenden Notifier:
HM_37BFBF { Rename(DEFINED HM_37BFBF, DEFINED, HM_37BFBF, global, Global) }

Wie ihr sehen könnt: Er übersetzt mir $NAME, $EVENT, etc sofort in deren Inhalt! Dadurch wird die Funktion für mich wertlos.

Ich habe einen Workaround, der funktioniert... Aber er ist für Programmierer unter euch sicherlich eine Schande anzusehen, deshalb möchte ich das richtig machen.

und zwar rufe ich folgendes, genau so, auf:

fhem('define ' . $name . '_NotifierA notify ' . $name . ' { Rename($EVENT, $EVTPART0, $EVTPART1, $NAME, $TYPE) }');
fhem('define ' . $name . '_NotifierB notify ' . $name . ' { Rename($EVENT, $EVTPART0, $EVTPART1, $NAME, $TYPE) }');

Wie ihr seht: es ist 2x der exakt selbe Aufruf, bis auf das, dass der obere Notifier <name>_NotifierA und der untere Notifier <name>_NotifierB heißt.
Das komische daran:
NotifierA: HM_37BFBF { Rename(DEFINED HM_37BFBF, DEFINED, HM_37BFBF, global, Global) }
NotifierB: HM_37BFBF { Rename($EVENT, $EVTPART0, $EVTPART1, $NAME, $TYPE) }

Kann mir bitteschön einer erklären, warum NotiferA die Variablen übersetzt und NotifierB nicht?
Ich muss diesen Workaround seit Monaten so nutzen.
Ich habe andere Klammern.. andere Anführungszeichen.. Escaping, etc probiert, aber ohne Erfolg. Entweder kam das Falsche dabei heraus, oder auch wieder das gleiche wie hier genannt.

Ich denke viel mehr Infos braucht ihr nicht.
Für den Fall:
Raspberry Pi, Jessie Lite, neueste Updates
FHEM 5.7 + heute wiedermal alles Upgedatet (dieser "Fehler" besteht weiterhin)
HomeMatic USB Stick
diverse HomeMatic Geräte

Danke und LG
Dodo

viegener

Ich habe Deine Erklärung schon gestern gelesen und nicht verstanden und bin auch heute gescheitert. Vielleicht wäre es gut, wenn Du mal Code anhängen würdest (insbesondere Deine myUtils und weitere beteiligte Objekte), Code tags verwenden würdest und auch etwas deutlicher beschreibst wo Du welchen Aufruf machst.

Denn wenn es ein Problem mit 99_myUtils gibt ist zu vermuten, dass es an Deinem Code in myUtils liegt, denn ansonsten steht da ja eigentlich nichts drin  ;)

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

crusader

ZitatKann mir bitteschön einer erklären, warum NotiferA die Variablen übersetzt und NotifierB nicht?


Deine Konstruktion löst im FHEM-Main-Script eine insgesamt etwas komplizierte Kettenreaktion aus. Nach meiner Vermutung läuft die in etwa so ab:

1. Das  Event-gesteuerte FHEM-Kommando wird zusammen mit einer Referenz auf die $EVENT-Variablen an den FHEM-'Interpreter' übergeben.
2. Dieser speichert die $EVENT-Variablen in einem globalen Hash, um sie nachfolgenden Befehlen aus der gleichen Command-Chain zur Verfügung zu stellen.
3. Da das FHEM-Kommando eine Perl-Routine aufruft wird anschließend der Perl-'Preprozessor' gestartet, welcher die zwischengespeicherten $EVENT-Variablen in lokale Perl-Variablen wandelt und dieses Konstrukt dem Perl-Interpreter übergibt. Der globale Zwischenspeicher wird dabei nicht gelöscht.
4. Der Perl-Interpreter behandelt nun die lokalen Variablen nach Perl-Regeln. (Da Du in Deinem String die entsprechenden Ausdrücke als Literale gekennzeichnet hast, bleiben die in diesem Schritt also erhalten.)
5. Der erste fhem()-Aufruf der Perl-Routine wird erneut (einzeln) an den FHEM-'Interpreter' übergeben. Dieser ersetzt $EVENT-Ausdrücke durch den Inhalt des immer noch gültigen globalen Hash. Danach löscht er diesen Speicher, weil der Aufruf nicht aus einer Command-Chain (sondern aus Deiner Perl-sub) stammt.
6. Der zweite fhem()-Aufruf findet nun keine $EVENT-Variablen und nimmt keine entsprechende Ersetzung mehr vor.


In der Version 5.6 ist möglicherweise der EVENT-Speicher schon vorher gelöscht worden, so dass sich ein anderes Verhalten ergibt.

Insgesamt ist wohl mit einer User-Routine hier keine ordentliche Lösung zu finden, weil der FHEM-'Interpreter' keine Variablen-Maskierung kennt.
Eine saubere Lösung würde ein modifiziertes notify-Modul erfordern, in dem das DEF entsprechend manipuliert wird.

Falls Du es 'quick and dirty' umsetzen willst, kannst Du als erstes Kommado in Deiner Perl-Routine ein
$evalSpecials = undef;
einfügen, aber verrate bitte niemandem, dass Du das von mir hast.