結論から言うと、あっさり捕まえることが出来ました。UDPで7070番ポートに、ばすんと、コマンドを送りつけるだけです。IPなんちゃらシリーズは、スイッチ以外に、モータやカメラの繋がったものもあり、単純なON/OFF以外のコマンドもあるようですが、とりあえず、スイッチの状態取得と、コントロール方法は突き止めました。
コマンドとしては、状態取得の時には"AVOISYS0"を送り、スイッチ制御の時には"AVOISYS1"+8bitのビットフィールドでスイッチの状態を表した数値(10進数で3桁、足りない桁数は末尾に\0を補う)を送るだけです。aviosysという会社名なのに、AVOISYSというコマンドは、typoなのか、何なのか……。
とりあえず、これを行なう Rubyのクラスを作ってみました。こんな感じです。
もちろん、これを利用して何か不具合が起こっても、責任は負えませんので、自己責任でよろしくお願いします。
# IP Power Controller Class
require 'socket'
class IPController
def initialize(target = nil, port = 7070)
@target = target
@port = port
@sw = []
end
def exec(cmd)
c = UDPsocket.open
c.send(cmd, 0, @target, @port.to_i)
r = c.recvfrom(1000)
s = if /^(\d+)/ =~ r[0]
$1.to_i
else
0
end
end
def status
cmd = 'AVOISYS0'
s = self.exec cmd
s = 0 if s < 0 or s > 255
0.upto 7 do |i|
@sw[i] = (s & (1 << i)) == 0
end
@sw
end
def on(n)
return -1 if n < 0 or n > 7
self.status
w = 0
0.upto 7 do |i|
if @sw[i] or i == n
w += (1 << i)
end
end
cmd = sprintf("AVOISYS1%d\0\0\0", w)[0, 11]
s = self.exec cmd
end
def off(n)
return -1 if n < 0 or n > 7
self.status
w = 0
0.upto 7 do |i|
if @sw[i] and i != n
w += (1 << i)
end
end
cmd = sprintf("AVOISYS1%d\0\0\0", w)[0, 11]
s = self.exec cmd
end
self.status
if @sw[n]
self.off n
else
self.on n
end
end
end
コメント