How to Update to the New Version of the Google AIY Project and Write Basic Mods

A new version of the Google AIY projects API was released in September. This is the version included in the Raspberry Pi image starting with aiyprojects-2017-09-11.img.

This version is a major rewrite so most of the original mods that had been developed no longer work.

This version does not use a main.py or action.py file.

The original version is still available on the Github repo under the master branch, the new version is available in the voicekit branch.

How to update

If you are starting fresh with a new install of the Raspberry Pi image follow the instructions on the aiyprojects site.

If you had the old version working and want to update to the new version I managed to do this by:

Cloning the new version in the /home/pi directory:

git clone -b voicekit https://github.com/google/aiyprojects-raspbian.git

This creates a new folder called aiyprojects-raspbian, the old version I had was in a folder called voice-recognizer-raspi I left that alone in case I wanted to go back to the old version.

How to start

Start the assistant by running one of the files in the src folder.

To start it automatically using systemctl you need to make your own systemd config file. There are some good instructions on the main aiyprojects page.

NOTE: If you were using the old version don’t forget to stop and disable the original voice-recognizer.service


sudo systemctl stop voice-recognizer.service
sudo systemctl disable voice-recognizer.service

The original version also used a service called status-led.service so you need to stop and disable this as well:


sudo systemctl stop status-led.service
sudo systemctl disable status-led.service

It took me a while to realise this was the reason the light was flickering when I first updated, 2 services were trying to interact with the led!

How to write your own mods

I used the assistant_library_with_local_commands_demo.py file as the basis of my mods, first make a copy of this file (keep the original so that you can refer back to it later if you want!), mine is called my_mods.py
I’ll use the example of adding the ability to change the volume of the assistant, this was included in the original version action.py but doesn’t seem to be in the new version.

This file is also available on Github.

Add keyword

To define the keyword look for the function process_event (starts with the line def process_event(assistant, event):)
In this function there is a section that looks like this:


    elif event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED and event.args:
        print('You said:', event.args['text'])
        text = event.args['text'].lower()
        if text == 'power off':
            assistant.stop_conversation()
            power_off_pi()
        elif text == 'reboot':
            assistant.stop_conversation()
            reboot_pi()
        elif text == 'ip address':
            assistant.stop_conversation()
            say_ip()

This is where custom keywords are recognised. To add your own follow the same format and add another elif after the line say_ip()

        elif text == 'volume up':
            assistant.stop_conversation()
            volume_up()
        elif text == 'volume down':
            assistant.stop_conversation()
            volume_down()

Tip! If you want to use part of the phrase in your command, for example a radio station you want to play use the format:

        elif 'radio' in text:
            assistant.stop_conversation()
            radio(text)

This will identify any phrase with the word radio in it and pass the whole phrase to the function you define.

Define the function

To define the functions volume_up and volume_down, to do this you need to enter the following *above* the process_event function

def volume(change):

    """Changes the volume and says the new level."""

    GET_VOLUME = r'amixer get Master | grep "Front Left:" | sed "s/.*\[\([0-9]\+\)%\].*/\1/"'
    SET_VOLUME = 'amixer -q set Master %d%%'

    res = subprocess.check_output(GET_VOLUME, shell=True).strip()
    try:
        logging.info("volume: %s", res)
        vol = int(res) + change
        vol = max(0, min(100, vol))
        subprocess.call(SET_VOLUME % vol, shell=True)
        aiy.audio.say('Volume at %d %%.' % vol)
    except (ValueError, subprocess.CalledProcessError):
        logging.exception("Error using amixer to adjust volume.")


def volume_up():
    volume(10)


def volume_down():
    volume(-10)

This actually adds 3 functions, the 2 functions called by the keywords volume_up and volume_down, these in turn call another function volume that actually changes the volume, most of the code in this is just copied from the original action.py. Doing it this way with a third function means we don’t have to repeat the volume change code, just tell it whether to change the volume up or down.

Another change from the original action.py is that instead of self.say() to get the box to say something the new version uses aiy.audio.say()

Restart the voice-recognizer service, use the service name you defined in your systemctl file!

sudo systemctl restart voice-recognizer.service

Check the logs for any issues

sudo journalctl -u voice-recognizer -f

Github

I am going to add the mods I’ve made using the new version to my Github fork under a voicekit branch.

Add a Comment

Your email address will not be published. Required fields are marked *