Google Assistant on Raspberry | Part 2: Custom actions

Words
562
Reading
3 min
Listen
Play
8y

google assistant.jpg

What Will I Learn?

  • How to create custom actions
  • How to connect Steemit API with Google Assistant
  • How to connect Coin Market Cap API with Google Assistant
  • How to control Smart Home devices with Google Assistant

Requirements

Difficulty

Intermediate

Already existing custom actions

  • Open terminal on your Raspberry and go to the Assistant main file
sudo nano /home/pi/voice-recognizer-raspi/src/main.py

Scroll down until you will see three functions. These are pre-installed custom actions
2018-04-08-133556_1824x984_scrot.png

  • First function makes assistant say "Good bye!" and shutdowns Raspberry
def power_off_pi():
        aiy.audio.say('Good bye!')
        subprocess.call('sudo shutdown now', shell=True)
  • Second function makes assistant say "See you in a bit!" and reboots Raspberry
def reboot_pi():
        aiy.audio.say('See you in a bit!')
        subprocess.call('sudo reboot', shell=True)
  • Third function gets Raspberry IP address and makes assistant speak it
def say_ip():
        ip_address = subprocess.check_output("hostname -I | cut -d' ' -f1", shell=True)
        aiy.audio.say('My IP address is %s' % ip_address.decode('utf-8'))
  • A bit under them you will see trigger commands
    2018-04-08-133725_1824x984_scrot.png
    When Assistant recognizes one of them, it stops sending commands to the Google Assistant API and execute appropriate function.

You can create your own functions and trigger words as well. As an example I will show how to use Assistant with Smart Home devices, Steemit API to get your account balance and Coin Market Cap API to check Steem price.

Steemit API

  • Open new terminal window and install requests library.
pip install requests
  • Open Assistant main file
sudo nano /home/pi/voice-recognizer-raspi/src/main.py

There are a few implemented libraries at the top of the file. Add necessary libraries under them.

import requests
import json

2018-04-08-133048_1824x984_scrot.png

Requests library allows you to make https requests and json library is used to manage data from API calls.

  • Below the other custom functions define your own one
def steemit():
    url = requests.get('https://steemit.com/@neavvy.json')
    data = url.text
    result = json.loads(data)
    aiy.audio.say('Your account balance is %s' %result['user']['sbd_balance'])

1.png

  • def steemit(): - define function
  • url = requests.get('https://steemit.com/@neavvy.json') - create variable to store data from https request (replace "neavvy" with your nickname)
  • data = url.text - convert the acquired data into text
  • result = json.loads(data) - convert JSON data into string
  • aiy.audio.say('Your account balance is %s' %result['user']['sbd_balance']) - make Assistant say your account balance. %s is a token which is replaced by string variable containing your account balance which is passed after % symbol.

Here is an example output of user object of the Steemit API. If you want to get a particular data you need to use a path to it. For example path to sbd_balance is user -> sbd_balance and that's why we used result['user']['sbd_balance'] in our function.

{
"user": {
"id": 81544,
"name": "curie",
"owner": {
"weight_threshold": 1,
"account_auths": [],
"key_auths": [
    [
    "STM69WGR1yhUdKrnzwQLDPnXrW9kaAERwHze8Uvtw2ecgRqCEjWxT",
    1
    ]
]
},
"active": {
"weight_threshold": 1,
"account_auths": [],
"key_auths": [
    [
    "STM5GAbbS84ViMEouJL3LKcM8VZzPejn68AfPaYaLZZDdmy98kwU5",
    1
    ]
]
"proxy": "",
"last_owner_update": "1970-01-01T00:00:00",
"last_account_update": "2016-12-04T12:47:39",
"created": "2016-09-02T10:44:24",
"mined": false,
"owner_challenged": false,
"active_challenged": false,
"last_owner_proved": "1970-01-01T00:00:00",
"last_active_proved": "1970-01-01T00:00:00",
"recovery_account": "anonsteem",
"last_account_recovery": "1970-01-01T00:00:00",
"reset_account": "null",
"comment_count": 0,
"lifetime_vote_count": 0,
"post_count": 229,
"can_vote": true,
"voting_power": 5960,
"last_vote_time": "2017-02-13T19:21:12",
"balance": "1577.838 STEEM",
"savings_balance": "0.000 STEEM",
"sbd_balance": "0.000 SBD",
"sbd_seconds": "2918395506",
"sbd_seconds_last_update": "2017-02-12T15:58:36",
"sbd_last_interest_payment": "2017-02-05T13:45:09",
"savings_sbd_balance": "0.000 SBD",
"savings_sbd_seconds": "0",
"savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
"savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
"savings_withdraw_requests": 0,
"vesting_shares": "141562477.072664 VESTS",
"vesting_withdraw_rate": "12897472.658235 VESTS",
"next_vesting_withdrawal": "2017-02-15T04:53:06",
"withdrawn": "116077253924115",
"to_withdraw": "167667144557061",
"withdraw_routes": 0,
"curation_rewards": 448416,
"posting_rewards": 154104841,
"proxied_vsf_votes": [
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
],
"witnesses_voted_for": 1,
"average_bandwidth": 855531960,
"lifetime_bandwidth": "10797835000000",
"last_bandwidth_update": "2017-02-13T19:21:12",
"average_market_bandwidth": 127424482,
"last_market_bandwidth_update": "2017-02-12T15:39:57",
"last_post": "2017-02-13T18:00:51",
"last_root_post": "2017-02-13T18:00:51",
"post_bandwidth": 19271,
"new_average_bandwidth": "370418659068",
"new_average_market_bandwidth": "93913506382",
"vesting_balance": "0.000 STEEM",
"reputation": "330673789878881",
"transfer_history": [],
"market_history": [],
"post_history": [],
"vote_history": [],
"other_history": [],
"witness_votes": [
"curie"
],
"tags_usage": [],
"guest_bloggers": [],
"blog_category": {}
},
"status": "200"
} 
  • Below the other trigger commands create your own one
elif text == 'my account balance':
    assistant.stop_conversation()
    steemit()

3.png

  • elif text == 'my account balance': - check if you said given phrase
  • assistant.stop_conversation() - stop sending commands to the Google Assistant API
  • steemit() - execute our function

Coin Market Cap API

  • Define your function (you can get data about any other cryptocurrency by replacing for example "steem" with "bitcoin" in http address)
def price():
    url = requests.get('https://api.coinmarketcap.com/v1/ticker/steem/')
    data = url.json()
    for coin in data:
        aiy.audio.say('Steem price is %s USD' %coin['price_usd'])

2.png

  • def price(): - define function
  • url = requests.get('https://api.coinmarketcap.com/v1/ticker/steem/') - create variable to store data from https request
  • list = url.json() - get JSON data from https request
  • for coin in list: - create a for loop to get a particular data from the list
  • aiy.audio.say('Steem price is %s USD' %coin['price_usd']) - make assistant say Steem price. Note that we used %s reference again.

Here is an example output of the Coin Market Cap API. We wanted to get price_usd and that's why we used coin['price_usd'] path.

[
    {
        "id": "steem", 
        "name": "Steem", 
        "symbol": "STEEM", 
        "rank": "29", 
        "price_usd": "1.79616", 
        "price_btc": "0.00026681", 
        "24h_volume_usd": "2454660.0", 
        "market_cap_usd": "460090654.0", 
        "available_supply": "256152377.0", 
        "total_supply": "273126471.0", 
        "max_supply": null, 
        "percent_change_1h": "0.02", 
        "percent_change_24h": "-1.02", 
        "percent_change_7d": "-11.71", 
        "last_updated": "1523363646"
    }
]
  • Create your trigger command
elif text == 'price':
    assistant.stop_conversation()
    price()

4.png

It is very similar to the provious command. We only used a different phrase and function.

Smart home

If you have smart home devices and you are able to control them via https request you can also integrate them with your Assistant.

  • Define your function
def light_on():
     on = requests.get('url_to_your smart_home_action')
     on.json()

5.png

  • def light_on(): - define function
  • on = requests.get('url_to_your smart_home_action') - create variable with your action url
  • on.json() - execute action
  • Create your trigger command
elif text == 'turn on the light':
    assistant.stop_conversation()
    light_on()

6.png

Here is how it works:

Curriculum

Thank you for reading. Hope this tutorial will be helpful.



Posted on Utopian.io - Rewarding Open Source Contributors

Google Assistant on Raspberry | Part 2: Custom actions | Ecency