Modul für Spracherkennung? (menschlichen Text in einen Befehl umsetzen)

Begonnen von Rince, 11 Dezember 2013, 18:37:13

Vorheriges Thema - Nächstes Thema

Rince

Ich poste hier mal meine Gedankengänge.
Wenn es nicht interessiert, bitte ignorieren :)
Wenn der Thread zu unübersichtlich ist, bitte nicht schimpfen, ja?


Ich würde gerne FHEM mit einer mir verständlichen Sprache steuern.

Als Beispiel:
Ich sage "mache bitte alle Lichter aus."

Sollte ein FHEM Befehl werden im Sinne von:

set => mache (oder schalte)
*. => alle (oder überall)
LICHT => Lichter (oder Lampen)
OFF => aus


Zusammen:
set *.LICHT off

Jemand ne Idee, wie man das in Perl-Code gießt?



Das ganze sollte als Quelle eine Textdatei nehmen. Die könnte von einer Spracherkennung kommen, oder aus einer eMail. Was mir wichtig ist, ist dass man nicht jeden Befehl einzeln skriptieren muss, und z.B. auch auf den Satzbau keine Rücksicht nehmen bräuchte.

Mache im Wohnzimmer die Heizung an
wäre gleich mit
Mache die Heizung im Wohnzimmer an.

$Tue
$Stockwerk
$Raum
$Geraet
$Befehl
$Stimmung (könnte man vielleicht auswerten, um auf ein vorhandenes "Bitte" anders zu reagieren als ohne :)

Beste Grüße

Rince
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Rince

Hi,
nachdem ich jetzt ein bisserl mehr gelesen und neue Dinge entdeckt habe, bringe ich diesen Thread nochmal hoch :)

Die FullScreen Browser App von Dirk http://forum.fhem.de/index.php/topic,10628.0.html hat ja schon eine gute Möglichkeit, gesprochenen Text in FHEM zu nutzen.
Leider ist die Abfrage mit diversen notifies noch nicht so richtig gut.

Daher bestünde vielleicht wirklich Bedarf für ein Modul, welches einen normalen Text nach diversen Schlagworten universell durchsucht und an Hand einer Matrix daraus Befehle bastelt?

Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Kuzl

AAh alles klar da ist das eindeutig besser aufgehoben als im TTS-Thread :D

Durchaus eine coole Idee das Grammatikunabhängige erkennen :)
Also die Texterkennung und Speicherung in eine Textdatei sollte ja mit deinem Modul aus "Der Raspi hört aufs Wort" möglich sein oder?

Anschließend kann man den Text aus der Datei auslesen (wie das in perl geht weiß ich allerdings nicht) , dann splitten und mit for-schleifen die einzelnen Variablen des Arrays auf die Schlagwörter durchsuchen. Anschließend aus den gefundenen Schlagworten den Fhem Befehl erstellen und ausführen :) - Also das ist jetzt mal eine Vorgehensweise die mir Spontan einfällt.



Rince

So in etwa war es gedacht, ja.
Nachdem die Web Fullscreen Browser App schon den Text bereit hält, scheint es klug den gleich zu benutzen, und optional wenn eine Textdatei da ist, deren Inhalt zu verarbeiten.

Aber genau das ist die Idee, ja :)
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Steffen

Hallo!

Diesen Gedanken finde ich sehr gut, war schon langer ein kleiner Wunsch, Fhem per Sprache zu steuern.
Hatte es ne Zeit mit der Android-App "AIVC" versucht, die Befehle gut umsetzten konnte auch mit Variablen,
doch setzte sie sehr oft aus und die Sprach Erkennung ließ nach ca.1m sehr nach.
Nutze jetzt auch das Modul von Tobi("Text2Speech") was die Ausgabe sehr angenehm macht.
Hoffe das in naher Zukunft vielleicht ein lösungs Ansatz finden könnten, stelle mich gerne zum Testen bereit, da meine Perl Kenntnisse nicht so dolle sind!

Mfg Steffen   

Rince

Na, dann haben wir 3 schon was gemeinsam :)

Nämlich keine Ahnung von Perl :(


Ok,
keine Ahnung ob es der richtige Weg ist:
Ich zitiere mal von dieser Seite:
http://pronix.linuxdelta.de/Perl_cgi/Perl/perl_kurs_kapitel14.shtml

#!/usr/bin/perl -w

use strict;

my $text = "Hallo Welt ich lerne Regulaere Ausdruecke kennen";

$_=$text;
if (/^Hallo/)  {print "Hallo am Anfang des Textes gefunden\n";}
if(/Hallo/)    {print "Hallo gefunden\n";}

#wird nicht ausgegeben
if(/^Welt/)    {print "Welt am Anfang gefunden\n"}
if(/Welt/)     {print "Welt gefunden\n";}

if (/kennen$/) {print "\"kennen\" steht am Ende\n";}
if (/kennen/)  {print "\"kennen\" gefunden\n";}
#wird nicht ausgegeben
if (/^kennen/) {print "\"kennen\" steht am Anfang\n";}

print "Der 1. Buchstabe des Strings lautet " ,  /^(.)/ , "\n";
print "Der letzte Buchstabe ist ein ",  /(.)$/  , "\n";

#Gibt kompletten String aus von Anfang ^ bis Ende $
print  /^(.*)$/ , "\n";




Den müssen wir jetzt umbauen:

Das my $text = Muss später entweder auf den Wert verweisen, den Dirk in seiner App an FHEM schickt, oder aber auf eine Textdatei (die das Skript aus dem RasPi hört aufs Wort Thread erzeugt); vermutlich später User-konfigurierbar (dann könnte man auch eMails da reinwerfen, die dann entsprechend ausgeführt werden)

Code (Das ist nur eine Idee, keinesfalls funktionierender PerlCode) Auswählen

$Tue = set
$Stockwerk = OG
$Raum = 0
$Geraet = 0
$Befehl = 0
$Stimmung = false


$_=$text; #vermutlich braucht an jetzt eine Perl Funktion, um alle Großbuchstaben durch Kleinbuchstaben zu ersetzen, wer weiß wie die Spracherkennung es so hält

if !(^/Haussteuerung/) die  #hier müsste quasi das Erste Wort "Haussteuerung" sein, sonst passiert nix => Gebt eurer Haussteuerung doch mal einen hübschen Namen :)

if (/ich bin ein sonderbefehl/)  {print "Direkt den Sonderbefehl ausführen, also vermutlich eine fest definierte Befehlsfolge ausführen\n";
                                                    print "so wie es das alte Skript immer macht. Lies mir den Börsenbericht vor, z.B.\n"}
if (/ich bin ein anderer sonderbefehl/)  {print "Direkt den anderen Sonderbefehl ausführen, also vermutlich eine fest definierte Befehlsfolge ausführen\n";
                                                    print "so wie es das alte Skript immer macht. Lies mir den Gefahrenbericht vor, z.B.\n"}

if(/bitte/)    {$Stimmung=true;} # wir wissen jetzt, dass unsere Haussteuerung mit einem Bitte angesprochen wurde :)

if(/lichter/|/lampen/|/beleuchtung/)     {$Geraet=*.LICHT;}

if(/Wohnzimmer/)   {$Ort=_wz;}

if(/mache/|/schalte/|/stelle/)  {$Tue=set;}

if(/ein/|/an/)  {$Befehl=on;}
if(/aus/|/ab/)  {$Befehl=off;}

{fhem $Tue $Stockwerk$Ort$Geraet $Befehl}
-1



So in meiner kindlichen Naivität jedenfalls.

Vermutlich hat das mit Perl soviel zu tun wie ein Sojawürstchen mit einem Schweinebraten, aber so in etwa könnte man sich das vielleicht vorstellen :)
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Kuzl

@Rince
ich glaub man kann die Groß-und Kleinschreibung beim durchsuchen des strings einfach nicht beachten lassen mit if(/TeXt/i)
entweder mit dem i oder mit s dahinter bin ich mir nicht mehr sicher :D

ebenfalls könnte man die Schlüsselwörter nach denen gesucht werden soll über ein oder mehrere attribute definiern und in ein array packen
man kann dann nämlich einfach if(/$Array[x]/i)    in eine for-Schleife oder eine "allof" schleife packen und wenn es zutrifft in einem weiteren Array die jeweils zugehörige variable auf 1 setzen. So kann man dann aus dem 2. Array auslesen, welche der definierten Schlüsselwörter vorhanden sind und daraus einen Befehl basteln[/size][/font] :)

Wuppi68

Hi,
Das Thema klingt Spannend :-)

Ich würde mir einen Parser zum Beispiel in C bauen und diesen Text dann direkt dort in FHEM Befehle umsetzen und dann direkt zB via http an diesen schicken ...
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

Kuzl

Hallo,
in C/C++ bin ich um einiges Fitter :D
Allerdings wäre das dann ein von FHEM unabhängiges Tool und kann dann nicht direkt auf Spracheingaben reagieren, da man ja nicht weiß, woher der Befehl kommt  ::)

Das Tool sollte eigendlich nur die Auswertung eines bereits vorhandenen Textes (z.B. Email oder Spracheingabe oder so) übernehmen und darauf reagieren. So sollte das ganze auf jeder Plattform lauffähig sein :)

Bin allerdings offen für andere Lösungen :) deine funktioniert natürlich genau so
(existiert übrigens bereits in diesem Lösungsansatz bereits in der app "Tasker" und wird von mir so verwendet)

Kuzl

Rince weißt du, wie man den Inhalt der Textdatei in eine Variable schreiben kann?

Und könnte man anstadt der Textdatei eine .log Datei nehmen? dann kann direkt auf das Ereignis reagieren glaube ich.

Grüße
Kuzl

Rince

In dem Perl Kurs dessen Link ich oben gepostet habe, sind die ersten Beispiele mit dem Öffnen einer Datei. Das müsste also einfach sein. Einfach abschreiben ;)

Finde es toll, dass du dich des Themas annimmst  :)
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Rince

Entschuldige, war schon halb am schlafen.
Hier in Kurzform:
#!/usr/bin/perl -w

Use strict;

print "Welche Datei wollen Sie durchsuchen : ";

chomp(my $file=<>);

open(FH, "< $file")
or
die "Konnte $file nicht öffnen\n";

undef $/;

my $search = <FH>;



ZitatWas bedeutet nun das undef $/ ? Wir setzen damit die Standardvariable $/ auf einen undefinierten Wert, womit Sie den "Schlürfmodus" des Eingabeoperators aktivieren. Dies sorgt dafür, dass Sie den gesamten Text in der Variable $search stehen haben.
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Kuzl

Ach kein Problem :D
ich werd das einfach mal Probieren sobald ich Zeit dafür finde :)
Allerdings kann sich das noch etwas ziehen, da ich keinerlei Programmiererfahrung mit Perl habe sondern eher in C/C++ zuhause bin :D
Ebenfalls hab ich keine Ahnung vom Aufbau eines solchen Moduls aber ich probiers einfach mal irgendwann muss man anfangen ;)

Rince ich hab gesehen, dass du in dem Thread von der App auch auf uns aufmerksam gemacht hast :D Rudi hat dort was von cmdalias geschrieben, allerdings kapier ich nicht ganz was genau der unterschied zu einem notify ist oder bin ich jetzt blöd ? :D

Viele Grüße
Kuzl

Rince

So wie ich es verstanden habe,  werden damit neue Befehle erzeugt, die man dann als FHEM Befehle nutzen kann.
Man kann also einen neuen Befehl definieren, der dann z.B. mehrere Befehle ausführt. So eine Art Makro.

Dieses Makro könnte dann z.B. von einem Notify aufgerufen werden.

Uns könnte das weiterhelfen:
Zunächst könnten wir erst mal eine Routine in der my99Utils schreiben. Das ist leichter als ein Modul.
Darin könnte man die Variable, die den Text enthält, mit cmdalias einfach direkt vergleichen auf eine feste Zeichenfolge, quasi einem festen Text direkt einen FHEM Befehl zuweisen.
Das wäre dann quasi für feste Befehlssätze jeweils ein Einzeiler.

Und wenn davon nix zutrifft, analysieren wir den Text eben Wort für Wort.

also:
Die Wörter kommen nach $event
das wird nun mit einer festen Zeichenfolge verglichen, die einen festen Befehl ausfürt.


So in etwa habe ich Rudolf verstanden.
Quasi eine FHEM basierte Alternative die einige Zeilen Perl Code spart.
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Kuzl

Achso okay damit kann man also in unserem fall mit einem befehl vergleichen - geht aber mit notify genau so deshalb versteh ich irgendwie den Sinn nicht ganz ich glaub ich steh aufm Schlauch :D

EDIT:
So ich hab nur kurz in der Pause geschrieben :D
Also der Vorteil besteht darin, dass man eine "Funktion" schreiben kann, die aufrufbar ist oder?
Man könnte quasi den Quellcode (wird schätze ich gar nicht soooo viel sein) zum Test einfach mal in so ein cmdalias basteln und dann diesem erstellten Befehl über ein notify den Text vom Event übergeben.

Bin mir jetzt nicht sicher ob das der Zweck war, den Rudi gemeint hat :D


Stimmt das ist einfacher einfach zum testen mal in in myutils zu schreiben.

Mal sehen wann ich mal Zeit finde damit bisschen zu probieren :) muss mir natürlich erst mal die App und das zugehörige Modul installiern :D