1. PhidgetBiff |
PhidgetBiffは,WebページやRSSを定期的に監視し,更新された場合に対応するLEDを点灯させる,いわば実世界版 Biffシステムです(図11).さらに,LEDとプッシュスイッチをペアで配置すれば,該当ページをスイッチひとつで表示することができます.このように,今回紹 介する中では,やや応用よりなシステムとなっています(図12).
ここでは,PhidgetBiffのハードウェア/ソフトウェアについて紹介していきます. なお,ソフトウェアのダウンロードはこちらから行えます. |
|
図11 PhidetBiffの外観 |
|
|
|
(Web/RSSが更新されると,LEDが点灯する) |
(プッシュスイッチを押すと,該当するWebページが表示され,LEDが消灯する.) |
図12 PhidetBiffの使い方 |
|
ハードウェア |
PhidgetBiff用のハードウェアとして,8つのLED/プッシュスイッチをペアで配置したデバイスを製作します(図13). |
|
図13 PhidetBiffのハードウェア |
|
LEDとプッシュスイッチは,ぷらっとホームで販売されているInterfaceKit Package に標準添付されています.また,バリエーションを増やしたい場合は,秋月電子や千石電商のWebサイトから,1個あたり10〜100円程度で購入することが可能です.
今回のハードウェアは,LED/プッシュスイッチを上下に並べたものを1セットとして,ユニバーサル基板上に8セット配置しています.LED/スイッチは,半田付けして固定した後,適当なケーブルでInterfaceKitのデジタル出力/デジタル入力に接続します. そして,InterfaceKitとPCをUSBケーブルで接続すれば,ハードウェアの準備は完了です. ここでは,ノートパソコンのディスプレイの左上部分にデバイスを取り付けています. |
ソフトウェア |
PhidgetBiffのソフトウェアは,PhidgetServerに接続するTCPクライアントとして,Rubyを用いて記述しています.PhidgetBiffを利用するためには,Cygwinから以下のように入力します.
%./PhidgetBiff.rb
オプションの設定などは,PhidgetBrowserとほぼ同様です.
ここでは,ソースコードの主要部分を参照しながら,PhidgetServerの処理の流れについて簡単に説明します.なお,PhidgetBrowserと共通する説明については割愛します. |
1. PhidgetServerへの接続 |
TCPSocketクラスを用いて,PhidgetServerに接続します. |
2. リストファイルの読み込み |
更新を監視するURLのリストを読み込みます.以下のように,一行にひとつのURLを記載したファイル("url.txt")を読み込み,配列に格納します.直接Webページを指定する以外に,RSSを指定することも可能です. |
["url.txt"]
http://mobiquitous.com/diary/index.rdf
http://pitecan.com/
http://namazu.org/~satoru/blog/index.rdf
def load_url(file = "url.txt")
uris = Array.new
File.open(file) do |f|
f.each do |line|
line.chomp!
uris.push(URI.parse(line))
break if uris.length > 8
end
end
uris
end
|
3. 更新時間の初期化 |
リスト内の各URLの,最終更新時刻を取得し,ハッシュに格納します.最終更新時刻('last-modified')は,httpのheadメソッドを用いて取得することができます.接続がタイムアウトされるなど,最終更新時刻が取得できない場合は,GMTの起算時間(1970年1月1日午前0時)を返します. |
def init_modified_time(uris)
modified_times = Hash.new
uris.each do |uri|
time = get_modified_time(uri)
modified_times[uri] = time
end
modified_times
end
def get_modified_time (uri, timeout = 2)
return nil unless /^http/ =~ uri.to_s
time = nil
dead = Time.at(0)
begin
uri_const = URI.parse(uri.to_s)
http = http_connect(uri_const, timeout)
response = http.head(uri.to_s)
if response.code.to_i != 200
time = dead
elsif response['last-modified']
time = Time.httpdate(response['last-modified'])
else
time = dead
end
rescue Net::ProtoFatalError => e # 404
time = dead
rescue
time = dead # timeout?
end
time
end
|
4. 更新時刻の監視 |
各URLの更新時刻を一定時間毎(標準では10秒間隔)に監視します.更新があった場合,LEDの点灯処理を行います. |
def biff_loop (uris, modified_time, sleep_time = 10)
while true
uris.each do |uri|
time = get_modified_time(uri)
next if time == nil
if(modified_times[uri] < time)
set_port(uris.index(uri), 1)
modified_times[uri] = time
end
end
sleep(sleep_time)
end
end
|
5. LEDの制御 |
デジタル出力の状態を制御し,LEDを点灯/消灯します. |
def set_port(socket, port, state = 0)
str = "Out,InterfaceKit,#{port},#{state}\r\n"
socket.print str
end
|
6. スイッチ入力の監視 |
受信したコマンドを解析し,各プッシュスイッチの状態を検出します.プッシュスイッチが新たに押された場合,該当するURLを開きます.また,デジタル出力を介して,該当するLEDを消灯します. |
def main
...
port, data = parse(line)
if data &&
data != port_states[port]
open_url(@uris[port])
set_port(socket, port)
port_states[port] = data
end
...
end
def parse(line)
args = line.split(",")
if args[0] == "In" and
args[1] == "InterfaceKit" and
args[2] == "Digital"
port = args[3].to_i
data = args[4].to_i
return port, data
end
end
|
7. Webページを開く |
プッシュスイッチが押された場合,該当するWebページを開きます.URLにRSSが指定されている場合は,RSSから適切なURLを抽出して利用します. |
def open_url(uri)
url = uri.to_s
if(uri.path =~ /[.]rdf$/)
url = parse_rss(uri)
end
system "cygstart #{url}"
end
def parse_rss(uri)
url = nil
Net::HTTP.start(uri.host) do |http|
begin
response = http.get(uri.path)
rss = RSS::Parser.parse(response.body)
url = rss.channel.link.to_s
rescue
end
end
url
end
|