@m_seki の

I like ruby tooから引っ越し

rendez-vousでraspberry piから通知もらってみた

Raspberry pi Model B(+じゃない方)をいただいたのでいろいろ実験しました!
抵抗やLEDなどパーツがおまけでついてる本を買って、その範囲でだけど。

http://victory7.com/?pid=65608266

それから、このGPIOアダプタが便利でした。

26pinのやつは探しにくくなりつつある気がします。
もちろん40pin版もあったよ。

ラズパイに割り当てられたIPアドレスを知りたい

ご家庭LAN環境にはDHCPでつないでます。最初はWiFi使ってたんだけど、試しに有線にしたら速くなってびっくりした。

PLANEX 無線LAN子機 (USBアダプター型) 11n/g/b 150Mbps MacOS X10.10対応 GW-USNANO2A (FFP)

モニターなしで運用したいので、DHCPで割り当てられたIPアドレスを調べるのがめんどうです。とりあえず、光ルータのDHCP払い出し一覧と記憶してるMACアドレスを突き合わせて調べてました。
慣れてくると突き合わせるのも速くなるんだけど、さすがにかっこわるいです。
むしろ、ラズパイからの情報を仮置きする揮発性の高い(?)サービスを作ろうかと思いました。TupleSpace / Rinda風なやつを作るぜ!!


あれ?Rinda?なんか覚えがある..。


あった。

rendez-vous - I like Ruby too.

3DSiPhoneでデータを交換するために書いたサービス。
ラズパイを起動したらここに向かってIPアドレスを書いて、同じ頃(60秒以内)にここから取得すればよいのだった。便利。さすが私。

数年ぶりに/etc/rc.localを編集して次の行を挿入。標準入力からのデータをtext/plainで指定したチャネルに送るだけ。
hostname -IってIPアドレス出力するのね。curlのオプションも初めて調べました。

hostname -I | curl -s -F 'file=@-;type=text/plain' -F 'name=チャネル' http://www.druby.org/cgi-bin/rdv > /dev/null

取得側はcurlなりSafariなりでwww.druby.org/cgi-bin/rdv/チャネルにアクセス。ラズパイの書き込みとPCの読み込みがうまく出会えれば割り当てられたIPアドレスが手に入ります。

dRubyによる分散・Webプログラミング

温度の取得

おまけでついていた1-wireの温度計を使って、室温を返すようにしてみました。タイムアウトの都合上、1分以内の古い情報が返ります。

#!/usr/bin/ruby

fname = '/sys/bus/w1/devices/28-0000XXXXXXXX/w1_slave'
value = File.read(fname)
if /t=([0-9]+)/ =~ value
  puts "#{$1.to_i / 1000.0}\t#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
else
  'failed'
end

1-wireのデバイスからのデータの取得と整形のRubyスクリプトと、curlで通知するshスクリプト

#!/bin/sh

while true; do
   /home/pi/temp.rb | curl -s -F 'file=@-;type=text/plain' -F 'name=チャネル' http://www.druby.org/cgi-bin/rdv > /dev/null
done

/etc/rc.localに追加して終わり。

su - pi -c "./temp.sh" &

数時間、放っといたらラズパイが止まってた...。放熱の問題なんだろうか..。

心配なので5分おきに取得してMyDripに書き込む実験中。

irb(main):064:0> while true
irb(main):065:1> t, v = e.read
irb(main):066:1> MyDrip.write(v.split("\t")[0].to_f, "temp-pi")
irb(main):067:1> puts v
irb(main):068:1> sleep 300
irb(main):069:1> end

eっていうのはこんなの。e = Ether.new("チャネル")してます。あえてcurlを使ってみてるところが不自然。

class Ether
  def initialize(channel='actor')
    @channel = channel
    @url = "http://www.druby.org/cgi-bin/rdv"
  end

  def write_string(str)
    File.open('/tmp/curl_out.txt', 'w') {|fp| fp.write(str)}
    write_file('/tmp/curl_out.txt', 'text/plain')
  end

  def write_file(fname, type='application/octet-stream')
    cmd = "curl -s -F 'file=@#{fname};type=#{type}' -F 'name=#{@channel}' #{@url}"
    result = `#{cmd}`
  end

  def read
    cmd = "curl -o /tmp/curl_in.bin -s #{@url}/#{@channel} -w '%{content_type}'"
    result = [`#{cmd}`, File.read('/tmp/curl_in.bin')]
  end
end

別の端末からMyDrip.headすると直近の温度が見える。

irb(main):005:0> MyDrip.head
=> [[1428263209500632, 19.187, "temp-pi"]]

アクターモデル

外部からラズパイに向かっても同じ方法で情報を渡せます。問い合わせをして、その結果を返すようなのも作れます(ネタがないけど)。
rdvを(信頼性の低い)メッセージ環境、チャネルを自身のアドレスと考えると、これはアクターモデルに見做せます。メッセージは単に送られるだけ。

後でかく。