happybirthday | RubyGems.org | your community gem host
使い方は以下の通り
require 'happybirthday' birthday = Happybirthday.born_on('2000-01-01') birthday.age.years_old # => 18続きを読む
happybirthday | RubyGems.org | your community gem host
使い方は以下の通り
require 'happybirthday' birthday = Happybirthday.born_on('2000-01-01') birthday.age.years_old # => 18続きを読む
普段お仕事でRailsアプリケーションを作ってて、今はチーム内共通のMySQLサーバーをみんなが参照している。
これをDocker化してうまくみんなにイメージを配布したかった。
前職ではMySQLにデータが投入済みのDockerイメージを作成して、コマンド一発でデータが入った状態のMySQLコンテナが立ち上がるようになっていたので、そのやり方を元同僚に聞いて再現してみることにした。
docker-composeを使って
の2つを立ち上げて利用する。
まずはデータ入りDockerイメージ作成
/var/lib/mysql
以下をコピーdocker build
すれば出来上がり続いてデータ入りのイメージから、データ投入済みMySQLコンテナを立ち上げる
順を追って詳細説明していきます。
公式イメージからMySQLコンテナの起動
起動したらDB作成とデータ投入
$ docker run -d --name db -e 'MYSQL_ALLOW_EMPTY_PASSWORD=yes' -p 3306:3306 mysql:latest
データ入りのファイルをホストにコピー
$ mkdir -p ./data/var/lib $ docker cp db:/var/lib/mysql ./data/var/lib
Dockerfileの作成
FROM busybox RUN mkdir -p /var/lib/mysql COPY data/var/lib/mysql /var/lib/mysql RUN chown -R 999:999 /var/lib/mysql VOLUME /var/lib/mysql CMD tail -f /dev/null
最後に
$ docker build .
docker-compose.ymlをつくって $ docker-compose up
version: '2' services: db-storage: image: {さっきつくったdocker image} volumes: - /var/lib/mysql db: image: mysql:latest ports: - 3306:3306 volumes_from: - db-storage
storage用のimageをDockerHubなどのレジストリにpushしておけば、他の開発者はプロジェクトのリポジトリをcloneして docker-compose up
するだけでデータ入りのDBが即座に立ち上がる。
最初これを作ろうとしたとき VOLUME
指定をするとimageにデータが保存されなくて困っていたところ、元同僚から「Dockerfileの中でVOLUMEを指定する前に追加したデータはimageに含まれるんですよ」というアドバイスをもらい無事に実現できたのでありがとうありがとうという感じ。
とりあえずやりたいことは実現できたが、微妙にやり切れてないのがdocker-compose.ymlをversion: 3
で書くことで、version3から volumes_from
が消えていてうまく書けなかったりしている。
ちょうど趣味プロジェクトでまあまあのデータ量のDBを扱うアプリケーションを作ろうとしていたので、Docker化をして友達の開発者とかに「こんな感じで動くよ」ってすぐに見せられて便利。
Docker imageにでっかいデータをのっけることの筋が良い悪い話はいったん置いといてください。
この記事を書いたあたりから、よりDDDについて知りたくなって追加で読み始めた本
現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法
業務におけるプログラミングでオブジェクト指向を実践するにはどうすればよいかを、ここまで具体的に書いてくれてる本は初めてだったので読んでよかった。
この辺の話が印象に残っていて
特に4章の「ドメインオブジェクトの見つけ方」にかかれていた「業務の関心事の3分類 ヒト・モノ・コト」の話に関しては
普段自分が仕事で要件や仕様を整理する時に意識していたことが言語化されていて感動した上に
そこで整理したドメイン知識やロジックをいかにドメインオブジェクトとして表現するのかについて、DDDでいうとこの戦術的なアプローチが紹介されていて学びがあった。
またDDDの文脈からは少し外れるけど
7章では画面とドメインオブジェクトの設計をどう連動させるかの話の中で、複雑な画面のデータを表現するドメインオブジェクトを作るのではなく
ドメインオブジェクトに合わせて画面を分割/分解する手法が紹介されていたのもよかった。
技術的なアプローチではなく、そもそもの画面仕様を変更することを検討する内容で
同じような場面に遭遇する気がするのでその時に使えそう。
また4,9章ではそれぞれドメインモデルを見つける/伝えるにあたって必要な資料や図、ドキュメントについて
何が必要なのかが詳細に書かれていて、こちらは1年目に読んでると精度高くプログラム以外の資産も残せたんだろうなーと思える内容だった。
DDDを通じてオブジェクト指向を実現するためのテクニックや手法の解説
+
業務でアプリケーションを開発をする上で必要な勘所
の2つを解説してくれている、とても実践的な本でした。おすすめ。
普段RailsでWebアプリを作っていて、いつクラスを作るべきか、どんなインターフェイスを作るべきか、そもそもよい設計やコードとは何なのかよくわからなくなっていた。
同僚に相談したらこの本を勧められて2017年に1回途中まで、年明けにもう1回全部通して読み直したのでいったんまとめる。
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
この本を読んでなおいろんな機能が詰まりまくったServiceクラスを作るPullRequestを出した自分に
丁寧にapp/models
以下に単一責任の原則に基づいたプレーンなクラスを作って、ドメインモデルを表現するコードレビューをしてくれた同僚がいた。
ちょうどそのレビューの最中に教えてもらった記事がある。
この記事に出てくるダメServiceクラスみたいなものを本当に作りかけていて危機感を覚えたし、具体的な問題意識を持って本を読み直すきっかけになった。
いまその時とは違う職場で働いているが、当時のコードレビューや本、記事で言われている内容がかなり役立っている。
新しい環境でコードを読みながらキャッチアップする機会が多く再認識したことがあって
今までapp/models
以下にActiveRecordを継承したモデルクラスだけが存在し、そのサービスのドメインロジックはそれっぽい名前のServiceクラスに手続き的な処理の羅列として閉じ込めるような書き方がされているコードをよく見た気がするし自分でもめっちゃ書いてた記憶がある。
こういうクラスがある場合に新しい環境でコードを読み始めてつらいと思ったのが、そのクラスがいったい何の責任を持ったクラスなのかわからなかったり、staticな呼び出しをされまくる便利クラスになっていて変更のためのコストが異常に高かったりすること。
たくさんの引数を渡してその内容によって処理の分岐をするif文の羅列、それに伴って膨らむrspecのcontextブロック
ロジックが詰め込まれていてしかもstaticに呼び出されたりすると、処理の内容を変更しようもんなら影響範囲がどこまで及ぶのか関数名でgrepして確認をしないといけない。(grepすれば調べられる分まだマシかも)
この本を読んでそういうコードを生まないためにどう対処するべきか、少しずつクリアに見えるようになり始めた。
特に役立ったと感じるのは
のあたり。
オブジェクトが「メッセージ」を送っている。という話がRubyのsend
メソッドと自分の中で結びついて気持ちよかったり
単一責任の話や、ダックタイプの話が直接先述のServiceクラスをリファクタするヒントになっていたりして
「明日、あのコードをどう直すか」というスピード感で自分の指針になったことにはとても感動した。
しかもありがたいことに今の職場でもこの本がデスクに置かれている同僚がいて、設計の相談が来た時にちょうどこの本に載っているような問題に遭遇して「あのパターンが使えるね」って話しながら設計に落とし込めたりする体験もできた。
ただ単にこの本を読んだ自分の考えを押し付けるわけでもなく「なぜそう思うか」を具体的に言語化した上でレビューしたり、共通の認識を持った上でお互いに納得いく設計にできたりしているので、当初思っていたよりもかなり読む価値のある本になっていた。ラッキー。
ドメイン駆動設計あたりが自分の中でホットなので冷めないうちに次はこの本を読んでみようと思う。
現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法
今年買ってよかったものを書きます
薬剤師の資格持ちの同僚の勧めで購入。どうやら最強酔い止めらしい。
調べてみたところ、とにかく酔い止め関連の効能がある成分が1番数多く入ってる薬らしく
昔から乗り物酔いがひどい僕が、小さいボートで東京湾に出てぐわんぐわん揺れても一切酔わなかった。ヘビロテ確定。
もっと吸水、さらに速乾!珪藻土バスマット(カイテキサラサラ SP 40X55) | ニトリ公式通販 家具・インテリア・生活雑貨通販のニトリネット
すごくいい。前まで布のバスマット使ってたけど
洗濯めんどいし、清潔感に欠けて嫌だったのが全部解決
成績は散々だったけども、個人的にベイビードライバーに並んで今年ベストに推したい作品
特撮ファンの僕は20年前の劇場版やTV版を子供の時に死ぬほど見ていて
今回のリメイクめっちゃ楽しみなくせに、期待値上げると爆死しそうだからという理由で斜に構えながら見に行ったら
もうそんな不安を吹き飛ばしてくれるほどいい感じのリメイクで、しっかり現代ティーンエイジャーの青春物語へと昇華されていて大満足
なんとか次回作で追加戦士トミーの登場を見てみたい
Koogeek スマートコンセント WiFiで制御する電源コンセント (ブラック)
Wi-FiにつながってiPhoneのSiriやコントロールセンター経由でON/OFFできるコンセント
うちでは加湿器や照明で使用中
ベッドから動かずに家電をつけたり消したりできるので寝落ちする時に幸せ
この記事を書いた時に合わせて導入した
無添加ミックスナッツ 1kg (くるみ,アーモンド,カシューナッツ) 食塩、オイル使用無し
ベッドから動かずに生活できるようになった結果太りまして
食生活を見直そうと購入
朝ごはんに毎日菓子パンを食べてたので、それをやめるべく
ヨーグルト + バナナ + ミックスナッツという
OLが食べてそうな朝食に変えたところ見事に体重減。
バナナとナッツでエネルギー摂取して、消化もいいっぽいので見事に昼前にはおなか減ってくる感じの生活になって最高
[サフィールノワール] ミラーグロス 9551013017 BK ブラック サイズ無し
痩せたということでおしゃれがしたい。
以前買った革靴の鏡面磨きに挑戦すべく、評判のよかったサフィールのワックスを購入。
鏡面磨きはやったことがなかったけど、このワックスがあればそんな僕でも初回からけっこういい感じに光らせられました。
痩せたら美味しいお刺身が食べたくなりまして
同僚からオススメされたこともあり導入。
透明な半透膜シートで
マグロの柵とかに巻いて冷蔵庫で20分くらい放置するといい感じに脱水してくれる。
以前は冷凍マグロを家で解凍して食べると水っぽいことが多かったんですが
これを導入してからは美味しいお刺身のお店っぽい、身が締まった刺身を食べることができるようになりました。
おすすめレシピは
しょうゆ 2 : 料理酒 1 : みりん 1の漬けダレに
解凍してから20分ほどピチットシートで脱水したマグロを5-15分ほど漬け込んで食べるマグロ丼です。
Nintendo Switch Joy-Con (L) ネオンブルー/ (R) ネオンレッド
ベタ中のベタっぽいですが、今年はこれが1番よかった。
買ったゲームはゼルダ、マリオ、マリオカート、スプラトゥーン、マイクラ、ヒューマンリソースマシンで全部めっちゃ楽しい。
かつてこんな体験をしたことがない。
特にゼルダとマリオについては自分の中のゲーム概念が覆る感じで
見えてるとこだいたいどこでも行けて、怪しいところにはだいたい何かあり、こうすりゃ何か起こりそうだな〜と思って試すと何か起こっちゃう体験がとにかく最高でした。
前回の記事ではSiri + Raspberry Pi + IRKitで
お部屋の家電を操作するところまで作りました。
今回は、その続編として
室温を計測し、規定の温度を外れた場合に自動でエアコンを操作して
お部屋の温度を快適に保つ方法を実践していきます。
先日、会社の勉強会で発表した際に使った資料がこちら
この発表で「エアコンの自動設定に任せられないのか」「そもそも目指す温度に設定しておけばいいんじゃないのか」という意見がありましたが
みたいな理由から今回の自作温度調節機能の開発がスタートしました。
お金がある人は最新モデルの霧ヶ峰とかを買うといいかもしれません。
霧ヶ峰 MSZ-GV2216(W) ピュアホワイト(2.2kW)
前回までに登場した
に加えて、ラズパイにUSB温度計のTemperを接続します。
接続する際は、本体に直接挿すと熱伝導でUSBスティック自体が熱くなるため
延長ケーブルなどで本体の熱が伝わらないように接続するのがコツです。
USB温度計! USB thermometer-528018
また、設置する位置が高かったり低かったり、当たり前ですが熱を放つ機械のそばにあるだけで計測結果が変わります。
自分の体感値と照らし合わせながら最適な設置場所を探してみてください。
我が家ではこれを「百葉箱ポジション」と呼んでいます。
こんな流れです。
発表スライドにも載っているのですが、開発中はmackerelを使わずに
毎分温度を取得して、低ければ設定温度を上げるようにしていたのですが
室温はすぐに上がらないため、ラズパイが温度を上げようとして
毎分エアコンの「ピッ」という音を聞かされることになりました。
また部屋がちょうどいい温度にもかかわらず
トイレに行くために一瞬だけ廊下へのドアを開けただけで冷気が入り込み
その冷気を拾ってラズパイが過剰に反応してしまうこともありました。
そこでmackerelを使って「○○分継続して温度が規定値を外れたら」という
webの外形監視っぽい仕組みを導入することで回避しています。
ラズパイにTemperを接続して温度を取得します。
商品にwindows用のインストーラーがついていますが、ラズパイ用にコマンドをビルドします。
【Raspberry Pi】USB温度計を付けてみる – Happy Life Hacking
mackerel-agentもgithubにarm版が公開されています。
Releases · mackerelio/mackerel-agent · GitHub
この中から mackerel-agent_linux_arm.tar.gz
をDLし、展開して利用します。
mackerel-agentのARM版バイナリーはRaspberry PI 2でもさくっと動く - Qiita
temperから取得できる温度を整形してmackerelに渡すためのスクリプトを用意
#!/bin/bash name="temper" monitor_time=`date +%s` temperature=`/opt/temper/temper | sed -e 's/.*,\(.*\)/\1/'` echo -e "${name}\t${temperature}\t${monitor_time}"
mackerelの設定ファイルに上のスクリプトを叩くように追記してagentを再起動
[plugin.metrics.process] command="sudo /home/pi/temper.sh" type="metric"
ここまでの手順でmackerelにメトリクスが表示されるようになったと思います。
Monitorの設定画面から
の設定をしたMonitorを作成しましょう。
我が家では 上限 23℃, 下限 21℃で、10分間既定値を外れた場合にAlertを発火するようにしています。
mackerelのmonitorがalert状態になったのを取得する必要があります。
今回は手軽にやりたかったので「cronで15分おきにAlert APIを叩く」という方法で確認を行っています。
アラート - Mackerel API ドキュメント (v0)
雑スクリプトで取得して、IRKitにリクエストを送ります。
#!/bin/bash cd `dirname $0` check_alerts () { curl https://mackerel.io/api/v0/alerts -H 'X-Api-Key:xxxxx' -H 'Content-Type: application/json' | jq '.alerts[]' } # 自動調節モードのOn/Offを確認 if [ ! -e /tmp/check.txt ]; then echo 'Auto control is off' exit 0 fi JSON=`check_alerts` ID=`echo $JSON | jq '.monitorId'` STATUS=`echo $JSON | jq '.status'` echo $ID echo $STATUS if [ $STATUS = '"CRITICAL"' ]; then echo `date` echo 'Status is CRITICAL' if [ $ID = '"xxxxx"' ]; then # 上限アラート sh ./22.sh sleep 1 sh ./21.sh elif [ $ID = '"xxxxx"' ]; then # 下限アラート sh ./22.sh sleep 1 sh ./23.sh else echo 'Unknown Alerts' fi else echo `date` echo 'Status is not CRITICAL' fi
やっていることは単純で
また序盤で「自動調節モードのOn/Offを確認」とコメントがありますが
ファイルの有無を自動調節モードの起動フラグとして利用しているだけです。
このファイルの作成/削除はhomebridge-cmdで管理しているため
「Hey Siri エアコン調節オン」みたいに声で自動調節モードを起動できるところがちょっとかっこよくて気に入ってます。
ある日のグラフです
という挙動で、その後いい感じに温度がキープできているのがわかるかと思います。
この日、ぼくは普通に暮らしており、温度に関することを一切意識していません。
このように、考えないといけないことが1つ減らせたのがとてもうれしいです。
今後はスマートコンセントを使って、加湿器も制御して湿度をコントロールできればと思っています。
今度からは、霧ヶ峰を買って解決できるようになりたいです。
ベッドでだらだらしていると、だんだんウトウトしてくる。
あーもうこのまま意識飛んで寝そう。っていう時に、電気とテレビを消すために
わざわざテーブルに置いてあるリモコンを取りに行きたくない。
続編としてエアコンの温度調整を自動化するところまでやりました。
この中でも今回の要はhomebridge
homebridge-irkitをラズパイで動かします。
このサーバーはHomeKit互換なため、設定ファイルにjsonで各家電の赤外線情報を定義することで
IRKitにHTTPリクエストを飛ばして、家電製品に赤外線信号を送ることができる。
{ "bridge": { "name": "Homebridge", "username": "CC:22:3D:ED:CE:30", "port": 51826, "pin": "000-00-000" }, "description": "IRKit Control", "accessories": [ { "accessory": "IRKit", "name": "電気", "irkit_host": "IRKit1B4D.local", "on_form": {"format":"raw","freq":38,"data":[19991,10047,1413,3579,1413,3579,1413,3579,1413,1111,1413,1111,1413,3579,1413,3579,1413,3579,1413,1111,1413,1111,1413,3579,1413,3579,1413,1111,1413,1111,1413,1111,1413,1111,1413,3579,1413,3579,1413,1111,1413,1111,1413,3579,1413,1111,1413,1111,1413,3579,1413,1111,1413,1111,1413,3579,1413,3579,1413,1111,1413,3579,1413,3579,1413,1111,1413]}, "off_form": {"format":"raw","freq":38,"data":[19991,10047,1319,3704,1319,3704,1319,3704,1319,1190,1366,1190,1366,3704,1319,3704,1319,3704,1319,1190,1319,1190,1319,3704,1319,3704,1319,1190,1319,1190,1319,1190,1319,1190,1319,3704,1319,3704,1319,1190,1319,3704,1319,1190,1319,1190,1319,1190,1319,3704,1319,1190,1319,1190,1319,3704,1366,1150,1319,3704,1319,3704,1319,3704,1319,1190,1319,65535,0,24574,19991,4878,1366]} } ] }
またIRKitに以下のHTTPリクエストを送ることで
1番最後に受信した赤外線情報をjsonで吐き出してくれます。
$ curl -i "http://10.0.1.2/messages" -H "X-Requested-With: curl" HTTP/1.0 200 OK Access-Control-Allow-Origin: * Server: IRKit/2.1.3.13.gbe33d36 Content-Type: text/plain {"format":"raw","freq":38,"data":[18031,8755,1190,1190,1190,3341,1190,3341,1190,3341,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,1190,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,65535,0,9379,18031,4400,1190]}
IRKit - Open Source WiFi Connected Infrared Remote Controller
必要な家電製品の赤外線を設定ファイルに書いたら
homebridgeサーバーを起動
pi@raspberrypi:~ $ homebridge *** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi. *** WARNING *** Please fix your application to use the native API of Avahi! *** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node> *** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi. *** WARNING *** Please fix your application to use the native API of Avahi! *** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister> [2017-02-08 23:42:24] Loaded plugin: homebridge-cmd [2017-02-08 23:42:24] Registering accessory 'homebridge-cmd.CMD' [2017-02-08 23:42:24] --- [2017-02-08 23:42:24] Loaded plugin: homebridge-irkit [2017-02-08 23:42:24] Registering accessory 'homebridge-irkit.IRKit' [2017-02-08 23:42:24] --- [2017-02-08 23:42:24] Loaded config.json with 7 accessories and 0 platforms. [2017-02-08 23:42:24] --- [2017-02-08 23:42:24] Loading 7 accessories... [2017-02-08 23:42:24] [テレビ] Initializing IRKit accessory... [2017-02-08 23:42:24] [電気] Initializing IRKit accessory... [2017-02-08 23:42:24] [エアコン] Initializing IRKit accessory... Scan this code with your HomeKit App on your iOS device to pair with Homebridge: ┌────────────┐ │000-00-000 │ └────────────┘
あとはiPhoneのホームアプリから接続設定をすると
HomeKit経由で各種デバイスのオンオフが可能。
Siriだけじゃなく、コントロールキットからも操作できて便利
Raspberry Pi3 Model B ボード&ケースセット 3ple Decker対応 (Clear)-Physical Computing Lab
ラズパイ3はけっこうメモリも豊富でよかった
常時起動の場合はヒートシンク要るとか聞いてたけど、今のとこなんとかなってる
冬だからかも?
IRKit - iPhone,iPadを使って外出先からエアコン等の家電を操作できる学習リモコン
青色LEDがちょっとまぶしいのが難点
後継機のNature Remoはちょっと値上がりして、動体センサーや湿度計もついてるらしい