Finden des DeviceNamens? Oder: Wer bin ich??

Begonnen von Tobias, 19 Juli 2016, 11:15:22

Vorheriges Thema - Nächstes Thema

Tobias

Hi,
in einer von extern aufgerufenen Prozedur innerhalb eines Moduls möchte ich den $hash ermitteln.
Das kann ich ja bekanntermaßen mit $def{DeviceName} machen.
Aber wie komme ich an den Namen des Devices? Ich kann diesesen NICHT der Prozedur als Parameter mitgeben

Maximal kenne ich noch den ModulNamen, nicht aber die DeviceInstanz :(
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

CoolTux

Also irgendwas musst Du schon haben, aus nichts kann man selten was machen. Auch wenn das uns Ossis oft nachgesagt wird. Also entweder $name oder $hash oder irgendwas anderes was die Instanz einmalig bezeichnet.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

betateilchen

Wenn es ein device ist, das es von diesem TYPE nur ein einziges Mal gibt, kannst Du mit defInfo() arbeiten.

Wenn es vom gleichen TYPE mehrere devices gibt, erscheint mir Dein Vorhaben generell wenig sinnhaftig.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Tobias

schade eigentlich, dachte das irgendetwas gibt...
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Thorsten Pferdekaemper

Hi,
wie soll denn das rein logisch gehen? Die Prozedur wird von "extern" aufgerufen und die Übergabe eines Device-Namens ist nicht möglich. Woher würdest Du dann selbst wissen, welches Device gemeint ist?
Das ist so, wie wenn man in eine Menschenmenge hineinruft "sag mir mal Deinen Namen".
Gruß,
   Thorsten
FUIP

Tobias

konkret geht es um die X_DbLog_splitFn. Die ist in (fast) jedem Modul  implementiert um die events in Reading/value/unit aufzuteilen.
Im DBLog Modul wird daher auf das Vorhandensein dieser Prozedur geprüft:
if($modules{$dtype}{DbLog_splitFn})
...
($reading,$value,$unit) =
        &{$modules{$dtype}{DbLog_splitFn}}($event);


Jetzt möchte ich die Prozedur mit einem 2ten Parameter aufrufen, also das aufrufende Device mitgeben. Damit hat dann das Modul die Möglichkeit den $hash zu bilden und auf Devicespezifische Variablen zuzugreifen.
Da aber nun in den Modulen nur ein Parameter erwartet wird, wird es jetzt überall "krachen"...

Gibt es eine Möglichkeit abzufragen, wieviel Parameter die Prozedur erwartet?
Dann könnte man es ja so machen:
if($modules{$dtype}{DbLog_splitFn}) {
  if (AnzahlArgs($modules{$dtype}{DbLog_splitFn} == 1) {
    ($reading,$value,$unit) = &{$modules{$dtype}{DbLog_splitFn}}($event);
  } elseif (AnzahlArgs($modules{$dtype}{DbLog_splitFn} == 2) {
    ($reading,$value,$unit) = &{$modules{$dtype}{DbLog_splitFn}}($device, $event);
  }
[...]

Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

betateilchen

Erstens ist die Funktion noch lange nicht in fast jedem Modul enthalten (eher umgekehrt) Und zweitens ist mir immer noch nicht klar, welchen Sinn das Ganze haben soll.  ???
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Woher nimmst Du die Information, aus welchem Modul Du die splitFn aufrufen willst? Dafür muss es doch eine Basis geben, die normalerweise ein device ist. Ansonsten ist doch das Modul überhaupt nicht geladen und die splitFn gar nicht vorhanden.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Thorsten Pferdekaemper

Hat denn $event nicht sowieso den Device-Namen mit drin?

Ansonsten: So ganz kapiere ich es nicht. Die X_DbLog_splitFn, die Du aufrufen willst, gehört die zu Deinem Modul oder zu einem fremden Modul (oder mehreren fremden Modulen)? Falls ersteres, warum bastelst Du Dir dann nicht einfach eine neue Funktion, die Du dann aufrufst? Falls letzteres: ...dann hast Du keinen Einfluss auf die Funktion, es wäre also auch nicht sinnvoll, irgendwas an den Parametern zu ändern.

Ich glaube nicht, dass Perl zur Laufzeit die Anzahl der Formalparameter kennt. Ich glaube, dass das intern einfach eine Liste ist, die immer beliebig viele Einträge haben kann.

Gruß,
   Thorsten
FUIP

Tobias

Das $event hat leider nicht den Devicenamen drin. Daz gehört nur: Reading,Value,Unit

Ich müsste dann zusätzlich auf Vorhandensein einer X_DbLog_splitFn2 prüfen...
Dachte es geht eleganter mit einer Prüfung, wieviel Argumente die Prozedur haben will
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Thorsten Pferdekaemper

Hi,
ich kapier's immer noch nicht. Wenn Du selbst diese Funktion schreibst, dann weißt Du doch sowieso schon, ob sie da ist oder nicht. ????
Vielleicht musst Du mal ein bisschen weiter ausholen und erklären, was Du wirklich machen willst.
Gruß,
   Thorsten
FUIP

Tobias

#11
Ich versuch es dir mit diesen Auszügen zu erklären:

Integration von DBLog in eigene Module: http://www.fhemwiki.de/wiki/DbLog#Integration_von_DBLog_in_eigene_Module
FHEM Development ModulIntro: http://www.fhemwiki.de/wiki/DevelopmentModuleIntro#X_DbLog_splitFn
Ein Beispiel der Integration im 10_MAX.pm: https://sourceforge.net/p/fhem/code/8382/

Innerhalb von DBLog (also in meinem Modul) prüfe ich, ob das Modul des generierenden Events diese SpitFn bereitstellt. Falls ja kann sauber die Unit getrennt ins DBLog geschrieben werden. Falls nein, ist das Value im DBlog ggf mit einer Einheit versehen. Problem dann: Charts die Zahlenwerte benötigen funktionieren nicht. Deshalb ist es wichtig die Unit vom Value getrennt zu speichern
Nun gibt es aber Situationen, wo der Modulautor (zb. vom km_200.pm Modul den $hash benötigt. Diesen bekommt er nur über den Devicenamen. Also überlege ich, den DBLog_splitfn zu erweitern und den Devicenamen mit zu übergeben.
Ohne mehr Logik, müssten jetzt alle DbLog_splitfn Funktionen in den implementierten Modulen daruafhin aber angepasst werden. Ich möchte aber abwärtskompatibel bleiben...
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

herrmannj

aber die notifyFn verrät doch den device namen ?

vg
joerg

betateilchen

#13
Die splitFn ist grundsätzlich modulspezifisch, nicht devicespezifisch, festgelegt.

Als Entwickler eines Moduls, das eine eigene splitFn bereitstellt, würde ich mich standhaft weigern, an dieser Tatsache irgendetwas zu verändern, was für mich völlig unsinnig unlogisch erscheint.

Zitat von: herrmannj am 19 Juli 2016, 14:33:16
aber die notifyFn verrät doch den device namen ?

Genau. Und genau deshalb ist auch in DbLog_Parse sowohl der deviceName als auch type und der komplette event bekannt.

Warum man da nun nochmal solche Kopfstände machen möchte, ist mir völlig schleierhaft.

Wenn der Modulautor von km_200.pm damit irgendein Problem hat, soll er sich darum kümmern, sein Modul so kompatibel zu machen, dass es sich an die vorhandenen Vorgaben hält.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Thorsten Pferdekaemper

Hi,
was passiert denn, mal so rein theoretisch betrachtet, in Perl, wenn man einer Funktion einen Aktualparameter mehr übergibt, als sie Formalparameter hat? Eigentlich gar nichts, oder?
Gruß,
   Thorsten
FUIP