In December 2016, Home Assistant 0.35 added a new Text-to-Speech component, thanks to Pascal Vizeli. The new component allows Home Assistant to send text-to-speech processed by either Google Translate or VoiceRSS to compatible media players linked to Home Assistant.

So now I have the missing piece to the puzzle. Home Assistant can now speak to me via my Sonos speakers. Brilliant! What’s even better is because Home Assistant is so powerful, I don’t need to write any external windows applications or run a webserver. I’m going to use the information already in Home Assistant, which will make things faster, and I can do it all in YAML. That means there’s nothing else except for Home Assistant installed that you need.

Before I dive in though, I’ve decided I’m going to make my announcement as a Home Assistant script. You could skip the script bit and add the announcement directly to an automation if you wanted, but for testing it’s nice to have a button in Home Assistant we can call to make the announcement.

Initial Setup

Let’s start off by creating a simple script, which we can call from Home Assistant to trigger the Text-To-Speech compontent. I have my Home Assistant setup to include scripts from a folder, so my configuration.yaml file looks like this.

configuration.yaml

YAML

1

2

3

homeassistant:

script: !include_dir_named scripts

I have a folder named scripts, which I place all my scripts into separately. So, now let’s start off with a simple test script, which I’ll name jarvis_greeting.yaml.

jarvis_greeting.yaml

YAML

1

2

3

4

5

6

7

alias: Jarvis Greeting

sequence:

- service: tts.google_say

data:

entity_id: media_player.office

message: Hello from Home Assistant

Be sure to change the media_player to your desired media player’s entity ID. You can find that from the States button in Home Assistant.

When we restart Home Assistant, there should be an option for us to call this script in the UI. If you’ve disabled the default view, you’ll need to add the following to your groups.yaml file somewhere. I’ll just place it on the home screen for now

groups.yaml

YAML

1

2

3

4

5

6

7

default_view:

view: yes

entities:

-sun.sun

-group.people

-script.jarvis_greeting

Restart Home Assistant, and you should now see the following available in your Home Assistant UI.

Go ahead and press that activate button. When you do, you should hear Home Assistant say Hello from Home Assistant. If you don’t hear it, check you entered the right entity_id in the script, and check your Home Assistant log files for any errors.

So, now that we can hear Home Assistant, and can invoke our script for testing when we need to, let’s start adding some data into our announcement.

Adding Weather

To start off with, I want my announcement to have the same details as my original version for CastleOS. So, let’s use the current weather conditions, and the forecast for today. We can use Home Assistant Components for this. I’m going to use the DarkSky Weather component. Let’s start off with adjusting our configuration.yaml file with what that component needs.

configuration.yaml

YAML

1

2

3

4

5

6

7

8

9

10

11

12

homeassistant:

script: !include_dir_named scripts

sensor:

- platform: darksky

api_key: NOTTELLING

monitored_conditions:

-summary

-temperature

-hourly_summary

-temperature_max

The values you put in
monitored_conditions: are important, as we’ll need those in our script.

Now we’re going to use Templating. It can be a bit intimidating at first glance, but Home Assistant’s templating is very very powerful. First, we need to tell our script we’re going to be passing template data in our message, so let’s change our script like so.

jarvis_greeting.yaml

YAML

1

2

3

4

5

6

7

alias: Jarvis Greeting

sequence:

- service: tts.google_say

data_template:

entity_id: media_player.office

message: Hello from Home Assistant

See how we changed
data: to
data_template:? That little change will allow us to make our text-to-speech message dynamic when it is called. Now let’s add in our weather data, and original greeting.

Good morning. It’s currently mostly cloudy and 21 degrees in Melbourne. Today will be morning showers then mostly clear, with a high of 24 degrees.

So let’s take a quick look at what’s going on here.

{{states.sensor.dark_sky_summary.state}} allows us to access the Dark Sky Weather Components current state for the summary. Home Assistant will keep this updated for us. We do similar things for the temperature, except for the temperature we’re going to use
round so that temperatures like 27.1 just become 27. I’m also using
replace on the hourly summary, so that there isn’t a full stop/period added in the middle of the sentence we’re speaking.

So everything is working as intended. I think we could make this a little bit more advanced. What if we press the activate button in the evening or afternoon? We don’t want Home Assistant saying good morning to us. So, let’s use some more templating magic to make Home Assistant give us the right greeting for the right time of day.

We’re using some
if statements and asking Home Assistant what time of day it is. If it is before 12pm, then always say Good Morning. If it’s after 12pm but before 6pm, say Good Afternoon. Otherwise say Good Evening. This looks much better.

Automating The Announcement

Now that our script will say the right greeting for the right time of day, it’s time to tell Home Assistant when we would like the announcement to be made. There’s a ton of ways you could do this. First time someone gets home. When a light turns on or off. At the same time everyday. Home Assistant is powerful like that.

Once you’ve decided on your triggers, all you need to call this script in your automation is

automation.yaml

YAML

1

2

3

4

5

action:

- service: homeassistant.turn_on

entity_id: script.jarvis_greeting

Bonus Round: Door Status and Commute Time

Home Assistant has a great range of components we can use in our templates. Here’s some ideas for some things you might want in your announcement.

If you’re a bit advanced, you could also setup your own Template Sensors for other bits of information you might want to know. There’s a lot you could add into your own announcement, and everyone will be different. For me, I’m going to concentrate on the last two from my list, whether my Balcony door is open and the commute time to work.

For the Balcony door, I’m using a Fibaro Z-wave door and window sensor. It reports true or false to Home Assistant. Using a Template Sensor, I have setup the door to look like this in my Home Assistant.

Now that our configuration has changed, let’s restart Home Assistant so our new settings will load up. Once restarted, we should have access to new sensors which Home Assistant will keep updated for us.

Now I only want to know how long it will take me to get to work in the morning. So, let’s add some more to our message, in a condition block.

Now if it is a weekend, I don’t want to hear about the time to work. So let’s also check the day of the week. If it is a Saturday or Sunday, don’t tell me the commute time. We’ll once again use the Python
strftime() function. 0 is Sunday and 6 is Saturday.

So now we will only be told about our commute time if it is between Monday and Friday, and before 9am.

Finally, let’s add a message if my balcony door has been left open. You can apply the same logic for a garage door, or a lock etc. Thanks to the Template Sensor I created above, this should be pretty easy.

jarvis_greeting.yaml

YAML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

alias: Jarvis Greeting

sequence:

- service: tts.google_say

data_template:

entity_id: media_player.office

message: >

{%ifnow().strftime("%H")|int<12%}

Goodmorning.

{%elifnow().strftime("%H")|int<18%}

Goodafternoon.

{%else%}

Goodevening.

{%endif%}

It's currently {{states.sensor.dark_sky_summary.state}} and {{states.sensor.dark_sky_temperature.state|round}} degrees in Melbourne. Today will be {{states.sensor.dark_sky_hourly_summary.state|replace(".", "")}}, with a high of {{states.sensor.dark_sky_daily_high_temperature.state|round}} degrees.

The current drive to Sydney in traffic is {{states.sensor.google_travel_time__driving.attributes.duration_in_traffic}}

{% endif %}

{% if is_state('sensor.balcony_door_status', 'Open')%}

Headsup: The balcony door has been left open

{%endif%}

Tying it all in together, here’s the message we should now get in the morning if the balcony door is open.

Good morning. It’s currently mostly cloudy and 21 degrees in Melbourne. Today will be morning showers then mostly clear, with a high of 24 degrees. The current drive to Sydney is 8 hours 42 mins. Heads up: The balcony door has been left open

Where to from here?

This is just a small sample of what you can do with the new Text-to-Speech component combined with Home Assistant’s templating syntax. You can apply the same logic to notifications sent to your phone, or even responses sent back to your Amazon Echo if you’re using your own Alexa service.

If you want to see what else you can do with templating in Home Assistant, I recommend you check out the following pages on the Home Assistant website.

Although the tool says valid yaml, am i not suppose to use their conversion to UTF-8? Because I am back to getting another error:
homeassistant.bootstrap: Invalid config for [homeassistant]: [script] is an invalid option for [homeassistant]. Check: homeassistant->script. (See /home/homeassistant/.homeassistant/configuration.yaml:2).

When I try to run the initial Good morning script, where it is puling the sensor information from Darksky, mine never activates the speaker. To troubleshoot, I removed some of the references to the Dark sky, and just put the following code ” Good morning. It’s currently {{states.sensor.dark_sky_summary.state}} and ” . When it played over my device, it said the text portions, but skipped right over the sensor reference.

I put your message into the Templates section of Home Assistant, and it worked. Can you try doing that? It’s the second last icon in the Home Assistant menu on the left Hand Side. (Services, States, Events, Templates, Info). Just copy-and-paste your entire message into that, and see if any errors come up on the right hand side.

Hi Phil, I followed your guide on here, but my networked media players (Bose and Onkyo) don’t seem to like the mp3 file, which media player do you use?
I put the message into the template section and it likes it, just the media players throw back errors.

I’d also check your Home Assistant UI. If you click on your media player in the UI, there should be a TTS option at the bottom of the card. If you enter some text there, does it play on your speakers? It might be an issue with the TTS on those speakers, as opposed to your template.

will parker

Hi Phil,

Thanks for getting back to me so soon 🙂

I this problem was caused by my base url being incorrectly configured, I am using SSL and hadn’t changed the port, I changed the port and the mp3 will play, but still will not play via either media player, neither of them have a TTS option available on their cards.

There is still one issue though, when I play the mp3 file that is generated, the greeting is incorrect, it is not using the right one for the time of day, it is currently 18:32 and it is saying good morning.

Thanks,

Will

will parker

I’ve found the problem with the time, a typo on my template.
Still neither of the media players will accept the file though 🙁

I’m thinking I might be able to get the Onkyo to work as I can send media from my Plex server to it, a little tinkering to be done.

Thanks,

Will

Glauber

The problem is caused exactly about you say: base URL.
When you using TLS, you need to change your base URL just for your domain.
Example: test.no-ip.org instead test.no-ip.org:8123.
If you change it in your configuration.yaml, everything works as expected.

Glauber

will parker

Hi Glauber,
Unfortunately this does not work with my Bose Soundtouch or Onkyo receiver, it must be either a limitation of the media players themselves or the HA components used, I have tried without the port number but the Soundtouch component still comes back with preset not found, I have since found that the Soundtouch software has been updated to allow TTS via Samsung SmartThings hub, so it should, in theory, be possible to update the HA component to use the same protocol and enable TTS in HA, time will tell.

Will

Cyn Tottka

Great write up and explanation. Do you know anyone who’s got this working on a squeezebox?
I can see the message getting over to LMS, I just can’t hear it.

Thanks! Unfortunately I don’t have any experience with Squeeze box. Could it be that the volume on the player is set to zero or something? Or perhaps the filepath being sent to the player is incorrect. I had this issue when using DuckDNS, and had to update my configuration slightly.

Cyn Tottka

Thanks for your reply. Not using SSL or DNS and HASS acts like it’s playing just can’t hear it. I played the file thru my laptop browser and it’s perfect. I know when I solve this I will have a good laugh!

Oh absolutely! It’s a PITA discovering a problem you’ve been working on for hours had such a simple solution.

I’ve never used Squeez box so excuse me if I’m wrong. In HASS does it display as a media device? On my Sonos speakers I can click on them in the UI and get a dialog which allows me to control playback. At the bottom of the card is a TTS input box. If you see that as well, if you type a test message there and click play, does it play?

If it does then there might be something wrong with how you’re calling it in your automation. If it doesn’t play, then there might be an issue with TTS playing from HASS in general.

Cyn Tottka

SB shows as a media device & I can click and send text. Then I go over to LMS & see it playing over & over again until I stop it. Volume is way up put hear nothing. I just found a thread that says squeezeplay works but not squeezelite but haven’t finished reading to the bottom. Unfortunately if that’s the case I would have to convince my husband to change from Max2Play to something else. Might not be able to win that one.