taiyoh's memorandum

@ttaiyoh が、技術ネタで気づいたことを書き溜めておきます。

アメッシュの画像を解析して、家に雨雲が近づいたら通知するツールを作った

 まあ、タイトルの通りなんですが。
 アメッシュの監視ってだけなら他に作ってる人がいるっぽいのですが、僕がやったのは、エリアごとに緊急度を付けて、家に雨雲が近づけば近づくほど緊急度が上がってるというのが分かるようになってます。

 これって要は、目標のポイントを中心とした円を何枚か用意しておき、それらの画像を1枚ずつ突き合わせてアメッシュの降水の様子を示した画像を論理積(AND)で重ねた時、ピクセルが残るかどうかによって、画像に応じた緊急度を判別させよう、ってことですね。そして気づいたら、imagemagickを使う場所が全部system関数を叩くようになってて、とても泣きそうです。でも、plenv等でPerlMagick入れるのめんどいし、他の処理をシェルスクリプトで書くのも自信ないんだもん。。。
 今になって色々考えてみたらすごい富豪的な探索方法なので、他の人も使えるようなサービスとしての設計にはなってないので、もっとローコストに実現できる方法を考えなきゃですね。多分なにかあるはず。

Data::ChangeFinderとData::AnomalyDetectなんてもんをこしらえてみた

 → taiyoh/p5-Data-ChangeFinder · GitHub
 → taiyoh/p5-Data-AnomalyDetect · GitHub
 fluent-plugin-anomalydetectの動作がかっこよかったので、もうちょっとfluentに頼らずにカジュアルに使えないかな、と思ったのが発端です。
 変化点検出のアルゴリズムはいくつかある、というところまではググって分かってきたのですが、じゃあそれらをPerlで1から実装できるのか、というとそこまでの力はないので、謹んでfluent-plugin-anomalydetectに入っていたFluent::ChangeFinderの実装をごっそりPerlに移植させていただきました。内部が理解できてないのに移植できるのかよ、ってのは全くその通りなのですが、とりあえずリファレンスになるruby側の実装を、同梱されてたテストデータのcsvを使って単体で実行してみて、その結果データと移植したPerl側の実行結果を照合させて、誤差が0.1%もなければ(内部でrand使ってるので、確実に同一の値にはなることはない)、ほぼ期待の動作になっているのではないか、という論拠のもとに移植しております。
 検出部分のモジュールができれば、あとはそれのインターフェイスになるものがあれば使いやすくなると思ったので、Data::AnomalyDetectというものも作りました。これは、Fluent::AnomalyDetectOutputのコア部分の実装を移植させてもらっております。これで初期化時のパラメータ指定はfluentのプラグインとほぼ同じになります。

 ↑動作サンプル
 あとお節介なこともしてて、AE::timerを使って定期的に検知処理を実行させるData::AnomalyDetect::Watchというのと、tcpで値を受け取ってスコアを返すという部分に特化させたData::AnomalyDetect::Recieveというのも同梱しました。ただ、特にRecieveの方はかなり原始的な作りだと思ってるので、本格的にやるにはもっと色々考慮しなくちゃいけないと思います。
 目下の課題は、ドキュメントを書かないといけないのと、outlier_bufferのデータを永続的に保持する(もしくは初期化時にロードさせる)仕組みが必要だな、というところです。

earthquake.gemの表示を少しだけ変更する

 最近、PC環境でのtwitterクライアントにearthquake.gemを使っています。twitter上を検索するとか、特定のアカウントのツイートだけ見るとか、今までは全部マウスでポチポチしてたのですが、earthquakeだと一つのプロンプトに集約できるのでいいですね。どうしようもない点といえば、ターミナルで動くので(アイコン含め)画像が見れないとか、そんなくらいか。
 で、本題。
 earthquakeの表示は、1ツイート1行というのがデフォルトの設定で、個人的にはちょっと見にくいなー、と悶々としていました。そんな時、「tmux+earthquake.gemな話 | himajinworks::blog」というエントリを読んで、そうだ、こうやって変えればええんや!とやっと気づいた次第です。で、表示系のプラグインを探し始めたのですが、自分の検索能力が低いせいもあって、なかなか出てこないので、もうこうなったらプラグイン書いて解決しよう、と決意。人が書いてるプラグインチラ見してなんとなく要領がつかめたので、こんな感じで作ってみました。
 → myoutput.rb
 :plugin installすればいけるのかな。僕は~/.earthquake/plugin/以下に置いて検証しながらだったので、その辺ちょっと分からないですが。表示はこんな感じになります。
f:id:sun-basix:20130630120106p:plain
 元々のlib/earthquake/output.rbのoutput :tweetのブロックを丸コピさせてもらって最後のstatus変数の作り方だけ変えたので、複数行ツイート等の表示は以前と変わらないです(少なくとも今のバージョンであれば)。

nginxで同じパスでPCとSPのページ出し分け(簡易版)

 今更ながら、nginxにmapという機能があることを知った。
 → HttpMapModule
 ということで、以下のことを試してみた。serverブロックの外側に以下のような記述を追加してみる(中に書くと怒られる)。

map $http_user_agent $myindex {
    default           /index.html;
    ~(iPhone|Android) /index_sp.html;
}

 んで、serverブロックの中のlocationの指定で

location / {
    root /path/to/document/root;
    index $myindex;
}

 って感じでindexの値をmapで指定した値に変えておくと、UserAgentに「iPhone」とか「Android」って入ってればindex_sp.htmlをインデックスファイルに、そうでなければindex.htmlをインデックスファイルにしてくれる。ifでずらずら書いてくやり方よりちょっと見やすくなるので良い感じかも。また、正規表現部分をもっと充実させれば、精度は上がっていくはず。

lirc_webを使ってどこからでも赤外線リモコンの操作ができるようにする

 335先生から「早く書け」とプレッシャーが来てるのでメモっておく。

  • 用意するもの
    • こちらのブログに書いてある部品一式
      • ブレッドボードあると楽ですね
    • lirc (これはapt-getでインストールできる。上記ブログ参照)
    • lirc_web

 特に回路図の載っているこちらのブログは、やることの根幹部分を成しているので、まず書かれていることは全部実行して、動作確認をしておいてほしい。ただ、一つだけ変えたところがあって、この人とほぼ同じ抵抗で設定すると、出力が弱くて肝心のレシーバまで信号が届かなかったので、赤外線LEDの前に置く抵抗は、確か4.7Ωか10Ωくらいに下げている。こうすれば、LEDにより電圧がかかるので、出力は増す。赤外線LEDも、「高輝度」と謳ってるものにしておくとより確実。

 そうして組み上がった回路とRaspberry Piはこんな感じになる(一例です)

DSC02953

 ブレッドボード上の右側の素子が赤外線受光素子で、ここにリモコンの信号をガンガンぶつけて学習させる。

 回路が組めて、ターミナル上から実際にリモコン操作ができることが確認できれば、もう8割以上やることは終わっている。あとは、「lirc_web」というnode.js製のツールを使って、ブラウザから操作できるようにする。lirc_webは元々Raspberry Pi上で動かすことを想定していて、APIにリクエストを投げると、パスからコマンドを解釈して、lirc_webプロセスからlircコマンドを投げてくれる。ただ、それだと家のネットワーク内からしか使えないので、認証はかけつつどこからでも操作できるようにしたいなぁ、と思ったので、app.jsのパス指定を以下の様に変更した。

 /api/streamというパスを新たに用意し、ここにつなぎっぱにしたプロセスに対し、APIのリクエスト情報をごっそり送るという変更を加えた。これをVPSで立ち上げた上で、以下のスクリプトを用意する。

 今度はこれをRaspberry Pi上から実行し、予めVPSに立てておいたlirc_webのシステムに対してアクセスし、つなぎっぱなしにしておく。これができれば、NAT越えの問題は楽々突破できるし、lirc_webのシステムに認証さえつけておけば、便宜上ある程度のセキュリティは保たれる筈。VPSに立てたlirc_webのシステムにブラウザからアクセスすると、こんな感じになる。

f:id:sun-basix:20130524002717p:plain

 因みに、今のところ上記の通り、ダイニングの明かりしか操作できてません。。。!とはいえ、ちょっとbasic認証がうざいけど、この存在は相当ライフチェンジングになってて、今までは帰って扉開けた瞬間だと真っ暗で、手探りで部屋のスイッチを探さないといけなかったけど、今は先にスマホから上記のコントロールページを出しておいて、鍵開けて扉開けた瞬間にスイッチ操作して明かりを点けられるので、それだけでもストレスがだいぶ減ってる。なお、そのダイニングの明かりは、後付けでリモコンで操作できるようになる機器をつけてある。

天井照明器具専用 リモコンスイッチOCR-04 07-0154

天井照明器具専用 リモコンスイッチOCR-04 07-0154

 最近、ソフトウェアだけで完結できるものじゃなくて、こうやって現実世界に反映される何かを組むのがすごく楽しいと思えるようになってきた。と言っても、まだ実質これしかできてないけど。

MTでエントリ以外の要素を任意のタイミングで自動的に再構築する

 MT情弱なのでぐぐってもなかなか出て来なかったし、ましてやPluginやToolも書きたくなかったので、頑張って探したら、これが出てきた
 → alfasado/mt-tools-rebuild-archives · GitHub
 やや古いツールだけど、一応現時点のMT最新版(5.2)でも動く。
 どの形式のテンプレートで作成したかでコマンドラインに入れる引数atの値が変化する。今回は、登録したユーザのプロフィール情報を定期的に反映させたくて、その反映するテンプレートがインデックステンプレートにあったので、

cd /path/to/mt
perl tools/rebuild-archives --at Index --blog_id 1,2

 という感じで実行すればOK。warningがウザいけど。

hubotにもunazu_kun的な機能を追加する

 「unazu_kunって何?」って方は以下を参照。
 → 社内IRCがカビ臭くてピリピリしてたので癒し系botを投入した後、リマインダー機能を搭載した話 - kenjiskywalker no memo
 → 多分結構バージョンの古いコード

 hubotで提供してるものがどれもかわいくないので、unazu_kun的な機能を以下のコードで追加した。pugはちょっとアリだけど、pugって最初に入れないといけないあたりがカジュアルじゃない。なお、リマインダは現時点で未搭載。(11:37追記 シンプルなリマインダ機能入れました。日をまたぐとかはこの正規表現じゃまだできないけど)

f:id:sun-basix:20130519105534p:plain

 もっと違う返答パターンもお待ちしております。