Wednesday, 5 February 2025

Home Assistant: Response to Google Home Query With Web Data

This example creates an automation, which uses configuration data from a currently playing media stream to acquire a what's playing response, then broadcasts that response back to the user via one or more google smart speakers.

Note that it is not currently (February 2025) possible to work out which speaker raised the actual request when processing commands with Home Assistant; and it is also not possible to respond on a speaker without announcing the response as a "broadcast message".

This method does, however, allow the response to temporarily reduce the volume of playing media and restore it after the message has been played.

There are 4 Steps required:

1. Create a rest_command by editing configuration.yaml

2. Create a Home Assistant automation, which will perform the actual sequence, calling the rest_command when json information needs to be retrieved from a web resource.

3. Create a Home Assistant Script, which will be used by Google Home to trigger the automation.

4. Create a Google Home Automation to trigger the script.


Step 1: Create a rest_command

Edit the configuration.yaml file, and add an include line for a rest_command.yaml file.

$ sudo vi configuration.yaml

...

rest_command: !include rest_command.yaml

Note that there is no indentation
Now create a rest_command.yaml file, and add the contents as follows:

$ vi rest_command.yaml

  fetch:
    url: "{{ url }}"
    method: GET

Note that the indentation is important, i.e.:

fetch:
url: "{{ url }}"
method: GET

The above example is a generic one (works for any website).  It may make things more readable / make things more maintainable if multiple entries are used for different information sources, for example:
  recipe_json:
    url: "https://dummyjson.com/recipes/{{ index }}"
    method: GET
In the above example, the 'index' variable will be used to retrieve the requested recipe.

Once the configuration.yaml and rest_command.yaml files have been created, select "Developer Tools / YAML / Check Configuration", and then "Restart" (if everything checks out OK).


Step 2: Create a Home Assistant automation

Create a new automation with Settings / Automations / Create Automation, and edit as YAML, and paste in the code below:

alias: "Automation: Recipe Information"
description: ""
triggers: []
conditions: []
actions:
  - action: rest_command.fetch
    data:
      url: https://dummyjson.com/recipes/1
    metadata: {}
    response_variable: json_response
  - action: notify.google_assistant_sdk
    metadata: {}
    data:
      message: Recipe for {{ json_response['name'] }} has {{ json_response['caloriesPerServing'] }} calories per serving
      target: my speaker
mode: single

The code accesses the dummyjson.com/recipes/1 website, and downloads the json output.  The actual output data is stored in the json_response variable as part of the first action.

The second action generates a notification message (broadcast) to the speaker called "My Speaker" extracting information from the json response to build up the string.

Select the automation and then 'Settings' from the ... menu, and ensure that a meaningful Entity ID is chosen - in this case, automation.recipe_information has been selected.  This is the handle by which the automation can be programmatically be launched.


You can perform a test run of this script by selecting "Run Actions" which is found in the ... menu for the automation entry, and when run, you should hear the speaker saying "Broadcast Message: Recipe for Classic Margherita Pizza has 300 calories per serving".

Presently (February 2025), there is no known way to send the message without the "Broadcast Message" prefix. There is also no known way of working out which speaker the request actually came from.  Finally, the ability to speak requests with parameters was removed by Google a couple of years ago.

Step 3: Create a Home Assistant Script

Now the Google Home application can't launch a Home Assistant automation, but it can launch a script, (it thinks the script is a scene) and the script in turn can kick off the automation.

Select Settings / Automation and Scenes / Scripts / Create Script, and edit as YAML, and paste in the code below:
alias: "HaScript: Recipe Information"
description: ""
sequence:
  - action: automation.trigger
    metadata: {}
    data:
      skip_condition: false
    target:
      entity_id: automation.recipe_information

Again, you can select the ... against the script and run it, and the speaker should tell you about the recipe again.


Step 4: Create a Google Home Automation

Finally, if you say "Sync My Devices" on your smart speaker, you should then be able to go into the Google Home app, and create a new Automation:
When I say to my Assistant: "Recipe Information"
Select Scene: HaScript: Recipe Information

Now when you say "Recipe Information",  the speaker called "My Speaker" will say "Broadcast Message: Recipe for Classic Margherita Pizza has 300 calories per serving"

What's Next

This is a relatively trivial example, but scripts can be performed using resources from any website, along with any entity resource already available within home assistant.  An example idea:
Triggered automation fires at 6pm:
  If the user is at home - checking {{states('sensor.myphone_geocoded_location')}}
    Fetch the horoscope of the day - using rest_command.fetch_horoscope
    And broadcast the horoscope on the bedroom speaker - using notify.googleassistant_sdk
    And also send the horoscope to the user - using notify.mobile_app_myphone