読者です 読者をやめる 読者になる 読者になる

taiyoh's memorandum

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

golangでBME280から情報を吸い出してよしなにする

相変わらず、goではなるべくニッチそうなlow layerなところを攻めております。
go用のI2C周りのライブラリはいくつかありますが、embdが割と素直な印象で、
実は先日BMP180というチップも買って、こちらであっさりと動かせるということを確認していました。

BMP180 気圧センサ(気温センサ付き)

BMP180 気圧センサ(気温センサ付き)

embd/bmp180.go at master · kidoman/embd · GitHub
↑このスクリプトをrpiで動かしてみたら修正なしで動いてしまい、かなりびっくりしました(とても優秀なサンプルでした)
ただ、僕の本命はBME280の方で、これは温度と気圧の他に湿度も計測出来る優れものです。
BME280搭載 温湿度・気圧センサモジュール

BME280搭載 温湿度・気圧センサモジュール

データシートを読んでると、BMP180と全然動かし方が違う。。。
http://trac.switch-science.com/wiki/BME280
当初はスイッチサイエンスさんが用意してくれたpythonスクリプトを元にgoに書き換えようとしましたが、
やっぱりスクリプト言語なので、よしなな型変換が多い。。。
一旦組み上がったので起動してみたら、温度が-84℃とか出てきたので、思わず笑ってしまいました。
github.com
↑動作確認のために上記のスクリプトを動かしてみたらちゃんとそれっぽい値は取れているので、恐らく結線は問題ないはず。
ということで、大元のチップメーカーであるBoschのドライバを参考にすることに。
GitHub - BoschSensortec/BME280_driver: Bosch Sensortec BME280 sensor driver
型や計算を上記のCのソースに沿う形に修正してみたところ、無事動きました!
f:id:sun-basix:20160208221724p:plain
最近、計測値の保存はAT&Tのm2xを使用しております。これも一応値に応じて何かをトリガーするとかできるっぽいです。やったことないけど。
rpiとチップはこんな感じで結線してます。
f:id:sun-basix:20160208212744j:plain

で、golangでBME280を動かすためのドライバは以下となります
github.com

gist7bdffe63dff403546c4e
動作サンプルはこんな感じ

電力モニター「はやわかり」に記録されているデータをgoで吸いだしてmackerelに送ってみる

承前
taiyoh.hatenablog.com
ついに前回のエントリの「hogehogeする」の中身が決まりました。
2年間完全に塩漬けにしてましたが、ふと思い立ったのでやることに。
当時吸い出す部分まで作って止めていたのは2つ理由があって、

  • amd64->armのクロスコンパイルに挑戦しようとしたが、cgoだと相当ハードルが高いということがわかった
  • 得られたデータをどこでどう閲覧・管理するかが決まってなかった

というのがありました。
goの環境についてはraspberry pi上で普通にビルドすればいいじゃん、と思えてきたのと、raspberry piで受け取ったデータをhogehogeする的なのを検索してみると、mackerelに送っているというエントリをいくつか見かけたので、時代はやはりこれだろう、と。実際、mackerel周りの導入はめっちゃ楽でした。
良くも悪くも、当時のコードはgo1.5でもビルドできたんですが、コールバックで渡すのがかっこ悪く見えてきたのと、シグナルのハンドリングはライブラリじゃなくね?とも思えてきたので、その辺を思いっきり書き直しました(どうせ僕しか使わないやつなので)。
また、一日かけて環境を整えていざ動かしてみたら、segmentation faultでホスト毎落ちるというのが見つかりました。参考にしたeagle-owlソースコードをもう一度読みなおしてみたら、大きめのbufferを用意した上でusb_bulk_readをし、返り値のバイト数に応じて小分けにしているという処理があったのを完全に失念していたので、これも追加しました。
で、どうにかこうにか値が取れるように。

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

最初に10Aを超えた値になったのは電子レンジを動かした時で、その直後に15Aを超えてるのは、ケトルでお湯を沸かし始めたからですね。(部屋の中寒いんだよ!)
いい感じで値が取得できるようになったかと。ここから先どうするとかは今後考えよう。。。
実際にraspberry piで動いてるコードは https://github.com/taiyoh/go-cm160/tree/master/example 以下にあります。へっぽこなのでご笑覧ください。
(どれくらいへっぽこだったかというと、昨日時点のコードだとmackerelに無駄にデータを送りまくってて、raspiのCPU使用率が90%を超えてました。大変申し訳ありませんでした!)
因みにこのコードの負荷についてですが、起動時は一瞬80%を超えることがありますがすぐに落ち着き、何かが徐々に上がってるということも今のところ見当たらず、平常時はmackerel-agentとcm160のプロセスを同時に動かしててもトータル12%くらいとなっております。

節電モニター

節電モニター

ubuntu版chromeでpulseaudioが落ちた時の対処

もう一度音が出るようにするには、現状、以下の2ステップを踏む

  1. $ pulseaudio --startでpulseaudioを起動し直す
  2. chromeを親プロセスから再起動する(単にウィンドウを閉じるのではなく、アドレスバーにchrome://restartを打ち込む)

というのも、どうやらubuntuchromeは、chromeの親プロセス起動時にpulseaudioの接続先を見つけるようだ。恐らく、子プロセスはそれを共有しているはず。それはそれでいいのだが、親プロセス側での接続できなくなった時の再接続の処理がうまくいってないか、そもそも接続を確認する手段がないのか、はたまたlinux版なので適当にされてるか、まあそのどれかではないかと思う(ソースを追う気力はない。。。)
ubuntuchrome使ってるけど音が鳴らなくなった」みたいなことをググってみると「rm -rf ~/.config/google-chrome/するといいよ」なんて回答が引っかかるけど、上記の2ステップを踏めばOK。

iRKitを買ったお話

 lirc+lirc_webのシステムを作ったのが去年の話なのですが、肝心のエアコンの信号はlircでは認識できなかったし、今年に入って例のブレッドボードで組んだ回路が動かなくなったんですね。そもそもブレッドボードはそんな長く使うものじゃない筈なんですが。。。
 いい加減リモートでon/offできるシステムは復活させたかったので、作った回路は捨てて、先週やっとiRKitを買いました。
 結論から言うと、早く買っておくべきでした。
 部屋に無造作に置いてても問題なく機器に届くし、なによりエアコンの信号をちゃんと認識してくれたのが大きかった。小さくてかわいいし。
 そんなわけで、例のlirc_webのクライアント側も修正し、結果ただのhttp送信装置となり(iRKitのIPを直接指定して信号の文字列を送るだけになったので)、これでやっと外からエアコンのon/offも操作出来るようになりました。実に1年半越し。大塚さんには本当に感謝です><
f:id:sun-basix:20140827080948p:plain
 先週末時点でライトのon/offはできるようになってたんですが、エアコンがどうも動いてなくて、原因を調べたら単にヘッダのContent-Lengthが抜けてただけでした。

 → IRKit - Open Source WiFi Connected Infrared Remote Controller

Macじゃない環境でもIRCで流れてくる画像を表示したい人生だった

 MacLimeChatのサムネイル表示機能が羨ましすぎるのですが、今使ってるマシンがUbuntuだったりして、悲しみが募っていたわけです(Macに変えればいいじゃん、というのは根本的すぎるのでスルーします)。そんな悲しみを紛らわすためにずっとIRCツールを探し続けてたのですが、サムネイル表示できるのはどうもなさそう。
 でも、そんな時に見つけたのがweecloudというweb frontendでした。
 → eirikb/weecloud · GitHub
 このweecloudというツールはweechatのrelayという機能を使って機能拡張を行うもので、weechatとはnode.jsでデータのやりとりを行い、ブラウザとはsocket.ioを使ってやりとりをしてます。表示部分に特化していて、かつその表示はHTMLなので(正確にはjade)、HTML・js・cssをいじれば自分好みの表示ができるやん、ということに気づいたわけです。
 ということで、早速拙い英語でp-r送ってみました
 → insert thumbnail if message has image url by taiyoh · Pull Request #25 · eirikb/weecloud · GitHub
 実際採用されるかは謎ですが。
 あと、このweecloudは手元で動かすことを想定していて、認証関連は完全にスルーしてるんですね。なのでうかつにVPSに置くのは厳しいのですが、ここであのtypester師謹製のgateの出番となります。用意したサブドメインへのアクセスは一番表に置いたnginxで受け、gateに渡す。あとは認証はgateがやってくれて、通れば更にその後ろのweecloudに渡してくれます。gateはwebsocketにも対応してるので、リアルタイム通信も問題ないです。また、weechatの起動してるサーバと同じ所でweecloudを動かすので、relay用のポートを外に空ける必要がなく、weecloudとの通信をsslにしておけば、そこそこ安全性も確保できるのではと思います。
 この成果を後輩に言ってみたら「努力がすさまじいwww」と小馬鹿にされたわけですが、冒頭でも言ったとおりサムネイル表示を出来る方法を探してたのと、gateを使ってみる口実が欲しかったというのが今回の目的なので、もしかしたら数日たったら飽きて戻ってる可能性もだいぶあります。

(追記: 8/22)
上記p-r、早速マージされておりました。

radikoで聞ける番組をcronで録音したくなったので

 作った
 → taiyoh/p5-radiko · GitHub
 rtmpdump、swftoolsffmpegがないと動きません。あとPerl側の依存モジュールはFurlMIME::Base64、Class::Accessor::Lite::Lazyくらいか。

 → 簡易Radiko録音ツール。要swftools/rtmpdump/libxml/wget/ffmpeg/lame
 こちらの方の作ったシェルスクリプトを大いに参考にさせていただきました。

 以下、使用例。

電力モニター「はやわかり」に記録されているデータをgoで吸いだしてhogehogeする

 数年前にイギリスから発売された製品に「OWL+USB」というのがあります。ブレーカーから延びてるケーブルに同梱されている送信機についたクリップを取り付け、それを無線で飛ばして受信機で受け取った後、表示・記録する、というものです。各国対応版となっており、当然日本の電圧にも対応しています。日本の代理店を介した製品名は「はやわかり」です。

電力モニター
電力モニター
2 Save Energy Ltd
売り上げランキング : 44157


Amazonで詳しく見る
by G-Tools
 これをraspiとつないで、データを取り出してサーバに送るとかなんか色々できたらいいなぁ、と思っていたのですが、提供されてるLinux版のツールが軒並み動かず、githubに転がってる野良ツールも期待した動作をしてくれないので、自分で書きました。
 → taiyoh/go-cm160 · GitHub
 参考にしたのは、Cで書かれた野良ツールの「eagle-owl」というものです。これをリファレンスにして、同じメッセージがのやりとりができればデータが取得できるはずで、あとの処理はまた別のレイヤーに任せる形にしよう、という考えの下進めていきました。内部でlibusbとやりとりするgo-libusbというライブラリも使っていて、これも一緒にインストールしておく必要があります。

# libusbの開発パッケージもインストールしておく
$ go get github.com/taiyoh/go-libusb
$ go get github.com/taiyoh/go-cm160

 テストとか全然用意できてなくて申し訳ないですが、実機を伴うのはとてもやりづらい。。。下にこれを使ったツールのサンプルを添えておきます。

 Waitメソッドの引数のコールバックに任意の処理を入れるような形にすれば、用途を限定せずにいろんなことができるようになるかな、と思いました。また、電圧も外から入力できるようにしたので、国が変わる度にワット数の計算が合わなくなることも避けられるはず。。。