子育てをGoogle Homeを使って効率化する

これは、[子育てエンジニアAdvent Calendar 2020](https://adventar.org/calendars/5302)の15日目の記事です

今年の10月に子供が生まれました。
まだ子育てを初めて2ヶ月ほどですが
我が家ではGoogle Homeが子育てで活躍してるので
子育てで役立つGoogle Homeの使い方について書こうと思います。

# 子育て中の悩み
子供が生まれて最初に驚いたのはミルクをあげる時間の量と長さでした。
ミルクを上げている間は左手で首を支えながら哺乳瓶を持ってあげるので
両手が塞がって、その状態では何も出来なくなります。

特に、新生児育児の場合はミルクの時間は3時間おきに30分ほどかかるので
夫婦合わせて24時間あたり、約4時間ほど両手が塞がった状態になる計算になります。
1日4時間両手が塞がるのは地味に不便です。

Google Homeを使うと、両手が塞がった状態でも
声だけで明日の天気を確認したり、家電を操作したり出来るようになるので
両手がふさがった状態で出来ることが増えて、ミルクの時間に出来ることが増えます。

# google homeで出来ること
google homeでは↓の機能をよく使ってます。

- 天気（OK, Google, 明日の天気は？）
- 今の時刻（OK, Google, 今何時？）
- タイマー(OK, Google, タイマー5分セット)
- アラーム(OK, Google, 明日の07:00にアラームをセットして

また、別売りのnature remoを使うと
赤外線リモコンを使った家電を声で操作出来るようになります。
我が家ではテレビ、電気、エアコンをgoogle homeと連携していて、
「OK Google, エアコンを暖房23度に設定して」
「OK Google, エアコンを消して」
「OK Google, テレビの音量を5上げて」
のように話しかけると、家電を操作出来るようになっています。
少し前までは
「OK Google, ネイチャーリモを使ってテレビを付けて」
のように長いワードで話しかける必要があったのと、
細かいカスタマイズが難しかったので
IFTTTという外部サービスを使って
「〜〜〜と話しかけたら、nature remoの%%%%の操作をする」
のような設定を一つ一つ設定していましたが、
IFTTTの有料化されたのをきっかけに
direct actionsを使うようにしたところ、
direct actionsの機能がかなり強化されていて、
エアコン、テレビや電気の一通りの操作は出来るようになっていました。
※ direct actionsについては、[nabure remoの公式blog](https://nature.global/jp/blog/2019/6/21/googlehome-cada)参照

# Google Homeアプリを使ってミルクの記録アプリを作った
Google Homeを使うことで、ミルクを上げている間も家電を操作したり、
簡単な調べ物が出来るようになりました。

そうしていると、ミルクの記録もGoogle Homeで出来ないかなと思うようになりました。

Google HomeはActions on Googleというサービスで
Google Homeアプリを使って機能を追加することが出来るので作ってみました。

```js
const {conversation} = require('@assistant/conversation');
const functions = require('firebase-functions');
const dateFns = require('date-fns');
const ja = require('date-fns/locale/ja');
const dateFnsTz = require('date-fns-tz');

const app = conversation({debug: true});

const MAX_RECORD_COUNT = 1000;

app.handle('recordMilk', conv => {
    const amount = conv.intent.params.amount.resolved;
    let milkRecords = conv.home.params.milkRecords || [];
    const now = new Date();
    const time = dateFnsTz.format(
        dateFnsTz.utcToZonedTime(now, "Asia/Tokyo"),
        "yyyy-MM-dd HH:mm:ss",
        {timeZone: "Asia/Tokyo"}
    );
    const timeDisplay = dateFnsTz.format(
        dateFnsTz.utcToZonedTime(now, "Asia/Tokyo"),
        "yyyy年MM月dd日HH時mm分",
        {timeZone: "Asia/Tokyo"}
    );
    milkRecords = milkRecords.concat({time: time, timeDisplay: timeDisplay, amount: amount});
    if (milkRecords.length > MAX_RECORD_COUNT) {
        milkRecords = milkRecords.slice(milkRecords.length - MAX_RECORD_COUNT);
    }
    conv.home.params.milkRecords = milkRecords;
    conv.add(`ミルクを${amount}ml記録したよ`);
});

app.handle('showLastMilk', conv => {
    const milkRecords = conv.home.params.milkRecords || [];
    if (milkRecords.length === 0) {
        conv.add("ミルクの記録がありません。");
    } else {
        const lastMilkRecord = milkRecords[milkRecords.length - 1];
        const lastMilkRecordTime = dateFnsTz.zonedTimeToUtc(lastMilkRecord.time, 'Asia/Tokyo');
        const now = new Date();
        const duration = dateFns.intervalToDuration({start: lastMilkRecordTime, end: now});
        const durationDisplay = dateFns.formatDuration(duration, {format: ['years', 'months', 'weeks', 'days', 'hours', 'minutes'], locale: ja}) || '0分';
        conv.add(`前のミルクは${lastMilkRecord.timeDisplay}に${lastMilkRecord.amount}ml記録したよ。前の記録から${durationDisplay}経ったよ。`);
    }
});

exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
```

上記のようなclound functionsのスクリプトを書いて、今年リリースされたActions Builderを使って「ミルクを`n`ml記録して」と、「前のミルクの記録を教えて」に反応してスクリプトが呼ばれるようにしました。

![スクリーンショット 2020-12-14 1.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8411/d37b33ef-0eaa-c245-27cd-d54dc4826f18.png)

こうすることで、ミルクを上げ終わったら
「OK, Google, ミルクレコーダーを使ってミルクを500ml記録して」
のように記録して、
そろそろミルクの時間かな？と思ったら
「OK, Google, ミルクレコーダーを使って前のミルクの記録を教えて」
と聞くことで、前のミルクからどのくらい経ったかがわかるようになりました。

# 記事を書いてる途中に気づいた事実
この記事を書いてる途中に気づいたんですが、
育児記録をスマホでつけられる「ぴよろぐ」というアプリを作っている人が
Google Homeアプリ版ぴよろぐを作っていました。
どうやら同じようなことが出来るみたいです。
というかこちらの方がミルク以外も記録も出来て高機能、、、
ぴよろぐを使ってる方はそちらを使うのが良いかもです。
ただ、ぴよろぐのアプリは前の記録からの経過時間は教えてくれないみたいなので
カスタマイズ性が高いアプリが作れたということで、、、

# 今後やりたいこと
google-home-notifierというnpmライブラリを使うと、Google Homeにpushで喋らせることが出来るので、ミルクの時間が近づいてきたらGoogle Homeに喋らせるとかやりたい。