Using Ruby to connect with multiple IP Input output interface, Netiom
I am trying to create an application written in ruby which communicates with multiple input/output interfaces over TCP/IP. The IO interface I am using is called a NETIOM. The interface has 16 digital inputs and 16 digital outputs.
How do I:
- handle multiple connections? Do I use an array?
- send a message through single connection and then see its response?
- 'do something' when an input is triggered? I would need to 开发者_如何学Pythonbe able to identify which input and interface it was triggered on.
This code works for one Netiom device and is also able to detect inputs being pressed but the code exits after a little while. I have been experimenting with classes and arrays but not getting anywhere.
require 'socket'
server = TCPServer.open(3012)
@socket = server.accept
@socket.puts "SEND\r\n"
while line = @socket.gets
puts line.chop
end
this code returns:
Digital inputs 1-8 : 11111111
Digital inputs 9-16: 11111111 Digital outputs 1-8 : 00000000 Digital outputs 9-16: 00000000
As the client acts in a particular way, I have written up some information about how it works. There is also a link to a pdf manual (take a look at 9th page). http://www.phaedrusltd.com/Download/NETIOM%20Instructions.pdf
I appreciate any help you can give me and many thanks for your time.
When programming the interface you can specify the IP address and port of the server that you want it to communicate, this would be our ruby server. By default, the interface is attempting to connect to the server every 10 seconds until the server finally accepts. Once the server accepts the connection, it should send the message "SEND" and the interface will then return some data with the status of all the inputs and outputs, displayed below. If and when we wanted to close the connection we would send the message "CLOSE".
The data that is returned:
Digital inputs 1-8 : 11111111
Digital inputs 9-16: 11111111
Digital outputs 1-8 : 00000000
Digital outputs 9-16: 00000000
If one of the 16 inputs is pressed while there is a connection, it sends the same data as before but it changes that particular input to a '0'
Digital inputs 1-8 : 01111111
// input 1 has been triggeredDigital inputs 9-16: 11111111
Digital outputs 1-8 : 00000000
Digital outputs 9-16: 00000000
When the button is released or let go the file is sent again but now the input is back to normal.
Digital inputs 1-8 : 11111111
// input 1 is back to normal.Digital inputs 9-16: 11111111
Digital outputs 1-8 : 00000000
Digital outputs 9-16: 00000000
If I want to turn output 8 on, I send A08, and to turn it off I send B08. I can toggle an output by using T08.
Use Thread for working with multiple connections, use a TCP server for manage TCP, and a NETIOM manager for work with your devices.
Something like that (not tested, it's a copy/past from my works) :
require 'socket'
require 'thread'
require 'timeout'
class TcpServer
def initialize(iOServeur,port)
@port=port
@ioserver=iOServeur
@th=[]
@server = TCPServer.new('0.0.0.0', @port)
@server.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
Thread.new do
begin
while (session = @server.accept)
Thread.new(session) do |sess|
begin
@th[Thread.current]=Time.now
ip=@session.peeraddr.last
@ioserveur.connection(ip)
request(ip,sess)
ensure
@ioserveur.deconnection(ip)
sess.close rescue nil
@th.delete(Thread.current)
end
end
end
rescue
error($!.to_s)
end
end
end
def request(ip,sock)
while (str=sock.read)
ret=@ioServer.received(ip,str)
if ret
sock.write(ret) if String===ret && ret.length>0
else
sock.close raise nil
return;
end
end
end
end
class IoServer
def initialize() end
def connection(ip) end
def deconnection(ip) end
def received(ip,str) return "" end
end
Thread.abort_on_exception = true if $DEBUG
BasicSocket.do_not_reverse_lookup = true
ios=IoServer.new
TcpServer.new(ios,8080)
gets # !!
精彩评论