# TWE command class
class TweCmd
attr_reader :srcdev, :command
def initialize(v)
@srcdev = v[1..2] # Source device
@command = v[3..4] # Command
end
end
# TWE 0x01 command class
class TweCmd01 < TweCmd
attr_reader :data
def initialize(v)
super(v)
@data = decode(v.strip[5...-2])
end
def decode(s)
s.scan(/.{1,2}/).inject([]) {|ary, v| ary << v.to_i(16)}.pack("c*")
end
def self.encode(s)
s.unpack("c*").inject("") {|str, c| str + ("0" + c.to_s(16))[-2,2]}
end
end
# TWE 0x81 command class
class TweCmd81 < TweCmd
attr_reader :lpi, :srcsdr, :tgtdev, :time
attr_reader :voltage, :di_sts, :di_chg, :ad
def initialize(v)
super(v)
@lqi = v[9..10].to_i(16) # LQI
@srcadr = v[11..18] # Source device
@tgtdev = v[19..20] # Target device
@time = v[21..24].to_i(16) # Time stamp
@relay = v[25..26].to_i(16) # Relay flag
@voltage = v[27..30].to_i(16) # Voltage
@di_sts = v[33..34].to_i(16) # DI status
@di_chg = v[35..36].to_i(16) # DI status change
ef = v[45..46].to_i(16) # AD1..AD4 bias
@ad = [
(v[37..38].to_i(16) * 4 + (ef & 0x03)) * 4, # AD1
(v[39..40].to_i(16) * 4 + ((ef & 0x0c) >> 2)) * 4, # AD2
(v[41..42].to_i(16) * 4 + ((ef & 0x30) >> 4)) * 4, # AD3
(v[43..44].to_i(16) * 4 + ((ef & 0xc0) >> 6)) * 4 # AD4
]
@prvDI = nil
end
def di
[ @di_sts & 0x01, (@di_sts >> 1) & 0x01,
(@di_sts >> 2) & 0x01, (@di_sts >> 3) & 0x01 ]
end
def relayed?
@relay > 0
end
end
class TweLite
attr_reader :target
def initialize
@ser = Serial.new(115200)
@sts = {}
@data = nil
@target = nil
end
def recv
v = @ser.gets
return nil if v == "" || v[0] != ":"
@data = v
case v[3..4]
when "81"
cmd = TweCmd81.new(v)
@target = cmd.srcdev unless @target
when "01"
cmd = TweCmd01.new(v)
else
cmd = v
end
cmd
end
def send(data)
data = data.to_s unless data.instance_of?(String)
if @target #!= "00"
body = ":#{@target}01"
body += TweCmd01.encode(data)
body += TweLite.sum(body)
body += "\r\n"
puts "SEND: #{body.inspect}" if $TWEDEBUG
@ser.puts body
end
end
def self.sum(v)
s = 0
v = v[1..-1] if v[0] == ":"
(v.size/2).to_i.times do |i|
s += v[i*2,2].to_i(16)
end
("0" + (256 - s % 256).to_s(16))[-2,2].upcase
end
def master?
@target && @target != '00'
end
end
twe = TweLite.new
di, count = nil, 1
loop do
if twe.master?
while v = twe.recv
case v
when TweCmd01
puts "RECV(#{v.srcdev}): #{v.data}"
when TweCmd81
di = v.di
end
end
end
# idle
unless twe.master?
msg = "test#{count}"
puts "SEND(#{twe.target}): #{msg}"
twe.send(msg)
count += 1
delay(1000)
end
end