openHAB :: Sprachausgabe auf einem Raspberry

30Mit Hilfe von TTS-Diensten ist es uns möglich, gesprochenen Text über an den Raspberry angeschlossene Lautsprecher ausgeben zu lassen. Wir nutzen dazu einen TextToSpeech-Modul, das uns eine API für die Kommandozeile bietet. Die Nachteile hieran sind natürlich, dass die Himbeere eine permanente Verbindung zum Internet benötigt und die zu sprechenden Sätze zum Anbieter gesendet werden. Die Umsetzung und Integration in openHAB zeigt dieser Artikel.

Verfügbare Artikel zu openHAB

little_blue_dot Einleitunglittle_blue_dot Einbinden der Internetgeschwindigkeitlittle_blue_dot RFID-Lesegerät einbinden
little_blue_dot Installationlittle_blue_dot Präsenzerkennung via Bluetooth und Pinglittle_blue_dot Einbinden von DS18B20-Sensoren
little_blue_dot Konfigurationlittle_blue_dot Kleines Netzwerkmonitoringlittle_blue_dot ical-Abfallkalender einbinden
little_blue_dot Reverse-Proxy für OpenHABlittle_blue_dot Einbinden von LG-Fernsehern [Update]little_blue_dot openHAB als Wecker
little_blue_dot Datenspeicherung und Statistikenlittle_blue_dot Einbinden Schaltern und Kontaktenlittle_blue_dot Einbinden von Bewegungssensoren
little_blue_dot Regeln planen und konfigurierenlittle_blue_dot Einbinden von Funksteckdosen (433 MHz)little_blue_dot Einbinden einer FritzBox
little_blue_dot Einbinden von USB-Steckdosenleisten (SIS-PMS)little_blue_dot Infrarotgesteuerte Geräte einbindenlittle_blue_dot Sprachausgabe auf einem Raspberry
little_blue_dot Einbinden von Temperatursensorenlittle_blue_dot Steuerung mit NFC-Tagslittle_blue_dot Schaltbare Steckdosenleiste mit Relais
little_blue_dot Externer Zugriff mit my.openhab

 

 

 

System aktualisieren

Zunächst aktualisieren wir unseren Raspberry mit dem bekannten

apt-get update && apt-get upgrade

 

Audio testen

Wir installieren die notwendigen Pakete, um Audio abspielen zu können mit:

apt-get install mplayer mplayer-gui alsa-base alsa-utils

 

Anschließend lassen wir den Raspberry das Soundmodul beim Booten starten:

echo 'snd-bcm2835' >> /etc/modules

 

Nun starten wir unser System neu:

reboot

 

Zum Testen besorgen wir uns zunächst irgendeine .wav-Datei und speichern diese auf unserem Raspberry:

mkdir -p /scripts/audio
cd /scripts/audio
wget -O testeins.wav http://www.ringelkater.de/Sounds/3aeusserungen_westfalen/GEJIDEL.WAV
aplay testeins.wav

Konnten wir den Herrn mit dem westfälischen Akzent vernehmen, haben wir den ersten Schritt geschafft.

 

2

 

 

Lautstärke erhöhen

Anschließend erhöhen wir die Systemlautstärke des Raspberrys auf 100%. Dafür eignet sich am besten das Programm alsamixer. Dieses starten wir in der Befehlszeile mit

alsamixer

alsamixer

Mit den Hoch- und Runter-Pfeiltasten erhöhen bzw. verringern wir die Lautstärke und „ESC“ beendet das Programm. Die getroffene Einstellung wird mittels

alsactl store

(ausgeführt als Nutzer root) gespeichert.

 

Anmelden bei einem TTS-Dienst

Bisher habe ich für die Sprachausgabe die TTS-Engine von Google genutzt. Diese wurde nun mit einem Captcha versehen, so dass diese für unsere Zwecke nicht mehr sinnvoll einzusetzen ist. Daher weichen wir auf einen anderen Anbieter aus. Nach einer kurzen Registrierung bei voicerss.org erhalten wir einen API-Schlüssel, den wir uns für unsere Zwecke speichern. Wie der Dienst von VoiceRSS einzusetzen ist, zeigt die kurze, aber verständliche Dokumentation unter http://www.voicerss.org/api/documentation.aspx. Es ergibt sich dementsprechend eine URL, die wie folgt aufgebaut ist:

http://api.voicerss.org/?key=DEIN_API_KEY&f=22khz_16bit_mono&hl=de-de&src=Hallo

Hier muss natürlich der nach der Registrierung erhaltene Key eingetragen werden.

 

 

TTS-Script erstellen

Nun erstellen wir ein Script, dass unsere Texte mit Hilfe vom TTS-Dienst von VoiceRSS vorliest.

nano /scripts/tts.sh

 

Wir kopieren das folgende Script in die neu erstellte Datei:

#!/bin/bash
/usr/bin/amixer cset numid=1 $2%

if [ -n "$3" ] ; then
    /usr/bin/aplay /scripts/audio/$3.wav &> /dev/null
fi

INPUT=$1
STRINGNUM=0
ary=($INPUT)

for key in "${!ary[@]}" ; do
    SHORTTMP[$STRINGNUM]="${SHORTTMP[$STRINGNUM]} ${ary[$key]}"
    LENGTH=$(echo ${#SHORTTMP[$STRINGNUM]})

    if [[ "$LENGTH" -lt "100" ]]; then
        SHORT[$STRINGNUM]=${SHORTTMP[$STRINGNUM]}
    else
        STRINGNUM=$(($STRINGNUM+1))
        SHORTTMP[$STRINGNUM]="${ary[$key]}"
        SHORT[$STRINGNUM]="${ary[$key]}"
    fi
done

for key in "${!SHORT[@]}" ; do
    say() { local IFS=+;/usr/bin/mplayer -ao alsa -really-quiet -noconsolecontrols "http://api.voicerss.org/?key=DEIN_API_KEY&f=22khz_16bit_mono&hl=de-de&src=${SHORT[$key]}"; }
    say $*
done

 

Wir erlauben die Ausführung des Scripts mit

chmod +x /scripts/tts.sh

 

und testen dieses sogleich:

/scripts/tts.sh "dies ist ein test" 100

Das Script erlaubt die dynamische Angabe der auszugebenden Lautstärke. Diese geben wir in diesem Aufruf mit 100% an. Zusätzlich kann vor dem vorgelesenen Text eine WAV-Datei abgespielt werden, die im Ordner „/scripts/audio“ erwartet wird. Z.B.:

/scripts/tts.sh "dies ist ein test" 100 kuckuck

…spielt zuvor die Datei „/scripts/audio/kuckuck.wav“ ab und liest anschließend den Text „dies ist ein test“ mit der Lautstärke 100% vor.

 

Integration in openHAB

Auf unserem Server, auf dem openHAB läuft, erstellen wir ein weiteres Script, um Texte remote auf dem Raspberry vorlesen zu lassen:

nano /scripts/vorlesen.sh

 

Das Script wird mit folgenden Inhalt befüllt:

#!/bin/bash
/usr/bin/ssh -i /scripts/.ssh/id_rsa root@192.168.1.$1 "/scripts/tts.sh \"$2\" $3 $4" &> /dev/null

 

Wir erlauben die Ausführung des Scripts durch

chmod +x /scripts/vorlesen.sh

und übertragen den Besitz an „openhab“ durch

chown openhab: /scripts/vorlesen.sh

 

Nun definieren wir ein neues Item, um in der openHAB-Sitemap die Lautstärke einstellen zu können, mit der die Texte vorgelesen werden:

Number BOXEN_EZ_VOL "Lautstärke [%.1f %%]"

 

Das neue Item binden wir in der Sitemap ein:

Slider item=BOXEN_EZ_VOL

 

4

 

 

Die Lautsprecher selbst sind an einem 433-MHz Sender angeschlossen, so dass diese nicht permanent eingeschaltet sein müssen:

Switch BOXEN_EZ <speaker> (grp_BOXEN) { exec=">[ON:/scripts/fsd.sh 10011 4 1] >[OFF:/scripts/fsd.sh 10011 4 0]" }

Die Steuerung von 433MHz-Geräten wird in diesem Beitrag und die Integration dieser in openHAB in diesem Beitrag beschrieben.

 

Eine praktische Anwendung findet beispielsweise als Regel in openHAB statt. Morgens lasse ich mich bei der zum Trödeln einladenden Tasse Kaffee gerne daran erinnern, dass ich mich auf den Weg zur Arbeit machen sollte. Dazu erstellen wir einen neuen Regelblock, der so strukturiert sein könnte:

rule "Morgens zur Maloche"
when
    Time cron "0 40 06 * * ?"
then
    executeCommandLine("/scripts/vorlesen.sh@@236@@Es wird langsam Zeit, zur Arbeit aufzubrechen.@@" + BOXEN_EZ_VOL.state + "@@clock", 2000)
end

Morgens um 06:40 Uhr wird auf dem Raspberry mit der IP „192.168.1.236“ der Ton „/scripts/audio/clock.wav“ abgespielt und anschließend der definierte Text vorgelesen. Die Lautstärke entspricht der in der Sitemap eingestellten (item: BOXEN_EZ_VOL). Die Angabe eines vorab abgespielten Tons ist dabei optional. Die doppelten @-Zeichen stehen in diesem Aufruf für ein Leerzeichen zwischen den Attributen.

 

Als weiteres Beispiel konstruieren wir uns eine digitale Kuckucksuhr. Zunächst erstellen wir auf dem openHAB-Server ein weiteres Script:

#!/bin/bash
#Script: /scripts/stunde.sh

/usr/bin/ssh -i /scripts/.ssh/id_rsa root@192.168.1.$1 '/usr/bin/aplay /scripts/audio/kuckuck.wav &> /dev/null && /scripts/tts.sh "Es ist $(date +%H) Uhr" 100 &> /dev/null'

…und erstellen eine neue openHAB-Regel:

 

rule "Kuckuck"
when
    Time cron "0 00 * * * ?"
then
    if(BOXEN_EZ.state == OFF) {
        sendCommand(BOXEN_EZ, ON)
        Thread::sleep(2000)
        executeCommandLine("/scripts/stunde.sh@@236", 2000)
        Thread::sleep(10000)
        sendCommand(BOXEN_EZ, OFF)
    }
    if(BOXEN_EZ.state == ON) {
        executeCommandLine("/scripts/stunde.sh@@236", 2000)
    }
end

Diese Regel führt stündlich das lokale Script „/scripts/stunde.sh“ aus, welches wiederum die Audiodatei „/scripts/audio/kuckuck.wav“ auf dem Raspberry mit der IP „192.168.1.236“ abspielt und anschließend die Stunde vorliest. Zusätzlich prüft diese Regel vorab, ob die Boxen im Esszimmer eingeschaltet sind oder nicht. Wenn nicht, werden diese für die Zeit der Aktion ein- und anschließend wieder ausgeschaltet.

Nun ist die eigene Phantasie gefragt. Es könnten beispielsweise Warnungen ausgegeben werden, wenn irgendein Wasserstand zu niedrig ist oder eine Temperatur einen Wert über-/unterschreitet. Selbst eine kleine „Alarmanlage“ (in Anführungszeichen!) könnte so umgesetzt werden.