omohayui blog

おも‐はゆ・い【面映ゆい】[形][文]おもはゆ・し[ク]《顔を合わせるとまばゆく感じられる意》きまりが悪い。てれくさい。

protobuf v2 で protocmp.IgnoreFields() 使う

はじめに

これは完全に自分用の備忘録です。
もしも同じところで引っかかった方がいて参考になる場合は別ですが、特に読んでいただくほどのものではないです。 あしからず!

Go protobuf API v1 と v2

blog.golang.org

The github.com/golang/protobuf module is APIv1.
The google.golang.org/protobuf module is APIv2.

こちらの記事にあるように、github.com/golang/protobuf が v1, google.golang.org/protobuf が v2 です。
そして、proto.Message インターフェイスを変換して、2つのインターフェイス間の移行を容易にする関数が用意されてるとありますが、
つまり下位互換性はないということです。

protobuf の Diff で cmpopts.IgnoreFields() を使う

テストの中で cmp.Diff で struct 同士の Diff を取ることはよくあると思うのですが、protobuf 同士でもこれを使うことがあります。
そして、 cmp.Diff で特定の field の diff を無視したいときに使うのが、 cmpopts.IgnoreFields() ですが、
これは v1 では ignore されるのですが、v2 に移行するときに必要になる protocmp.Transform() と合わせて使おうとすると、ignore されません。

// protobuf v1
if diff := cmp.Diff(want, resp,
    cmpopts.IgnoreFields(todopb.Task{}, "Created", "Updated"),
); diff != "" {
    t.Errorf("differs: (+got -want)\n%s", diff)
}

そこで、v2 では、 cmpopts.IgnoreFields() を使う必要があります。

// protobuf v2
if diff := cmp.Diff(want, resp,
    protocmp.IgnoreFields(proto.MessageV2(&todopb.Task{}), "created", "updated"),
    protocmp.Transform(),
); diff != "" {
    t.Errorf("differs: (+got -want)\n%s", diff)
}

protocmp.Transform() を付けなくてはいけないという認識はあったのですが、ここを書き換えることに気づかず、なんで ignore されないんだろうなって考えてました。

以上、備忘録です。

Dialogflow CX Competition に応募してみた

はじめに

そもそも Dialogflow CX って何?という方がこれを読んでくれているかもしれないので、ざっくりと説明すると、2020年に Google Cloud がリリースしたチャットボットやテレフォニーエージェント(代理で電話応答してくれるボット)を構築するためのボット構築プラットフォームのことです。
従来の Google アシスタントアプリの作成や簡単なチャットボット作成に利用されていた Dialogflowは、Dialogflow ES(Essentialsの略)にブランド化されていますが、CX は大規模だったり、複雑な仮想エージェントに適していて、エンタープライズレベルのプロジェクト用に進化しています。
...という訳で CX はお値段もエンタープライズ向けだったので、正直私もドキュメントを読んだりしていても GCP のコストが気になって気軽に触ったことがありませんでした。

Dialogflow CX Competition とは?

Dialogflow CX Competition (global) は、Google 公式が開催している Dialogflow CX を使ったコンペです。

f:id:omohayui:20210808171049p:plain

このコンペには2種類の応募方法があります。

  • UX Designers - Write a conversation flow
    • UXデザイナー向けの種目で、COVID-19 に関連するテキストチャットボットの会話フローを設計します。(例:ワクチン接種のスケジューラー、FAQ、旅行先での許可に関するボット)
  • Bot Developers - Build an integration
    • チャットボット開発者向けの種目で、Dialogflow CX API を使用して、チャットボットの統合環境を構築します。(例:ウェブサイト、ブログ、WhatsApp、CRMCMS、モバイルなどにチャットボットを組み込む)

特典その1:無料のトレーニン

私がまず応募してみようと思った理由は、無料の Dialogflow CX トレーニングを受けられるというところです。 とりあえず参加申請すると数日後に Qwiklabs のオンライントレーニングへの招待メールがきます。
Qwiklabs で受けることができるのは2つのコードラボなのですが、ここで実際に動かせる Dialogflow CX の環境はシュミレーターなどではなく、トレーニング用に発行された GCPアカウントで実際に Cloud Console にログインして Dialogflow CX の開発をすることができます。
ひとつ注意点なのは、「Start Lab」ボタンを押したら1時間半以内にそのコードラボを終わらせないといけないということです。時間になったら、トレーニング用のアカウントから強制ログアウトされて、一度作ったチャットボットは二度と触れません。もう一度「Start Lab」することはできますが、新しいアカウントになるので最初からチャットボットを作り直しになります...
なので、「Start Lab」ボタン押す前にコードラボの内容を一通り読んでおくことをおすすめします。私は英語読むの遅いので先に読んでないと間違いなく間に合わなかったと思います。
あと、ditectintent のURL設定するところがコードラボの説明だと間違っている気がしました。(Feedbackに書いておいたけれど)

特典その2:Dialogflow CX Tシャツ

これは受賞者に貰えるとかではなくて、プロポーサルを提出した先着200名に無料配布してくれるという特典です。
プロポーサルの期限は 8/9 なのですが、(日本時間ならまだ間に合うので皆さん急いでとりあえず応募してみましょう!)先日、提出した私のプロポーサルでも先着200名に入っていたらしく、Tシャツをオーダーすることができました。
男性・女性用、サイズも自分で選べました。

特典その3:受賞者には豪華賞品

UXデザイナー向け、チャットボット開発者向け受賞者それぞれ、1位から3位までの方々には Fitbit Sense や Nest Hub, Lego Kit などの賞品がついてきます。私は受賞は狙っていませんが、StarWarsLego Kit は欲しいな...って少し思いました。はい。
あと、「The Definite Guide to Conversational AI with Dialogflow and Google Cloud」という本もついてくるそうです。
(これ、Amazon で調べたら 6000円以上するのね...)

これからのタイムライン

8/9 から応募されたプロポーサルの審査が始まり、Best idea として50のプロポーサルがノミネートされます。
ノミネートされた人は、実際に会話フローの構築やチャットボットの統合環境を作って 8/31 までにソースコードを提出します。
コントリビューターは全員、Googleから SNS や Dialogflow の Webサイトを通じて紹介されるらしいです。
自分のプロポーサルがノミネートされるされないに関わらず、ノミネートされたコードがオープンソースとして見れるというのはうれしいですね。
そして、最終的な受賞者の発表は 9/13 です。

万が一、私のプロポーサルが50のノミネートに入ったら、また続きを書きたいと思います。ではでは。

長縄跳びのトラウマ

はじめに

昨日、Googleさんが主催してる Women Developer Academy というイベントの初日で Cultivate Confidence というセッションに参加したときに、ふと自分に自信が持てない傾向になった原因はなんだろうって勝手に深堀りをしてみた。

→セッションの中で紹介された女の子の "Daily Affirmation (毎日の自己肯定)" 超かわいい。

小学生の見えてる世界

子どもの頃、私はいわゆる運動音痴で、国語、算数、理科、社会、音楽、図工、家庭科がオール5でも体育は2か3みたいな成績の子だった。

中でも、長縄8の字跳び(みんなで一斉に飛ぶやつじゃなくて、一人ずつ跳んでは抜けて連続回数を競う)という種目がめちゃくちゃ苦手で、クラス対抗の長縄跳び大会がある度に世界の終わりを願うほど嫌いだった。

f:id:omohayui:20210718103203p:plain:w300

当時のルールだと最長の連続回数を競うので、一人ずつ跳んでいってカウントが伸びていっても、一人下手な子がいるとそこでカウントがリセットされる。
40人クラスだったとして、ド下手が一人いたら、そのクラスの記録は40超えることはないのだ。

必然的に私はクラス全員に迷惑をかけることになる。
優しい子の「練習すれば上手くなるよ」という励ましも、私にとっては「足手まとい」「無能」の烙印を押されたようにしか聞こえなかったし、どんなに嫌でも絶対に練習を欠席してはいけない重圧も感じてた。

そんな感じで、みんなに迷惑をかけている自分はこの世にいきている価値がないと思うぐらい自信を失って、普段の時間にクラスメイトに話しかけるのすら苦手だった。

大人の見えてる世界

高校生のときに私の世界は180度変わったと思う。授業でもイベントでも選択する自由が与えられた。
クラス対抗のスポーツ大会とかはあったけど、自分が少しでも活躍できる種目を選ぶことができたし、それなりに楽しかった。

大人になって、気づいたことがある。
長縄を跳べなくたって、誰にも迷惑をかけていないのだ。
社会人になってからそこそこ長い年月が経ったけれども、一度も長縄8の字跳びを強要されたことはないし、跳べないという事実で誰かを困らせたりもしたことはない。

小学生の自分に教えてあげたい、長縄が跳べなくても、この世に生きている価値はあると。

それで?

結局、Cultivate Confidence とは関係ない話になってしまったけど、子どもの見えてる世界って外からの影響を受けやすいし、範囲が狭いからそれしか見えてなかったり、逃げ道がないから自己否定に走りがちなんだなって。

これはきっと色々な選択が与えられたはずの大人にも言えることで、見えてる範囲が狭いと自分のだめな部分、嫌いな部分ばかりが脳内を占めてしまって、自分の良い部分、達成したことが薄れていってしまう。

子どもでも大人でも、まわりが心理的安全性を確保してくれるのが、自己否定に陥りがちな人を減らす手段にはなると思うけど、自ら Cultivate Confidence するには、一つ一つ、自己肯定してくのが良いのかな。

ということで自分も毎朝鏡に向かって、I can do anything good! って叫ぼうと思います。嘘です。

E2E Testing for Google Assistant Apps

これは何か?

先日、GDG Tokyo New Year LT大会 2021 で「E2E Testing for Google Assistant Apps」というテーマでLTをさせて頂いたのですが、5分では伝えきれない点があったので、こちらの記事に詳細を書くことにしました。

会話形アクションにこそ自動テストが必要

GoogleアシスタントアプリやAlexaスキルを作ったことがある方は、経験されているかもしれませんが、 会話型アクションをテストするのってすごく大変なんですね。
ちょっとインテントのフレーズを変えただけでも、その対象のシーンまで会話を持っていかないといけないので、何度も同じことを言ったりして労力を奪われてしまいます。
そこで必要になってくるのが End to End の自動テストです。
一度テストを作ってしまえば、改修のたびに都度都度、話しかけるという手間もなくなります。

Assistant Conversation Testing Library

github.com

Actions on Google には E2Eテストがコードベースで書けるライブラリが用意されています。
これは、Actions API をラップしていて、テストスイートを定義すれば、自分で作ったアクションにクエリを送信して、返ってきたレスポンスに対して検証することができます。
また、テスト実行前に Actions API の writePreview メソッドをコールすることで、Draftから自分のプロジェクトにプレビューを作成し、そこに対してテストすることができます。つまり、リリース前にひととおりの検証ができるってことですね。

Setup

Actions API を有効にする

従来のテストライブラリ actions-on-google-testing-nodejs ではテスト対象の Action のプロジェクトとは別のプロジェクトの Actions API を使ってテストができたのですが、こちらはテスト対象のプロジェクトで Actions API を有効にする必要があります。
また、比較的最近作られた Actionプロジェクトではデフォルトで Actions API は有効になっているそうです。

  1. Google API Consoleにアクセス
  2. プロジェクトをテスト対象のものに切り替え
  3. "Actions API" を検索し、もしenabled になっていない場合は enable にする

f:id:omohayui:20210207001841p:plain:w300

Service Account Key を作成する

  1. 同じプロジェクトで、Credentials pageにアクセス
  2. "Create credentials" > "Service account" をクリック
  3. service account name に actions のテスト用だと分かるような名前をつけて Create
  4. Role に "Actions" > "Actions Admin" を指定する
  5. Service Account Key をJSONファイルでダウンロード

f:id:omohayui:20210207002923p:plain:w300

READMEには Role(権限) に project.OWNER を付けろって書いてあったけど、強すぎる。actions.ADMIN で動いたのでこちらがおすすめ → こちら PullRequest 出したら merge してもらえました!

github.com

環境変数 GOOGLE_APPLICATION_CREDENTIALS の設定

ダウンロードした JSON ファイルを環境変数GOOGLE_APPLICATION_CREDENTIALS セットします。
他のプロジェクトでは使いたくないものなので、direnv などを使って .envrc に記載しておくのがおすすめです。

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service_account.json

ライブラリのインストール

npm install @assistant/conversation-testing --save
# 以下は必要な人は入れる
npm install @types/mocha --save
npm install mocha --save
npm install typescript --save

Test Code 作成

テストコードを書いていきます。
ここでは、今日食べるものを占ってくれる「カワウソ食べ物占い」のテストコードをサンプルにしています。

import 'mocha';
import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing';

const PROJECT_ID = 'otter-fortune-telling-xxxxx';
const TRIGGER_PHRASE = 'カワウソ食べ物占いにつないで'; // 呼び出すフレーズ

const DEFAULT_LOCALE = 'ja-JP';  // 各言語の指定
const DEFAULT_SURFACE = 'PHONE'; // 各デバイスの指定

describe('Action project', function () {
  // write Preview するときは set timeout したほうが良い
  this.timeout(60000);
  let test: ActionsOnGoogleTestManager;

  before('setup test suite', async function() {
    test = new ActionsOnGoogleTestManager({ projectId: PROJECT_ID });
    await test.writePreviewFromDraft();
    test.setSuiteLocale(DEFAULT_LOCALE);
    test.setSuiteSurface(DEFAULT_SURFACE);
  });

プロジェクトIDには、テストしたいアクションのプロジェクトIDを記載し、トリガーフレーズにはアクションを呼び出すフレーズを入れます。 ロケールsurfaceでは、テストしたい言語やデバイスを指定することができます。

// おやつを占うテストパス
it('should match Snack Type, and end the conversation', async function () {
  await test.sendQuery(TRIGGER_PHRASE);

  // TestManager を使って API レスポンスをアサーションする
  test.assertSpeech('カワウソたべもの占いへようこそ! 占ってほしいのはランチ?ディナー?それともおやつ?');

  // ユーザークエリをアクションに返答する
  await test.sendQuery('おやつ');

  // 正規表現を使ってアサーションする
  test.assertSpeech(`ふむふむ。おやつか〜。\nそんな君におすすめのおやつは.*楽しみだね〜!もう一回やる?`, {isRegexp: true});

  // 会話を終了させる返答をする
  await test.sendQuery('やらない');
  test.assertSpeech('じゃあまたね!');
  // 会話が終了していることを確認する
  test.assertConversationEnded();
});

ここでは、テストスイートを定義しているのですが、お菓子を占ってもらって会話終了、という流れをテストしています。
このテストマネージャーには各種アサーションのメソッドが用意されているので、それを使ってレスポンスや、会話が終了していることを検証します。
もちろん正規表現やリストも使えるので、柔軟にテストは書いていくことができます。

// ランチを占ってから、もう一回占うテストパス
it('should match Lunch Type, and again the conversation', async function () {
  await test.sendQuery(TRIGGER_PHRASE);

  test.assertSpeech('カワウソたべもの占いへようこそ! 占ってほしいのはランチ?ディナー?それともおやつ?');

  await test.sendQuery('ランチ');
  test.assertSpeech(`ふむふむ。ランチか〜。\nそんな君におすすめのおやつは.*楽しみだね〜!もう一回やる?`, {isRegexp: true});

  // 会話を続ける返答をする
  await test.sendQuery('やる');
  // シーンAgainに遷移したことを確認する
  test.assertScene('Again');
  test.assertSpeech('占ってほしいのはランチ?ディナー?それともおやつ?');
  // 会話が終了していないことを確認する
  test.assertConversationNotEnded();
});

このテストでは、占ったあとに会話を終了せずにシーン Againに遷移することをテストしています。

Run Tests

先程作成したテストコードのファイルは、src/test/ 下に配置します。 そして、package.json に以下の script コマンドを追加しておきます。

  "scripts": {
     "test": "mocha --recursive --require ts-node/register src/test/*.ts",
   },

テストを実行します。

npm run test

出力結果

Failed した結果

f:id:omohayui:20210207155659p:plain:w600

「もう一回やる?」「やる」のあとに、シーン Again に遷移してほしいのに、会話が終了してしまい、期待値と異なるメッセージが返ってきています。 そして、コンソールには期待したレスポンスと実際に返ってきたレスポンスのDIFFが表示されます。

Pass した結果

f:id:omohayui:20210207155756p:plain:w800

レーニングフレーズを修正すると、テストが通りました。

Assertions 各種

用意されているアサーションは、assertSpeech や assertScene だけではありません。 Assertions を確認してください。

  • assertText - テキストレスポンスの検証
  • assertCard, assertImage, assertTable, etc - 各表示要素の検証
  • assertIntent - クエリにマッチしたインテントの検証
  • assertSessionParam, assertUserParam, assertHomeParam - セッションストレージなどストレージへのパラメータの検証

ただ、まだビルトインインテントトランザクションのテストは未対応となっているので、これから拡張されることを期待しています。

まとめ

  • 会話型アクションのインテグレーションテストはとても大変
    • でも自動テストがあれば改修も気軽にできる
  • Actions on Google には E2Eテスト用のライブラリが提供されている
    • Draft の状態に対して E2Eテストができるので、リリースする前の自動テストとして利用できる
    • テストモジュールにはさまざまなアサーションが用意されているので、ディスプレイに表示する要素のテストもできる
    • 現時点では、ビルトインインテントトランザクションのテストは未対応

所感:やはりこれだけの内容を5分でやるのは無理があった・・・

DevFest 2020 で Local Home SDK を使った開発の話をしました

これは何か?

先日、GDG DevFest Tokyo 2020 と言うイベントで、
「Local Home SDK を使った Local Fulfillment とオリジナルホームデバイスの開発について」という話をしてきました。

DevFest は、Google Developer Group (GDG) コミュニティによって世界各地で開かれるデベロッパー向けイベントです。
そんな規模の大きいイベントに登壇させていただけるのは恐縮なのですが、せっかくなので話した内容をより詳しく記事にしようと思います。

発表自体は Youtubeに上がっているので、気になる方は Google Home のマイクをオフにして、ご視聴ください(私が発表内で「OK Google」を連呼した為に、複数の視聴者が被害に遭われました。。。)

youtu.be

発表内容詳細

Agenda

  1. Smart Home Action について
  2. Smart Home 統合フロー
  3. Local Fulfillment を使った構成
  4. Local Fulfillment を使うメリット
  5. Local Home SDK を使った開発方法
  6. オリジナルホームデバイスのデモ
  7. 使ってみた感想など

Definition of the term

本資料での用語定義💡

※ 注意したいのは、デベロッパーとは Google Assistant 本体を開発している人でなく、ホームデバイスを開発している人です。

Smart Home Action

f:id:omohayui:20201021235520p:plain
smart home action

Smart Home Action を構築すると、ユーザーが “OK Google 電気をつけて” と自宅の Google Home に話かけると、デベロッパーの Cloud Fulfillment が呼び出され、ユーザーの自宅にあるホームデバイスを制御できるようになります。 また、ユーザーはボイスコントロールだけでなく、iOSAndroidなどのスマートフォンGoogle Home アプリからリモコン操作のように各デバイスを制御することもできます。

Smart Home Controls

Smart Home Control
これは余談ですが、Android11 では電源ボタン長押しでホームデバイスの操作ができるようになりました。
これでさらにホームデバイスの操作が簡単になったかと思います。

Smart home integration flow

Google Home からホームデバイスを管理できるようになるまでの Smart Home のフローを説明していきます。

Sync Device

f:id:omohayui:20201022000438p:plain
Sync Device
まずユーザーは Google Home アプリでホームデバイスを登録します。
このタイミングで、アシスタントはデベロッパーの Fulfillment に SYNC インテントを送信して、ホームデバイスの情報と Traits と言うデバイスが持っている機能のリストを取得します。
本来はこの前にデベロッパーのサービスを認証するためにデベロッパーが用意した Authorization URL, Token URL にアクセスし、アシスタントは OAuth Token を取得する必要などがありますが、この図からは省略しています。
今この図を見ると、SYNC インテントに対して Cloud Fulfillment が、デバイスタイプ LIGHTで、ON/OFFの traits が使えるよという情報を返しているのが分かると思います。

  • Device Type - ホームデバイスの種別
    • CAMERA, DISHWASHER, DRYER, LIGHT, OUTLET, PHONE, REFRIGERATOR, SPEAKER, SWITCH, THERMOSTAT, TV, VACUUM, WASHER など
  • Traits - デバイスが持っている機能のリスト
    • OnOff, StartStop, Brightness, ColorSpectrum, ColorTemperature, Dock, TemperatureSetting など

SYNCインテントに返す Device Type, Traits はデベロッパーが自由に指定できるものではなく、Google Assistant 側で予め定義されたものです。 自分で作ったホームデバイスを、どの DeviceType にして、どの Traits を受け取るようにするか決める前に、ドキュメントで定義されたものの一覧を確認することをおすすめします。

Execute Command

f:id:omohayui:20201022000856p:plain
Execute Command

ユーザーが Google Home に “OK Google 電気をつけて” と話しかけるとデベロッパーの Fulfillment は電気をONにする実行コマンドを含む EXECUTE インテントを受け取ります。
そして、Fulfillment はユーザーの自宅にあるホームデバイスに対して電気をONするというリクエストを行います。

Query Device Status

f:id:omohayui:20201022001019p:plain
Query Device Status

「リビングの電気は点いてる?」とユーザーが Google Home に質問したり、「音量を上げる」「明るさを上げる」のような相対的なコマンドを処理するときに、アシスタントは QUERY インテントデベロッパーの Fulfillment にリクエストします。
そして、Fulfillment はデバイスの状態をアシスタントに返してあげます。
この図だと、デバイスは今、ONになっているよというのをアシスタントに返しています。

Smart Home with Local Fulfillment

f:id:omohayui:20201022001143p:plain
Smart Home with Local Fulfillment

一連の流れで、ホームデバイスを操作するには、デベロッパーは Execute Command を受け取ってホームデバイスへそれを伝える Cloud Fulfillment を作成する必要がありました。 ですが、Local Home SDK を利用すると、Local Fulfillment を作成し Google Home 上でデベロッパーが書いた JavaScript を動かし、ホームデバイスを制御することができます。 また、Cloud Fulfillment は Local Fulfillment が機能しなかった際の fallback としても機能します。

Benefits of using Local Fulfillment

ホームデバイスを提供する企業としてのメリット🏭

  • Cloud Fulfillment を経由しないので、遅延が少ない、安定稼働できる
  • Local Fulfillment が動かない時は Cloud に fallback させることができる

オリジナルホームデバイスを作成する個人のメリット👩‍💻

  • ローカルネットワークからデバイスを操作できるので、マイコンボードで作ったデバイスと連携が簡単
  • バイスはローカルネットワークからしか叩かれないのでセキュリティリスクが下がる

How to use Local Home SDK

Implement Local Fulfillment app

Local Fulfillment に必要な Handler

  • IDENTIFY handler
  • EXECUTE handler
  • REACHABLE_DEVICES handler (only Hub)

※ REACHABLE_DEVICES Handler は、IDENTIFY Handler がアクセスするホームデバイスをプロキシとして利用したい場合にのみ必要になります。

IDENTIFY handler

f:id:omohayui:20201022001630p:plain
IDENTIFY handler

Google Homeバイスが再起動時に、ローカルネットワーク上で未確認のデバイスを検出すると、IDENTIFY handler をトリガーします。
このとき Google Home がスキャンする構成は、Actions console で設定した値に基づいてデバイスを探しに行きます。
IDENTIFY Handler は、ホームデバイスがスキャンに対して返すデータ(local device id)を取得し、これをアシスタントに送信します。
そして、IDENTIFY Handler からの verificationId が前述に登場した SYNC インテントが取得した other Device Ids のいずれかと一致する場合、アシスタントはホームデバイスの関連付けを確立します。

EXECUTE handler

f:id:omohayui:20201022001813p:plain
EXECUTE handler

アシスタントは、Cloud Fulfillment への EXECUTE Intent と同じ入力値を EXECUTE handler に渡します。 同様に、EXECUTE hander は、EXECUTE Intent の処理と同じ形式で出力データを返します。
また、Localfulfillment は、デバイスIPアドレスに直接アクセスできません。 代わりに、CommandRequestインターフェイスを使用して、UDPTCP、またはHTTPのいずれかのプロトコルに基づいてコマンドを実行します。

How to debug Local Fulfillment

Google Home 上で動いている Javascript をどうやってデバッグして開発するのか?というところを説明します。
Actions console 上の Testing URL に、自分で作成した Local Fulfillment を実行する HTMLページのURLを追加すると、 Google Home 上で実行される JavascriptデバッグChrome の DevTools 上で出来ます。

f:id:omohayui:20201022002155p:plain
Actions console

f:id:omohayui:20201022002312p:plain
Chrome DevTool

Demo

youtu.be

1.スマホGoogle Home アプリからデバイスを追加します。
今回は Otter Light というデバイスを Otter Smart Home というスマートホームアクションに作成しているので、最初に Otter Smart Home というサービスとアカウント連携をします。
アカウントをリンクさせたら、追加するデバイスを選んで、ホームを選んで、部屋を選んで、すると、Otter Light がアプリ上から操作できるようになります。

2.次に、Google Home 上で動作するJavaScriptデバッグします。
Chrome の DevTool の inspect を開いて、Nest Audio の inspect のリンクをクリックします。
すると Console Log に Nest Audio を再起動したタイミングだったり、一定間隔でリクエストしてきた IDENTIFY hander のログが確認できます。

3.アプリから実行してみます。 ラズパイ上で動いている UDP サーバが、Nest Audio から Execコマンドを受け取り、赤外線が送られて電気がついたり、消えたりしてます。
4.最後に Google Home から声で実行してみます。

使ってみた感想

  • Local Home SDK は手軽に Google Home や Home アプリと連携ができて便利
  • QUERY Intent を処理しようとすると Cloud Fulfillment 上でデバイスのステータスを管理しなくてはいけない
    • Cloud ↔ Home Deviceのやり取りは無くならない、元々 Fallback は必要な前提だと思われる
  • Local Fulfillment の修正を反映するのに時間がかかる
    • Google Home を再起動してから反映されるまで10, 20分待つこともある

おまけ

Twitter で「(デモで使っている赤外線が)結構遠くまで届いてそうだったので何を使っているのか気になる」という話が上がっていたので、赤外線学習リモコンモジュールという強力で便利なやつを紹介しました。

[Amazon] BitTradeOne ラズベリーパイ専用学習リモコン基板 [ 完成品 ] ADRSIR