FHEM Forum

FHEM => Automatisierung => Thema gestartet von: klausw am 07 Januar 2014, 17:25:51

Titel: modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 07 Januar 2014, 17:25:51
Hallo zusammen,

ich schreibe gerade ein Modul um ein I2C IC (LED PWM Treiber) angeschlossen ans Pi in FHEM einzubinden. Das funktioniert auch soweit (ich dimme damit über einen Treiber die Halogenlampen in meiner Vitrine).
Jetzt habe ich noch eine weitere Hardware mit der ich ähnliches machen will: http://www.mobacon.de/wiki/doku.php/de/netzer/index (http://www.mobacon.de/wiki/doku.php/de/netzer/index) Ein kleines Modul mit Mikrocontroller, das es ermöglicht über TCP/IP direkt auf den internen I2C Bus zuzugreifen.
Jetzt gibt es 2 Probleme, zum einen möchte ich kein zweites Modul schreiben und zum anderen kann es ja auch sein, das ich mehrere I2C ICs anschließen will, das Netzermodul aber nur eine Verbindung akzeptiert.
Wenn ich es richtig verstanden habe ist der two level approach dafür die beste Lösung.
Das ganze würde sich etwas weiter gedacht recht flexibel gestalten lassen, z.B. so:
xx_RPI_I2C, xx_BBB_I2C, xx_Netzer_I2C,... für die Ansteuerung
und:
xx_I2C_PCA9635, xx_I2C_BMP180, ... für die ICs
So ließen sich auch neue Hardwareplattformen schnell integrieren.

Ich habe mit schonmal das CUL modul angeschaut, bin aber nicht schlau draus geworden.
Woher weiss z.B. ein logical device, auf welches physical device es zugreifen muss wenn mehrere vorhanden sind.
Beispiel:
ich habe 2 dieser Netzermodule und das Paspberry mit je einem I2C IC bestückt und möchte diese natürlich auch separat ansprechen können.
Gibt es da einfache Beispielmodule?

Grüße
Klaus

Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: rudolfkoenig am 07 Januar 2014, 17:42:18
ZitatWoher weiss z.B. ein logical device, auf welches physical device es zugreifen muss wenn mehrere vorhanden sind.

Siehe AssignIoPort(), $hash->{IODev}, IOWrite().
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 08 Januar 2014, 18:15:49
ah langsam steige ich durch

mit IOWrite() wird dann die WriteFn vom physical ausgeführt?

und umgekehrt?

Wenn ich vom physical was ans logical senden will, nehme ich vermutlich Dispatch()
Aber woher weiss das physical Device (oder eher fhem) an welches logical device die Message geehn soll?
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: justme1968 am 08 Januar 2014, 18:33:52
edit: da hat die hälfte gefehlt.

ja. das geht über dispatch. das globale dispatch findet über Clients und MatchList welche dispatchFn in welchem client device typ dann aufgerufen werden soll. dieses (dein) dispatch ist dann dafür zuständig rauszufinden welches logische device dann gemeint ist. die meisten module machen das dann rückwärts über ein $modules{<device type>}{defptr} über das sie den hash zu einer eindeutigen id finden.

gruss
  andre
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: rudolfkoenig am 08 Januar 2014, 19:13:50
Wobei man inzwischen auf Clients verzichten koennte: Dispatch hat mit Clients anfgefangen, aber fuer das automatische Laden von Modulen beim autocreate war mehr Info notwendig, deswegen wurde MatchList eingefuehrt. Leider habe ich es versaeumt dabei Clients abzuschaffen. Logische Module muessen ein Match Eintrag haben, um nur passende Module aufzurufen. Auf diesen koennte man wegen MatchList auch verzichten.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: justme1968 am 08 Januar 2014, 19:17:24
ohne die Clients funktioniert aber umgekehrt das AssignIoPort nicht.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: rudolfkoenig am 08 Januar 2014, 19:24:47
Klar, "koennte" bedeutet auch nur, dass man dazu fhem.pl anpassen muesste. Solange sind Client, MatchList & Match alle notwendig.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 09 Januar 2014, 01:27:18
Zitat von: justme1968 am 08 Januar 2014, 18:33:52
edit: da hat die hälfte gefehlt.

ja. das geht über dispatch. das globale dispatch findet über Clients und MatchList welche dispatchFn in welchem client device typ dann aufgerufen werden soll. dieses (dein) dispatch ist dann dafür zuständig rauszufinden welches logische device dann gemeint ist. die meisten module machen das dann rückwärts über ein $modules{<device type>}{defptr} über das sie den hash zu einer eindeutigen id finden.

vielen Dank schonmal, ich muss trotzdem nochmal nachhaken ;)


Ich möchte das ganze gern mit I2C Befehlen machen (also die Botschaften zwischen physikalischem und logischem modul).
z.B. eine den Inhalt eines Registers von einem I2C IC lesen. Beim senden des requests ist die Adresse des IC's in der Botschaft (die auch dem $code entsprechen könnte) enthalten.
Das Problem aber ist, das in der Antwort nicht mehr die Adresse des I2C IC's drinsteckt. Das heisst wenn mehrere clients definiert sind dann klappt die Zuordnung nicht mehr.
Das heisst doch, ich müsste es irgendwie sequentiell machen?


Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: justme1968 am 09 Januar 2014, 08:29:29
1. es ruft alle clients der reihe nach auf bis der erste etwas zurück gibt

2. es muss natürlich parseFn heissen

3. das defptr wird nur innerhalb des moduls verwendet. du musst irgendetwas verwenden das im define bekannt ist und das in der
parseFn anhand der antwort abgeleitet werden kann.

wenn es keine eindeutige zuordnung zwischen antwort und device gibt du aber sicher stellen kannst das die antworten ohne ausnahme in der gleichen reihenfolge wie die kommandos kommen kannst du versuchen es darüber zu lösen. also die die reihenfolge in einem fifo merken und in parse auslesen.

wenn das nicht klappt fällt mir gerade nichts ein wie es mit mehreren clients pro physikalischem device gehen kann.

gruss
  andre
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 09 Januar 2014, 11:18:29
Bin zwar noch nicht so weit, aber falls du diese Anpassung vornimmst. Wie bekomme ich diese Veränderung mit?
Zitat von: rudolfkoenig am 08 Januar 2014, 19:24:47
Klar, "koennte" bedeutet auch nur, dass man dazu fhem.pl anpassen muesste. Solange sind Client, MatchList & Match alle notwendig.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: rudolfkoenig am 09 Januar 2014, 11:35:57
1. Das ist ganz unten auf der TODO (wenn ueberhaupt)
2. Ich wuerde es hier posten
3. Es wuerde ja weiter funktionieren, nur Client und Match waere irrelevant.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 10 Januar 2014, 14:23:22
ich habe mit einfach die CUL und FS20 Module hergenommen und auf der Basis begonnen.

und wieder ein paar Fragen bzw. Gedanken:
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: rudolfkoenig am 10 Januar 2014, 14:56:19
1. an ParseFn werden die (vom ReadFn) gelesenen Daten uebergegeben. ParseFn erzeugt mit den update*Readings Funktionen die Events/Readings, und liefert den Namen der betroffenen logischen Geraete zurueck.
2. das ist schlecht, weil solange FHEM blockiert wird. Sowas stoert viele enorm.
4. ReadFn wird vom gloabalen select aufgerufen, sie liest die Daten und ruft Dispatch() auf, falls ein Paket komplett ist. Dispatch filtert doppelte Nachrichten, sucht den passenden logischen Device (und laedt das Modul, falls es noch nicht geladen ist), ruft dessen ParseFn auf, und triggert die Events.

Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 10 Januar 2014, 15:35:20
Zitat von: rudolfkoenig am 10 Januar 2014, 14:56:19
2. das ist schlecht, weil solange FHEM blockiert wird. Sowas stoert viele enorm.
Die Antwortzeit vom I2C liegt im ms Bereich. Kann das problematisch werden?
Für ungültige Befehle könnte ich ja einen timeout einbauen.

Die 2. Variante währe ein Sendepuffer.
Es sollte eigentlich keine Nachricht kommen, für die nicht schon das Modul geladen ist. Der I2C arbeitet als Slave und sendet nix von sich aus.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 15 Januar 2014, 22:46:38
mit dem sendepuffer funktioniert es ganz gut

jetzt habe ich eine weitere Hürde:
wenn ich z.B. ein I2C IC mit beispielsweise 16 GPIOs habe möchte ich ja für jeden GPiO einen eigenen define machen. Bisher nutze ich nur die I2C Adresse um in der ParseFn über defptr das passende Modul zu finden.
Wenn ich allerdings für alle 16 GPIOs ein define machen, dann würden sich alle angesprochen fühlen.
Das hätte den evtl. den Vorteil, das Einstellungen, die für mehrere GPIOs gelten auch an alle weitergegeben werden.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: justme1968 am 15 Januar 2014, 22:55:36
1. der key muss eindeutig sein. wie du das erreichst hängt von deinem modul ab. wenn du dein device mit adressen hast ist die adresse gut. wenn du das device weiter unterteilst kannst du diese unterteilung einfach an den key dran hängen. also als key dann z.b. '<addr>.<pin>' verwenden.

je nach dem wie dein modul ausschaut geht das auch gemischt.

2. vielleicht ist es sinnvoll das modul in zwei teile zu trennen. eins was für alle 16 pins auf einem device zuständig ist und eins das als client dran hängt und dann jeweil für 1 oder mehrere pins zuständig ist. eventuell haben die pins ja auch unterschliedliche aufgaben. eins steuert vielleicht einen rolladen, dann sollte es up und down als kommandos geben, ein anderes vielleicht eine lampe, dann sollte es on und off geben.

für das client device kannst du dir auch mal readingsProxy anschauen. damit kannst du genau einen 'teil' (bei dir eben 1 oder mehrere pins) eines device als eigenständiges device ansprechen und flexibel mit eigenen kommandos und icons und webCmd versorgen.

gruss
  andre
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 16 Januar 2014, 00:26:42
Zitat von: justme1968 am 15 Januar 2014, 22:55:36
2. vielleicht ist es sinnvoll das modul in zwei teile zu trennen.
dann würde es ein three level approach werden, I2C-Schnittstellenmodul->I2C-ICModul->Pinmodul
geht das überhaupt?
Zitat von: justme1968 am 15 Januar 2014, 22:55:36
für das client device kannst du dir auch mal readingsProxy anschauen. damit kannst du genau einen 'teil' (bei dir eben 1 oder mehrere pins) eines device als eigenständiges device ansprechen und flexibel mit eigenen kommandos und icons und webCmd versorgen.
Den nutze ich schon für ein anderes Modul. Klappt super. Aber das mit den GPIOs war nur ein Beispiel.
Es könnten stattdessen auch PWM Stufen sein (die nutze ich für meine Vitrinenbeleuchtung) oder RGB Treiber.
Da würde readingsProxy sicher an seine grenzen stoßen.

Grüße
Klaus

gruss
  andre
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: justme1968 am 16 Januar 2014, 01:20:05
ja. das geht auch mit drei stufen. wobei die zweite und dritte stufe aber anders zusammen arbeiten wie die ersten beiden. ich verwende das bei panstamp/swap/rgb modul. die schnittstelle zwischen swap und nachfolgendem modul ist aber selber gebaut.

so lange es set und get und eindeutige readings gibt sollte es mit dem readingsProxy funktionieren.

und selbst wenn nicht ist es vielleicht immer noch einfacher den readingsProxy für die einfachen dinge zu verwenden und wenn es nicht mehr geht ein eigenes modul zu schreiben oder auch den readingsProxy zu erweitern.

erst wenn so viel logik nötig ist das du mehr code schreibst als du durch den readingsProxy einsparst ist ein eigenes modul besser.

aber pwm stufen sollte eigentlich noch gehen und rgb geht auf jeden fall. sogar mit farbigen lampen icons und colorpicker. spiff verwendet das um mit einem readingsProxy und ECMD einen dmx controller für farbige lampen zu steuern.

gruss
  andre
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 16 Januar 2014, 18:54:00
Dein readingsProxy Modul verwende ich ja schon erfolgreich für einfache Schalter.
define netzer1b readingsProxy netzer01:Port_b
attr netzer1b room Netzer
attr netzer1b setFn {($CMD eq "off")?"b 0":"b 1"}
attr netzer1b setList on off
attr netzer1b valueFn {($VALUE == 0)?"off":"on"}

Es Anstelle mehrerer einzelner Module zu verwenden ist verlockend. Aber am PWM/Dimmer bin ich bisher gescheitert.
sobald ich eine setlist mit state:slider,0,1,100 anlege kommt folgende Fehlermeldung:
Unknown argument 40, choose one of on off state:slider,0,1,100 off-for-timer off-till on-till on-for-timer intervals blink

Hast du einen fhem.cfg Auszug zu einem Dimmer für readingsProxy?

Ein weiteres Problem könnte sein, das ich für off -> 0 und für on/bzw 100 den Wert FF zurückliefern muss.
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: justme1968 am 16 Januar 2014, 19:38:18
das problem ist das es für state noch keine sonderbehandlung gab.

wenn ein slider für <cmd> mit '<cmd>:slider,min,step,max' definiert wird ruft fhemweb nach dem eingestellen normalerweise 'set <device> <cmd> <value>' auf. wenn <cmd> abder state ist lässt fhem das state weg und ruf nur 'set <device> <value> auf.

das habe ich eben im readingsProxy repariert und es ist ab morgen im update.

du kannst es heute schon mit einem anderen reading/wert anstelle von state testen. also pct/bri oder was auch immer.

das mit 0 für off und FF für on und 100 ist kein problem.genau dafür ist ja die setFn da.

gruss
  andre
Titel: Antw:modul für ein I2C Device auf unterschiedlicher Hardware (two level approach?)
Beitrag von: klausw am 17 Januar 2014, 18:30:44
Hi Andre,

danke, state funktionert jetzt.

Ich wusste gar nicht, das es auch noch andere slider gibt.

Grüße
Klaus