Google Assistant SDKのアップデートに、デバイスアクションの実装というのがあります。
サンプルコードをのぞいてみるとなんとなくそれっぽい記述があったり、デバイス登録の手順で謎のキーワードが出てきたりしたので、なんとなく使えるのかな?というところから、実際にいじってみました。
準備
前の記事までの手順でVoice kitが使えるようになっている事とします。
また、サンプルコードは前の記事でコピー&編集したものを続けて使用します。
後述しますが、Voice HATにLEDを接続するため、LEDを準備してください。
デバイス登録の更新
既に登録されているデバイスの情報を更新し、デバイスが特定のアクションに反応するようにします。
まずデバイスモデルの情報を更新します。
(env) pi@raspberrypi:~/AIY-voice-kit-python $ googlesamples-assistant-devicetool register-model --manufacturer "Assistant SDK developer" --product-name "Assistant SDK light" --type LIGHT --model <model-name> --trait action.devices.traits.OnOff --trait action.devices.traits.Brightness --trait action.devices.traits.ColorTemperature
ここで出てくる--type
と--trait
の種類はGoogle Assistant SDKのドキュメントを参考に選択します。上記の例では、ライトのオンオフ・明るさ・色の調整をするオプションをつけていることになります。
コマンドを実行し、うまく更新されたら、念のため確認します。以下のような出力が得られるはずです。
(env) pi@raspberrypi:~/AIY-voice-kit-python $ googlesamples-assistant-devicetool list --model
Device Model Id: <model-name>
Project Id: <Project ID>
Device Type: action.devices.types.LIGHT
Trait action.devices.traits.Brightness
Trait action.devices.traits.ColorTemperature
Trait action.devices.traits.OnOff
確認ができたらデバイス情報を更新します。
(env) pi@raspberrypi:~/AIY-voice-kit-python $ googlesamples-assistant-devicetool register-device --device <device-id> --model <model-name> --client-type SERVICE
ここまでエラー無く行けばおそらく情報の更新は完了しています。
Voice HATにLEDをつなぐ
AIY ProjectのページにあるVoice HATのGPIOと、Voice kitに付属のマニュアルP.58を参考に、LEDをつなぎます。
今回はフルカラーLEDを使って、Servo0にLED赤、Servo1にLED緑、Servo2にLED青を接続しました。
サンプルコードの追加改造
デバイスアクションが実行された際にGPIOを直接たたいてLEDを光らせるようサンプルコードを改造します。
前の記事で編集したファイルを引き続き使用します。
PWMを使ったりすればよかったのかもですが、あくまでサンプルなのでかなり手抜きです、ご了承ください。
hotword.py
--- hotword.py.1 2018-02-21 02:42:00.071501759 +0900
+++ hotword.py 2018-02-22 03:59:04.228139279 +0900
@@ -21,6 +21,8 @@ import argparse
import os.path
import json
+import RPi.GPIO as GPIO
+
import google.auth.transport.requests
import google.oauth2.credentials
@@ -34,6 +36,10 @@ from google.assistant.library.file_helpe
DEVICE_API_URL = 'https://embeddedassistant.googleapis.com/v1alpha2'
+# GPIO Pin no.
+RED_PIN = 26
+GREEN_PIN = 6
+BLUE_PIN = 13
def process_device_actions(event, device_id):
if 'inputs' in event.args:
@@ -48,6 +54,30 @@ def process_device_actions(event, device
yield e['command'], e['params']
else:
yield e['command'], None
+ if e['command'] == 'action.devices.commands.OnOff':
+ if e['params']['on']:
+ GPIO.output(RED_PIN,GPIO.HIGH)
+ GPIO.output(GREEN_PIN,GPIO.HIGH)
+ GPIO.output(BLUE_PIN,GPIO.HIGH)
+ else :
+ GPIO.output(RED_PIN,GPIO.LOW)
+ GPIO.output(GREEN_PIN,GPIO.LOW)
+ GPIO.output(BLUE_PIN,GPIO.LOW)
+ if e['command'] == 'action.devices.commands.ColorAbsolute':
+ print(e['params']['color']['spectrumRGB'])
+ if e['params']['color']["spectrumRGB"] & 0xff0000:
+ GPIO.output(RED_PIN,GPIO.HIGH)
+ else:
+ GPIO.output(RED_PIN,GPIO.LOW)
+ if e['params']['color']["spectrumRGB"] & 0x00ff00:
+ GPIO.output(GREEN_PIN,GPIO.HIGH)
+ else:
+ GPIO.output(GREEN_PIN,GPIO.LOW)
+ if e['params']['color']["spectrumRGB"] & 0x0000ff:
+ GPIO.output(BLUE_PIN,GPIO.HIGH)
+ else:
+ GPIO.output(BLUE_PIN,GPIO.LOW)
+
def process_event(event, device_id):
@@ -139,6 +169,13 @@ def main():
credentials = google.oauth2.credentials.Credentials(token=None,
**json.load(f))
+ # GPIO setup
+ GPIO.setmode(GPIO.BCM)
+ GPIO.setwarnings(False)
+ GPIO.setup(RED_PIN,GPIO.OUT)
+ GPIO.setup(GREEN_PIN,GPIO.OUT)
+ GPIO.setup(BLUE_PIN,GPIO.OUT)
+
with Assistant(credentials, args.device_model_id) as assistant:
events = assistant.start()
pushtotalk.py
--- pushtotalk.py.1 2018-02-21 02:18:19.228083473 +0900
+++ pushtotalk.py 2018-02-22 04:04:27.796660481 +0900
@@ -22,6 +22,8 @@ import os.path
import sys
import uuid
+import RPi.GPIO as GPIO
+
import click
import grpc
import google.auth.transport.grpc
@@ -54,6 +56,10 @@ DIALOG_FOLLOW_ON = embedded_assistant_pb
CLOSE_MICROPHONE = embedded_assistant_pb2.DialogStateOut.CLOSE_MICROPHONE
DEFAULT_GRPC_DEADLINE = 60 * 3 + 5
+# GPIO Pin no.
+RED_PIN = 26
+GREEN_PIN = 6
+BLUE_PIN = 13
class SampleAssistant(object):
"""Sample Assistant that supports conversations and device actions.
@@ -296,6 +302,13 @@ def main(api_endpoint, credentials, proj
$ python -m googlesamples.assistant -i <input file> -o <output file>
"""
+ # GPIO setup
+ GPIO.setmode(GPIO.BCM)
+ GPIO.setwarnings(False)
+ GPIO.setup(RED_PIN,GPIO.OUT)
+ GPIO.setup(GREEN_PIN,GPIO.OUT)
+ GPIO.setup(BLUE_PIN,GPIO.OUT)
+
# Setup logging.
logging.basicConfig(level=logging.DEBUG if verbose else logging.INFO)
@@ -363,8 +376,33 @@ def main(api_endpoint, credentials, proj
def onoff(on):
if on:
logging.info('Turning device on')
+ GPIO.output(RED_PIN,GPIO.HIGH)
+ GPIO.output(GREEN_PIN,GPIO.HIGH)
+ GPIO.output(BLUE_PIN,GPIO.HIGH)
else:
logging.info('Turning device off')
+ GPIO.output(RED_PIN,GPIO.LOW)
+ GPIO.output(GREEN_PIN,GPIO.LOW)
+ GPIO.output(BLUE_PIN,GPIO.LOW)
+
+ @device_handler.command('action.devices.commands.ColorAbsolute')
+ def colorabsolute(color):
+ logging.info(color["spectrumRGB"])
+ if color["spectrumRGB"] & 0xff0000:
+ logging.info('RED')
+ GPIO.output(RED_PIN,GPIO.HIGH)
+ else:
+ GPIO.output(RED_PIN,GPIO.LOW)
+ if color["spectrumRGB"] & 0x00ff00:
+ logging.info('GREEN')
+ GPIO.output(GREEN_PIN,GPIO.HIGH)
+ else:
+ GPIO.output(GREEN_PIN,GPIO.LOW)
+ if color["spectrumRGB"] & 0x0000ff:
+ logging.info('BLUE')
+ GPIO.output(BLUE_PIN,GPIO.HIGH)
+ else:
+ GPIO.output(BLUE_PIN,GPIO.LOW)
if not device_id or not device_model_id:
try:
実際試してみる
hotwordの場合、「OK Google、ライトをつけて」というようなワードでLEDが点灯します。同じく、「ライトを消して」「ライトを青にして」「ライトを赤に」等でLEDが制御できるようになります。
pushtotalkの場合はいちいちボタンを押す必要がありますが、あとは同じ動作になります。