Skip to content

Text-to-Speech in openHAB

In my ongoing endeavor to improve our home, a while ago I added a notification when the washing machine and the dryer are finished. The notification is send to a Telegram channel. Over the summer vacation I added a number new ChromeCast Audio devices (Google no longer offers the Audio CC, if you need one get one now). One is placed in the kitchen. Not only can I listen to music while eating breakfast, I can also output notifications, by using the CC as an audio sink in openHAB.

To make that useful, I decided to use a Text-to-Speech system. openHAB offers a couple different TTS systems, however most of them need a cloud integration, and therefore a working Internet connection. The "Pico TTS" works standalone, and was my favorite choice for this implementation.



The default Debian installation in Raspbian does not have Pico TTS available, it's in the "non-free" repository. So I had to install that first. The Ansible Playbook:

- name: add Debian non-free signing key
    keyring: /etc/apt/trusted.gpg.d/debian-10.gpg
    state: present

- name: add Debian non-free repository
    repo: "deb {{ ansible_distribution_release }} non-free"
    filename: "non-free"
    state: present
    update_cache: yes
  register: non_free_repository

Then install the Pico TTS package:

- name: Install TTS packages
      - libttspico-utils
    state: present

And configure it in openHAB:

- name: Set TTS settings
    dest: /etc/openhab2/services/runtime.cfg
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
    state: "{{ item.state }}"
    - { regexp: '^#? ?org.eclipse.smarthome.voice:defaultTTS=', line: 'org.eclipse.smarthome.voice:defaultTTS=PicoTTS', state: present }
    - { regexp: '^#? ?org.eclipse.smarthome.voice:defaultVoice=', line: 'org.eclipse.smarthome.voice:defaultVoice=picotts:enUS', state: present }
    - restart openhab2


In my rules file for the washing machine and the dryer I expanded the notification a bit:

if (now.isAfter(now.withTimeAtStartOfDay.plusHours(6).plusMinutes(0)) && now.isBefore(now.withTimeAtStartOfDay.plusHours(23).plusMinutes(0))) {
    if ({{ CC_Kitchen_Audio|replace(':','_') }}_volume.state != 50) {
        {{ CC_Kitchen_Audio|replace(':','_') }}_volume.sendCommand(50)
    playSound("{{ CC_Kitchen_Audio }}", "computerbeep_55.mp3")
    say("Washing machine is finished", "picotts:enUS", "{{ CC_Kitchen_Audio }}")

The "{{ CC_Kitchen_Audio }}" is replaced by Ansible with the actual details of the ChromeCast. I described the details in this blog posting.

The "say()" command accepts 3 parameters:

  • The text
  • The language (US english here)
  • The audio sink (the ChromeCast)

Before the text is spoken, I also output a short beep, to raise attention and activate the ChromeCast. And I set the volume to 50 percent if that is not yet the case.

Finally all of this only happens if the time is between 6 in the morning and 11 in the evening. Don't want the system to talk in the middle of the night, if someone might sleep in the next room.


No Trackbacks


Display comments as Linear | Threaded

No comments

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
Form options