FHEM steuert Arduino IR-Sender/Empfänger als FS20 IRF-Ersatz

Begonnen von tomcat089, 22 April 2014, 12:06:48

Vorheriges Thema - Nächstes Thema

tomcat089

Hallo,
ich bin mittlerweile seit 1 Jahr begeisterter Nutzer von FHEM und habe schon alles in die Automatisierung einbezogen, was sich bei mir über FS20 "sinnvoll" schalten läßt, aber jetzt komme ich bei einem neuen Projekt seit 2 Wochen, trotz stundenlangem Suchen nicht weiter. Im Detail:

FHEM-Server ist ein RaspberryPi mit CUL. Als Universal-IR-Fernbedienung(Send/Receive) habe ich einen Arduino Uno mit Ethernet im Einsatz, da leider der FS20-IRF nicht mehr produziert wird und als Alternative das iTach-Gerät ziemlich teuer ist.

Das neue Projekt soll die beiden Systeme nun koppeln. D.h. vom Arduino empfangene IR-Signale sollen von ihm dekodiert und dann an FHEM als FHEM-Befehle weitergereicht werden, genauso wie Steuerungsbefehle aus FHEM an den kleinen Microcontroller in seiner Funktion als IR-Sender geleitet werden sollen. Wichtig ist mir hier vor allem die Fähigkeit zur Bidirektionalität.

Für beide Wege möchte ich eine einzige TELNET-Verbindung nutzen. FHEM ist dabei der Telnet-Server. Client ist der Arduino.

Der Hinweg, also die Kette: Hand-IR-Sender->Arduino->FHEM und dann das Auslösen von Aktionen auf FHEM funktioniert. Nur den Rückweg, also wenn FHEM seine Befehle über die gleiche Verbindung an den Arduino senden möchte, bekomme ich nicht hin. Ich habe keine Ahnung wie ich die bestehende Telnet-Session, die vom Arduino einmalig initiiert wird, dafür nutzen kann. D.h. FHEM soll bestimmte Ausgaben an diese TELNET-Session leiten, wo sie der Arduino als Befehle übernimmt, in IR kodiert und an die IR-Geräte sendet.

Ich habe mich für TELNET entschieden, da es auf beiden Systemen einfach zur Verfügung steht. Der Arduino soll als Client fungieren, da ich diese Lösung zukünftig als "Multi-Client"-Lösung in mehreren Räumen einsetzen möchte.
Das Ganze bewegt sich bei mir nur im LAN ohne WAN-Verbindung. Sicherheitsaspekte sollten daher nicht so wichtig sein.
Ist der Plan mit TELNET vollkommen abwegig und könnte man auch eine andere Kopplung realisieren, die besser für diesen Zweck geeignet ist? Wichtig: Arduino kann ich aufgrund von HW/SW-Beschränkungen nur entweder als TELNET/UDP-Server oder als Client konfigurieren.
Kann mir da jemand helfen?
Gruß
Achim
RaspiPi v4, Funkmodule: nanoCUL a-culfw 433, nanoCUL a-culfw 866, 2 broadlink, 10 HM-LC-BL1PBU-FM, 4 HM-CC-RT-DN, 2 HM-OU-CM-PCB,2 HM-ES-PMSW1-PL, 2 HM-PB-6-WM55,2 HM-SEC-SIR-WM,4 HM-SEC-SD-2, 4 HM-CC-RT-DN,2 MAX ShutterContact, 2 EnOcean TCM_ESP3_1, 1 nano jeelink, 1 KLF200, 5 Somfy IO, 1 panStick

rudolfkoenig

Ich kann zwar auch eine Bastelloesung, wie Du das vorgestellt hast, mit FHEM als Server vorstellen, sowas ist aber fuer Benutzer kompliziert aufzubauen, da es etliche dummys mit bestimmten Namenskonvention benoetigt.

Eine "richtige" FHEM Loesung schaut so aus:
- Arduino als TCP/IP Server
- physisches FHEM Modul, jeweils eine Instanz pro Arduino.
- logisches FHEM Modul, jeiwels eine Instanz fuer eine IR Quelle oder Ziel, per IODev an das physische Modul gebunden.

An deine Stelle wuerde ich aber versuchen auf dem Arduino ein iTach zu emulieren, und von der Arbeit von UliM profitieren (10_iTachIR.pm / 88_iTachIRDevice.pm, http://forum.fhem.de/index.php/topic,22463.0.html)

ntruchsess

Zitat von: rudolfkoenig am 22 April 2014, 12:44:51
Eine "richtige" FHEM Loesung schaut so aus:
- Arduino als TCP/IP Server

Besser FHEM als TCP/IP-Server und den Arduino als Client. Arduino als Server ist für persistente Verbindungen wg. der mangelnden Resourcen eher nicht zu empfehlen. Wenn der Arduino Client ist, dann ist es trivial zu garantieren, dass nur eine Verbindung zur gleichen Zeit offen ist.

Den Rest aber wie gehabt.
while (!asleep()) {sheep++};

tomcat089

Danke für die schnellen Antworten. Ich verstehe es so, daß ich dafür auf jeden Fall Module schreiben sollte. Arduino als Client sehe ich auch so. Da hat der kleine MC durch FW/Libs nicht mehr viel Platz für Programme und Daten.
Leider sind in der aktuellen Version von FHEM die Module von Uli nicht drin. Wenn ich sie habe, sehe ich, wie ich sein Vorgehen adaptieren kann. Vor allem die wechselseitigen Nutzung der Verbindung ist für mich momentan das Haupt-Problem. Der iTach ist ja nur als IR-Sender ausgelegt und nicht als Empfänger.
RaspiPi v4, Funkmodule: nanoCUL a-culfw 433, nanoCUL a-culfw 866, 2 broadlink, 10 HM-LC-BL1PBU-FM, 4 HM-CC-RT-DN, 2 HM-OU-CM-PCB,2 HM-ES-PMSW1-PL, 2 HM-PB-6-WM55,2 HM-SEC-SIR-WM,4 HM-SEC-SD-2, 4 HM-CC-RT-DN,2 MAX ShutterContact, 2 EnOcean TCM_ESP3_1, 1 nano jeelink, 1 KLF200, 5 Somfy IO, 1 panStick

ntruchsess

#4
Hier mal ein bischen was zum Einlesen, wie man eine persistente Client-Server-Verbindung zwischen FHEM und Arduino realisiert:

Öffnen eines TcpServer-ports:
FRM_Start
Schließen des selbigen:
FRM_Undef
Annehmen von neuen Verbindungen:
FRM_Read
Erkennen und Schließen von clientseitig geschlossenen Verbindungen:
FRM_Ready

Kommunikation in beide Richtungen über DevIo_SimpleWrite und DevIo_SimpleRead
DevIo_SimpleRead ruft man aus der ReadFn heraus auf (Das ist in FRM_Read im Aufruf an $device->poll() gekapselt). So ist sichergestellt, dass man DevIo_SimpleRead nur aufruft, wenn auch wirklich Daten angekommen sind. D.h. aus der ReadFn ruft man auch den Code auf, der eingehende Daten parsed und darauf reagiert.

Aufpassen muss man beim Zuweisen des IODevs in den (FHEM-)Client-Devices des Physikalischen Devices. Wenn AssignIOPort aufgerufen wird, wenn schon ein (tcp-)client verbunden ist, wird das temporär erzeugte FHEM-device als IODev zugewiesen:
FRM_Client_AssignIOPort

Arduino-seitig kannst Du den EthernetClientStream aus der ConfigurableFirmata benutzen, dann brauchst Du Dich nicht mehr selber um das Wiederverbinden zu kümmern. Wird einfach per Constructor mit einem EthernetClient-objekt und der gewünschten Ethernet-konfiguration verheiratet, danach kann man den Stream so wie jeden anderen (wie z.B. das Serial-object) nutzen. Einen nicht verbundenen Client erkennt man  an den Return-werten -1 der Methoden peek und read bzw. 0 bei write. Zum Aufrechthalten bzw. automatischen Wiederverbinden der Verbindung musst Du nur in der Arduino-main-loop regelmäßig die maintain-methode aufrufen.
Funktioniert sowohl mit der normalen Ethernet-library (für Arduino Ethernet und originale (WIZ5100)-shields), als auch mit UIPEthernet (für Enc28J60 basierte Shields).

Viel Spaß,

Norbert

P.S.: wenn es Dir was genutzt hat, mach aus obrigem + Deiner neu gewonnen Erfahrung bitte einen Eintrag im FhemWiki
while (!asleep()) {sheep++};

tomcat089

Hallo Norbert,

danke für die ausführliche und geduldige Beschreibung.

Firmata hatte ich in diesem Zusammenhang gar nicht gesehen. Klingt aber plausibel und ich werde mich da "einlesen". Das Ganze ist aber bei Weitem komplizierter als erwartet. Ich dachte, mit einem flotten Dreizeiler könnte man das Problem lösen.

Ich befürchte, ich werde Dich in der nächsten Zeit noch mit etlichen Fragen nerven  ;)

Aber klar, wenn es läuft, dann gibts einen Eintrag ins Wiki.
Gruß
Achim
RaspiPi v4, Funkmodule: nanoCUL a-culfw 433, nanoCUL a-culfw 866, 2 broadlink, 10 HM-LC-BL1PBU-FM, 4 HM-CC-RT-DN, 2 HM-OU-CM-PCB,2 HM-ES-PMSW1-PL, 2 HM-PB-6-WM55,2 HM-SEC-SIR-WM,4 HM-SEC-SD-2, 4 HM-CC-RT-DN,2 MAX ShutterContact, 2 EnOcean TCM_ESP3_1, 1 nano jeelink, 1 KLF200, 5 Somfy IO, 1 panStick