[gelöst] Arduino Movi-Shield offline Spracherkennung in FHEM einbinden

Begonnen von joginet, 03 Februar 2018, 19:50:50

Vorheriges Thema - Nächstes Thema

joginet

Hallo Forum,
heute habe ich mein Arduino-Movi-Shield bekommen, damit möchte ich eine "offline" Sprachsteuerung für FHEM bauen.

Das Shield funktioniert prima, jetzt brauche ich noch die Verbindung zu FHEM. Ich habe es versucht mit ECMD.
Der Arduino hängt per USB am FHEM-Server (NUC mit Linux Mint).
Per
define movi ECMD serial /dev/ttyACM0@9600
kann ich den Arduino erreichen.
Ich verstehe aber die Sache mit der classdef nicht, die Beispiele und die commadref habe ich gelesen aber nicht verstanden.
Über den seriellen Monitor der Arduino IDE kann ich den "MOVIEvent" auslesen, mit dieser (Satz-)Nummer könnte ich eine FHEM-Aktion auslösen.
(siehe screenshot).
Hat jemand einen Tipp für mich, wie die classdef. aussehen muß?

Gruß, Jochen


Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

joginet

#1
Hallo nochmal,
Ich habe in FHEM schon viel erreicht, in der Regel durch "Copy&Paste" und Ausprobieren und dadurch dann auch "verstehen".
Aber diesmal bekomme ich es einfach nicht hin.
Ich habe mir jetzt alle verfügbaren Posts und Wikis durchgelesen. Die classdefs, die ich gefunden haben - z.B. um irgendwelche Ports auszulesen oder Temperatursensor-Werte zu erfassen - verstehe ich nicht, denn Sie enthalten "Device-spezifische Readings" wie "0R15" für Relais oder irgendwelche Temperaturwerte, Umwandlungen in Hex-Werte, usw.

Ich habe versucht, diese classdefs entsprechend "umzubauen" aber im Endeffekt weiss ich gar nicht, was ich da tue.
Ich dachte auch, mein Englisch wäre ganz ok, aber die ECMD, ECMDDevice und classdef-Beschreibungen in der Englischen Commandref habe ich auch nicht verstanden, ebensowenig die Perl-Syntax, die Separatoren, usw.
Um ehrlich zu sein, ich verstehe nur "Bahnhof".

Ich möchte den Wert "MOVIEvent [201}" hinter dem "#" aus meiner seriellen Kommunikation filtern (das ist sozusagen die "Satznummer") und zum schalten eines Device benutzen.

Das steht in meinem FHEM-Logfile wenn ich "GO DARK" für "Lampe aus" sage:

2018.02.04 08:06:58 3: MOVI: read MOVIEvent[141]: END ACTIVELISTEN\r\r\nMOVIEvent[201]: GO DARK\r\r\nMOVIEvent[202]: #1\r\r\nMOVIEvent[150]: SPEAKING\r\r\n (\115\117\126\111\105\166\145\156\164\133\061\064\061\135\072\040\105\116\104\040\101\103\124\111\126\105\114\111\123\124\105\116\015\015\012\115\117\126\111\105\166\145\156\164\133\062\060\061\135\072\040\107\117\040\104\101\122\113\015\015\012\115\117\126\111\105\166\145\156\164\133\062\060\062\135\072\040\043\061\015\015\012\115\117\126\111\105\166\145\156\164\133\061\065\060\135\072\040\123\120\105\101\113\111\116\107\015\015\012)

Wie gesagt, die Nummer hinter "MOVIEvent[202]: #"  brauche ich, in diesem Fall also die "1". Kann mir bitte jemand bei der classdef auf die Sprünge helfen?

Gruß, Jochen

PS: In vielen (ähnlichen) Posts steht dazu "lies Dich erstmal in die PERL-Materie ein". Das ist sicher sinnvoll und auch zielführend. Im Moment ist mein Bastel-Schwerpunkt aber die Spracherkennung und es fehlt mir "nur" an der Auflösung des seriellen Signals für ein ECMDDevice.
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

CBSnake

Moin Jochen,
man könnte das Reading (ist es denn eins?) Mit userreading zerlegen und die Nummer extrahieren.
Könnte man nicht auch auf Go Dark triggern?
Grüße
Achim
FHEM auf Debian 10, HM-Wlan, JeeLink-Wlan, Wlanduino, ConBee, TP-Link Steckdose, GHoma Steckdosen, Shelly Steckdosen

joginet

#3
Moin Achim,
ja - das ist die Frage - wo bekomme ich ein Reading aus dem "unspezifiziertem" Traffic her.
Userreading habe ich auch schon versucht, in meinen classdef-versuchen habe ich auch schon versucht auf "DARK" zu triggern.
Wobei später (bei mehr Befehlen) die Satznummer natürlich einfacher ist.
Das ist auch egal, wenn ich es erstmal verstanden haben, kann ich es sicher umbauen.
Wenn ich es richtig verstanden habe, extrahiert die classdef erst das verwendbare Reading aus dem ganzen seriellen Traffic?

Gruß, Jochen
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

CBSnake

Hmmm,
zu classdef muss ich mich auch erstmal einlesen ;-)
Auf die schnelle würde ich das mit doif und userreading oder notify und evtpart versuchen

Grüße
Achim, den Sprachsteuerung abseits von Amazon und Google auch brennend interessieren ;-)
FHEM auf Debian 10, HM-Wlan, JeeLink-Wlan, Wlanduino, ConBee, TP-Link Steckdose, GHoma Steckdosen, Shelly Steckdosen

joginet

Das einzige Event ist "UNKNOWNCODE", damit kann ich auch z.B. per DOIF reagieren  8)
Ich fürchte, ich komme nicht um die classdef herum - nur wie?
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

Mike73

Hallo joginet,

geht denn dem erwarteten Datenstrom ein Kommando an den MOVI voraus ?  ( OK, MOVI kenne ich nicht, aber mit ECMD hab ich schon einiges gemacht )  .

Hast du denn schon eine Classdef?  Wie sieht dein Define vom MOVI aus ? 


Gruß

Mike 

joginet

#7
Moin,
Zitat( OK, MOVI kenne ich nicht, aber mit ECMD hab ich schon einiges gemacht )  .

Das hier ist der Movi: http://www.audeme.com/
Darauf gebracht hat mich dieser Thread: https://forum.fhem.de/index.php/topic,66748.msg746043.html#msg746043

Zitatgeht denn dem erwarteten Datenstrom ein Kommando an den MOVI voraus ?

Ja, ein Voice-Befehl.

ZitatWie sieht dein Define vom MOVI aus ? 

siehe erster Post: define movi ECMD serial /dev/ttyACM0@9600

Verbose=5. Ein classdef habe ich natürlich versucht anzubinden, momentan habe ich meine Versuche gerade wieder gelöscht.
Ich habe versucht, mir aus diversen Beispiel-classdefs etwas passendes zurechtzukopieren, leider ohne Erfolg.
Habe versucht, mit reading <reading> match "<regex>" eine Variable zu übergeben, allerdings scheitert es schon an der Übergabe an das ECMDDevice. Das habe ich angelegt, aber nicht verstanden.

Im Logfile wird alles angezeigt, was nötig wäre, nur im Event-Monitor kommt immer nur "UNKNOWNCOMMAND"

Ich bräuchte mal eine Erklärung "für Doofe", wie ich einen Wert mit der classdef extrahiere und an ein ECMDDecvice übergebe.

Gruß, Jochen
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

joginet

Ok, evt. ein neuer Ansatz. Eventuell ist auch dieser falsch und nicht zielführend.
Ich habe mal Spasseshalber ein Jeelink-Device angelegt:

define myARDUINO JeeLink /dev/ttyACM0@9600
attr myARDUINO event-on-change-reading .*


Damit gibt es Events, zwar mit "UNKNOWNCODE" drin, aber ansonsten sauber und sortiert. Darauf müsste doch ein DOIF reagieren können?

2018-02-04 16:47:05 JeeLink myARDUINO UNKNOWNCODE MOVIEvent[200]: CALLSIGN DETECTED
2018-02-04 16:47:05 JeeLink myARDUINO UNKNOWNCODE MOVIEvent[140]: ACTIVELISTEN
2018-02-04 16:47:08 JeeLink myARDUINO UNKNOWNCODE MOVIEvent[141]: END ACTIVELISTEN
2018-02-04 16:47:08 JeeLink myARDUINO UNKNOWNCODE MOVIEvent[201]: GO DARK
2018-02-04 16:47:09 JeeLink myARDUINO UNKNOWNCODE MOVIEvent[202]: #1
2018-02-04 16:47:09 JeeLink myARDUINO UNKNOWNCODE MOVIEvent[150]: SPEAKING


Habe es bisher nicht hinbekommen...
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

Mike73

Hallo Jochen,

zu ECMD ist da https://wiki.fhem.de/wiki/ECMD was gesagt. 

Grundsätzlich funktioniert ECMD so, dass du einen Befehl an das Gerät sendest und eine Antwort erwartest die du dann auswertest. WENN das MOVI nach diesem Prinzip arbeitet, kannst du das ECMD-Modul dazu "missbrauchen" .
Die Befehle werden mit den set/get-Aktionen des ECMD-Devices abgesetzt. Eben dazu brauchst du die classdef. Die legt fest, wie zB der set-Befehl als Kommando  an das MOVI geschickt wird.

However ..

Du brauchst eine classdef, die verbindest du mit dem ECMD-Gerät MOVI
attr MOVI classdefs <CLASS>=<pfad-und-dateiname-der-classdef>


Dann ein ECMDDevice zB

define meinVoice ECMDDevice
attr meinVoice IODev MOVI
attr meinVoice class <CLASS>


Dann kannst du mit

set meinVoice <befehl>


den Befehl an das MOVI schicken.

Sowei so gut.

Als Beispiel classdef kannst du die aus dem Wiki umbauen https://wiki.fhem.de/wiki/AVR-NET-IO#Digitale_Eing.C3.A4nge_in_FHEM_einbinden

Die Extraktion der Nummer aus der Ergebniszeile wird mitels eines regex ( regulären Ausdrucks) bewerkstelligt. Grundsätzliches Verständnis ist erforderlich : https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck


Wenn du nun in der Classdef zB folgendes ersetzt:


get read postproc {\
m/read MOVIEvent\[(\d{1,3})\].*/ ;\
my $retval = $1;\
}


Dann sollte nach Abarbeitung des Befehls die (ein- bis) dreistellige Nummer in den eckigen Klammern im Reading "read" des Devices meinVoice zu finden sein.



joginet

#10
Ok, schonmal danke. Meine classdef. liegt in /opt/fhem/FHEM und heisst "ECMD_Arduino.classdef".
Also:
attr MOVI classdefs ABC=/opt/fhem/FHEM/ECMD_Arduino.classdef
richtig?

Für das ECMDDevice :

attr meinVoice class ABC

oder?

Meine classdef sieht so aus:

get read postproc {\
m/read MOVIEvent\[(\d{1,3})\].*/ ;\
my $retval = $1;\
}


ZitatDann sollte nach Abarbeitung des Befehls die (ein- bis) dreistellige Nummer in den eckigen Klammern im Reading "read" des Devices meinVoice zu finden sein.

Da steht nur "read". Was mache ich falsch?

Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

joginet

Ahh, ok - das habe ich überlesen:
ZitatGrundsätzlich funktioniert ECMD so, dass du einen Befehl an das Gerät sendest und eine Antwort erwartest die du dann auswertest. WENN das MOVI nach diesem Prinzip arbeitet, kannst du das ECMD-Modul dazu "missbrauchen" .

Ich glaube, es gibt da nichts zu senden. Ist mein ECMD-Ansatz evt. grundfalsch? Der Traffic ist ja zu sehen, aber nicht als Event - nur im log.

Gruß, Jochen

PS:
Hast Du meinen Post mit dem Jeelink-Device gesehen? Da gibt es sauber sortierte Events, kann ich evt. auf diese triggern - mit einen Userreading, z.B.?
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

joginet

Uff - das war ein langer Tag ! Aber: der Durchbruch - man glaubt es kaum, ich habe es geschafft  ;D ;D ;D

Aber nicht mit dem ECMD Device sondern durch Anlegen einen "Pseudo JeeLink Devices".

define myARDUINO JeeLink /dev/ttyACM0@9600
attr myARDUINO event-on-change-reading .*


Das Teil hat dann ein Internal "RAWMSG" und auf dieses kann ich mit einem DOIF triggern:

define meinDoif DOIF ([myARDUINO:&RAWMSG] =~ "#0") (set Arbeitszimmer1 on) DOELSEIF ([myARDUINO:&RAWMSG] =~ "#1") (set Arbeitszimmer1 off)

Eigentlich ganz easy.
Im Movi-Sketch kann man ganz einfach Befehle eintragen, die Sätze haben dann "Satznummern". Diese liesst das DOIF aus den Internals aus. Möglich wäre auch das triggern auf den Text.

Ich sage: "Arduino" (Triggerword)
Arduino: (piep)
Ich: "Let there be light"
Arduino: "And there was light"
Im JeeLink Internal "MSGRAW" wird der MOVIEvent[201]:#0 ausgegeben, das DOIF triggert auf die "#0" und die Lampe "Arbeitszimmer1" geht an.
Bei "Go Dark" (=MOVIEvent [201]:#1) geht die Lampe aus.

Das ganze gibt es auch mit Deutscher Erkennung & Stimme, das muß ich noch einstellen. Fertig ist die Offline-Alexa !

Ich mach mir jetzt erstmal ein Pils auf und rede noch ein bisschen mit meiner Arbeitszimmerlampe  ;D

Vielen Dank nochmal für Eure Eingaben.

Gruß, Jochen
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi

CBSnake

FHEM auf Debian 10, HM-Wlan, JeeLink-Wlan, Wlanduino, ConBee, TP-Link Steckdose, GHoma Steckdosen, Shelly Steckdosen

joginet

Eine Sache noch:
solange das FHEM-device auf "opened" steht, kann man auf den Arduino keine Sketche hochladen (z.B. um neue Sätze einzufügen).
Da ist die USB-Schnittstelle dann vom FHEM blockiert.
Ich ändere dann kurzfristig die Schnittstelle des JeeLink-Devices in der DEF (z.b. in /dev/ttyACM3@9600) und nach upload wieder zurück.

Ansonsten ist das "Einlernen"  neuer Sätze denkbar einfach. Über die Arduino-IDE im MOVI-Sketch einfach eintragen + hochladen:

Für die Erkennung:

recognizer.addSentence("Aussenlicht an");   // Add German sentence 8

und für das Sprach-Feedback:

if (res==8) {                    // Sentence 8
    digitalWrite(led, HIGH);        // Turn on LED
    recognizer.say("Die Aussenbeleuchtung ist jetzt eingeschaltet!"); // Respond a sentence in German
  }


Deutsch kann er jetzt auch schon, der Kleine:

http://www.instructables.com/id/Connection-less-German-Speech-Recognition-and-Synt/

Die Deutsche Stimme ist nicht so perfekt wie bei Alexa&Co. und kann zum Beispiel keine
Umlaute. "Das Ku-echenlicht ist jetzt eingeschaltet!"  ;D

Ich habe aber beim Morgenkaffee bereits 3 Zimmer beleuchtungstechnisch plus die Aussenbeleuchtung plus den Multiroom-Lautsprecher in der Küche ("Arduino - Musik an !") eingebunden. Das geht wirklich fix.
Ich werde mir jetzt noch ein externes Mikrofon anschaffen, dann muß ich von der Küche aus nicht so schreien.
Außerdem: vielleicht eine nette Box für alles, noch liegt die nackte Platine a.d. Schreibtisch. Eine LED wird an den Arduino-PINs ja schon angesteuert, evt. kann man da was mit "Leuchtkranz" bei Spracherkennung und Voice-Feedback basteln.

Gruß, Jochen
Meine Konfig: FHEM auf NUC i5 mit Mint, HM-LAN, div. HM Schalter und Heizungsthermostate, FB 6840LTE mit Dect200, HUE bridge, HUE bulbs + Lightstrips, VU+Duo2 und Philips-TV Steuerung, Pushmail, Floorplan, Sprachsteuerung + Feedback per Arduino mit MOVI-Shield, LMS Multiroom mit 7x Pi