IFTTT, Google Assistant, Google Sheetsで赤ちゃんの授乳を記録する

Geek Women Japanアドベントカレンダーの9日目です。

qiita.com

ただいま、今夏に生まれた第2子の育休中です。そして気が付きました。授乳中は身動きがほとんど取れない…!何なら視線さえも縛られる…しかし口だけは自由だ!と。

お手軽なIFTTTを使って、Google Assistant + Google Sheetsで赤ちゃんの授乳記録を作ることにしました。

準備

アカウント

  • IFTTTアカウント
  • Googleアカウント

これらは、既に用意されているものとします。

また、IFTTTにGoogleアカウントを連携しておきます。

Google Assistant

iOSの「Google アシスタント」アプリを使って動作を試しました。 アプリにも、IFTTTに連携したGoogleアカウントを設定しておきます。

Google Homeで動作させてみたかったのですが、今日までに届きませんでした!残念!)

記録するもの

毎日の赤ちゃんの授乳状況を記録するものとします。

そして一口に「授乳」と言っても、実際の手法は様々なのですが、、今回は「ミルクの授乳」について取り扱います。

IFTTT

f:id:takopomm:20171209010538p:plain

アプレットを作成してみます。

何をするか

アシスタントからの入力で、

  • いつ
  • ミルクを
  • どのくらい飲んだか

スプレッドシートに記録します。

例えば、「ミルクを140」と言ったら、「現在日時にミルクを140ml飲んだ」ことを記録するようにします。

This

Google Assistant」を選びます。

f:id:takopomm:20171209010426p:plain

Choose trigger

数値を1つ含むので、「Say a phrase with a number」を選択します。

f:id:takopomm:20171209010810p:plain

Complete trigger fields

例えば「ミルク100」と言ったら動作して欲しいので、このようにしました。

f:id:takopomm:20171209011215p:plain

#で数値が取得できます。#の前(後)には空白が必要です。

アシスタントからの返答には、お母さんへのねぎらいの言葉を付け加えておきます。(もしミルクをお父さんがあげている場合は、お父さんへ!)

f:id:takopomm:20171209011515p:plain

言語は「日本語」を選択して「Create trigger」すれば、Assistantの動作の出来上がりです。

That

スプレッドシートに記録したいので、「Google Sheets」を選びます。

f:id:takopomm:20171209012010p:plain

Choose trigger

行を追加したいので、「Add row」を選びます。

f:id:takopomm:20171209012347p:plain

Complete action fields

記録先のスプレッドシートの指定と、セルに書き込む内容を指定します。

f:id:takopomm:20171209012516p:plain

自分のGoogle Driveスプレッドシートを作成しておきます。 私の場合は、

というものを用意したので、上の画像のような設定になっています。

セルに書き込む内容の指定で、「日時」はCreatedAtパラメータを利用したいところですが、現状動作していないそうです。 そのため、スプレッドシート側にスクリプトを埋め込んで、日時を記録できるようにします。

Spreadsheet

日時を記録するために、スプレッドシートスクリプトを追加します。

f:id:takopomm:20171209013552p:plain

function

セル(最後の行, 指定の桁)に、現在日時を書き込みます。

function addDate(e) {
  var row = SpreadsheetApp.getActiveSheet().getLastRow();
  SpreadsheetApp.getActiveSheet().getRange(row, 1).setValue(new Date());
}

トリガー

「シートに値の変更があった時」に、上のfunctionが実行されるようにします。

f:id:takopomm:20171209013644p:plain

参考

動作確認

Assistantアプリで、「ミルク120」と言ってみます。

「ミルクを120ミリリットルですね。お疲れ様です!」と返してくれました。

f:id:takopomm:20171209014329p:plain

スプレッドシートにはこのように記録されました。

f:id:takopomm:20171209014531p:plain

実際には、ミルクだけでなく母乳の場合も記録できるように、IFTTTにいくつか追加しました。 phraseが多少異なるだけで、やることは同様です。 すごくお手軽に、なかなか実用的なものが出来る…!!!

感想

  • 個人的には手書きの日記も好きなので、スプレッドシート上に完全移行するかどうかは決めかねていますが、身動きが取りづらい状況でも記録できるのはとても便利。

  • 1日に何分授乳したか、1ヶ月に何時間授乳したか…といった情報を返してくれるようにもしたい。 手書きの育児日記からは読み取りにくいデータを、お手軽に知れたら面白そう。

  • DialogFlowも使ってみよう。

  • 授乳を頑張るお母さんの心もアシストできるといいな!

Geek Woman Japan ミニカンファに子どもと一緒に行ってきました

2017/03/04に開催されたGeek Women x Microsoft - Geek になりたい人のためのミニカンファに行ってきました。

geekwomenjapan.github.io

(毎度イベント行ってきたレポが数ヶ月後になってます…ぬぬぬぬ)

今回も子どもと一緒に行ってきました

託児サービスを用意してくださっているということで、今回もありがたく利用させていただきました。 無料で託児を利用できるのは、本当にありがたいことです。感謝、感謝です!

託児を利用してみて

前回のカンファレンスで託児をお願いしたことで、私の中で何かの壁を一枚突破したようで、以前ほどの葛藤も少なく申し込みすることができました。 それはきっと、前回の経験を通じて「お母さんでもカンファレンスや勉強会に参加してもいいんだ!」と、自分の中に薄っすらとある罪悪感のようなものが吹っ切れて、気持ちが前向きに定まったからかもしれません。

今回は午後からの開催ということもあり(?、たまたまかもしれませんが)、託児の開始時刻から数人のお友達と一緒に過ごすことができて、子どもも楽しかったようでした。 我が子も3歳半になり「誰かと一緒に遊ぶことが楽しいと感じる時期」に入ったこともあるかもしれません。

託児のスタッフさんはとても温かく迎え入れてくださって、(母に似て)人見知りな我が子でも、とてもリラックスできた様子でした。(昼寝までしっかり済ませたそうで…びっくり!)

セッションの感想

今回は(前回と比べると)技術系のセッションが多く、ジャンルも様々で面白かったです。 未知の内容ばかりで、もっと技術を学んで行こう!とテンションが上がり、とても良い刺激を受けました。

その中でもやはり、女性が業界でどう働いて行くかという話は興味深く、「GeekなWomenならではのセッション」という感じがあります。 個人的にはこういったセッションを、今後もまた聞けるといいなと思っています。

Markdown形式でメモしたものをGitHub上に置いています。 4セッション聴いたうちの2つ分です。

※自分用メモなので間違いもあると思いますがご了承ください…!

github.com

懇親会

本当は参加したかったのですが、子どもも「おなかすいた〜早く帰ろう〜」という感じだったので、わいわい賑わう懇親会会場を横目に、そそくさと退散してきました…!

カンファレンスは、懇親会などに出て交流を持つことも大事なミッション(?)のひとつだと思うようになったので、それが達成できなかったのは残念です。。

それと、「こういう場に子どもを連れてはいけないのでは…」と思い込んでいる節もありました。 実際のところはどうだったのでしょう…?? もし幼児が一緒に居ても大丈夫だったら、わずかな時間でも顔を出してみても良かったなと思いました。

まとめ

やはり、カンファレンスや勉強会に参加すると刺激になってとても良いです。 普段はエンジニア女性が一人という環境で仕事をしているので、世の中にはこれだけたくさんの女性エンジニアが活躍していらっしゃる!と実際に体感するだけでも、自分の世界が広がるように感じます。

カンファレンスの楽しみを知れたばかりなのですが、今夏第二子出産になるので、しばらくイベント等には参加できなくなりそうです。うーむ…もっと行きたい!

またいつの日か、「託児あり+土日祝+日中開催」という素敵な条件のイベントがあれば、第二子は夫にお任せしてまた子どもと一緒に参加したいなとこっそり考えています。

NSTableViewの行ドラッグ&ドロップをやってみた

今回はNSTableView内の行をドラッグで移動させてみます。

やること

  1. ドラッグ元の行番号をPasteboardに保存する。
  2. ドロップされた時に、そのドロップを受け入れるかチェック。
  3. ドロップを受け入れたら、Pasteboardに保存していたドラッグ元の行番号を取り出して、ドロップ先と入れ替えるなど。

3では用途に応じて、移動元の行と移動先の行に対して自由に操作を行います。
今回は、移動元と移動先を「入れ替える」挙動にしてみました。

実装

NSTableViewDataSourceの以下3つを実装します。

1. ドラッグ元の行番号をPasteboardに保存する

func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
    // Pasteboardにドラッグ元の行情報を記録
    let data = NSKeyedArchiver.archivedData(withRootObject: rowIndexes)
    let item = NSPasteboardItem.init()
    item.setData(data, forType: draggingUTIType)
    pboard.writeObjects([item])
    return true
}

ペーストボードを使う所が少々トリッキーだなと感じました。

2. ドロップされた時に、そのドロップを受け入れるかチェック

func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation {
    // 今回は、同じTableViewからのDropのみを受け付ける
    guard let source = info.draggingSource() as? NSTableView, source === tableView else {
        return []
    }    
    return .move
}

例えば、別のウィンドウからファイルをドロップするような場合もここに入ります。 ファイルのドロップを受け入れたい時、または受け入れたくない時は、ここで許可や拒否をします。

  • .moveを返す:ドロップを受け入れる
  • []を返す:ドロップを受け入れない

NSDragOperation

今回は「移動」させたいのでNSDragOperation.moveを返しています。 NSDragOperationには、他にも.copyなどの操作があるので、移動以外にも使えるようです。(試していません)

3. ドロップを受け入れた後の処理

func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool {
    // ドラッグされたアイテムのUTI typeを確認
    guard let item = info.draggingPasteboard().pasteboardItems?.first?.data(forType: draggingUTIType) else {
        return false
    }
    // Pasteboardに記録しておいたドラッグ元の行Noを取り出し
    guard let sourceRowIndexes = NSKeyedUnarchiver.unarchiveObject(with: item) as? IndexSet, let from = sourceRowIndexes.first else {
        return false
    }

    // ... 入れ替えの処理など ...
    
    return true
}
  • ドラッグされたアイテムのUTIを確認して整合性チェック
  • Pasteboardに記録していたドラッグ元の行番号を取り出し

などしています。

ここではドロップ先の行番号が取得できるので、移動元と移動先の行番号を使ってデータの入れ替えなどを実装できます。

UTI

今回初めてUniform Type Identifiersの事を知りました。

サンプルではpublic.dataを指定しました。(誤っているかもしれません)

サンプル

以前にNSTableViewを試したサンプルに、ドラッグで行を入れ替えるコードを追加しました。

github.com

以上です!

NSTableViewをCocoa Bindingsで使ってみた

TableViewにデータを表示するためにCocoa Bindingsを初めて使ってみたので手順をメモしておきます。

環境

はじめに

ViewControllerにTableViewを設置しておきます。

f:id:takopomm:20170405151155p:plain

こんな感じです。

1. Array Controllerを設置

f:id:takopomm:20170405151356p:plain

Array ControllerをSceneの中に追加します。

f:id:takopomm:20170405151403p:plain

@IBOutletでViewControllerに接続しておきます。

class ViewController: NSViewController {
    @IBOutlet var arrayController: NSArrayController!

2. モデルを書く

TableViewに表示したいパラメータを持つモデルを定義します。

例えば、「No」「名前」「年齢」などなど…自由に。

3. Array Controllerにコンテンツを追加

先ほどIBOutletで接続したArray Controllerに、TableViewに表示したいパラメータを持つモデルデータを追加します。

arrayController.content = [もでる1, もでる2, もでる3, ...]

という感じです。

4. Storyboardの設定

4.1 Array Controller

Array Controllerを選択した状態で、Attributesの設定項目Object Controllerを編集します。

f:id:takopomm:20170405151707p:plain

  • Class Name: 先ほど定義したモデルのクラス名
  • Keys: モデルのパラメータ名を+から追加

f:id:takopomm:20170405151717p:plain

このような感じにしておきます。

4.2 Table View

Table Viewを選択した状態で、Bindingの設定項目Table Content - Content を編集します。

f:id:takopomm:20170405152031p:plain

  • Bind to Array Controller: チェックをONにする
  • Controller Key: arraygedObjectsのままにしておく

4.3 Table View Cell

Table View Cellを選択した状態で

f:id:takopomm:20170405152516p:plain

Bindingの設定項目Valueを編集します。

f:id:takopomm:20170405152523p:plain

  • Bind to Table Cell View: チェックをONにする
  • Controller Key:空欄のまま
  • Model Key Path:objectValue.xxx

Model Key Pathxxxの部分には、自分で定義したモデルの、表示したいパラメータ名を指定します。 上記の例ではnumberというパラメータを指定しています。

パラメータ名だけを指定してもダメなようです。objectValueが必要でした。

すべてのTable View Cellに設定する

TableViewのカラムが複数ある場合は、すべてのTable View Cellに対して、4.3のようにモデルのパラメータ名を指定しておきます。

以上で準備完了です。

5. 実行

f:id:takopomm:20170405152838p:plain

表示できました!

TableViewDataSourceを指定しなくても、データを表示できる所がいいですね。

ハマったところ

Table View CellModel Key Pathに何を設定したらよいか分からず色々と試していたら、Storyboardのビルドが一向に進まず、しかしエラー内容は特に表示されず、、という状況になってしまい困りました。。

サンプル

上記の実装だけですが、GitHubに置きました。

github.com

Nexus 5Xにfactory imageを焼こうとした時の試行錯誤帳

factory imageを焼こう

Android OのDeveloper previewが出ましたね。
私は普段iOSをメインに使っていることもあり、Androidはちょっと冒険しやすい環境なので早速入れてみました。
バックアップを取る必要がある人は、factory imageを焼く前にバックアップを完了させておきます。私は特に何もせず始めてしまいました。(そしてすべてのデータがきれいさっぱりなくなりました!)

インストールの際に詰まったこと

端末がロックされているためインストールに失敗していました。

解決法

Androidの設定画面でOEMロックを解除してから、fastbootモードを起動、端末のロックを解除してからインストールします。

インストール手順

factory imageを手持ちの端末にインストールする手順を書き残しておきます。

環境

  • Nexus 5X
  • Android 7.0
  • Mac OSX 10.11
  • adbコマンドはすでに使える状態であることを想定しています。

手順

1: Nexus 5X用のfactory imageをダウンロードしてくる

2: Nexus 5XとPCをUSBで接続

3: Nexus 5Xの設定-開発者向けオプション-OEMロック解除をONにしておく

4: Nexus 5Xをfastbootモードにする

$ adb reboot bootloader

上記を実行して、Nexus 5Xをfastbootモードで起動させます。

5: 端末のロックを解除する

fastbootモードになると、ドロイド君のお腹がパカッと開かれてる画面になると思います。(ちょっと可愛い…!)
この画面下部の方に、

DEVICE STATE - locked

と表示されている場合は、端末がロックされている状態です。
この状態ではインストールできないので、以下のコマンドを実行して、端末のロックを解除します。

$ fastboot flashing unlock

すると、ロックを解除するか確認する画面が端末に表示されます。

「Yes」を選択しようと画面をタップしても反応しないです。
端末右横の「音量ボタン」を押すと、カーソルが動きます。
Yesにカーソルが合ったら、「電源ボタン」を押すと、ロック解除が実行されます。

ロックが解除されると、

DEVICE STATE - unlocked

と表示されます。

6: シェルを実行する

ダウンロードしたfactory imageのフォルダの中に、flash-all.shがあるので、これを実行します。

$ ./flash-all.sh

(↑カレントディレクトリがfactory imageのフォルダな状態で実行しています)

すると、色々と実行されていき、OSがインストールされます。

以上です!

Geek Women Japan 2016 に子どもを連れて行ってきた話

昨年11月に開催された、Geek Women Japan 2016に行ってきた時の振り返り話です。

eventdots.jp

しかしもう既に4ヶ月も過ぎてしまっておりますが。。
(明日開催されるミニカンファの前に何とか投稿したかった…!)

とてもありがたい事に、このカンファレンスでは託児所を用意してくださっているということで、まだオムツもはずれていない子ども3歳と一緒に行ってきました。(小声:パパが快く子守をしてくれればよいのになぁと思いつつ)

託児を利用するか悩みました

このカンファレンスにはどうしても行きたかったので、夫に何とかお願いするか託児を利用させてもらうか、ギリギリのギリギリまで悩んだ結果、託児を利用させてもらう事に決めました。が、その選択をして本当に良かったです。

実は当日の朝も、託児を利用することに対して妙な罪悪感のようなものを持っていて(←この気持ちはお母さんあるあるかなと思いますが…)、

「託児してまで参加してよいものか…」「私はダメなお母さんなのでは…」「やっぱりキャンセルしようか…」

とずっと葛藤していましたが、「ええいもう行ってみるだけ行ってみよう!」とモヤモヤをえいと振り払って出発しました。

いざ託児のお部屋へ

そして託児室にお邪魔してみると、午前中は我が子一人だけだったようで、 「あっ…なんだかとても申し訳ない…」と内心滝汗をかきました。。
たった一人のために保育の方々が来てくださったと思うと、非常に申し訳ない気持ちでいっぱいに。。

午前のセッションは少し早めに終わり、お昼の時間がゆったり取れたので、子どもと一緒に代々木公園に行きました。
この日はとてもお天気が良かったです。
青空の下、持参したお弁当を食べて、どんぐりを拾い、のんびりお散歩してから戻りました。

午後からは託児の方が他にもいらっしゃって、室内がとてもにぎやかに! 「あぁ、よかったー…」と正直ホッとしたことを覚えています。

ぬいぐるみを頂きました

託児室では、Salesforceのキャラクター(アストロくん?)のぬいぐるみをいただきました。今でも「タヌキしゃん」と呼び可愛がっています。
特にしっぽの部分がふわふわしているのが気持ち良くてお気に入りのようです。
しっぽをなでなでしながら寝付く…という、なんとも素敵な入眠アイテムとなっております。
肌触りが良いぬいぐるみ、最高!

子どもを連れて参加すること

子はまだ3歳なので理解できていないとは思いますが、こういった場に少しでも慣れ親しんでもらえたら、お母さんは嬉しいなぁと思っています。
(昨年夏のMakerFairも、私がどうしても行きたかったので連れて行きました)
(その時は早々にぐずり出してしまい、ほとんど見れずに終わりましたが…)

こういった託児サービスを無料で提供して下さることは本当にありがたかったです。そして休日開催であったことも。 未就園児を育てている私にとっては、この2点のお陰で、イベント参加への敷居は格段に下がりました。

託児は有料でも利用したいです。(ですが千円程度なら…!す、すみません…)

じっと座って静かにお話を聴けるくらいの年齢になったら、一緒に聴講してみたいなぁとも思いました。(個人的な夢です)

最後に

託児所を手配してくださったスタッフの方々。
お昼の時間には「お子さまと一緒にお外に出られても良いですよ」と柔軟に快く対応してくださった託児室の方々。

本当にどうもありがとうございました。とてもとても、感謝しております。

昨年は仕事と育児とアレコレ悩みすぎて自ら荒波にざぶーんと飲み込まれていたような時期がありましたが、GeekWomenJapan2016でプラスのエネルギーを沢山もらったので心の元気が復活しました。参加して本当に良かったです!

明日のミニカンファレンスも楽しみにしています。

Swiftで色のenumを作ってみる

CGColorのenumを作ってみようと思いました。

CGColorのenumを作ってみる

色の定数を作っているところが気持ち悪いというか…!
もうちょっと何とかならないかなと考え中ですが、一旦出力しておきます。