Ist die Steuerung meiner Danfoss Air Lüfung per FHEM möglich?

Begonnen von marcus42, 29 April 2013, 18:00:45

Vorheriges Thema - Nächstes Thema

marcus42

Hallo zusammen,

bei uns zuhause arbeitet eine Danfoss Air Unit als Lüftungsanlage. Diese würde ich gerne über FHEM steuern. Das Steuergerät der Lüftung spricht Z-Wave und meine Frage ist ob mir jemand sagen kann, ob eine Steuerung per Z-Wave Stick und FHEM möglich ist.

Nach Recherche im Internet konnte ich zumindest ein Dokument finden in dem die relevanten "Device and Command Classes" angegebn sind.

Link zum PDF:
http://www.pepper1.net/zwavedb/uploads/resources/5a8c092487db9fa408978940e68a16873e4830da.pdf

Kann jemand helfen?

Vielen Dank vorab!

Gruß
Marcus

rudolfkoenig

Die wesentlichen Klassen (HRV_STATUS/HRV_CONTROL) sind zwar im FHEM Modul nicht implementiert, vmtl. muss man aber nur nach etwas experimentieren 5-10 Zeilen Hex-Code samt Bedeutung in 10_ZWave.pm/%zwave_class eintragen.

Die Codes der Parameter sind zwar in CommandClassSpec dokumentiert, mir fehlen aber die Codes der Klassen selber, in der frei verfuegbaren Quelltexten der zwapi bzw. openzwave kann ich sie nicht finden.
Laut CommandClassSpec muessten diese Nummer in einem ZW_classcmd.h dokumentiert sein.

Gerade gefunden: laut http://www.pepper1.net/zwavedb/device/184 ist es 0x37/0x39 :).
So'n Datenbank braeuchten wir auch fuer alle von FHEM unterstuetzten Geraete :)

marcus42

Hallo Rudolf,

vielen Dank für Deine prompte Rückmeldung!

Ich habe gerade in das besagte File 10_ZWave.pm geschaut und wüsste ehrlich gesagt noch nicht wo ich wie ansetzen muss.

Wenn ich Dich richtig verstanden habe, dann siehst Du aber gute Chancen mit Bastelwillen (bei mir vorhanden!) die Verbindung zu der Kiste herzustellen?!

Zunächst erstmal müsste ich mir den entsprechenden ZWave USB-Stick besorgen.

Darf ich Dich nochmal um Hilfe bitten, wenn die den Stick besorgt und in meiner FB7390 installiert habe?

VG
Marcus

rudolfkoenig

>  Ich habe gerade in das besagte File 10_ZWave.pm geschaut und wüsste ehrlich gesagt noch nicht wo ich wie ansetzen muss.

Die neu eingefuegte Zeile mit HRV_CONTROL zu sowas wie beim SWITCH_BINARY oder SWITCH_MULTILEVEL zu erweitern.

marcus42

ZWave Stick ist bestellt ... werde berichten.
Danke für die Infos!

VG
Marcus

marcus42

Der AEOTEC Z-Stick S2 ist hier nun angekommen und in die FB eingestöpselt.
Das entsprechende .ko Modul habe ich mit insmod geladen.

Das Modul des ZWDongle sagt nun Status 'Initialized'

In den Details steht dazu steht(Id geXt)

Readings:
homeId HomeId:xxxxxxxx CtrlNodeId:01 2013-05-02 18:05:09
nodeList 1 2013-05-02 17:26:18

Ist dies nun schon das 'ccd' der Lüftung oder ist dies der USB-Stick selbst?

Wenn ich es richtig verstehe muss ich nun in der 10_ZWave.pm unter HRV_STATUS z.B. den Command HRV_STATUS_REPORT mit einem HexWert hinterlegen welcher in einer .h Header-Datei ZW_classcmd.h aus einem SDK zu finden ist.

Kann man diese Werte irgendwie selber ermitteln?

Ich benötige nochmal Hilfe!

Danke vorab!



rudolfkoenig

In der nodelist kommt ueblicherweise mit 1 der USB-Stick selbst vor.
ZWave Geraete muss man mit diesem Stick (dem "controller") auch paaren, sonst kriegt man keine Daten (ungleich FS20): ZWDongle in pairing versetzen, und irgendein Knopf am geraet 3-mal druecken. Siehe auch Geraet-Doku.

Fuer die Klassen HRV_STATUS/HRV_Control muss man get/parse/set Eintraege definieren.
Beispiele anhand von SWITCH Multilevel erklaert:

set: { ..., dim => "01%02x", ... }
 Das set Befehl dim wird definiert (set dev ? liefert auch dim zurueck), und damit ist das in FHEMWEB verfuegbar. Da es ein % enthaelt (siehe man sprintf fuer details) wird genau ein Parameter enrwartet. Dies wird dann als hex formatiert (%02x), und zum Geraet samt Adresse und CRC geschickt. 01 ist das Uebliche Hex-Wert fuer set, das findet man bei den anderen Open-Source ZWave programmen heraus.

parse: { "032603(.*)"=> '($1 eq "00" ? "state:off" :
                         ($1 eq "ff" ? "state:on" :
                                       "state:dim ".hex($1)))',}, },

Parse analysiert Nachrichten vom Geraet (adresse/CRC ist schon gestrippt). In diesem Fall kommt 032603<HEXWERT> rein, wobei <HEXWERT> 00 ist fuer aus, ff fuer an und sonst ein Wert zw. 1 und 99 fuer ein Dimmwert. Dies wird als "state:xx" als FHEM-Event losgeschickt.

get: { swmStatus => "02" }
  Das get Befehl swmStatus wird definiert (get dev ? liefert es als Moeglichkeit zurueck), und beim Ausfuehren wird 02 (ueblicher Hexwert fuer get) mit den restlichen Daten (adresse, crc, etc) gesendet, und auf die Antwort gewartet. Die Antwort wird mit parse (siehe oben) analysiert, und ausgegeben.

Fuer die Beiden Klassen muss man solche Zeilen konstruiren, siehe auch die anderen Beispiele.
Die Klassennumer sind vermutlich richtig (HRV_STATUS == 37, HRV_CONTROL==39), die Nummer fuer set/get/parse sind mir unbekannt, aber hoffentlich gleich 1/2/3 wie bei den anderen Klassen.

Die restliche Bedeutung der HRV Parameter steht in dem besagten PDF, was (inoffiziell) auf dem Web zu finden ist :)

marcus42

Hallo Rudolf,

vielen Dank für die ausführliche Hilfestellung!

Ich werde in den nächsten Tagen etwas mit der Konfiguration rumspielen und danach Bericht erstatten :-)

VG
Marcus

marcus42

Hallo zusammen,

nun sind aus den paar Tagen doch ein paar Monate geworden,
aber der Sommer war viel zu schön, um nur am Rechner zu tüfteln :-)

Mit neuem Elan habe ich nun einige Versuche gestartet und kann einen Erfolg vermelden:

Zunächst habe ich nach einiger Suche ein sehr hilfreiches File gefunden,
in dem auch viele andere (sogar alle?) ZWave CommandClasses samt der zugehörigen Befehls-Codes aufgeführt sind.

Ich habe es als Anhang beigefügt.

Vielleicht hilft es ja dem Einen oder Anderen auch so wie mir.

Damit konnte ich schon mal erfolgreich einige der Steuerkommandos auf meiner KW-Lüftungsanlage ausführen
und Sensorwerte auslesen.

Sobald ich etwas Vorzeigbares für die FHEM datei 10_ZWave.pm habe, melde ich mich wieder ...

Gruß
Marcus

marcus42

Hallo,

ich habe mal versucht die CommandClass HRV_STATUS zu implementieren.
Für mich sieht es erst mal ok aus(siehe Anhang).

Ich bin mir nur nicht sicher, ob bei Minustemperaturen der korrekte Wert angezeigt wird.
Der ausgelesene Wert ist ein "signed" Wert.

@Rudolf: Kannst Du hier helfen?


  HRV_STATUS               => { id => '37',
    get   => {hrvStatus            => "01%02x",
              hrvStatusSupported   => "03",},
    parse => { "0637020042(....)"  => 'sprintf("outdoor_air_temperature: %0.1f C",'.'hex($1)/100)' ,
               "0637020142(....)"  => 'sprintf("supply_air_temperature: %0.1f C",'.'hex($1)/100)' ,
               "0637020242(....)"  => 'sprintf("exhaust_air_temperature: %0.1f C",'.'hex($1)/100)' ,
               "0637020342(....)"  => 'sprintf("discharge_air_temperature: %0.1f C",'.'hex($1)/100)' ,
               "0637020442(....)"  => 'sprintf("room_temperature: %0.1f C",'.'hex($1)/100)' ,                                                  
               "0537020501(..)"    => 'sprintf("relative_humidity_in_room: %s %%",hex($1))' ,
               "0537020601(..)"    => 'sprintf("remaining_filter_life: %s %%",hex($1))' ,
               "033704(..)"        => 'sprintf("status_supported: %b",hex($1))' ,
                     },},            




rudolfkoenig

Da es mehrere Moeglichkeiten gibt negative Werte darzustellen, waere es toll, wenn Du ein Beispiel (hex-Wert, und was es ungefaehr sein soll) zeigen koenntest.

Z.Zt. eine Aufgabe fuer den Tiefkuehlfach :)

marcus42

Hallo Rudolf,

es werden 2 Byte für die Darstellung der Temperaturen verwendet.
anbei ein paar Beispiele:


   Dec Hex
 32767 0x7FFF
  1025 0x0401
     2 0x0002
     1 0x0001
     0 0x0000
    -1 0xFFFF
    -2 0xFFFE
 -1025 0xFBFF
-32768 0x8000


Bei meiner Anlage wird dann mit 2 Nachkommastellen gerechnet und muss dafür durch 100 geteilt werden.

Aus der 1025 wird dann 10.25 Grad Celsius.

Gruß
Marcus

rudolfkoenig

Habe
- eine Funktion fuer das Vorzeichen eingebaut, bitte testen.
- die Readings nach in-fhem-ueblich umbenannt bzw. nach dem im development vereinbarten camelCasing konvertiert.
- dokumentiert
- eingecheckt -> ab morgen per update verfuegbar

Sonst:
- das Bitfield fuer hrvStatusSupported ist noch sehr "technisch", kannst du Deine bits zeigen oder (noch besser) irgendwo die Diste rauskriegen?
- z.Zt werden vmtl. nur Werte die durch 100 zu teilen sind erfasst, dass muss noch (bei Bedarf :) erweitert werden.

marcus42

#13
Hallo Rudolf,

positive Temperaturen funzen, für negative muss ichnoch ein bisschen warten.
Die Lüftungsanlage passt nicht ins Gefrierfach ;-)

Ich habe eine kleine Sub-Routine für das Bitfeld geschrieben.
magst Du mal drüberschauen, ggf. anpassen und einchecken?


#####################################
# interpretation of bitmask
# returns supported Parameters by hrvStatus
sub getHrvStatusSupported($)
{
  my ($p) = @_;
  $p = hex($p);
  my $string = "\n";
 
  if ($p >= 128 ){
    $p = $p-128; 
   }
  if ($p >= 64 ){
    $string = $string."6 = remainingFilterLife\n";
    $p = $p-64; 
  }
  if ($p >= 32 ){
    $string = $string."5 = indoorHumidity\n";
    $p = $p-32; 
  }
  if ($p >= 16 ){
    $string = $string."4 = indoorTemperature\n";
    $p = $p-16; 
  }
  if ($p >= 8 ){
    $string = $string."3 = dischargeAirTemperature\n";
    $p = $p-8; 
  }
  if ($p >= 4 ){
    $string = $string."2 = exhaustAirTemperature\n";
    $p = $p-4; 
  }
  if ($p >= 2 ){
    $string = $string."1 = supplyAirTemperature\n";
    $p = $p-2; 
  }
  if ($p == 1 ){
    $string = $string."0 = outdoorTemperature";
  }
   
  return $string;
}



Der Aufruf erfolgt hierüber:


  HRV_STATUS               => { id => \'37\',

  (einige Zeilen entfernt...)

               "033704(..)" =>
                   \'sprintf("supportedStatus: %s", getHrvStatusSupported($1))\', },},



Danke vorab!

Marcus

marcus42

#14
Hallo Rudolf,

ich habe mal die (für mich) wichtigsten Parameter für HRV_CONTROL eingepflegt.
Dies wird von mir noch erweitert werden.

Ich würde mich trotzdem freuen, wenn Du diesen Code bei Gelegenheit schon mal einpflegen könntest.

Vielen Dank!

Marcus


  HRV_CONTROL              => { id => '39',
      set   => {bypassOff => "0400",
                bypassOn  => "04FF",
                ventilationRate => "07%02x",
               },
      get   => {bypass          => "05",
                ventilationRate => "08",
               }, 
      parse => { "033906(..)"=> '($1 eq "00" ? "bypass:off" :
                                 ($1 eq "ff" ? "bypass:on" :
                                               "bypass:dim ".hex($1)))',
                 "033909(..)"=> 'sprintf("ventilationRate: %s",hex($1))',
                     },},