外からスイッチを制御する(3)

  • 投稿日:
  • by
  • カテゴリ:

結論から言うと、あっさり捕まえることが出来ました。UDPで7070番ポートに、ばすんと、コマンドを送りつけるだけです。IPなんちゃらシリーズは、スイッチ以外に、モータやカメラの繋がったものもあり、単純なON/OFF以外のコマンドもあるようですが、とりあえず、スイッチの状態取得と、コントロール方法は突き止めました。

コマンドとしては、状態取得の時には"AVOISYS0"を送り、スイッチ制御の時には"AVOISYS1"+8bitのビットフィールドでスイッチの状態を表した数値(10進数で3桁、足りない桁数は末尾に\0を補う)を送るだけです。aviosysという会社名なのに、AVOISYSというコマンドは、typoなのか、何なのか……。

とりあえず、これを行なう Rubyのクラスを作ってみました。こんな感じです。
もちろん、これを利用して何か不具合が起こっても、責任は負えませんので、自己責任でよろしくお願いします。

# -*- 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

def inv(n)
self.status
if @sw[n]
self.off n
else
self.on n
end
end
end