日本全国酒飲み音頭
テーマソングです https://t.co/sDeiatGuSU
— mot (@pg_mot) 2018年4月7日
水曜は週の真ん中だから酒が飲めるぞ
— mot (@pg_mot) 2016年10月8日
水曜日は週の真ん中だから酒が飲めるぞ
— mot (@pg_mot) 2016年11月16日
もっとGoogle Homeで作ったスマートホームを自慢したい男たち
こちらは RCC OBOG Advent Calendar 2017 - Adventar の9日目の記事です。
前日は irgaly さんの KotlinなAndroidプロジェクトがBreakpointで止められない問題 - Qiita でした。
まずは前置き
GoogleHomeのこと書こうとしたら5日目、PG_nokkii大先輩の Google Homeで作ったスマートホームを自慢したい男たち - Qiita に完全に先を取られたので、なんとかして差分を作るか別のことを書こうと思ったのですが、まあ物事には限度ってやつがあるので当初の予定通りGoogle Homeの話を書きます。
Google Homeって?
昨今話題のスマートスピーカーの一種です。Googleが開発し販売しています。内部にはGoogle Assistantが搭載されており、これ自体はAndroidでも利用可能なものです。 GoogleHomeにはユーザインターフェースとして画面は搭載されておらず、マイクとスピーカーでしかユーザとのコミュニケーションが取れません。 VUI(Voice User Interface)としての色が濃く、表示できる情報量、ユーザからのインプット手法が普段のアプリケーションとは大きく違います。 このあたりの特色についてはこちらの資料 https://docs.google.com/presentation/d/14EO9b9DitmtZ1SGTA1-9L6M7XkU4Pv0FgMgxvhgN6G8/htmlpresent が大変参考になるのでぜひご覧になってください。
何をしたか
今回はGoogleHomeに「テレビつけて」というとFireTVが起動し、「テレビ消して」というとFireTVがオフになる仕組みを作りました。
まずはシステム全体図がこちら。
全体像
全体像はGoogleHomeからスタートしていますが、逆のテレビをつける仕組みから説明したほうが簡単なのでそちらから順に説明します。
仕組み
テレビの操作
テレビと言っていますが裏はFireTVです。FireTVがHDMIスイッチャーを介してモニタに接続されています。 まずFireTVのon/off制御ですが以下のPythonスクリプトを利用します。
こちらは読んで字のごとく、PythonからFireTVを操作できるすごいやつです。 内部の仕組みとしてはすごい力技で見どころです。 そもそもFireTVは内部的にはAndroidで動いています。Androidにはadbというデバッグツールがありますが、 このデバッグツールはネットワーク越しにアドレスとポートを指定してホームボタンイベントを発行したり、戻るボタンイベントを発行させることができます。 そうですね、adbでFireTVを叩いてやればネットワーク越しに操作が可能ということになりますね。
さて取り出したるはGoogle謹製のPythonのみで書かれたadbコマンド実装
こいつを操作するためのサーバサイド実装がpython-firetvです。これであとはcurlを叩けばFireTVが操作できるようになるっていう寸法です。
HDMIスイッチャーの操作
さてHDMIスイッチャーも操作する必要があるのですがそれはこちらを使います。
iBUFFALO HDMI切替器 3台用 リモコン付 Nintendo Switch動作確認済 ブラック BSAK302
- 出版社/メーカー: バッファロー
- 発売日: 2012/01/23
- メディア: エレクトロニクス
- 購入: 3人 クリック: 10回
- この商品を含むブログ (9件) を見る
このスイッチャーは赤外線に対応していますのでささっとラズパイに赤外線LEDをつけて叩くようにしましょう。 参考にしたサイトがリンク切れで死んでいてキャッシュしかみつからなかったのでとりあえずこれで勘弁してください。
これは後日改めて自分でまとめたいと思います。
FireTVAPIを叩き、赤外線飛ばしてくれるHubotくん
さてあとはFireTV APIを叩いて赤外線を飛ばせば良いんですが、毎回ログインしたりするのは面倒なので、Hubotにやらせてslack越しに触らせましょう。 Hubotのコードは以下
実際のコードはここ、https://github.com/pgmot/bot/blob/master/src/scripts/remote_control.js
非常にシンプルでコマンドに合わせて irsend
と curl
を叩いているだけです。簡単。
このようにコマンドに合わせて動いてくれました。
GoogleHomeからコマンド発行をする
さてあとは簡単な話です。GoogleHomeの入力をどうやって受け取るかというとIFTTTを利用します。 IFTTTにはGoogle Assistantとの連携機能が実装されていますのでこれを使います。 IFTTTはSlackにPostする機能もあるのでこれを組み合わせればGoogleHomeからSlackを操作してbot操作が可能になります。
IFTTTでは4つの種類の処理が可能です。
- Say a simple phrase: 特定の文字列に反応します
- Say a phrase with a number: 特定の数値に反応し、後続の処理に数値を引き渡せます
- Say a phrase with a text ingredient: 特定の文字列に反応し、後続の処理に文字列を引き渡せます
- Say a phrase with both a number and a text ingredient: numberとtextの組み合わせができます
今回はつけるか消すかなので、Say a simple phraseを利用します。
ひとつの連携に3つまでのフレーズが登録可能です。適宜設定しましょう。
あとは「テレビつけて」というフレーズが来たら、Slackに「tv on」と通知すれば、Hubotが読み取ってHDMIスイッチャーの操作とFireTVの操作をしてくれるようになりました。 やったー
問題点にぶつかる
これは問題点っていうほどではないんですけど、これを連携させるとSlackが大変なことになりました。
画像中ではエアコンの操作をしていますが、これをgeneralでガンガンされると不要な通知がガンガン来まくって最悪になります。 そこでbot専用部屋を作って対応しました。ボット部屋にはマスターであるところの自分を入れないことで通知が来なくなり快適になりました。 というかなんですか、ボットたちが裏でよしなに連携取り合ってるっていうシチュエーション良くないですか???ありえんよさみが深い、、、、
Google Homeを喋らせる
さてGoogle Homeなかなかいいおもちゃでしたが、1つ問題点があります。 それはGoogle Homeから喋らせることができないのです。基本的にはOk Googleから始めることしかできないので、たとえば何らかの通知をさせたいといったことはできません。 はて困ったと色々調べていると便利なソフトを見つけました。
こちらGoogle Homeを喋らせるnodeのライブラリです。今日久々に調べたら導入してみた系記事がいくつかあったのでそちらを参考にすると良いでしょう。 仕組みはこちらも力技で、まずテキストをGoogle TTS(Text to Speech)でmp4に変換してその音源をChromecastの要領でGoogle Homeにぶん投げるという実装がなされています。なので微妙に声が違います。 こちらの実装はbot中ではこちらにあります。https://github.com/pgmot/bot/blob/master/src/scripts/google-home-notifier.js
こちら実際に喋って便利かなと思い、たとえばリプライを通知しよう!となって実装しようとしたところで、ちょっとまて、絶対それ深夜にリプライ飛ばしてくる異常者が発生するやろこれアカンやつやとなりましたので実は特に通知部分の実装をしていません。
この問題の回避にはユーザの状況を認識して適切なタイミングで通知するような仕組みが必要で、まずユーザのコンテキスト認識する研究を引っ張ってきてだな、スマートフォンを用いた、ウェアラブルデバイスが普及し、、行動認識技術が、、、加速度センサ、、、、ウッ頭が、、、、、、
まあマジレスすると部屋の電気がついてるかどうかを取ればいいと思います。ついてたら家にいて起きてるときなので。
その他問題点
これはなかなか致命的で、しかも後からアップデートで予約語が増えたりします。実際にテレビ消してコマンドが乗っ取られた。
- Actions on Google/Dialogflowだと最初に「○○(アプリ名)につなげて」の準備コマンドが必要になる
これ毎回いうの絶対マヌケなのでなんとかしてほしい、IFTTTはそういう準備コマンドがいらないので最高
- IFTTTで登録できる文言数が少ない
反対にIFTTTは登録できる文言数が3つまでしかなく、いろいろなパターンを一括で登録みたいな機能もないのでコマンド追加は地獄のように大変。IFTTTは今すぐAPIを提供してほしい。
まとめ
まあいいおもちゃだし、今なんか安いから今のうちに買っとけ
ISUCON7本戦で人権を失いました(1年ぶり2度目)
こちらは RCC OBOG Advent Calendar 2017 - Adventar の1日目の記事です。
このadvent calendarは1, 2, 3日目が空席の状態で始まってしまう悲しい立ち上がりとなってしまいそうだったので急遽昼休みの時間を使って記事を書いています。 @pg_mot です。
今日はISUCON7本戦参加してきた話を書こうと思います。
予選突破の様子はこちら
本戦問題については本家にて公開されているのでこちらを参考にしてください
競技としては、某クッキークリッカーのマルチ対応したゲームで、クリックする対象は椅子という感じです。Chair Construct Online。 Websocketによる通信が常時行われており、各クライアントは椅子のクリックイベント、自動で椅子を生み出すアイテムの購入情報を送ってきます。 それをサーバサイドでうまく計算してWebsocket越しにクライアントに返すというゲームでした。
競技開始直後
最初は気軽にWebsocketね〜と思っていましたが、ゲームについて説明がなされた際に気になるボタンがありました。 はて5000兆って何ビットで入るっけ? 🤔、、、、エッ完全に嫌な予感がするぞ。となる。
とりあえず落ち着いてドキュメントを読んだりコードを読んだりプロファイラを仕込んで様子を見たりするところからはじめました。
プロファイラ編
いつもどおり abcang くんがプロファイラを仕込んだところうまくプロファイリングができないという問題にあたりました。 クライアントとサーバはWebsocketでつながりっぱなしなのでHTTP一発の通信などを想定して行うプロファイラがうまく動かずここでチームは早くも動揺してしまいます。
一部のプロファイルは取れなくもない状態だったので、そこから重いところに手を付けながら作業開始となりました。
アプリにやったこと
- アイテム定義を毎回DBから読んでいたのをアプリ側に直接書いて読むようにした
- Websocketを処理するサーバを分散するように最初のロビーサーバの実装を変えた
- 現在時刻の取得をDB介していたのをアプリでやるようにした
- むだなeach loopの削減(abcang)
- 計算した椅子の数の結果をDBで保持するように(syusui)
- Redis導入してそこにデータを置く(syusui)
結果
12009点で30組中18位という結果になりました。結果としては残念なものになってしまいましたが、昨年の本戦ではなんと初期実装点数を下回るという最悪の状況になってしまっていたので、少なくとも改善ができるようになったというのは成長できたのかなと思っています。
リポジトリはこちら gitlab.com
感想
今回の問題は基本的にアプリ側に課題が集中しており、nginxやMySQLなどのチューニングに一切手を出さずに終わってしまいました。 そうなるとミドルウェアとかそのあたりが得意な僕とabcangくんはかなりやることが減ってしまい、syusuiくんにはかなり負担をかけてしまったと思います。 この辺はアプリ実装力をもっと固めていく必要がありますね。
当初からRuby一本でやっているチーム新卒ですが、競技開始時に今回の課題的にもしかしてRubyがきついのではないかという議論が発生しました。 NodeやGolangに切り替えるという方針もあったのですが、 我々のチームはRuby以外の経験があまり多くなく、ここで言語を変えるのは危険すぎるという判断と、 メタ推理として言語に差のある競技はしてこないであろうというところから今回もRubyを選択しました。
ISUCON7 本選の利用言語比率 : ISUCON公式Blog
終わってみて使用比率を見ると半分以上がGolangになっているのをみて、Golangもちゃんと勉強しようなという気持ちになりました。
競技後の講評で、まずガッとオンメモリ化するという解法が示されていました。 これまでチームの戦略として必要になるまでオンメモリ化はしないという戦略を多く取っていました。 オンメモリ化にはかなりの労力を要することから、これは必要だというプロファイルが取れるまで取らない戦略でした。 しかし今回プロファイラがうまく動かずに動揺してしまいかなり保守的に競技を進めてしまいました。この点ドラスティックにやっていける胆力と経験をもっと積まなくてはなと思いました。 また当初危惧していた5000兆脚ボタンについて、危惧していたにも関わらずここの多倍長整数が足を引っ張るぞ!と思い至れなかったのは本当に実力不足だと思っていて本当に悔しいです。
今年の本戦も昨年に引き続き自らの新たな課題を見つけることができました。 全体としてアプリ実装力がとても低いということに気がつけたので地道にコードを書いていきたいと思います。
来年も開催されるのであれば本戦出場したいです。ちなみにチーム二年目は未定でそろそろ人も変えませんかという話をしているので、一緒に出てくれる人を募集しています。
最後になりますが、ISUCON7運営の皆様、本当にありがとうございました。
RCC OBOG Advent Calendar 2017。明日の2日目は asakuraくんが書いてくれました
そして人権を取り戻した(ISUCON7予選突破したぞ!!!)
覚えていますか、人権を失った日のことを、、、
あの日から一年、私たちは成し遂げました。
というわけで1年ぶり2度目のISUCON本戦出場です!やったー🎉🎉
メンバーは昨年ともに頑張った @abcang1015 くん、 @syusui_s くんです。 昨年は皆卒業を控えた学生でしたので「チーム卒業」として戦いました。 今回は全員が新卒になったということで「チーム新卒」という名前でエントリーしました。
前回は学生枠での突破ということでしたがなんと今回は1日目2位という自分でもかなり驚く結果となりました。
ここではざっくりチームで何をしたかという流れを書いておきます。
結果
1日目2位 268,588点 (全体では7位)
リポジトリ
nginx.confは最後の方ちゃんと管理できてないので厳密じゃないです
役割分担
あまりガッツリ決まって無くて、最初の行動としては
- pg_mot: レギュレーションと渡されたサーバ見て戦略考える
- abcang: プロファイラ仕込みまくる
- syusui_s: コード読んでコメント撃ちまくる
というところから始まりました。
あとはコード読んだりプロファイラの結果を見たりレギュレーションから点数算出方法見たりしてドコが肝になりそうかを考えてissueを潰していくみたいな感じです。
自分のやったこと
- めっちゃサーバスペック低い上、画像返さないといけないのに100Mって絶対詰まると思う
- レギュレーション見てるとどうやらキャッシュが大事っぽいので、nginxのその辺の設定について調べ始めて設定する
- あとMySQLがToo Many Connectionで落ちるじゃん何だこれってなったので、max_connectionsあたりのパラメータいじる(どうやら実装がバグっていたらしいこれはabcangくんが直した)
- 残りは二人を応援しながらログとか眺めてた
今回もあんまり仕事してないですね。。。あとはチームの議論を回したりしてた。
良かった点
- 今回謎のハマりみたいなのが一切なくスムーズに作業できた
- ISUCON6で空気感わかってたおかげっぽい。8時間練習は大切
- ちゃんとプロファイラとかで計測してから改善した
- コレは本当に大切ですね
- これやったら良くなりそうみたいな雑な感覚じゃなくて、ちゃんと理由を持って修正できた
- 意味のある行動ができた
- まず1台でやってあとで2台にするという戦略が取れた
- 6本戦ではできなかったこと
良くなかった点
- 互いにちゃんとコードとかレギュレーション全部見れてなかった
- ぼく: コードあんまり深く読めてない
- なんと今回commit一回もしてない,,,
- abcang: レギュレーションほとんど読んでない
- 終了1時間前ぐらいに「あーfetchって直接点数に意味ないんですね」などと供述し、、、
- 厳密には意味はあるけど、、、
- syusui_s: しゅーすいくんは偉いからちゃんと読んでた(読んでなかったら記事書いて白状して)
- ぼく: コードあんまり深く読めてない
感想
去年出たし一年でどれだけこれたか試してみようやというあたりから始まったのですが、まさか本戦に出れるとは思っていませんでした。 次こそ優勝狙ってやっていくぞ!
運営の皆様、今回準備で大変だったとは思いますが改めて勉強になりましたし、楽しかったです。 本戦も楽しみにしています!!!
新宿オフィス楽しみ!!!!!
メンバーの感想
ここにはsyusui_sくんの記事が入ります
人生
人生わからなさすぎて毎日仕事でひたすらコード書いたりインフラいじったりドキュメント読んでるけど、このままでいいのか感のまま日々を過ごしている。 人が生きると書いて人生、、、
Github;shopの顛末
夢
3週に1度ぐらいのペースで去年末に亡くなった祖父の夢を見る。 夢の中ではごく自然なんだけど、目が覚めた瞬間に現実を思い出して泣いてしまう。
僕はいわゆる初孫ということもあって、大変にかわいがってもらったと思っている。 小さい頃は色んな所に連れて行ってくれたし、大きくなってからも沢山の支援をしてくれて、院まで行けたのは祖父の力が大きかったと思う。 なにより祖父の家にあったWin95と当時としては一般家庭には珍しいインターネット回線は、僕の心をひきつけたし、そうして今の仕事につながっているのだろう。 晩年は異常な切れ者だったと言われる姿はなくボケ老人となっていたが、それでも僕には優しくしてくれたし、今でもあの笑顔が浮かぶ。
夢の中に出てくるときは大抵僕が弱っているときで、いつまでも心配させたくないんだけど、それでも励ましてくれているようで、目が覚めて一通り泣いたあとは、気合が入る。 あまりスピリチュアルなものは信じてないし、身も蓋もないことを言えば、泣けばスッキリして気合が入るというメカニズムなんだろうけど、それでも僕には十分すぎる。 早いこと出てくる必要がなくなるように、気合い入れてやっていこう。
最期に直接言えなくてちょっと後悔してるけど、ありがとう。お盆には帰るよ。