Geht momentan nicht? Aber hallo wie gut das mit einem kleinen Umweg geht!
Seit kurzem ist Mountain Lion mit der Diktierfunktion raus (für mich genauso unbrauchbar wie am iPad 3). Auch wenn ich es nie zum Diktieren benutzen wollte ist es für eine Steuerung der Hausautomation prinzipiell prädestiniert, da die Erkennungsquote sehr gut ist und die Spracherkennung einen String zurückliefert den man sehr leicht in Skripten auswerten kann. So habe ich mal ein wenig getestet und war begeistert!
1. Feststellung: die Diktierfunktion ist relativ zügig
2. Feststellung: die Diktierfunktion erkennt ein Terminal Fenster als „Textbox“
Der schnellste Weg führte natürlich in Richtung AppleScript, da ich das schon ganz gut drauf habe.
Bevor wir zum Scripting kommen, die Vorbereitungen, damit das prinzipiell jeder umsetzen kann, was ich hier erkläre:
1. Diktierfunktion in den Systemeinstellungen aktivieren
Und den Kurzbefehl zum Aktivieren der Diktierfunktion auf:
2. Sprachausgabe auf Deutsch Stimme „Steffi“ einstellen
einfach im Fenster der Diktierfunktion den Reiter auf „Sprachausgabe“ wechseln
3. In den Bedienungshilfen die „speakable items“ aktivieren
Darauf hin erscheint der Controller
Nun können wir zu den beiden Scripten kommen. Das erste ist ein Hilfsscript welches durch die „speakable item“ ausgelöst wird. Dieses wird später in den Pfad der verfügbaren Sprachbefehle kopiert, wo sich die leider alle in Englisch gesprochenen rudimentären Sprachbefehle von MacOS befinden.
Nun das Script voicehelper.scpt
tell application "Terminal" to activate delay 1 tell application "Terminal" to activate tell application "System Events" tell process "Terminal" -- Bitte den Pfad auf den eigenen Benutzerordner anpassen! keystroke "cd /Users/max/Desktop/ac_voice/" & return keystroke "osascript voice.scpt " keystroke (ASCII character 34) delay 1 keystroke "d" using command down delay 5 keystroke "d" using command down delay 1 keystroke (ASCII character 34) key code 76 -- Enter auf Nummernblock delay 5 --keystroke "q" using command down -- beendet TextEdit per Apfel-Q end tell end tell tell application "Terminal" to quit
Das Script manipuliert schlicht das Terminalfenster und übergibt so das Gesprochene an das eigentliche „intelligente“ Script voice.scpt weiter, welches die Worte in Befehle umsetzt.
voicehelper.scpt muss z.B. in home.scpt umbenannt werden (vorzugsweise als Duplikat) und dann in den „speakable items“ Ordner in der Benutzerlibrary kopiert werden, damit es dort als neuer Sprachbefehl erkannt wird.
Nun das Script voice.scpt :
Der Aufruf aus dem Terminal sieht quasi so aus: osascript voice.scpt „Schalte das Licht in der Küche ein“
-- URL für Homematic XMLAPI Request property XMLAPI : "http://192.168.1.10:90/xmlapi/statechange.cgi" on run this_file set voicecommand to " " set goodcommand to 0 --say (this_file) set voicecommand to (this_file) as text --say voicecommand if voicecommand contains "Kaffee" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=15961&new_value=true'" set goodcommand to 1 end if if voicecommand contains "Abend" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=7765&new_value=false'" set goodcommand to 1 end if if voicecommand contains "Alles aus" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=7773&new_value=false'" set goodcommand to 1 end if if voicecommand contains "Siri" then say "Verdammt hör auf mich so zu nennen! Ich bin 10 mal besser als Siri." set goodcommand to 1 end if if voicecommand contains "hass" then say "Das beruht ganz auf Gegenseitigkeit. Wenn du mich so hasst dann schalte ich halt keine Lichter mehr für dich!" set goodcommand to 1 end if if voicecommand contains "versteh" then say "Dann sprich deutlicher." set goodcommand to 1 end if if voicecommand contains "Jalousien" then if voicecommand contains "runter" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=36931&new_value=0.0'" set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=33590&new_value=0.0'" set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=33565&new_value=0.0'" set goodcommand to 1 end if if voicecommand contains "hoch" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=36931&new_value=1.0'" set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=33590&new_value=1.0'" set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=33565&new_value=1.0'" set goodcommand to 1 end if if voicecommand contains "stop" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=36932&new_value=true'" set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=33591&new_value=true'" set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=33566&new_value=true'" set goodcommand to 1 end if end if if voicecommand contains "Licht" then if voicecommand contains "Küche" then if voicecommand contains "ein" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=1465&new_value=true'" set goodcommand to 1 end if if voicecommand contains "aus" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=1465&new_value=false'" set goodcommand to 1 end if end if if voicecommand contains "Vitrine" then if voicecommand contains "ein" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=1494&new_value=true'" set goodcommand to 1 end if if voicecommand contains "aus" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=1494&new_value=false'" set goodcommand to 1 end if end if if voicecommand contains "Wandlampe" then if voicecommand contains "ein" or "ein" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=1623&new_value=true'" set goodcommand to 1 end if if voicecommand contains "aus" or "aus" then set ReturnValue to do shell script "curl -s '" & quoted form of (XMLAPI & "?") & "' -d 'ise_id=1623&new_value=false'" set goodcommand to 1 end if end if end if if voicecommand contains "led" then if voicecommand contains "Wohnzimmer" then if voicecommand contains "orange" then -- Ansteuerung LED Controller set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Za255a72a0a5'" set goodcommand to 1 end if if voicecommand contains "blau" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Za21a0a255a5'" set goodcommand to 1 end if if voicecommand contains "rot" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Za255a0a0a5'" set goodcommand to 1 end if if voicecommand contains "grün" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Za0a255a0a5'" set goodcommand to 1 end if if voicecommand contains "aus" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Za0a0a0a5'" set goodcommand to 1 end if end if if voicecommand contains "Kugel" then if voicecommand contains "orange" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Ya255a72a0a5'" set goodcommand to 1 end if if voicecommand contains "blau" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Ya21a0a255a5'" set goodcommand to 1 end if if voicecommand contains "rot" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Ya255a0a0a5'" set goodcommand to 1 end if if voicecommand contains "grün" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Ya0a255a0a5'" set goodcommand to 1 end if if voicecommand contains "aus" then set ReturnValue to do shell script "curl -s '" & quoted form of ("http://192.168.1.20:8080/ledcontr/contr.php?" & "?") & "' -d 'com=Ya0a0a0a5'" set goodcommand to 1 end if end if end if if goodcommand = 0 then say "Entschuldigung. Ich verstehe den Befehl, " & voicecommand & ", nicht." end if end run
Durch die Verschachtelung wird ohne weiteres zutun ein Satz wie: „Schalte das Licht in der Küche aus“ ausgewertet nach den Kriterien „Licht“ & „Küche“ & „aus„. Vom Sinn kann also auch ohne Probleme „Licht Küche aus“ oder „Bitte das Licht in der Küche ausschalten“ gesagt werden 🙂
Das voice-Script kann so nach eigenen Bedürfnisses quasi grenzenlos erweitert werden…
Build your own Siri !
Ich war echt erstaunt, wie gut das mit den verschachtelten IF-Bedingungen geklappt hat 🙂 Geht mit Sicherheit eleganter, ist vielleicht ein guter Denkanstoß für Andere…
Das komplette Paket mit den Scripten gibts hier zum Download…
Hier noch ein Video vom Einsatz der Scripte:
Fragen und Anmerkungen willkommen! Bitte zeigt dann euere Projekte, falls Ihr meinen Quellcode verwendet oder ihn als Denkanstoß nutzt.
Nachtrag „Tips & Trick“ Ansteuerbare Geräte und Haussteuerungen:
Ich verwende, wie an vielen Stellen erwähnt, die Homematic Steuerung (CCU-1) von ELV. Die Zentrale hat ein AddOn „XMLAPI“ installiert welche auf einem 2. Webserver über (wie im Skript) CURL angesprochen wird. Stellvertretend kann man also über einfache HTTP Request so ziemlich alle anderen Systeme ansteuern. (Beispiele wo es sofort ohne Weiteres möglich ist: Dreambox, IR-Trans, Homematic mit XMLAPI). Bei der Dreambox kann man über das Webinterface alle Tasten der Fernbdienung „drücken“ und somit das Fernsehen per Sprache kontrollieren. Beim IR-Trans in Verbindung mit der Gerätedatenbank selbiges für alle angelernten IR Befehle.