FHEM mit SIRI von Apple steuern

Begonnen von RBpi, 02 Januar 2013, 00:58:47

Vorheriges Thema - Nächstes Thema

RBpi

Hallo zusammen,

anbei ein kleines How-To, um Siri Proxy auf der RBpi zu installieren und FHEM über Siri steuern zu können.

Ich habe nicht viel Ahnung in Sachen FHEM / Linux / RBpi und kann daher nur beschränkt weiteren Support leisten. Evtl. entsteht hier aber eine interessante Diskussion für alle.

Was ist Siri?
Siri (Akronym von Speech Interpretation and Recognition Interface) ist eine Software von Apple, die der Erkennung und Verarbeitung von natürlich gesprochener Sprache dient und so Funktionen eines persönlichen Assistenten erfüllen soll. Die Sprachdaten werden bei bestehender Internetverbindung an einen Apple-Server übertragen, dort verarbeitet und das Ergebnis an das Endgerät zurückgemeldet. Das Vorläuferkonzept stammt ursprünglich von der gleichnamigen Siri Inc., die Apple im Jahr 2010 übernommen hatte.

Verfügbarkeit
Siri ist auf dem iPhone 4S, iPhone 5, iPad (3. Generation) und iPod touch (5. Generation) verfügbar und erfordert Internetzugriff.

Wie funktioniert die Siri Spracherkennung
Siri kommuniziert per HTTPS mit dem Server guzzoni.apple.com und sendet diesem ACE-Requests, eine Methode, die in HTTP nicht definiert ist. Mitgesendet wird ein sogenannter X-Ace-host, eine eindeutige ID, die jedem iPhone 4S zugeordnet ist. Die dabei gesendeten Binärdaten sind mit zip komprimiert.

Siri kodiert die aufgenommene Sprache mit dem freien Codec Speex, der speziell für die Sprachkompression entwickelt wurde. Wer Siri auf einem anderen Gerät als einem iPhone 4S nutzen will, muss die dort aufgenommenen Daten also ebenfalls mit Speex kodieren. Zudem wird ein gültiger X-Ace-host benötigt, der sich laut Applidium recht einfach aus einem iPhone 4S auslesen lässt. Die Entwickler gehen davon aus, dass es kein großes Problem ist, den X-Ace-host zum persönlichen Gebrauch für ein anderes Gerät zu nutzen. Sollten ein X-Ace-host aber in großem Umfang missbraucht werden, ist davon auszugehen, dass Apple den Account sperren wird.
Zusammen mit den Audiodaten übermittelt das Telefon weitere Informationen an den Server und dieser liefert seinerseits umfangreiche Metadaten mit seinem Analyseergebnis zurück, einschließlich Wahrscheinlichkeitswerten und Zeitstempeln für jedes einzelne Wort.
Quelle: http://de.wikipedia.org/wiki/Siri_%28Software%29

Siri Proxy auf RBpi installieren (inkl. Wartezeit ca. 150 Minuten)

Per SSH Client oder im Terminal folgende Befehle eingeben:
sudo apt-get update

sudo apt-get upgrade

sudo apt-get install dnsmasq ruby build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion

bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"

echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile

Auf einer Ubuntu VM unter Win7 dauert der Befehl ca. 5 Minuten, auf der RBpi ca. 105 Minuten:
rvm install 1.9.3
rvm use 1.9.3 --default
DNS Server konfigurieren
sudo nano /etc/dnsmasq.conf
Folgende zeile suchen #address=/double-click.net/127.0.0.1 und # entfernen und wie folgt aufbauen (Im Beispiel 192.168.1.120 = IP RBpi):

WICHTIG: Das Zertifikat richtet sich nach der iOS-Version (hier iOS 6.0.0):
address=/guzzoni.apple.com/192.168.1.120
Speichern mit Strg+O, Enter und Strg+X

DNS Server neustarten
sudo /etc/init.d/dnsmasq restart
Siri Proxy aus GIT Hub clonen
git clone git://github.com/plamoni/SiriProxy.git
In den neu erstellten Siri Ordner wechseln
cd SiriProxy
Abfrage mit Y (Yes) bestätigen
mkdir ~/.siriproxy
cp ./config.example.yml ~/.siriproxy/config.yml

Rake installieren (Dauer ca. 10 Minuten)
rake install
Zertifikate generieren
siriproxy gencerts
Siri Proxy bundeln (inkl. evtl. vorhandener Plugins)
siriproxy bundle
Wenn Siri mit dem User pi installiert wurde, muss noch folgendes gemacht werden (Danke an Markus Niemann)
sudo ln -s /home/pi/SiriProxy /root/SiriProxy
sudo ln -s /home/pi/.siriproxy /root/.siriproxy

Zusätzlich musst Du noch die example-config zur default-config machen:
cp /home/pi/SiriProxy/config.example.yml /home/pi/.siriproxy/config.yml
Aufgrund einer weiteren Änderung an der CFPropertyList muss noch folgendes angepasst werden:

sudo nano siriproxy.gemspec

Die folgende Zeile (ziemlich am Ende)
s.add_runtime_dependency "CFPropertyList"
mit folgender Zeile ersetzten, bzw. erweitern:
s.add_runtime_dependency('CFPropertyList', '2.1.2')

Speichern mit Strg+O, Enter und Strg+X

Siri updaten (ca. 90 Sekunden)
rvmsudo siriproxy update .
Server starten (ca. 20 Sekunden)
rvmsudo siriproxy server
Der Befehl wird bestätigt:
ZitatStarting SiriProxy on port 443..SiriProxy up and running.
Zertifikate auf iOS Gerät übertragen
Das Zertifikat liegt im Ordner ~/.siriproxy/ca.pem und können per WinSCP von der RBpi auf den Rechner kopiert und dann z.B. per Mail an das iOS Gerät verschickt werden. Anschließend muss das Zertifikat auf dem Gerät geöffnet und installiert werden.

WLAN DNS Adresse ändern
In der WLAN Verbindung auf den kleinen blauen Pfeil klicken
Dort die DNS Adresse auf die Adresse eurer RBpi anpassen
Um alles zu aktivieren, anschließend den Flugmodus aus- und einschalten

Wenn der SiriProxy Server läuft kann über den Befehl "Test Siri Proxy" Siri getestet werden. In der Konsole erscheint
Zitat[Info - iPhone] Received Object: SpeechPacket
[Info - iPhone] Received Object: FinishSpeech
[Info - Guzzoni] Received Object: SpeechRecognized
[Info - Plugin Manager] Processing 'Test Siri Proxy '
[Info - Plugin Manager] Matches (?i-mx:test siri proxy)
[Info - Plugin Manager] Applicable states:
[Info - Plugin Manager] Current state:
[Info - Plugin Manager] Matches, executing block
[Info - Plugin Manager] Say: Siri Proxy is up and running!
Plugins
Um eigene Befehle hinzufügen kann entweder das Beispiel-Plugin bearbeitet werden oder ein eigenes installiert werden.

1) Beispiel Plugin ändern (wir befinden uns im SiriProxy Ordner)
cd plugins/siriproxy-example/lib/
sudo nano siriproxy-example.rb


2) Plugin herunterladen:

In das .siriproxy Verzeichnis wechseln
cd .siriproxy

Config.yml erweitern
sudo nano config.yml
Plugin hinzufügen
- name: 'PluginName'
git: 'git://github.com/pfad/name.git'

Wichtig: Ruby - Klasse = Großbuchstabe am Anfang

FHEM steuern

Telnet installieren
sudo apt-get install telnet
Für FHEM Befehle z.B. folgendes einfügen:
 listen_for /Licht ein/i do
    say "F H E M schaltet das Licht ein" #Siri schreibt und sagt den Befehl

    require 'net/telnet'
    t = Net::Telnet::new( "Timeout" => 5,
                          "Prompt"  => /%/,
                          "Host"    => "192.168.1.120",
                          "Port"    => 7072 )
    #t.login("*MY ACCOUNT*", "*MY PASSWORD*")
    t.cmd("String" => "set tisch_licht on", "Match" => //)
    t.cmd("quit")
    t.close
    request_completed
  end

Nach jeder Änderung / Installation eines Plugins muss folgendes ausgeführt werden:

Aus dem SiriProxy Verzeichnis heraus:
rvmsudo siriproxy update .
rvmsudo siriproxy server

Um nicht jedesmal mit einem Gerät zu testen, kann auch eine Konsole von SiriProxy gestartet werden:
rvmsudo siriproxy console
Hier können die eigentlich gesprochenen Siri-Befehle eingegeben werden und das Coding wird durchlaufen:
>> Licht ein

Ergebnis:
=> F H E M schaltet das Licht ein

Quellen:
http://www.idownloadblog.com/2011/12/09/how-to-install-siri-proxy-tutorial-video/
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=63&t=25118&p=231345
https://groups.google.com/forum/#!topic/fhem-users/ekHQomwmvXw


MarkusN

Hallo,

danke für das Tutorial. Ich habe bereits seit einiger Zeit SiriProxy bei mir laufen, und zwar für genau diesen Zweck. Ich gehe jedoch nicht den Umweg über Telnet sondern nutze die fhem.pl:

   listen_for /schalte.*aquarium.*ein/i do
        say "Ok, ich schalte das Licht im Aquarium ein..."
        system "/usr/bin/fhem.pl localhost:7072 'set Licht_Aquarium on' &"
        request_completed
    end

    listen_for /schalte.*aquarium.*aus/i do
        say "Ok, ich schalte das Licht im Aquarium aus..."
        system "/usr/bin/fhem.pl localhost:7072 'set Licht_Aquarium off' &"
        request_completed
    end


Interessant wird es wenn man nicht jedes Device und jeden Schaltzustand berücksichtigen müsste sondern SiriProxy checkt ob es das Device gibt und dann ggf. eine Fehlermeldung zurückwirft. Hier gibt es ein sehr schönes Beispiel. Leider reichen meine Programmierkenntnisse nicht aus um so was zu zaubern.

RBpi

Hallo Markus,
Zitat von: Markus Niemann schrieb am Mi, 02 Januar 2013 21:09Ich gehe jedoch nicht den Umweg über Telnet sondern nutze die fhem.pl:
mein Umweg kommt noch aus der Zeit, wo ich keine Raspberry hatte und FHEM und SiriProxy auf zwei getrennten Systemen laufen hatte.

Deine Variante ist natürlich viel einfacher! Danke.

Das Conding in deinem Link sieht als Grundlage sehr vielversprechend aus.

Am Ende müsste ja soetwas rauskommen (kein funktionierendes Coding!)
listen_for /Schalte (on|off)(?: das)? ([a-z]* ?[a-z]*)/i do |userAction, deviceName|
    while userAction.empty? do
userAction = ask "Welcher Zustand?"
    end
    while deviceName.empty? do
deviceName = ask "Welches Gerät?"
    end
    system "/usr/bin/fhem.pl localhost:7072 'set "#{deviceName.chop}" "#{userAction.chop}"' &"
    say "Schalte das Gerät "#{deviceName.chop}" "#{userAction.chop}" ."
    request_completed
end


Viele Grüße
Ludwig

RBpi

Hi Markus,

hier schonmal eine ganz einfache Version zum ein-/ausschalten:
Zitat# Geraet on/off schalten
  listen_for /Schalte (on|off)(?: das)? ([a-z]* ?[a-z]*)/i do |action, device_name|
    run_action_on_device action, device_name
    request_completed
  end

    private
  # Befehl ausfuehren
  def run_action_on_device action, device_name
     system "/opt/fhem/fhem.pl localhost:7072 'set #{device_name} #{action}' &"
      say "Schalte #{device_name} #{action}."
  end
Der Gerätename darf keine Unterstriche beinhalten und sollte (da ja gesprochen) möglichst einfach sein.

Ich werde mich mal am Wochenende daran setzen und noch einen Check einbauen und ggfs. wie in meinem anderen Beitrag beschrieben falls nicht vorhanden Siri nochmal nachfragen lassen.

Viele Grüße
Ludwig

poeppe

Hallo,
vielen Dank für die gute Anleitung, leider habe ich noch ein Problem damit SiriProxy automatisch zu starten. Ich habe zwar schon ein paar Sachen ausprobiert die ich bei Google gefunden habe aber da scheitert es bei mir dann an den Linux Kenntnissen. Startet ihr SiriProxy immer manuell oder automatisch (wie?)? Danke schon mal vorab für helfende Worte ;)

Zum Thema Plugin bin ich noch auf das Homematic Siriproxy Plugin gestoßen: https://github.com/hobbyquaker/siriproxy-homematic . Sicher ganz interessant sich das mal zum besseren Verständnis auch anzuschauen.

Netior

Hallo RBpi

Herzlichen Dank für die tolle Anleitung!
Eine Frage: Hast du auch schon Werte über telnet abgefragt?
Ich bekomme den Wert zurück, aber die Telnet session endet dann immer im timeout.

Hattest du das Problem auch oder war bei dir di Kommunikation zwischen Siri und FHEM nur einseitig?

mfg

Netior


Netior

Hallo Markus

Hab mittlerweile Siri und fhem auf einem RPi laufen.
Hat du mal Zustände oder Variabeln von FHEM holen lassen, so dass Siri diese zurückgibt?
Per Telnet hats schlussendlich geklappt. Aber habe keine Ahnung wie man das mit dem systemaufruf bewerkstellingen kann.
Wär das dan auch mit ReadingValue wie mit telnet?

Mfg

Netior

Atze

weiss net ob es das ist was du willst. ich frage z.b. mein S300TH so ab:


...
listen_for(/wie ist das raumklima/i) { show_temperature }  
...
def show_temperature
    say "Die Klimawerte werden überprüft"    
    Thread.new {          
       ret = `/opt/fhem/fhem.pl localhost:7072 'getstate tmp_EDV'`
       tmp = ret.split(' ').first.delete('T,:').sub(/\./,',')
       hum = ret.split(' ').last.delete('H,:').sub(/\./,',')
       say "Derzeit sind im Büro #{tmp} Grad und #{hum} Prozent Luftfeuchte."
       request_completed
    }
  end


geht bestimmt noch eleganter aber es geht.
FHEM 5.8 , RPi 2 / CUL 3.2 / JEELINKnano - PCA301 / nanoCUL a-culfw 1.05.03
HMS: rm1002, s300th / FHT: fht8v-3, fht80tf
FS20: fs20st, fs20sm8, fs20s8m, fs20rsu, fs20rbm, fs20pce, fs20pcs, fs20ue1, fs20irp2, fs20dwt, fs20rpt-3, fs20str-2, fs20kse
IT: ITDM-250, ITLS-16, ITW-852, IT-1500
G-Data Milight

Netior

Hi Atze

Danke für den Tipp. Jetzt klappts!

Gruss

Ascoban

Wie kann ich das Programmieren das siri sich ein bisschen zeit lässt zwischen befehlen.
Ich habe sonnst das problem das fhem das nicht schaltet.

beispiel:

    listen_for /gute nacht siri/i do
        say "gute nacht mein meister ich schalte dann mal alles aus..."
        system "/opt/fhem/fhem.pl localhost:7072 'set Schrank off' &"
        system "/opt/fhem/fhem.pl localhost:7072 'set Aquarium off' &"
        request_completed

Atze

schau mal ob dich das weiter bringt....
http://stackoverflow.com/questions/16275295/how-to-delay-say-actions-in-siri-proxy-plugin

oder in fhem direkt mit z.b. sleep, definierst dir eine gruppe z.b. "alles_aus" den du im siriproxy einmal aufrufst....
FHEM 5.8 , RPi 2 / CUL 3.2 / JEELINKnano - PCA301 / nanoCUL a-culfw 1.05.03
HMS: rm1002, s300th / FHT: fht8v-3, fht80tf
FS20: fs20st, fs20sm8, fs20s8m, fs20rsu, fs20rbm, fs20pce, fs20pcs, fs20ue1, fs20irp2, fs20dwt, fs20rpt-3, fs20str-2, fs20kse
IT: ITDM-250, ITLS-16, ITW-852, IT-1500
G-Data Milight

Ascoban

wenn ich eine Gruppe definiere habe ich das selbe Problem das er die befehle zu schnell ab arbeitet.
ich benutze allerdings auch nur einen einfachen Funksender am gpio port

BenWend

Hallo,

vielen Dank für dieses super Tutorial! Es hat alles wunderbar und auf Anhieb geklappt.

Ich hatte lediglich ein Problem mit dem Starten des Siriproxys: Zwar konnte ich per Putty den Siriproxy starten, jedoch wurde der Siriproxy jedesmal beendet, wenn ich Putty geschlossen habe. Nach ein wenig googeln fand ich diese Lösung, die (bisher) sehr gut funktioniert:

https://gist.github.com/earlcochran/1566193/raw/61b4cbb7be00de08710fa629d1627db518ec24b7/runsp.sh

# Run with rvmsudo sh runsp.sh {start|keepalive|stop}

Alle meine Lampen sind jetzt eingebunden, mein AV/Receiver lässt sich ebenfalls ein- und ausschalten sowie die Alarmanlage scharf bzw. unscharf schalten. Das einzige was man jetzt nicht mehr tun sollte, ist Siri zu beleidigen. Sie beleidigt dann nämlich zurück :oP

Schöne Grüße

Ben

sTaN

Hallo Zusammen!

Ich habe mich auch endlich mal auf den Siriproxy gestürzt. Aktuell läuft er dank der super Anleitung unter Ubuntu in einer VM auf meinem Mac Air. Ich hätte ihn zwar auch auf dem Mac direkt installieren können aber so kann ich mehr rumspielen. Ziel ist dann ein Raspberry Pi. Allerdings auch noch unter 1.9.3 (gibt ja schon 2.0.0). Hat da schon jemand ein Update auf ruby 2.0.0 gemacht?

Ein paar weitere Fragen zu den FHEM Befehlen habe ich dennoch. Habt ihr die siriproxy-examples.rb einfach bearbeitet oder eine neue angelegt? Wenn ja, gibt es damit Probleme oder einfach z.B. siriproxy-fhem.rb anlegen, anschließend sirirpoxy bundle und server ausführen, oder ist es dann doch nicht so einfach?

Wäre es vielleicht möglich hier oder im Wiki die Dateien zu posten, um ein paar Beispiele und Anregungen zu haben?

Kann ich ebenfalls die fhem.pl nutzen oder muss ich den Umweg über telnet gehen (FHEM läuft auf FritzBox 7390 und Proxy wie gesagt in einer VM auf dem Mac)

Ansonsten weiter so und danke für die gute Vorarbeiten!

Gruß sTaN
Raspberry Pi 3
2 x CUL CC1101-USB-Lite 868MHz
FS20 Komponenten, Philips HUE, Alexa-Fhem, MAX! Geräte, homebridge, harmony, Unifi, FirtzBox, MQTT, Aurora, Denon, Sonos, TabletUI, CALENDAR, EGPM2LAN, Pushover

sTaN

Ok meine Frage, ob ich die fhem.pl nutzen kann, wenn der Siriproxy in einer VM und FHEM auf der FritzBox läuft, hat sich soeben mit nein beantwortet:

[Info - Plugin Manager] Processing 'Schalte das TV Licht aus'
[Info - Plugin Manager] Processing plugin Example
[Info - Plugin Manager] Matches (?i-mx:Schalte das TV Licht aus)
[Info - Plugin Manager] Applicable states:
[Info - Plugin Manager] Current state:
[Info - Plugin Manager] Matches, executing block
[Info - Plugin Manager] Say: Ok, ich schalte das Licht am Fernseher aus...
[Info - Plugin Manager] Sending Request Completed
sh: 1: /usr/bin/fhem.pl: not found


Oder gibt es eine Möglichkeit die Datei entfernt anzusprechen? Aktuell habe ich ans Ende der siriproxy-example.rb folgende Zeilen eingefügrt:

 #FHEM Befehle
  listen_for /Schalte das TV Licht ein/i do
       say "Ok, ich schalte das Licht am Fernseher ein..."
       system "/usr/bin/fhem.pl fritz.box:7072 'set TVBacklight on' &"
       request_completed
   end

   listen_for /Schalte das TV Licht aus/i do
       say "Ok, ich schalte das Licht am Fernseher aus..."
       system "/usr/bin/fhem.pl fritz.box:7072 'set TVBacklight off' &"
       request_completed
   end


Aber auch klar, da die Datei auf dem entfernten System liegt. Gibt es dafür einen Befehl um vom extern via telnet auf die Datei zuzugreifen, ohne die etwas umständlichere Methode von RBpi?

Gruß
Raspberry Pi 3
2 x CUL CC1101-USB-Lite 868MHz
FS20 Komponenten, Philips HUE, Alexa-Fhem, MAX! Geräte, homebridge, harmony, Unifi, FirtzBox, MQTT, Aurora, Denon, Sonos, TabletUI, CALENDAR, EGPM2LAN, Pushover