Autor Thema: Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe  (Gelesen 643 mal)

Offline fireball

  • Developer
  • Full Member
  • ****
  • Beiträge: 243
Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« am: 13 Januar 2021, 08:41:05 »
Hallo FHEM-Community,

nachdem ich jetzt lange einfach nur Nutzer war, wollte ich auch mal etwas versuchen und habe jetzt schon viel Zeit investiert und freu mich das es bisher ganz gut lief.

Meine Lüftungsanlage die Danfoss Lüftung AirUnit konnte bereits mit einem Modul von Marcus42 über ZWAVE angesteuert werden, allerdings nicht alle Funktionen.
Mir war das jetzt nicht genug und ich habe geschaut, was kann man noch machen.
Im OpenHab Forum bin ich dann fündig geworden. Die Jungs da haben die Netzwerkkommunikation rausgefunden und dann ein Modul in Java geschrieben.

Ich habe mich dann bei mir umgehört und keinen gefunden, der JAVA in PERL umschreiben kann... also 1 Woche PERL lesen und "verstehen" und ich hatte ein PERL-Script, welches über div. sub()´s die Funktionen ansteuern kann.

Jetzt  möchte ich das gern in einem FHEM Modul haben. Das ist meine nächste große Herausforderung. Ich kann zwar den meisten Code lesen und halbwegs verstehen, aber ich bin nicht so tief in der Programmierung zu Hause, dass ich mir größeres zutraue...

Anbei habe ich aber durch viel c+p aus dem LUXTRONIK und CofoAir Modulen mein eigenes gestrickt...
Aber ich habe viele Fragen und vor allem versteh ich nicht alle Bereiche des FHEM Modules...
Und ich weiß auch nicht ob überall das ExceptionHandling richtig ist...

Meine bitte wäre, ob erfahrene PERL/FHEM-Modulprogrammierer mir an der Stelle jetzt weiterhelfen könnten, damit das Modul fertig wird.

Ich bin mir nicht sicher ob das alles so funktionieren könnte und ob das Intervall richtig laufen würde und noch ein paar allgemeinere Frage...
viele habe ich auch im Code markiert...

allgemeine Fragen:
- Methodenaufrufe in Luxtronic.pm ohne "&" davor, geht das auch?
- Kann man einfach in seiner Prod-Instanz das Modul zum Testen reinwerfen? Nachteile wegen den globalen Hashwerten?
- gibt es eine Möglichkeit einen Block an Code nur bei verbose 5 auszuführen, speziell für get und set Methoden, die da ein paar Zeilen haben, fürs adv. Logging.

   #Log3 $name, 5, "set $name $cmd $val";
   #Log3 $name, 5, "recvData in AirUnit_setFanSpeed(): $tempresponse\n";
   #my $tempresponse2 = unpack("H*" , substr($tempresponse,0,1));               #### Kann man das nur bei verbose = 5 ausführen?
   #Log3 $name, 5, "recvunpackData in AirUnit_setFanSpeed(): $tempresponse2\n";


- Ist das intervallbasierte einlesen  Einlesen der Werte, so korrekt... ist das Einlesen der READINGS überhaupt korrekt?!
- Sind die Rückgabewerte in den FHEM Sub´s korrekt?

- Wo sollte ich diese globalen Variablen speichern!? Ist das ok am Anfang des Moduls?
my @W_DISABLE_BOOST_AUTOMATIC = (0x01, 0x06, 0x17, 0x02);   #### REGISTER_1_WRITE, BOOST_AUTOMATIC ON/OFF
Theoretisch könnten sie mittlerweile auch direkt in die sub()´s...

Folgende Sektionen haben ich gebaut:
  $hash->{DefFn}    = "AirUnit_Define";         # nur kopiert und angepasst
  $hash->{UndefFn}  = "AirUnit_Undefine";      # nur kopiert
  $hash->{GetFn}    = "AirUnit_Get";         # kopiert und angepasst, aber nicht wirklich benötigt, eher ein TEST
  $hash->{SetFn}    = "AirUnit_Set";         # selber erstellt
  $hash->{AttrFn}   = "AirUnit_Attr";         # nur kopiert und angepasst
  $hash->{ReadFn}   = "AirUnit_Read";         # selber erstellt, da werden die Readings erstellt

GET ist nur so zum testen von GET.. aktuell habe ich noch nichts außer evtl. einem manuellen Update der READINGS, was ich/man da bräuchte...

Es wäre toll, wenn ihr mir helfen könntet. Leider konnte ich das nicht im Developer-Bereich posten, daher hier.

VG
René

PS: PERLCRITIC habt ich auch mal genutzt, da sagt nur "Subroutine prototypes used" und "return" statement with explicit "undef"

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1550
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #1 am: 13 Januar 2021, 17:16:31 »
Hallo Rene,

- Methodenaufrufe in Luxtronic.pm ohne "&" davor, geht das auch?
Funktionen werden heute meist ohne & aufgerufen. Wenn man allerdings Funktionen über Variable aufruft, sieht das anders aus. In vielen älteren Modulen (auch bei mir) sieht man Variablenzweisungen mit dem Namen einer Funktion. Schöner ist es allerdings statt dessen eine Referenz auf die Funktion zu übergeben. Da kommt dann wieder ein \& ins Spiel.
Kennst Du https://www.geos.ed.ac.uk/~bmg/software/Perl%20Books/OReilly.Perl.Cookbook.pdf ?

- Kann man einfach in seiner Prod-Instanz das Modul zum Testen reinwerfen? Nachteile wegen den globalen Hashwerten?
Ich würde von Angang an mit Test-Files (siehe https://forum.fhem.de/index.php/topic,111061.15.html) arbeiten. Das muss keine eigene Installation sein, aber zum rufst Du separat perl fhem.pl -t Testfile.t auf. Das mache ich direkt aus Visual Studio Code heraus. Beispiele findest Du im SVN. Für HTTPMOD und Modbus habe ich meine Tests dort auch eingecheckt: https://svn.fhem.de/trac/browser/trunk/fhem/t/FHEM/98_Modbus
Zudem würde ich das Modul auch gleich mit eigenem Namespace (package AirUnit statt package main) schreiben. Im aktuellen 98_Modbus.pm habe ich das umgesetzt.

- gibt es eine Möglichkeit einen Block an Code nur bei verbose 5 auszuführen, speziell für get und set Methoden, die da ein paar Zeilen haben, fürs adv. Logging.
   #Log3 $name, 5, "set $name $cmd $val";
   #Log3 $name, 5, "recvData in AirUnit_setFanSpeed(): $tempresponse\n";
   #my $tempresponse2 = unpack("H*" , substr($tempresponse,0,1));               #### Kann man das nur bei verbose = 5 ausführen?
   #Log3 $name, 5, "recvunpackData in AirUnit_setFanSpeed(): $tempresponse2\n";
Darum kümmert such Log3. wenn das Attribut verbose nicht hoch genug ist, dann werden die Logs nicht erzeugt. Im Modulcode prüft man das selbst normalerweise nicht.

- Ist das intervallbasierte einlesen  Einlesen der Werte, so korrekt... ist das Einlesen der READINGS überhaupt korrekt?!
- Sind die Rückgabewerte in den FHEM Sub´s korrekt?
- Wo sollte ich diese globalen Variablen speichern!? Ist das ok am Anfang des Moduls?
my @W_DISABLE_BOOST_AUTOMATIC = (0x01, 0x06, 0x17, 0x02);   #### REGISTER_1_WRITE, BOOST_AUTOMATIC ON/OFF
Theoretisch könnten sie mittlerweile auch direkt in die sub()´s...

Kennst Du die Wiki-Seiten dazu?
https://wiki.fhem.de/wiki/DevelopmentModuleIntro
https://wiki.fhem.de/wiki/DevelopmentModuleAPI
die sollten vieles beantworten.


Folgende Sektionen haben ich gebaut:
  $hash->{DefFn}    = "AirUnit_Define";         # nur kopiert und angepasst
  $hash->{UndefFn}  = "AirUnit_Undefine";      # nur kopiert
  $hash->{GetFn}    = "AirUnit_Get";         # kopiert und angepasst, aber nicht wirklich benötigt, eher ein TEST
  $hash->{SetFn}    = "AirUnit_Set";         # selber erstellt
  $hash->{AttrFn}   = "AirUnit_Attr";         # nur kopiert und angepasst
  $hash->{ReadFn}   = "AirUnit_Read";         # selber erstellt, da werden die Readings erstellt

Das würde ich gleich als Referenz und nicht als Funktionsnamen übergeben.


Frag doch mal bei den Moderatoren nach einer Freigabe für den Development-Bereich im Forum. Da wäre der Thread besser aufgehoben und es gibt viele Leute, die helfen können.

Gruss
   Stefan

Offline fireball

  • Developer
  • Full Member
  • ****
  • Beiträge: 243
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #2 am: 13 Januar 2021, 20:11:48 »
Hallo Stefan,

danke für deine ersten Worte.
Also das Kochbuch kannte ich nicht, ich habe meine ganze Ideen immer einzeln gegoogelt und ausprobiert und naja.. ein paar programmierkenntnisse sind noch so im Kopf verblieben...
Ich schau mir das Buch mal an... manche Dinge kann ich aber lesen und lesen und lesen und versteh sie einfach nicht.

Genauso isses mit den FHEM Modulaufbau und Xer-Funktionen usw... auch habe ich verstanden, dass FHEM jeden Menge nützlicher Funktionen bereitstellt, einige habe ich ja auch genutzt... Bulkupdate usw... aber ist das alles richtig plaziert ... und und und...

Das mit dem Testen hab ich überflogen, aber noch nicht verstanden ich war jetzt drauf und dran mir ein zweites Fhem zu installieren und das Modul rein zu werden und dann zu schauen ob es geht...

Packagename habe ich geändert.

Die Modulseiten bin ich schon einmal durch... muss ich wohl nochmal... aber es wäre schön ein Feedback zu haben, wo noch meine Schwachstellen liegen...

Was habe ich gerade noch gemacht:
- Packagename geändert...
- die & bei den Methodenaufrufen entfernt
- die SetMethoden haben keinen Rückgabewert... ich habe dort als Rückgabe die getMethode nochmal aufgerufen...
- die SetMethoden und GetMethoden habe ich bei mir schon mal um die globalen Übergabeparameter reduziert und direkt in den Methoden eingetragen, die muss man nicht übergeben... das ist sinnfrei...

Ich hänge mal nachher ne neue Version dran, aber es wäre interessant zu wissen ob ich mit dem Modul auf dem richtigen Weg bin und die Xer-Methoden so sinnig sind?!

VG+Danke
René

Offline fireball

  • Developer
  • Full Member
  • ****
  • Beiträge: 243
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #3 am: 13 Januar 2021, 21:23:12 »
ich habe jetzt schnell ein FHEM installiert, das Modul reingeworfen und dann define gemacht, folgende Fehler bekomme ich:

wenn ich package nicht auf main setze, sondern mein eigenes nehme, dann streikt Fhem bei:
Global symbol "$readingFnAttributes" requires explicit package name (did you forget to declare "my $readingFnAttributes"?)
Was muss ich denn "importieren" damit das geht? use main oder sowas?
bei package main; gehts...


Dann kommt bei meinen
readingsBulkUpdate usw überall:

Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at ./FHEM/98_AirUnit.pm line 311.
Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at ./FHEM/98_AirUnit.pm line 314
.

aber die Zeile
sub AirUnit_Initialize($)
{
  my ($hash) = @_;

Ist wie bei anderen Modulen und laut Doku gesetzt...

und dann finde ich noch sowas:

2021.01.13 21:11:45 1: PERL WARNING: Subroutine AirUnit_Initialize redefined at ./FHEM/98_AirUnit.pm line 54.
2021.01.13 21:11:45 1: PERL WARNING: Subroutine AirUnit_Define redefined at ./FHEM/98_AirUnit.pm line 70.
2021.01.13 21:11:45 1: PERL WARNING: Subroutine AirUnit_Undefine redefined at ./FHEM/98_AirUnit.pm line 117.
2021.01.13 21:11:45 1: PERL WARNING: Subroutine AirUnit_Attr redefined at ./FHEM/98_AirUnit.pm line 129.
2021.01.13 21:11:45 1: PERL WARNING: Subroutine AirUnit_Get redefined at ./FHEM/98_AirUnit.pm line 149.
2021.01.13 21:11:45 1: PERL WARNING: Subroutine AirUnit_Set redefined at ./FHEM/98_AirUnit.pm line 180.
2021.01.13 21:11:45 1: PERL WARNING: Subroutine AirUnit_GetUpdate redefined at ./FHEM/98_AirUnit.pm line 236.

VG+Danke
René

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1550
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #4 am: 13 Januar 2021, 22:09:41 »
Hallo René,

In https://forum.fhem.de/index.php/topic,29972.0.html im Reply #5 hatte ich mal ein stark gekürztes Modul samt Paket als Beispiel für ein Problem gepostet. Da siehst Du das mit dem Import und Export ganz gut. Du musst tatsächlich alle Funktionen und Variablen, die Du aus dem package main verwendest importieren und zumindest deine InitFn exportieren.
Ich würde die Sequenz aus einem größeren Modul, z.B. Modbus kopieren.
Wenn Du ein eigenes package verwendest, dann müssen die Funktionen nicht alle mit Deinem Präfix beginnen. Ich nenne die dann einfach getFn, setFn, readFn etc. Speziell ist nur die X_Initialize, die sollte einfach nur Initialize genannt werden und wird durch das exportieren im package zu AirUnit_Initialize. Darin erzeugst Du dann ja die Refrenzen zur getFn etc.

SetFn sollten übrigens im Erfolgsfall undef zurückgeben.

Der Fehler mit $name kommt daher dass die Variable nicht existiert. Da fehlt ein $name = $hash->{NAME} in der Funktion.

Den Rest muss ich mir erst mal ansehen aber nachdem Dein Thread jetzt im Developer-Bereich gelandet ist, bekommst Du bestimmt noch mehr Feedback :-)

Gruß
    Stefan

Offline fireball

  • Developer
  • Full Member
  • ****
  • Beiträge: 243
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #5 am: 13 Januar 2021, 22:10:16 »
Sooooo ich bin etwas weiter...

der Punkt mit readingFnAttributes und package main, habe ich nicht rausgefunden...

der Haupgrund meiner vielen Fehler lag darin, ich musste überall in jedes Methode
my ($hash) = @_;
my $name = $hash->{NAME};

hinzufügen, dann lief es.

dann noch ein paar Kleinigkeiten...

Jetzt wird das Modul angelegt, aber verschwindet gleich wieder, man findet es nicht wieder...

Can't use string ("1") as a HASH ref while "strict refs" in use at ./FHEM/98_AirUnit.pm line 621.
oder
Can't use string ("4") as a HASH ref while "strict refs" in use at ./FHEM/98_AirUnit.pm line 621.
seh ich immer im fhem.log...

Anbei die letzte Version...
VG+Danke
« Letzte Änderung: 13 Januar 2021, 22:12:04 von fireball »

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1550
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #6 am: 13 Januar 2021, 22:17:00 »
Meistens übergibt man an die Funktionen von Fhem-Modulen als ersten Parameter die Referenz auf den Geräte-Hash und nennt diese Refernz in der Funktion $hash.

Wenn Du in der Funktion GetTemperature als Übergabe den $hash erwartest und damit $hash->{NAME} holen möchtest und dann aber die Funktion mit anderen Werten oder arrays aufrufst, dann kommen solche Fehlermeldungen.

Gruß
   Stefan

Offline fireball

  • Developer
  • Full Member
  • ****
  • Beiträge: 243
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #7 am: 14 Januar 2021, 10:44:15 »
Hi Stefan

danke für den Link,
Hallo René,

In https://forum.fhem.de/index.php/topic,29972.0.html im Reply #5 hatte ich mal ein stark gekürztes Modul samt Paket als Beispiel für ein Problem gepostet. Da siehst Du das mit dem Import und Export ganz gut. Du musst tatsächlich alle Funktionen und Variablen, die Du aus dem package main verwendest importieren und zumindest deine InitFn exportieren.
Ich denke ich habe es verstanden, das war auch noch hilfreich: https://forum.fhem.de/index.php?topic=91406.0

Ich habe das gleich mal umgebaut, eigenes Package und nur das importiert, was ich von FHEM als funktionen auch in meinem Modul habe. Ich hoffe das reicht und ich habe nichts globales notweniges übersehen... kann ja sein, dass es sowas wie ein Satz an Hauptfunktionen gibt, die man immer mit reinnehmen sollte?!

Das Export habe ich noch nicht kapiert, was muss ich alles exportieren? nur das Initialize oder alles?!


Weiterhin nochmal ne kurze Frage zu den Übergabeparametern...
Ich geb ja jetzt in jeder Sub immer den $hash über, damit ich daraus $name lesen kann, damit überall die Log3 Funktion funktioniert, also so:
sub AirUnit_getOFFON($) {
# read true/1/OFF or false/0/ON for DISABLE_BOOST_AUTOMATIC, DISABLE_BOOST_AUTOMATIC
my ($hash) = @_;
my $name = $hash->{NAME};
my $sendData = pack("C*", @_);
Log3 $name, 5, "sendData in AirUnit_getOFFON(): $sendData\n";
my $tempresponse = AirUnit_sendRequest($sendData);
Log3 $name, 5, "recvData in AirUnit_getOFFON(): $tempresponse\n";
my $tempresponse2 = unpack("H*" , substr($tempresponse,0,1));
Log3 $name, 5, "recvunpackData in AirUnit_getOFFON(): $tempresponse2\n";
my $onoff = hex(unpack("H*" , substr($tempresponse,0,1)));
print  "recvunpackhexData in AirUnit_getOFFON(): $onoff\n";
if($onoff == 0){
return "An"
}elsif($onoff == 1){
return "Aus"
}else {
die "Unbekannter Paramter $onoff\n";
}
}

Das heißt doch auch, dass ich meinen Methodenaufruf ändern muss von
AirUnit_getONOFF(@BOOST); auf AirUnit_getONOFF($hash, @BOOST);oder???

Und wenn ich das mache, wie komme ich dann in der Methode an meine Werte?
ist dann $_[0]  der Hash und $_[1] mein @BOOST?

Bei den setMehoden genauso... wenn ich da noch einen 3 Paramter drin hätte... wäre das dann $_[2]?

VG+Danke
René

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1550
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #8 am: 14 Januar 2021, 16:05:02 »
Hallo Rene,

Das sind keine Fhem spezifischen Dinge sondern allgemeine Perl-Themen. Die Übergabe von Werten an Funktionen in Perl hat durchaus ein paar Spezialitäten und um nicht zwei Seiten zu schreiben, die in einschlägigen Büchern viel besser drinstehen, würde ich Dich z.B. an das Perl Cookbook verweisen. In Kapitel 10.1 (hab gerade nachgesehen) steht genau das alles gut drin (gibt es wie oben verlinkt als PDF zum Download). Sicher auch in anderen Perl-Büchern.

Kurz zusammengfasst ist es üblich zunächst @_ auf lokale Variablen zu verteilen und nicht mit @_[] zu arbeiten.
Erster Befehl ist also
my ($hash, $a, $b) = @_;

oder
my $hash = shift;  # the device hash ref
my $a    = shift;  # the command xyz
my $b    = shift;  # ...
letztere Variante hat den Vorteil, dass man die Parameter schöner hinter dem jeweiligen Wert dokumentieren kann. Aber das ist Geschmackssache.

Wenn es viele oder auch optionale Parameter werden, dann wird das unschön und dann ist es eleganter, Hash-Referenzen zu übergeben (Beispiel aus den HTTPMOD-Utils):
#########################################
# Try to convert a value with a map
# called from Set and FormatReading
sub MapConvert {
my $hash    = shift;
my $oRef    = shift;                                        # hash ref for passing options and variables for use in expressions

my $map            = $oRef->{'map'} // '';                  # map to use
my $reverse        = $oRef->{'reverse'} // 0;               # use reverse map
my $action         = $oRef->{'action'} // 'apply map';      # context for logging
my $UndefIfNoMatch = $oRef->{'undefIfNoMatch'} // 0;        # return undef if map is not matching,
my $inVal          = $oRef->{'val'};                        # input value
my $name           = $hash->{NAME};

das ruft man dann so auf:
$val = MapConvert ($hash, {map => $map, val => $val, undefIfNoMatch => 0});            # keep $val if no map or no match

Ich hoffe, das hilft Dir weiter.

Gruss
   Stefan

Offline fireball

  • Developer
  • Full Member
  • ****
  • Beiträge: 243
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #9 am: 14 Januar 2021, 16:11:19 »
Hi,

anbei nochmal die letzte Version...
Ich rufe jetzt meine Methoden so auf:
AirUnit_getModelSN($hash, @MODEL_SN);
oder
AirUnit_setMode($hash, @W_MODE, $val);

FHEM meckert jetzt:
2021.01.14 16:01:16 0: Too many arguments for AirUnit::AirUnit_setMode at ./FHEM/98_AirUnit.pm line 209, near "$val)"
Too many arguments for AirUnit::AirUnit_getMode at ./FHEM/98_AirUnit.pm line 214, near "@MODE)"
Too many arguments for AirUnit::AirUnit_setONOFF at ./FHEM/98_AirUnit.pm line 223, near "$val)"
Too many arguments for AirUnit::AirUnit_setONOFF at ./FHEM/98_AirUnit.pm line 227, near "$val)"
Too many arguments for AirUnit::AirUnit_setOFFON at ./FHEM/98_AirUnit.pm line 231, near "$val)"
Too many arguments for AirUnit::AirUnit_setOFFON at ./FHEM/98_AirUnit.pm line 235, near "$val)"
Too many arguments for AirUnit::AirUnit_getTemperatur at ./FHEM/98_AirUnit.pm line 281, near "@OUTDOOR_TEMPERATURE)"
Too many arguments for AirUnit::AirUnit_getTemperatur at ./FHEM/98_AirUnit.pm line 283, near "@ROOM_TEMPERATURE)"
Too many arguments for AirUnit::AirUnit_getTemperatur at ./FHEM/98_AirUnit.pm line 285, near "@SUPPLY_TEMPERATURE)"
Too many arguments for AirUnit::AirUnit_getTemperatur at ./FHEM/98_AirUnit.pm line 287, near "@EXTRACT_TEMPERATURE)"


Was ist denn jetzt falsch...
Bei SET wird der Hash übergeben, eine Liste und ein Wert?
sub AirUnit_setMode($@$)
Bei GET nur Hash und Liste
: sub AirUnit_getOFFON($@)

VG
René

PS: Ansonsten habe ich bisl umgebaut mit Package, dem split Kommando usw...

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1550
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #10 am: 14 Januar 2021, 18:02:17 »
Hallo Rene,

schau doch mal https://perldoc.perl.org/perlsub an.
Im zweiten Absatz:

Zitat
The Perl model for function call and return values is simple: all functions are passed as parameters one single flat list of scalars, and all functions likewise return to their caller one single flat list of scalars. Any arrays or hashes in these call and return lists will collapse, losing their identities--but you may always use pass-by-reference instead to avoid this. Both call and return lists may contain as many or as few scalar elements as you'd like. (Often a function without an explicit return statement is called a subroutine, but there's really no difference from Perl's perspective.)

Eine Variable nach einem Array zu übergeben geht also nicht so - allenfalls als Referenz auf das Array.

Dann noch ein paar Sachen zum Code:

Wenn Du package AirUnit verwendest, dann müssen Deine Funktionen nicht mehr mit AirUnit_ beginnen. Du bist dann eh in Deinem eigenen Namespace.

ReadFn vs GetUpdate:
wenn Du zyklisch alle z.B. 60 Sekunden Werte abfragen möchtest, dann ruft man so etwas wie GetUpdate per InternalTimer auf und setzt innerhalb von getUpdate den Timer neu.
GetUpdate verschickt dann die Anfragen, wartet aber nicht auf die Antwort, damit Fhem in der Zeit nicht blockiert. Das ist die Aufgabe der ReadFn. Die wird aus dem Fhem-Hauptschleife aufgerufen wenn es etwas (eine Antwort) zu lesen gibt.
Das setzt aber voraus, dass Du Fhem den IO machen lässt. Derzeit öffnest Du ja selbst jedes mal eine TCP-Connection und wartest auch gleich auf die Antwort. Das ist keine gute Lösung.
Ich würde das über das DevIO-Modul machen.

Gruss
   Stefan


Offline fireball

  • Developer
  • Full Member
  • ****
  • Beiträge: 243
Antw:Danfoss Lüftung AirUnit - neues Modul - brauche Hilfe
« Antwort #11 am: 16 Januar 2021, 18:56:00 »
Hi Stefan, Hi all,

also ich ich glaube ich bin jetzt sauber was die Übergabe in meinen Funktionen angeht. Ich übergebe überall den "$hash, meine Liste", sowohl bei GET als auch bei SET.

Dann habe ich die Initialize Methode... die sollte sauber sein.

sub Initialize($)
{
  my ($hash) = @_;

  $hash->{DefFn}    = "Define";
  $hash->{UndefFn}  = "Undefine";
  $hash->{GetFn}    = "Get"; # aktuell nur Dummy
  $hash->{SetFn}    = "Set";
  $hash->{AttrFn}   = "Attr";
  $hash->{AttrList} = "disable:0,1 ".
"allowSetParameter:0,1 ".
$readingFnAttributes;
}

Define
- sollte passen, es wurde ja schonmal ein Gerät angelegt.
- hier wird der InternalTimer gelöscht und neu angelegt und GetUpdatemit dem $hash aufegrufen.

Undefine
- ist c+p und sieht wie bei anderen auch aus. => Zumindest wie in Luxtronix
- RemoveInternalTimer und BlockingKill wird aufgerufen

Get
 - ist noch Dummy, aber reagiert auf die get Einträge des Devices... macht nur nix...

Set
- Konnte ich noch nicht testen, baut aber die die @Listen zusammen und sendet dann mit dem $hash zusammen an die Funktionen, je nach Set des Device

Attr
- ist c+p und sieht wie bei anderen auch aus...

GetUpdate
- hier wird auch immer der InternalTimer gelöscht und neu angelegt und GetUpdatemit dem $hash wieder aufegrufen, quasi in einer Schleife(Intervallbasierend)
- gleichzeitig ruft BlockingCall die  DoUpdate und UpdateAborted auf.

Warum wird DoUpdate nur mit dem Namen aufgerufen?!? Muss da der $hash nicht auch mit übrgeben werden?
Hab beides probiert, passiert nix...

DoUpdate
- liest mit readingsBeginUpdate, readingsBulkUpdate und readingsEndUpdate die Readings in den $hash.

UpdateAborted
- soll diesen RUNNING_PID ???? löschen...

dann kommen meine Funktionen...

Soweit alles gut, aber wenn ich ein Device anlegen will, dann kommt diesemal kein Device, sonder Fhem restartet einfach...
Ich gebe zu, viel ist Copy+Paste aus Luxtronik, aber der Rumpf sollte doch jetzt passen... oder, ich seh den Wald nicht mehr und nach Stunden vor dem Code auch aktuell keinen Ansatz...

Ich glaube mein Problem liegt in meinem DoUpdate, ich habe einfach nicht verstanden warum in Luxtronix
  $hash->{helper}{RUNNING_PID} = BlockingCall("LUXTRONIK2_DoUpdate", $name, "LUXTRONIK2_UpdateDone", 25, "LUXTRONIK2_UpdateAborted", $hash) unless(exists($hash->{helper}{RUNNING_PID}));

diesen Aufruf gibt, ich glaube in LUXTRONIK2_DoUpdate werden nur die Arrays erzeugt und in LUXTRONIK2_UpdateDone die Werte geladen...
Viell brauch ich das alles nicht...



Fhem log verbose 5:
2021.01.16 18:39:38 4: Connection accepted from WEB_192.168.178.127_56390
2021.01.16 18:39:38 4: WEB_192.168.178.127_56390 GET /fhem?; BUFLEN:0
2021.01.16 18:39:38 4: WEB: /fhem? / RL:1340 / text/html; charset=UTF-8 / Content-Encoding: gzip
 / Cache-Control: no-cache, no-store, must-revalidate

2021.01.16 18:39:38 4: WEB_192.168.178.127_56390 GET /fhem/pgm2/style.css?v=1610818736; BUFLEN:0
2021.01.16 18:39:38 4: WEB_192.168.178.127_56390 GET /fhem?XHR=1&inform=type=status;filter=;since=1610818777;fmt=JSON&fw_id=14&timestamp=1610818780019; BUFLEN:0
2021.01.16 18:39:41 4: Connection closed for WEB_192.168.178.127_56390: EOF
2021.01.16 18:39:41 4: Connection accepted from WEB_192.168.178.127_56391
2021.01.16 18:39:41 4: WEB_192.168.178.127_56391 POST /fhem&fw_id=14&fwcsrf=csrf_305768141714800&cmd=define+AirUnit+AirUnit+192.168.178.9%3A30046+60; BUFLEN:0
2021.01.16 18:39:41 5: Cmd: >define AirUnit AirUnit 192.168.178.9:30046 60<
2021.01.16 18:39:41 5: Loading ./FHEM/98_AirUnit.pm
Undefined subroutine &main::Define called at fhem.pl line 3763.
2021.01.16 18:39:43 5: Initializing Type Library:
2021.01.16 18:39:43 1: Including fhem.cfg
2021.01.16 18:39:43 5: Cmd: >attr global userattr cmdIcon devStateIcon:textField-long devStateStyle icon sortby webCmd webCmdLabel:textField-long widgetOverride<
2021.01.16 18:39:43 5: Cmd: >attr global autoload_undefined_devices 1<
2021.01.16 18:39:43 5: Cmd: >attr global logfile ./log/fhem-%Y-%m.log<
2021.01.16 18:39:43 5: Cmd: >attr global modpath .<
2021.01.16 18:39:43 5: Cmd: >attr global motd SecurityCheck:
  WEB is not password protected

Protect this FHEM installation by defining an allowed device with define allowed allowed
You can disable this message with attr global motd none<
2021.01.16 18:39:43 5: Cmd: >attr global statefile ./log/fhem.save<
2021.01.16 18:39:43 5: Cmd: >attr global verbose 5<
2021.01.16 18:39:43 5: Cmd: >define WEB FHEMWEB 8083 global<
2021.01.16 18:39:43 5: Loading ./FHEM/01_FHEMWEB.pm


Jemand ne Idee, was es jetzt ist?
VG+Danke
René