J.A.R.V.I.S inspired announcement/greeting for Home Assistant

Almost a year ago, I wrote about my J.A.R.V.I.S inspired morning wake-up announcement with CastleOS. Since then, I’ve moved to Home Assistant and sadly, lost my morning announcements.

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.

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.

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

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.

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.

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.

When that’s executed we should now hear something like this.

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

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.

  • Stock prices using the Yahoo Finance component
  • Pricing and ETA information from Uber
  • The next event on your Google Calendar
  • The open/closed status of a door (like a Garage Door)
  • The commute time to get to work using Google Maps

 

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.

 

So, let’s setup the new sensors we’ll need first.

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.

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

 

The Latest In Your Inbox

Enter your email address below to receive my latest blog posts and videos about Home Automation in your Inbox

 

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.

When creating your own templates, be sure to check your syntax with the Templates section inside Home Assistant. It’s the second last option on the menu (near the help/about icon).

Recommended Posts
  • rpitera

    Nice work, as always Phil! This not only gave me some ideas, but it also cleared up the use of if, then, else in automations for me. Bookmarking this for later research!

    • Thanks Rob! Glad you found it helpful πŸ™‚

      • Craig

        Hi There Phil, what model sonos speakers are you using? Thanks Craig

        • Hey Craig,

          I’m using a bunch of Sonos Play 1 speakers. I’ve also got a Sonos One in the kitchen to get Alexa in there as well. For the TV, I’m using a Sonos Playbar with the Sonos Sub.

          There is also the Play3 and Play5, however I’m in an apartment. From what I’ve read online, others say that two Play 1 speakers are better than a single Play 3 speaker. I can’t justify the Play5 for such a small house (and the price) at the moment.

  • IKROWNI

    Lots of great information in this tutorial. Great job!

  • Sid Sapphire

    Great tutorial for newbies. Helped a lot in clearing some stuff.

  • Joe Stan

    I am getting the following error: homeassistant.bootstrap: Invalid config for [homeassistant]: [script] is an invalid option for [homeassistant]. Check: homeassistant->script. (See /home/homeassistant/.homeassistant/configuration.yaml:2).

    Please keep in mind this is a fresh install – All-in-one

  • Jimmy Budd

    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.

    Any ideas?

    • Did you change data to data_template?

      Mind posting your YAML?

      • Jimmy Budd

        I did change it to data template. My YAML is shown below:

        #Attempt at Good Morning Message
        script:
        jarvis_script:
        alias: Jarvis Greeting
        sequence:
        – service: tts.google_say
        data_template:
        entity_id: media_player.Living_room_Home
        message: >
        Good morning. It’s currently {{states.sensor.dark_sky_summary.state}}

        • Jimmy Budd
          • Strange. Nothing jumps out at me as to why it wouldn’t work for you.

            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.

            I’m wondering if your message gets too long, and the TTS engine (Google I assume?) can’t render it.

  • Johnny Karlberg

    too bad the report are in english and not swedish

  • will parker

    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.

    Onkyo error:
    ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
    Traceback (most recent call last):
    File “/usr/lib/python3.4/asyncio/tasks.py”, line 233, in _step
    result = coro.throw(exc)
    File “/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/core.py”, line 1025, in _event_to_service_call
    yield from service_handler.func(service_call)
    File “/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/__init__.py”, line 409, in async_service_handler
    yield from getattr(player, method[‘method’])(**params)
    File “/usr/lib/python3.4/asyncio/futures.py”, line 388, in __iter__
    yield self # This tells Task to wait for completion.
    File “/usr/lib/python3.4/asyncio/tasks.py”, line 286, in _wakeup
    value = future.result()
    File “/usr/lib/python3.4/asyncio/futures.py”, line 277, in result
    raise self._exception
    File “/usr/lib/python3.4/concurrent/futures/thread.py”, line 54, in run
    result = self.fn(*self.args, **self.kwargs)
    File “/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/__init__.py”, line 709, in play_media
    raise NotImplementedError()
    NotImplementedError

    Bose error:
    WARNING (Thread-4) [homeassistant.components.media_player.soundtouch] Unable to find preset with id https://***********************.duckdns.org:8123/api/tts_proxy/e1709264400d158c4f9bd8656a78232407667a0a_en_-_google.mp3

    • Hey Will,

      I am using Sonos speakers.

      From your traceback it looks like its a problem not being able to find the MP3 file. Can you load the MP3 file from your browser at https://***********************.duckdns.org:8123/api/tts_proxy/e1709264400d158c4f9bd8656a78232407667a0a_en_-_google.mp3 ?

      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.

Start typing and press Enter to search