Dynamic Alexa Flash Briefing via Routines

This has been something I’ve really wanted for a long time but it hasn’t been possible on the alexa devices until now. The idea is that I want to be able to have a flash briefing that pulls data from home assistant to be dynamic based on factors such as time and what Routine was requested from alexa. The solution is to add an input_boolean before the routine calls the flash briefing to let HA know which set of data to say.

Here is a screenshot of the alexa routine:

and here is the package code:

################################################################
## Packages / Alexa
################################################################

################################################
## Customize
################################################

homeassistant:
  customize:
    packages.alexa: &customize
      package: 'alexa'

    input_boolean.alexa_goodnight:
      friendly_name: "Alexa Goodnight"
      emulated_hue: true

    input_boolean.alexa_goodmorning:
      friendly_name: "Alexa Goodmorning"
      emulated_hue: true

################################################
## Alexa
################################################

input_boolean:
  alexa_goodnight:
    name: Alexa Goodnight
    initial: off
  alexa_goodmorning:
    name: Alexa Goodmorning
    initial: off


automation:
  - alias: Turn off alexa input booleans.
    trigger:
      platform: state
      entity_id: input_boolean.alexa_goodnight, input_boolean.alexa_goodmorning

      to: 'on'
      for:
        seconds: 10

    action:
      - service: homeassistant.turn_off
        data_template:
          entity_id: "{{ trigger.entity_id }}"

alexa:
  flash_briefings:
    alexa:
      - title: Flash Briefing
        text: >
            {% set greetings = [
                "I hope you slept well",
                "Rise and Shine",
                "Each morning we are born again. What we do today is what matters most.",
                "Morning is wonderful. Its only drawback is that it comes at such an inconvenient time of day.",
                "When you arise in the morning, think of what a precious privilege it is to be alive—to breathe, to think, to enjoy, to love—then make that day count!",
                "You’ve got to get up every morning with determination if you’re going to go to bed with satisfaction.",
                "The sun is new each morning" ]
            %}
            {% set cold_temperature = [
                "Burrrr it's cold outside",
                "Bundle Up",
                "Don't forget a jacket, it's cold outside",
                "It's going to be cold today" ]
            %}

            {% set perfect_temperature = [
                "Looks like a great temperature",
                "You may need a light jacket maybe, but it looks good",
                "I'm just an AI but it looks like a nice day" ]
            %}

            {% set hot_temperature = [
                "Wow it is hot outside",
                "Try not to get sunburned",
                "I hope you know someone with a swimming pool" ]
            %}


            {% if (states.sensor.dark_sky_apparent_temperature.state | int) <= 60 %}
                {% set weather_greeting = cold_temperature | random %}
            {% elif 60 < (states.sensor.dark_sky_apparent_temperature.state | int) <= 80 %}
                {% set weather_greeting = perfect_temperature | random %}
            {% elif (states.sensor.dark_sky_apparent_temperature.state | int) > 80 %}
                {% set weather_greeting = hot_temperature | random %}
            {% endif %}

            {% if states.input_boolean.alexa_goodmorning.state == 'on' %}
                Good Morning Keaton, {{ greetings | random}}. <break time="1s"/> In the weather you can expect it to be {{ states.sensor.dark_sky_hourly_summary.state  | lower }}
                with a current temperature of {{  states.sensor.dark_sky_apparent_temperature.state }} degrees. {{ weather_greeting }}
            {% elif states.input_boolean.alexa_goodnight.state == 'on' %}
                Goodnight Keaton, don't let the bed bugs bite.
            {% endif %}

Eventually I plan to program it to be even more dynamic, such as taking into account if I’ve just come home. I am also a university student and am working on adding to the goodnight message if I have forgotten to turn any any assignment. Let me know what you think and enjoy!

7 Likes

With this it doesn’t call the Alexa Flash Briefing?

This does require that you follow the instructions on this page: https://home-assistant.io/components/alexa/ under the flash briefing setup section and connect it up with your custom skill in alexa.

1 Like

@keatontaylor
thank you very much. Works great! I changed your automation so the morning boolean turns on in the morning and vice-versa. One question though; Alexa is reading the command as opposed to taking the break. Any ideas?

it is actually reading this aloud? Weird, certainly not the case for me. I’d make sure that you’re surrounding the actual text in single quotes not double quotes if that is an issue.

@keatontaylor
yes, it’s reading the “break time=“1s”/>” bit, including the greater than at the end. But not the less than at the beginning.

1 Like

Yeah I definitely think it has something to do with the double quotes…

Try going to http://home-assistant-ip:8123/api/alexa/flash_briefings/alexa?api_password=api_password and make sure the output has the break time stuff escaped.

[{“mainText”: “Good Morning Keaton, Rise and Shine. <break time=“1s”/> In the weather you can expect it to be mostly cloudy throughout the day. \n with a current temperature of 61.1 degrees. I’m just an AI but it looks like a nice day”, “titleText”: “Flash Briefing”, “uid”: “63c22c89-b4e2-4743-9fb4-a2e6a1aedfdc”, “updateDate”: “2017-11-12T01:19:34.0Z”}]

Here’s what mine looks like

@keatontaylor thank you.
I had to set up this as an intent, because I’m on HTTPS and could not configure flash_briefings. I just doesn’t connect.
Anyway, when I test the skill on the Amazon website, it doesnt read the break, but it does on the device.
very strange.

So in your case you’re not using routines?

No I couldn’t get it to work. When I tried to create it in the Amazon console, It kept telling me it can not connect to the URL.
So i adapted it to Intents.

Yeah, that is one of the annoying side effects of flash briefings. They require https and do not support lets encrypt certificates

yes, how did you set it up? The ssl.

My solution was to use amazon lambda microservice API gateway. Using most of the instructions provided here:

However, I changed the lambda code to simply relay the message from HA.

from __future__ import print_function
import json
import urllib
import datetime
def respond(err, res=None):
 return {
 'statusCode': '400' if err else '200',
 'body': json.dumps({
 "uid": res['uid'],
 "updateDate": res['updateDate'],
 "titleText": res['titleText'],
 "mainText": res['mainText'],
 "redirectionUrl": "HOME-ASSISTANT-URL" 
 }),
 'headers': {
 'Content-Type': 'application/json',
 },
}
def lambda_handler(event, context):
    print(event)
    print(context)
    response = urllib.request.urlopen('https://HOME-ASSISTANT-URL/api/alexa/flash_briefings/alexa?api_password=password')
    html=response.read()
    rawdata = json.loads(html)
    return respond(None, rawdata[0])
1 Like

Hi Keaton, finally got a AWS account
Looking for some guidance
on our py code i pressume I have to change this:

“redirectionUrl”: “HOME-ASSISTANT-URL”

and

response = urllib.request.urlopen(‘https://HOME-ASSISTANT-URL/api/alexa/flash_briefings/alexa?api_password=password’)

ok Keaton, so yes. Changed that and the Lambda works!
now how do I add it to the amazon briefing console. If I pick Flash Briefing Api, there’s only URL option.

In the lambda instance under Triggers you should see something like this:

The invoke URL is what you need to provide in the flash briefing url in the alexa developer console. Also, see the tutorial instructions provided above.

Thank you very much. Got it working now.

Hi Im trying to get this work but having an issue hopefully you guys dont mind helping me with. I was trying to setup the flash briefing but ran into the not connecting because of my lets encrpyt cert.

So I found this thread and created another lambda function hoping to go that route. Im getting this when I try and access the invoke url. {“message”: “Internal server error”}

my ha config is: (just testing with something simple first)

alexa:
  flash_briefings:
    test:
      - title: Who is watching Plex?
        text: "{{states('sensor.plex_template')}}"

This is the function code:

from __future__ import print_function
import json
import urllib
import datetime
def respond(err, res=None):
 return {
 'statusCode': '400' if err else '200',
 'body': json.dumps({
 "uid": res['uid'],
 "updateDate": res['updateDate'],
 "titleText": res['titleText'],
 "mainText": res['mainText'],
 "redirectionUrl": "https://xxx.xxx.xxx/" 
 }),
 'headers': {
 'Content-Type': 'application/json',
 },
}
def lambda_handler(event, context):
    print(event)
    print(context)
    response = urllib.request.urlopen('https://xxx.xxx.xxx/api/alexa/flash_briefings/alexa?api_password=stayout12!')
    html=response.read()
    rawdata = json.loads(html)
    return respond(None, rawdata[0])

Im thinking this might be wrong but idk what to use?
"redirectionUrl": "https://xxx.xxx.xxx/"

I would really like to add it as a flash briefing, its just not possible with lets encrpypt at all?

thank youuuu!!!

When I use the flash briefing way, if I take the url for the flash briefing and put it into a browser i get what amazon should be getting. So the hang up is due to the cert for sure?

thank you so much for sharing this. i feel this is much better than the official instruction. now it works with let’s encrypt SSL.