Ich habe ein USB-Relais von Sainsmart (FTDI-USB-Device). Ansteuern funktioniert wunderbar mit dem Code unten.
Mit FTDI_Get als GetFn wollte ich den Zustand des Relais abfragen, allerdings frage ich mich, was ich dann mache:
Siehe am Code die Stelle: # WAS MUSS ICH HIER MACHEN? direkt setzen oder readingsSingleUpdate
dero
package main;
use strict;
use warnings;
use Device::FTDI;
sub FTDI_Initialize($) {
my ($hash) = @_;
$hash->{DefFn} = "FTDI_Define";
$hash->{SetFn} = "FTDI_Set";
$hash->{GetFn} = "FTDI_Get";
return undef;
}
sub FTDI_Get($) {
my ($hash) = @_;
my $dev = Device::FTDI->new( "serial" => $hash->{SERIAL} );
$dev->set_baudrate(9600);
$dev->set_bitmode( 0xFF, Device::FTDI::BITMODE_BITBANG );
$dev->read_data( my $b1, 1 );
# WAS MUSS ICH HIER MACHEN? direkt setzen oder readingsSingleUpdate
return undef;
}
sub FTDI_Set($$$) {
my ($hash, $name, $cmd) = @_;
if( $cmd ne "on" && $cmd ne "off" ) { return "Unknown argument $cmd, choose one of on off"; }
my $mask= 1 << $hash->{INDEX};
my $dev = Device::FTDI->new( "serial" => $hash->{SERIAL} );
$dev->set_baudrate(9600);
$dev->set_bitmode( 0xFF, Device::FTDI::BITMODE_BITBANG );
$dev->read_data( my $b1, 1 );
my $state= unpack("C",$b1);
if( $cmd eq "on" ) { $state= $state | $mask; }
else { $state= $state & ~$mask; }
$dev->write_data( pack "C", $state, 1 );
readingsSingleUpdate($hash,"state",$cmd,1);
return undef;
}
sub FTDI_Define($$) {
my ($hash, $def) = @_;
Log 1, "FTDI: define $def";
my @a = split("[ \t][ \t]*", $def);
return "syntax: define <name> FTDI <serial> <index>" if (int(@a) != 4);
$hash->{STATE} = "Initialized";
$hash->{NAME} = $a[0];
$hash->{SERIAL} = $a[2];
$hash->{INDEX} = $a[3];
FTDI_Get($hash);
return undef;
}
1;
readingsSingleUpdate oder statt Single Begin/Batch/End.
Allerdings ist das nur dann sinnvoll, wenn man die Abfragen nur per Hand/at machen will, und das ist unwahrscheinlich. Besser wartet man darauf, dass das Geraet einem was sagt.
Wie andere Module das machen:
- per DevIo_OpenDev device oeffnen. Dieser traegt ins $hash das geoeffnete FD ein, und meldet diesen $hash fuer die ueberwachung per select an.
- select ruft Modul->ReadFn auf, falls auf dem FD Daten zum Lesen anstehen.
- ReadFn liest die Daten von der Schnittstelle, analysiert sie, und benachrichtigt den Rest von FHEM per readingsSingleUpdate.
Falls das System zweistufig aufgebaut ist wie CUL vs. FS20, dann
- ruft (das CUL-)ReadFn nicht direkt readingsSingleUpdate auf, sondern die globale Dispatch Funktion mit den von der Schnittstelle gelesenen Daten
- Dispatch wiederum sucht ein passendes Modul (z.Bsp. FS20), und ruft dessen ParseFn auf.
- ParseFn ruft readingsSingleUpdate auf (state:on), und liefert den Namen des (FS20) Geraetes zurueck an Dispatch.
Danke für die ausführliche Erläuterung. Jedoch kann ich das Relay nicht über DevIo ansprechen, da ich nirgendwo im Netzt Docs dazu gefunden habe, wie man Kommandos an das Relay per serielle USB-Schnittstelle (TTYUSB) absetzt. Das ist ja Voraussetzung für DevIo, d.h. Ansprechen als File.
Ich konnte nur rausfinden, wie man die Relais über Device::FTDI (libftdi) "direkt" ansteuert. Da bekomme ich aber kein File-Handle fürs Select.
Der einzige Ausweg, wäre die Relais zu pollen. Allerdings kann eh nur der Rechner, an dem die Relais hängen, die Relais schalten. Also entweder FHEM oder ein anderer Prozess (unwahrscheinlich). Ich wollte Get nur der Vollständigkeit halber implementieren, damit man in FHEM den Zustand der Relais überprüfen kann.
Muss ich dann also in GET readSingleUpdate machen? Immer ODER nur wenn der State gechanged hat?
dero
So, meine Alarmanlage läuft!!!
- RPi
- RFXTRX433
- HMLAN
- USB-RELAIS (zur Sirenenansteuerung)
- 4x IT PIRS
- 3x HM PIRS
- 1x HM Hutschienen-Relais zum Blinken der Wohnzimmer-Lampen
dero
Hallo, ich bitte hier mal um Hilfe in einer anderen Anwendung. Ich habe auch ein SainSmart USB4 Channel Relay und möchte einen Kanal für das Ein-und Ausschalten einer Therme benutzen. Das USB-Relay habe ich an die FritzBox angeschlossen, es wird auch erkannt. Den Treiber (von dero im Eingangsthread) habe ich kopiert und als '99_MyUSBRelay' ablegen wollen. Ich erhalte aber diese Fehlermeldung:
Can't locate Device/FTDI.pm in @INC (@INC contains: /var/InternerSpeicher/fhem/lib/perl5/site_perl/5.12.2/mips-linux
Damit bin ich als Neuling überfragt.
- Wo erhalte ich eine FTDI.pm her?
- Wie rufe ich später ein Relay auf (set xxx on)?
Device::FTDI musst Du installieren: http://search.cpan.org/~zwon/Device-FTDI-0.05/lib/Device/FTDI.pm
Frag mich aber nicht, wie das ging...
dero
ooops.... das habe ich mir nicht so kompliziert vorgestellt. Da muß man ja erst die libftdi installieren, bevor FTDI selbst installiert werden kann. Ist keiner hier im Forum, der eine How to-Anweisung geben kann? Die FTDI-chips sind doch sehr häufig im Einsatz.
never give up....
Ich versuche weiterhin, das USB-Relay an den Start zu bringen. Von der o.g. Webseite habe ich die Datei heruntergeladen und in den Ordner /fhem/lib/perl5/site_perl/5.12.2/mips-linux/ entpackt. FTDI.pm befindet sich im Ordner /Device/
Es gibt nun eine andere Fehlermeldung beim Ausführen der von mir so genannten Datei "99_MyUSBRelay" (des Treibers hier im Eingangsthread):
Attempt to reload Device/FTDI.pm aborted. Compilation failed in require at ./FHEM/99_MyUSBRelay.pm line 4. BEGIN failed--compilation aborted at ./FHEM/99_MyUSBRelay.pm line 4.
Also die Zeile
use Device::FTDI;
Ist das Anlegen des Treibers vom Eingangsthread überhaupt richtig als 99_xxx-Datei? Vielleicht mache ich hier einen grundlegenden Fehler.
Hallo Forum, hallo dero,
ich habe nun auch mit FHEM gestartet und musste natürlich direkt mal vollgas geben, indem ich mir ein USB-8-Kanal-Relaisboard von sainsmart gekauft habe.
Mit deros Code und viel geduldt habe ich FHEM nun davon überzeugen können das Modul zu 99_FTDI.pm zu laden und zu aktivieren. Allerdings funktioniert die Sache noch nicht so ganz, wie ich mir das vorstelle.
Ich muss sagen, dass die Installation für den Neuling eine Tortur ist, da die Auführungen hier doch sehr dürftig sind. Linuxkenntnisse und grundlegende Programmierkenntnisse sollten vorausgesetzt sein.
Um der Allgemeinheit den Einstieg zu erleichtern mal meine Vorgehensweise im Folgenden.
Erst habe ich per sudo apt-get install libusb-1.0-0-dev libusb1.0-0 habe ich die libusb installiert.
Dann habe ich per sudo apt-get install libftdi-dev libftdi1 die nötigen pakete für den ftdi-chip geladen.
Weiter wurde mit apt-get install libyaml-appconfig-perl installiert, damit cpan vernünftig funktioniert. Dazu gleich mehr.
Nun kann man mit CPAN beginnen. Ich habe dazu via sudo cpan den interaktiven Modus gestartet und mit der folgenden Anleitung das Programm initialisiert.
http://learnperl.scratchcomputing.com/tutorials/configuration/
CPAN braucht ewig für den Download der Module, was durch ...... symbolisiert wird. Drückt nicht hektisch strg + c. CPAN wird sich auf dem PI auch darüber beschweren, dass es nicht mehr aktuell ist. Das kann man getrost ignorieren und einfach die"." weiter durchlaufen lassen, bis sich CPAn wieder meldet.
Hier innerhalb der CPAN-Session muss man nun noch via "install Try::Tiny" ein Modul installieren, scheint irgendeine Testsuit zu sein oder so. Das übersteigt mein aktuelles Verständnis der Materie.
Dann muss man ebenfalls in cpan mit "install Device::FTDI" die Perlbibliotheken für FTDI installieren. Und hoffen, dass der Prozess durchläuft. Cpan ist das sehr geschwätzig und weißt einen auf fehlende Bibliotheken hin. Wenn die Anleitung befolgt wurde, sollte aber alles glatt gehen. Andernfalls ist Google der Freund und helfer in der Not.
Nun muss man (beim Raspberry Pi) in /opt/fhem/FHEM/ via sudo nano 99_FTDI.pm den Code von dero in einer Datei eintragen.
Die Funktion FTDI_GET habe ich dabei wie folgt ergänzt (bzw zusammengerätselt):
sub FTDI_Get($) {
my ($hash) = @_;
my $dev = Device::FTDI->new( "serial" => $hash->{SERIAL} );
$dev->set_baudrate(9600);
$dev->set_bitmode( 0xFF, Device::FTDI::BITMODE_BITBANG );
$dev->read_data( my $b1, 1 );
#Hier ist die Ergaenzung für die Ratlose Zeile aus dem Eingangspost
readingsSingleUpdate( $hash, "state", $dev, 1 );
return undef;
}
Mit strg+x wird nano beendet und mit J das Speichern bestätigt.
Zum Abschluss wird noch der Besitzer der Datei zu fhem geändert, indem man sudo chown fhem 99_FTDI.pm eingibt.
Ich musste FHEM neustarten, damit das Modul geladen wird. Ob alles gut gelaufen ist kann man dann noch in der Log von fhem nachgucken.
Mehr Hilfestellung kann ich nun leider auch nicht geben. Ich hoffe, dass sich der Threadersteller nochmal zu seinem Baby zu Wort meldet.
Nun zu meiner eigetnlichen Frage zurück ;-)
Was ist mit <serial> in "define <name> FTDI <serial> <index>" gemeint und wo beginnt der Index (0 oder 1)?
@dero: Und habe ich die Zeile in deinem Code richtig ergänzt?
Gruß
Scopy
Hallo
Hat jemand das Modul am laufen.
Habe mir das USB Modul gekauft weil ich dachte das es einfacher zu verkabeln ist. :)
Leider nützt es nichts wenn ich es gar nicht ansprechen kann. :o
Kann mir jemand helfen?
Eingebunden ist es jetzt wie scopeeye beschrieben.
Leider weis ich nicht mehr weiter. ??????
Ich würde mich bereit erklären, dass mal im Wiki zu dokumentieren.. Habe erst letzte Woche FHEM auf einem Pi2 aufgesetzt und bin dabei über FTDI gestolpert, aber es funzt wieder... Und schützt mein Haus vor Einbrechern (hängen zwei Sirenen dran...).
Außerdem würde ich gerne meine 42_FTDI.pm im FHEM svn haben... Wer hilft?
Dero
So, ich habe einen neuen Thread angelegt...