2023年12月7日木曜日

クラフト系ゲーム環境とサーバーと猫の話

mhidakaが建立した Advent Calendar 2023 7日目です。

近況としては数年前に転職していわゆる技術の最前線からはやや距離は置いているものの、新しい事業を作るというところで割と真面目に働いています。コードは普通にガチャガチャ書いてます。

プライベートではクラフト系だったりPvEのゲームとかは好きなので、ゲーミングPCを自作したり、ゲーム用サーバーを建てたりとかあれこれやってます。

デスクまわりはこんな感じです。机の下にキューブ型ケースの自作用PC2台を積んで置いていて、それぞれゲーム用PCとサーバー用PCです。


ゲーム用PCがどんなんか

構成はよく変えるけど、だいたいAMD系であることが多いです(純粋に好みとして)。
キーボードはゲーミングキーボード的なのを何度か買おうと考えたけど、結局ストロークの浅いのが好みなのでThinkPadキーボードをずっと使ってます。
マウスは超軽量という評判に惹かれて買ったHyperX Pulsefire Haste 2を愛用してます。
クラフト系ゲームをやっていると左手が忙しいのでRazer Tartarus V2も併用している。
インディーズゲームとかを遊ぶときに、ダウンロード元を何処まで信用できるかに懸念があるので、他のPCとは独立させています。
ここ数年で長くプレイしたゲームはこの辺り。
  • Icarus | The Future of Survival
  • Valheim
  • 地球防衛軍5
  • Empyrion
  • ARK
  • Watch Dogsシリーズ
  • Minecraft
Valheimで建築した出雲大社の巨大神殿

Icarusで火事で焼け落ちる拠点を呆然と眺める姿


サーバー機にしてるPC

数人でクラフト系のゲームをやってるとホスト(サーバー)を誰がやるかが課題に挙がります。自分がプラッと建築とかしたくても、ホスト役の人がゲームを起動してないとワールドに入れないのは都合が悪いんですよね。レンタルサーバーを使うのもいいけど、建てっぱなしにするのはお金が継続的に掛かるし勿体ない。なのでサーバーを建てることに。

以前はDeskMiniという流行りのMini PCにDebian Linuxを入れてそれにLinuxGSMというサーバーを建てるのを便利にするのをいれて運用していました。


ただ、ゲームの数が増えてくると1個のPCで管理すると別のゲームに影響しそうなので、ゲームごとに分けたくなり、だからといって物理的にPCを増やすのは面倒なので、仮想化環境を構築することにしました。
それが今のサーバ機にしているPCで、Proxmox VEで中に複数のサーバーが動いています。こだわりどころで言えば、クラフト系のゲームのサーバーって結構メモリを食うので、メモリを128GB積んでいること。さらにECCメモリなので、動かしっぱなしにしても謎なエラーを気にしなくて良いと言うのがあります。


また、Proxmox VEにはPCI(e) Passthroughの機能があり、仮想マシンに物理のGPUを接続できます。なので勉強がてら仮想マシンのUbuntuでJupyter NotebookStable Diffusionとか動かしてみたりとかにも使っています。ただ、MircoATX用の小さい筐体にあれこれ詰め込んだ結果、中身が地獄みたいになっているのはご愛嬌です。

詰め込みすぎたサーバー機の中身

ネットワークのお話

仮想マシンとしてサーバーをたくさん建てるのは良いけど、外からのアクセスを考えるとルーティングをちゃんとしないといけません。罠になりそうなのが2つあります。1つは契約してるインターネットプロバイダがそもそも外から繋げられるようになってるかです。もう1つは使っているルーターのポート開放の挙動です。ポート開放がなかなかの曲者で、一般向けのルーターだとポート開放の機能がオマケ程度になっていて、アクセス元が内側か外側かで挙動が変わって、動いたり動かなかったりするケースがあるからです。なのでこの辺りで嵌ったら正式にサポートしているルーターを使うことをオススメします。僕はメルカリで購入したYAMAHA RTX830を使っています。


余談:猫用定点観測カメラ&給餌器

自宅に猫が2匹いますが、飼い主の朝が遅いため、朝御飯はタイマー付きの給餌器に任せています。ただちゃんとご飯を食べられているかの確認(黒白さんが灰錆さんのご飯を強奪するんですよ、、、)に録画用のRaspberry PIを設置しています。

仕組み的にはRasplerry PiにインストールしたDebian Linux上でこんな感じのシェルスクリプトをcronで決まった時間に実行しているだけです。(ついでに録画されたファイルはnginx経由でローカルネットワークからのみ閲覧できるようにしてます。)

#!/bin/sh

OUT_DIR=/var/www/html/movies
FILE_NAME=`/bin/date "+%Y%m%d-%H%M%S"`.mp4

# USBをオンにしてLEDライトを点灯
/usr/sbin/uhubctl -a on -p 2

# カメラの設定
/usr/bin/v4l2-ctl \
  --set-fmt-video=width=320,height=240,pixelformat=YUYV \
  -d /dev/video0
# ffmpegで録画
/usr/bin/ffmpeg \
  -f video4linux2 \
  -s 320x240 \
  -t 600 \
  -i /dev/video0 \
  -r 10 \
  -c libx264 \
  -threads 4 \
  $OUT_DIR/$FILE_NAME

# USBをオフにしてLEDライトを点灯
/usr/sbin/uhubctl -a off -p 2

ご飯の時間になるとこれによって録画されるという寸法です。

給餌器と録画用Raspberry Piの配置

撮影された動画

なお、晩御飯は人間が手であげているのですが、ご飯時になるとこういう感じで圧を掛けてきます。
飼い主に御飯の圧を掛ける2匹


来年とかに思うところ

コロナ禍も落ち着いてきて、物理イベントも増え始めたので、物理的に何か作りたいと思う今日この頃です。

2020年8月14日金曜日

一年越しの転職ブログ:Ubie株式会社にジョインしました

概要

2019年10月にUbie株式会社に入社していたのでその報告です。

なんで今頃書いたの?

入社エントリーを書いてとめっちゃせっつかれました。物臭なのと入社前後がいろいろ変わった時期で忙殺されていて書けていなかったのですが、いま思えばUbieには入社を決めるだけの魅力があったので、遅くなりつつも筆を取ることにしました。


君は誰?

僕自身、いろんなことをやっていたのですが、twitterSlideShareの講演資料WantedlyのプロフィールQiita、このブログなど、いろんなところに情報が散らばっているので、ざっと自己紹介します。


何がしたい人?

個人としては手を動かして何かを作っていたい、社会との接点としては何かを作るなら誰かの役に立つもの、面白いものでありたい人です。


社会人になるまで

小学校のときにN88-BASICを触りプログラムを学び始めました。中高生のころは小遣いを溜めてPC部品やVisual BasicやVisual C++を買ってました(当時は無料で手に入る開発環境がなかったのです)。ずっとコードは書いていたものの高校くらいまでは学校の勉強をほとんどしてなかったので成績は低空飛行していました。両親および教師から「プログラムの仕事なんかない」といわれたのを真に受け(実際、当時は少なかった)、比較的得意だった物理科に進学した。当時は情報工学科がある大学はとても少なく、選択肢が無かったのもあります。とはいえ、大学3年のときにやはりプログラムがやりたいと考え、このころにJava(1.4→5の時期)とLinux(2.4〜2.6の頃)を独学で学び始める。当時の自分はライブラリを使うという考え方が無く、なんでもかんでもフルスクラッチで作っていたが、そのときの経験が今に生きているとも感じている(2D物理エンジンや3Dのレンダラー、通信プロトコルも自分で作ってた)。
大学院の修士課程のころに諸事情でメンタルをブッ壊し、新卒の就職活動をしくじる。就職氷河期の終わり頃で新卒カードを失うとまず仕事にありつけないDead or Alive状態でした。


社会人になってから

新卒でしくじったものの何とか仕事にはありつけた。しかし当時はバブルが弾けて以降、プログラマを正規雇用する企業はとても少なく、プログラマは派遣や受託企業で案件単位で動かされるリソースという扱いで、僕もそのうちの一人でした。2014年くらいまではSIerさんやメーカーさんでWindowsアプリ作ったり、業務系Web作ったり、Androidアプリを作ってました。
ただ、この頃の自分はかなり擦れています。僕自身、要求されたものを期限内に作っていたつもりですが、何か提案/提言すると「たかがプログラマ」という扱いをされていました(実際何度も言われた)。とはいえ、当時の自分はプロダクトを如何に作るかを知りませんでした。手を動かすのは好きだったので個人でいろんなものを作ってはいたけれど、それらをプロダクトとするのに何が必要なのかを知らなかったのです。
あの頃、SIerさんやメーカーさんで会った方々に聞くと「面白ければバズって広がる」とか「良いプロダクトを作れば自然と広がる」と返って来ましたが、いまいちピンと来ず、悶々とする日々を送っていました。だけど、これは後にいろんな勉強会やハッカソン、特にStartup Weekendに参加したことで、少しずつ理解でき、解消されていきました。もっとも、この辺りは昨今のプロダクト開発に関わっている方は普通に備えているマインドセットだとは思うので、「プログラマは依頼されたものを作っていれば良い」という環境に長くいた当時の僕に抜けていた考え方だったのだと思います。
その後、紆余曲折あり2014年12月に前職であるWantedlyにジョインしました。当時はまだ20人くらいで、Androidのアプリ開発に軸足を置きつつ、プロダクト開発に携わらせて貰いました。その時に学んだことや得たものはWANTEDLY TECH BOOKや、DroidKaigiを通してアウトプットさせて貰っています。Wantedlyにジョインしたモチベーションは、自分の氷河期時代だったころの学生にあった「如何に面接官を攻略して内定を勝ち取るか」や「会社員は社内のストレスに耐えていくもの」という価値観、「社会人と学生の接点の少なさ」に課題を感じており、それらを変えたいというものでした。いずれもプロダクトを通して、やれることと、自分のやりたいと思ってたことがおおよそできたので、後は後任の人達に任せて自分は別に移ることにしました。


今回の転職活動はどんなんだったか?

知人やWantedlyやLinkedIn経由で何社かお話を聞き、その会社の社会的意義と自分の能力や時間を掛けたいかどうかを基準に選びました。特に僕はモチベーションがピーキーなので、それが維持できるものを優先して探していました(逆に給与面や福利厚生については自分の能力から相場くらいであれば気にしない、ただし安売りはしない)。給与面や福利厚生面、技術的なTRYなど、魅力的なオファーはいくつか頂いていたのですが、その中でも自分の中で医療分野における課題やそこへの自分への興味と技術的なtryが重なり、Ubieへの入社を決めました。
このとき面談等していただいた会社および採用担当の方々には時間を割いて頂き、本当にありがとうございました。深く感謝申し上げます。


Ubieに入社前と入社を決めるまで

Ubieに来る前まではAndroidアプリをメインとしていたのでKotlin言語を使っていて、その言語界隈で名前が通っていた、@ngsw_taro さん、@sys1yagi さん、@shiraj_i さんの3人がUbieに在籍していたのは知っていました。
最初にカジュアル面談で話を聞いたときはサーバーサイドKotlin(Spring Boot)を使っていることや、AIで医療をサポートをしていることを聞きました。特に後者のAIの文脈は、僕自身学生時代に知識情報処理を学んでいたので「まぁ今のコンピューターならできるよね」くらいの認識だった(僕が学生だった2000年頃のPCではGPGPUは珍しく、CPUの性能も低く、32bitの壁でメモリも足りず、厳しかった)。なので最初の頃はUbieはスタートアップ的なプロダクトや組織の成長はするだろうと思いつつも、既に目指す未来が現実的な状態になっているように聞こえたので、一回断っていました。
その後、代表の阿部と話したところ、現在の医療現場には僕の認識を遥かに超える課題があること、それらが改善できれば医療従事者だけでなく、医療を受ける人にもメリットがあり、敷いては世界中の医療の改善に繋がるということを知りました。
たとえば医師の方は時間外労働の上限が960時間(普通は360時間)というとても厳しい環境に置かれています。他の職種ならば忙しいなら売上が増えるので人を増やすことができるのですが、医療系は学校の数が限られているため、それができず、如何に業務負荷を減らすかが肝になるとのこと。
現在、医療現場で課題になっていることの多くはテクノロジーで改善できるとのこと。そこの改善にフォーカスし、実際に現場に導入され実運用されているプロダクトはUbie以外には殆ど無いないとも。でも、そこがゴールでは無く、Ubieのミッションに「テクノロジーで人々を適切な医療に案内する」とあるように、むしろそこから先にある。
僕自身、過去にSIerさんで凄まじい量の紙ベースで行われていた生産管理をITストラテジストの方とシステム化して改善をしたことがあり、それは楽しい仕事だったことを覚えています。でもUbieが解決しようとしている課題はそれの遥か上をいっているし、社会的意義も大きく、自分もそれに携わりたいと思いました。
自分はエンジニアというよりも何かを作るのが好きな身として、自分が作っていて楽しいもの、そしてそれが人の役に立つものであって欲しく、Ubieがそれに一番近いものだったので、ジョインを決めました。


Ubieにジョインしてからのギャップや印象

ときどき巷で「スタートアップらしさ」というものが話題にあがります。「スタートアップなら〇〇するよね」みたいなやつです。でもUbieだとそういうのはあまり見ません。あるのは「その場その時勢における最適を選んだら結果としてそうなった」です。言語化すると当然のことなのかもしれないのですが、現実ではそれに嵌ってしまっているスタートアップはチラホラと見かけます。それが起こってない辺り、自分の想像の斜め上を行っていました。
僕がジョインした頃は社内でスクラムの運用が始まった頃でした。丁度そのとき面白いことが起こっていました。タスクのストーリーポイント(課題の大きさ)を決めるときに、数字がデフレを起こしていたのです。簡単にいえば実際2週間くらい掛かるタスクを「いけるっしょ!」で1週間と見積もったりするやつです(ストーリーポイントを工数扱いすると怖い人に起こられるのですが)。勢いがあるにしても、ちょっと勇み足状態でした。でも、メンバーの課題への気づく能力と意識が凄まじく、数字の適正化とタスク分解が数スプリントで行われるようになり改善されました。
組織についても今のUbieのビジョンやメンバー構成、ビジネスなどを考慮した上でどの手法が適しているかを踏まえつつ、組織を作っていっているので流石だと感じています。僕の過去の経験でもワンマンの組織には各メンバーの納得感が欠落する課題があり、話し合いベースの組織だと意思決定が延々として進まない課題があったと記憶しています。これらの躓きやすい課題に嵌まり込まずに、一緒に組織の実装を協力して作っていける人達がメンバーにいると感じています。ソフトウェアでは思想と設計と実装は中々思ったとおりに擦り合わないけど、組織でも同じだと僕は考えています。それをメンバー全員が一緒に考えていける人達だと感じています。


実際、普段は何をしてるの?

僕は「AI問診Ubie」という所謂ToBプロダクトの開発に携わっています。平たくいうと医療機関様で患者さんが使うタブレットとお医者さんのPCで使用するWebアプリケーションです。バックエンドはKotlinとRuby、フロントエンドはReactをType Scriptで書いています。たまに「AI受診相談Ubie」というToCプロダクトのコード(Vue.js)も書いています。
コードを書く以外だと、スクラムの各種セレモニー(プランニングやリファインメント、デイリースクラムなど)に参加したり、全体のOKRや採用の作業もしています。これだけ聞くと「エンジニアの仕事じゃない」と思われるかも知れません。実際、そんなふうに考えていた時期が俺にもありました(AA略)、が、プロダクト的な議論も採用も、少なくとも今のフェーズでは自分が関わることがミッションの達成には必要と感じています。Ubie自体、全員で採用をしていく組織です。


Androidアプリ開発者からWeb開発者になったこと

9年ほど前にAndroidを知ったとき、当時はあのような小型のデバイスでプログラムが容易に書けるデバイスは珍しく、のめりこみ、その後、8年ほどAndroidのお仕事でご飯を食べることができました。時期的にはAndroidの機能がPoorで最新情報をずっとウォッチし、新しいものが出るたびにキャッチアップし、自分のアイディアに組み合わせられないかという遊びをよくしていました。そして、それらの課程をまとめ、勉強会などにアウトプットしていました。縁あってDroidKaigiへの登壇も何度か務めさせていただきました。でもAndroidも9年も経つと成熟し、僕の興味の中心からは逸れてきていました。
僕はもともと個人でLinuxサーバーを立てたりするくらいLinux環境が好きでした。しかし最近のDockerやKubernetes、KVMやqemuという環境はついていけてなく、他にも所謂HTML5の上にいろんな技術が出てきていても、興味があるだけで止まっていました。
大きな勉強会とかで登壇できてたのは楽しかったし、名残惜しいと思いつつも、自分の興味が薄れてきてることを続けても誰も幸せにならないなと思ったので、新しいことをやっていきたいと思います。


閑話休題

長い雑文ですがここまで読んでいただいてありがとうございました。Ubieはいい会社なので、このブログを読んで少しでも興味を持って頂けたら嬉しいです。この記事では医療業界的な難しい話は敢えて書きませんでしたが、カジュアル面談等でご説明することは可能ですので、お話を聞きに来て貰えれば幸いです。

Ubie株式会社ホームページ https://ubie.life/

2020年1月24日金曜日

M5Stackで猫のトイレを体重計にする

猫様の体重を測るのが大変だったので、猫のトイレで体重計が測れれば嬉しいなと思ってやってみました。改造には何処のご家庭にもあるM5Stackとロードセルを使用しました。

概要

猫がトイレに乗ったとき、その数字をGoogleスプレッドシートに追記されるようなシステムを作ります。重量の測定にはロードセルをトイレの下に仕込み、その値をM5Stackで読み取ります。読み取った値はM5StackからHTTP通信で、GoogleスプレッドシートのGoogle Apps Scriptで作ったAPIに送信します。




ハードウェアの作成

ハードウェアの作成というと物々しいですが、今回作るものは市販の部品をパパっとハンダ付けするだけです。どんな部品を使っているのか、どう接続しているかを見ていきましょう。

用意する部品

使用する部品は次の通りです。これらの他に、ユニバーサル基盤やピンヘッダなどの小物は適宜使用します。
  • M5Stack Basic
  • ロードセル 4ポイント(薄型) 200kg(50kgx4)
    • 荷重を電気信号に変換する装置です。
    • 電気信号は微弱なため、そのままでは読み取れないので、専用のADコンバータが必要です。
    • 秋月電子で購入しました。
  • HX711使用 ロードセル用ADコンバータ モジュール基板
    • ロードセルの信号を読み取り、デジタル信号の変換するモジュールです。
    • 動作電圧は4.5V~5.5Vであるため、M5Stack
    • 秋月電子で購入しました。
  • ロジックレベル双方向変換モジュール
  • ケース
    • 百円均一のケースです。
    • トイレの近くに設置する都合上、作成する基盤が汚れないようにするのに使用します。

配線を考える

接続にはM5Stackの向かって右側のコネクタを使用します。今回は通信にはGPIOの16と17を使用しています。
余談ですがM5Stackのポートは、ディスプレイやスピーカーなど内部で接続しているものと競合するものがあります。この図では16と17を使用していますが、PSRAMと競合するため、PSRAMを使用する場合は適宜別のGPIOを使用して下さい。
具体的な配線は次の図のようになります。ロードセル用ADコンバータは5Vで動作するため、M5Stackにはロジックレベル双方向変換モジュールを介して接続しています。


ブレッドボードとサンプルスケッチで動作確認する

回路を実際にハンダ付けする前に、ブレッドボードを使って各部品を実験的に接続し、サンプルスケッチで動作確認をしましょう。秋月電子の「HX711使用 ロードセル用ADコンバータ モジュール基板」のページにArduino向けのサンプルソースがあるので、それを動かします。微調整が必要ですがそれは次の2種類です。


  • ピンアサインに関するもの
    • ADコンバータのデータ出力(DAT)とクロック入力(CLK)のピンを指定します
      • #define pin_dout  17
      • #define pin_slk   16
  • ロードセルのパラメーター
    • ロードセルが出力する信号について、ロードセルの仕様書に基づいて値を設定します。
      • #define OUT_VOL   0.0005f    // 定格出力 [V]
      • #define LOAD          50000.0f   // 定格容量 [g]

一通り動作確認が取れたら回路を作っていきましょう。

回路を作る

配線図を元に、黙々とハンダ付けします。

ハンダ付けが終わったら、テスターで想定外の繋がり方をしていないかを確認します。確認ができたら部品を乗せます。
一通り接続したらサンプルスケッチを動かし、ブレッドボードのときと同じように動くか確認しましょう。

Googleスプレッドシートを準備する

M5Stackがデータを送信する先となるGoogleスプレッドシートを準備します。作りたいものは簡単に次のようなイメージです。


  • データを受信したとき、その月のシートが無ければ作る
  • 受信したデータを書き込む
    • データは計測された値をそのまま記録する
      • センサーの故障時に気づきやすくするため、生のデータで保存する
    • 変化前と変化後の値を記録して、引き算すれば重量が計算できる


Googleスプレッドシート上には次のように見えることをイメージしています。


スクリプトを書く

Googleスプレッドシートのメニューのツール→スクリプトエディタでスクリプトエディタが開けます。
スクリプトの詳細については割愛しますが、HTTP通信のGETのパラメーターでロードセルの検知した重量の変化前(raw_weight_from)と変化後(raw_weight_to)の2つを受信するようにします。
今回作成したスクリプトは次のものになります。



スクリプトを公開する

スクリプトエディタでポチポチするだけで公開できます。

M5Stackで認証を通すのは大変なのと機密情報でもないので、今回はアクセス権限を「Anyone」にします。

スクリプトを動作確認する

公開したときのURLをcurlコマンドなどで開いてみて動作確認をしましょう。次の例ではパラメーターとしてraw_weight_fromとraw_weight_toを付け加えています。成功すればスプレッドシートにデータが追加されているはずです。
curl 'https://script.google.com/macros/s/ここにキーが入る/exec?raw_weight_from=30&raw_weight_to=40'

M5Stackのソフトウェアを作る

もっとも楽しいM5Stackのソフトウェアを作っていきましょう。
単純にロードセルの値を計測するのはサンプルスケッチで確認できました。しかしこれだけでは猫の体重を測ることはできません。それは値の計測は0.1〜0.2秒間隔で行っていますが、ゆっくりと乗ったり、乗った後に動いていると、値が安定しないからです。

値が安定したと判断する方法

値が安定するまで待つようにすればいいですが、ソフトウェア的にはどのように判断するかを決めなければなりません。幸い、この問題は高校数学で習う分散を使えば簡単に解決できます。だいたい0.1〜0.5秒間隔で計測した値を過去5〜10個くらい記憶しておき、それらの分散を計算し、分散が一定以下に下がれば安定していると見做すとすれば、それらしく動きます。この手の計算方法は他にもあるので、調べて使いやすいものを使うといいでしょう。

他にソフトウェアに必要な機能

今回作成するものの目的を達成するには、他にも次のような機能が必要になります。
  • WiFiに接続できる
    • M5Stackの標準ライブラリで可能
  • HTTPS通信でデータを送信できる
    • ルート証明書をハードコードすればHTTPClientで可能
この辺りは適宜調整して実装します。

ソフトウェアのソースコード

最終的なソースコードは次のようになりました。



組み立て

ハードウェアとソフトウェアの一通りの部品が揃ったら組み立てて行きましょう。一度にやると失敗したときにわからなくなってしまうので、一つずつ進めていきます。

猫のトイレに設置するための脚を作る

今回使用しているロードセルは次の写真のような形をしています。
このままでは取り付けられないため、固定用の部品を作ります。今回はBlenderで適当にモデリングして3Dプリンタで印刷しました。
印刷が終わった部品をロードセルに嵌め込みます。

改めて動作確認する

使用するロードセルは4つで1セットのものなので、配線をした後、仮でプラケースに取り付け、想定通りに重量が計測できるか動作確認をします。

この写真の例では6キロが計測できました(少々誤差が乗ってますが)。

ケースを作る

M5Stackと基盤は剥き出しのままでは、不意にオシッコが掛かったりしてショートしてしまうかもしれません。簡単にでもケースを作りましょう。今回は100円均一で買ったケースを使います。
まず、中に仮置きして、マジックで印を付けます。

次にカッターで切り抜きます。手を切らないように気をつけましょう。


最後に部品を納め、コードを通します。所々はテープで目張りをするといいでしょう。


設置する

一通り終わったら、ロードセルを猫のトイレに取り付けて、可動させましょう。


課題

実際に動かしているといくつかの課題があることに気づいたので紹介します。

ロードセルの値が安定するまでの閾値

ロードセルの値が安定するための閾値に分散を使用しましたが、閾値を適当に決めたのと、うち猫様はゆっくりとトイレに乗ったり、前脚だけ乗せて一回止まったりするため、数回に分けて計測されることがありました。閾値の調整が必要そうです。

静電気の話

ロードセルの信号は微弱なため、静電気で値が容易にブレます。特にこれを作っていた頃は冬場だったのもあり、絶対値で計測すると1kgくらいズレることがありました。デバッガで繋いで放置していると、少しずつ値が上昇していくこともありました。厳密な重量系の設計ならば、それらを踏まえて設計するのでしょうが、そこまで余裕はないので悩ましいところです。
とはいえ、継続的に測定していれば、体重が減少傾向か増加傾向かはわかるので、猫様の健康管理という意味では十分だと思います。

おわりに

完成してからこの記事を書き上げるまで、なんだかんだで3週間くらい間が開きましたが、適当に作った割に前述の課題が残りつつも安定稼働をしているようです。M5StackやGoogleスプレッドシート、3Dプリンター、今回は使用しませんでしたがAndroidやRaspberryPiなど、今では電子工作に便利ないろんな部品が簡単に手に入るようになりました。生活をよくするものを作れるのは楽しいので、こういうものを活用してこれからもいろいろなものを作っていきたいと思います。

左:チャーリーさん[7.2kg]、右:犀(セイ)さん[4.3kg]


2018年6月18日月曜日

M5Stackを使ってCatbell Notifierに繋がるペリフェラルを作る

作るもの

Catbell NotifierはAndroid ThingsおよびAndroidデバイス(5.0以降)で動作しますが、それにBLEで通信して状態を表示したり、光って知らせるためのペリフェラルをM5Stackを使って作ります。




Catbell Notifierとは

Android ThingsやAndroidデバイスで動作する、CIのビルドのような時間が掛かるものの通知をディスプレイに表示するためのアプリです。

プロジェクトサイト:https://github.com/cattaka/CatbellNotifier




このアプリ自体はディスプレイに状態を表示し続けますが、M5Stackという小さな開発モジュールにBLEで通信することで、そちらの液晶にも状態を表示できます。

M5Stackについて

M5StackはESP32というモジュールに次のようなものが扱える形でパッケージングされた開発モジュールです。
  • 320 x 240 TFTカラーディスプレイ
  • microSDカードスロット
  • スピーカー
  • 各種I/Oピン
Arduino IDEにM5Stackのライブラリを追加すると、Arduino IDEで開発できます。


価格も5000円弱と安価で、Switch ScienceやAmazonでも手に入ります。
ESP32はBLE(Bluetooth Low Energy)やWiFiのための技適が通っており、安価にこういったペリフェラルを作ることができます。


Catbell Notifier用のファームウェア

プロジェクトサイトの中にファームウェアのソースコードがあります。
これをM5Stackに書き込むことでAndroid上で動作するアプリと通信ができるようになります。


アプリ上での設定

ナビゲーションドロワーからPeripheral Settingsを開きます。


ペリフェラルの電源が入っていれば、リストにペリフェラルのBluetoothのMACアドレスが表示されます。表示されない場合は何処かおかしいです。
もし原因がわからない場合はnRF Connect for MobileのようなアプリでM5Stackに接続できるか確認し、問題を切り分けましょう。


チェックを入れ、トップの画面に戻ると接続されます。


LEDを取り付けて光らせる

M5Stackには拡張コネクタが有り、そこにフルカラーLEDを取り付けることで光らせることができます。

 

使用しているLEDはOSTBMCZ2C1DというカソードコモンのフルカラーLEDです。


配線図は次の通りです。

実際に実装したもののは次のとおりです。裏表の配置に気をつけましょう。

 

M5Stackに繋ぐためのケーブルも作ります。
フラットケーブルにコネクタをカシメて作ります。

 

動作確認で光らせるには、Edit Statusの編集画面から行えます。



筐体を作る

3Dプリンターで筐体を作れます。
3DモデルはBlenderで作ったものと、それをSTLにエクスポートしたものがあります。


筆者はReplicator Dualを使っているので、それようにMakerBotで並べて印刷します。丸い小さな円盤はヘルパーディスクと呼ばれる、印刷中に熱収縮で剥がれるのを防止するためのものです。



印刷が終わって塗装したい場合はヤスリやパテ、サーフェイサーで表面を整えます。

 

塗装が終わったら組み立てます。底面のネジはそのままだと机を傷つけることがあるのでクッションゴムを付けます。

 

 

最後に透明な樹脂で作った可愛いゴーファーのフィギュアを乗せます。

 


おわりに

通知をM5Stackに表示するペリフェラルを作りました。筐体は無くてもM5Stackだけでも動作させることができるため、電源さえ繋げられれば複数のM5Stackを接続して設置もできます。開発を楽しくする小物としていかがでしょうか。

2018年6月4日月曜日

CIの通知に便利なCatbell Notifierを作りました

モチベーション

最近のソフトウェア開発ではビルドやテストコードを自動で実行してチェックするCI(Continuous Integration)サービスを使用することが多くなりました。多くのGitHubのようなソースコードのホスティングサービスからもCIサービスが利用できるようになっています。

たとえばGitHubでのCIのチェック結果は各pull-requestに表示されます。

このチェック結果はpull-requestの画面に表示される以外にも、
Slackのような外部のサービスに連携することで、
スマホのようなデバイスにも通知することができます。

スマホへの通知も便利ですが、数が多くなるとそもそも見なくなってしまうため、
これらの通知がリアルタイムで反映され、表示されるものが欲しくなりました。
また机に置ける小さなディスプレイもペリフェラルとして欲しいです。


作るもの

WebhookのURLにアクセスすると、リアルタイムにそれが更新されるデバイスを作ります。デバイスにはAndroid Things(通常のAndroidでも可)を使用します。



Androidアプリには筆者が作ったCatbell Notifierというアプリを使用します。

モチベーションの項で言及した「机に置ける小さなディスプレイもペリフェラル」の作り方については、別の記事にて紹介します。

Catbell Notifierの仕組み

Webhookのアクセスからのリアルタイムな反映はFirebase Cloud Firestoreを使うことで実現します。AndroidアプリがFirestoreをオブザーブし、WebhookがFirestoreを更新します。具体的な流れは次のようになります。

  1. CIサービスがWebhookにアクセスする
  2. Google Cloud FunctionsにデプロイされたWebhookがFirebase Cloud Firestoreのデータを更新する
  3. Firebase Cloud Firestoreへのデータの更新がAndroidアプリに同期される
  4. Androidアプリが画面の更新やペリフェラルへ通知する
  5. ペリフェラルが液晶やLEDを光らせて知らせる


道具


Catbell Notifierのインストールと設定

Android Thingsが動作するRasbberry PI 3か、Lolipop(Android 5.0)以降のデバイスを準備します。
GitHubのreleasesからAPKをダウンロードし、adbコマンドなどでインストールします。
インストールが終わればCatbell Notifierを起動します。



起動したらサインアップします。



最初は何もないため、まずtopicを作成します。







topicにはGitHubのリポジトリ名を指定すると良いでしょう。



Webhookを確認する

Webhook Settingsを確認します。





この画面にはWebhookにアクセスするための情報が表示されています。notify_v1とnotify_v2の2つが表示されていますが、まずはnotify_v1の動作確認をしましょう。
curlコマンドなどで表示されているURLに、token、topic、item、statusを付加してアクセスします。

  • token : 認証のためのトークンです。
  • topic : 自分で作成したものの名前を指定します。
  • item : ブランチの名前のような表示したい名前を指定します。
  • state : Statusに表示されているものを指定します。これは自分で編集できます。

具体的なcurlコマンドを使ったときの例は次のようになります。
$ curl "https://us-central1-catbell-notifier.cloudfunctions.net/notify?token=<表示されているToken>&topic=CatbellNotifier&state=running&item=test_branch"
{"success":true,"topic":"CatbellNotifier","item":"test_branch","state":"running"}
レスポンスのsuccessがtrueならば成功です。
最初の画面に戻ると項目が追加されていることが確認できます。



Webhookを各サービスに対応させる

前述のnotify_v1はtoken、topic、item、stateを一つのURLにしてアクセスしました。
GitHubやBitriseといったサービスのOutgoing Webhookでは、itemやstateはHTTP通信のPOSTとして送られてきます。

このため、notify_v1のWebhookはこれらのサービスに対して直接使用することができません。この問題はnotify_v2のWebhookを使うことで解決できます。
Catbell NotifierにはこれらのHTTP通信の内容から、itemやstateを取り出す仕組みがあります。これはナビゲーションドロワーのServicesから確認できます。GitHubやBitriseはプリセットされています。





たとえばGitHubでは次のように指定されています。
追記:2018-06-04時点でこの指定に誤りがあったため、v0.7.1で修正しました


GitHubにWebhookを設定する

notify_v2のWebhookをGitHubに設定しましょう。
設定は次の通りです。

  • PayLoad URL
    • https://us-central1-catbell-notifier.cloudfunctions.net/notify_v2?token=<自分のトークン>&service=GitHub&topic=<作成したtopic>
  • Content type
    • application/jsonにする
  • Event
    • statusのみにする






設定が終われば、何かブランチをPushしましょう。
例えば"add_info_webhook_v2"というブランチをpushすると、画面に次のように追加されます。



おわりに

複数のリポジトリに跨った開発をしていると、どのリポジトリの何が最新であるか、それが素早く把握したいときがあります。紹介したCatbell Notifierを使えばそれの見える化をできます。見える化して楽しいチーム開発ができればと思います。
また、今回は触れませんでしたが、ソフトウェア開発に置けるCIに限らず、他の用途にも使えますので、ご興味のある方は他の用途も試してみてください。