rmodbus 1.3.3 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/NEWS.md +19 -0
- data/README.md +8 -8
- data/examples/perfomance_rtu.rb +55 -56
- data/examples/perfomance_rtu_via_tcp.rb +54 -55
- data/examples/perfomance_tcp.rb +54 -55
- data/examples/simple_xpca_gateway.rb +85 -0
- data/examples/use_rtu_via_tcp_modbus.rb +14 -11
- data/examples/use_tcp_modbus.rb +14 -11
- data/lib/rmodbus/client/slave.rb +333 -0
- data/lib/rmodbus/client.rb +15 -10
- data/lib/rmodbus/debug.rb +12 -15
- data/lib/rmodbus/errors.rb +26 -2
- data/lib/rmodbus/ext.rb +72 -51
- data/lib/rmodbus/options.rb +4 -1
- data/lib/rmodbus/proxy.rb +14 -9
- data/lib/rmodbus/rtu.rb +89 -125
- data/lib/rmodbus/rtu_client.rb +22 -2
- data/lib/rmodbus/rtu_server.rb +16 -12
- data/lib/rmodbus/rtu_slave.rb +26 -3
- data/lib/rmodbus/rtu_via_tcp_server.rb +12 -19
- data/lib/rmodbus/server/slave.rb +18 -0
- data/lib/rmodbus/server.rb +227 -84
- data/lib/rmodbus/sp.rb +10 -12
- data/lib/rmodbus/tcp.rb +9 -10
- data/lib/rmodbus/tcp_client.rb +3 -0
- data/lib/rmodbus/tcp_server.rb +41 -35
- data/lib/rmodbus/tcp_slave.rb +19 -18
- data/lib/rmodbus/version.rb +3 -2
- data/lib/rmodbus.rb +20 -21
- metadata +63 -50
- data/Rakefile +0 -29
- data/examples/simple-xpca-gateway.rb +0 -84
- data/lib/rmodbus/rtu_via_tcp_client.rb +0 -26
- data/lib/rmodbus/rtu_via_tcp_slave.rb +0 -29
- data/lib/rmodbus/slave.rb +0 -310
- data/spec/client_spec.rb +0 -88
- data/spec/exception_spec.rb +0 -119
- data/spec/ext_spec.rb +0 -52
- data/spec/logging_spec.rb +0 -89
- data/spec/proxy_spec.rb +0 -74
- data/spec/read_rtu_response_spec.rb +0 -92
- data/spec/response_mismach_spec.rb +0 -163
- data/spec/rtu_client_spec.rb +0 -86
- data/spec/rtu_server_spec.rb +0 -30
- data/spec/rtu_via_tcp_client_spec.rb +0 -76
- data/spec/rtu_via_tcp_server_spec.rb +0 -16
- data/spec/slave_spec.rb +0 -55
- data/spec/spec_helper.rb +0 -54
- data/spec/tcp_client_spec.rb +0 -88
- data/spec/tcp_server_spec.rb +0 -129
data/spec/tcp_client_spec.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
# -*- coding: ascii
|
2
|
-
require 'rmodbus'
|
3
|
-
|
4
|
-
describe ModBus::TCPClient do
|
5
|
-
describe "method 'query'" do
|
6
|
-
before(:each) do
|
7
|
-
@uid = 1
|
8
|
-
@sock = double('Socket')
|
9
|
-
@adu = "\000\001\000\000\000\001\001"
|
10
|
-
|
11
|
-
TCPSocket.should_receive(:new).with('127.0.0.1', 1502).and_return(@sock)
|
12
|
-
@sock.stub(:read).with(0).and_return('')
|
13
|
-
@cl = ModBus::TCPClient.new('127.0.0.1', 1502)
|
14
|
-
@slave = @cl.with_slave(@uid)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should send valid MBAP Header' do
|
18
|
-
@adu[0,2] = @slave.transaction.next.to_word
|
19
|
-
@sock.should_receive(:write).with(@adu)
|
20
|
-
@sock.should_receive(:read).with(7).and_return(@adu)
|
21
|
-
@slave.query('').should == nil
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should not throw exception and white next packet if get other transaction' do
|
25
|
-
@adu[0,2] = @slave.transaction.next.to_word
|
26
|
-
@sock.should_receive(:write).with(@adu)
|
27
|
-
@sock.should_receive(:read).with(7).and_return("\000\002\000\000\000\001" + @uid.chr)
|
28
|
-
@sock.should_receive(:read).with(7).and_return("\000\001\000\000\000\001" + @uid.chr)
|
29
|
-
|
30
|
-
expect{ @slave.query('') }.to_not raise_error
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should throw timeout exception if do not get own transaction' do
|
34
|
-
@slave.read_retries = 2
|
35
|
-
@adu[0,2] = @slave.transaction.next.to_word
|
36
|
-
@sock.should_receive(:write).at_least(1).times.with(/\.*/)
|
37
|
-
@sock.should_receive(:read).at_least(1).times.with(7).and_return("\000\x3\000\000\000\001" + @uid.chr)
|
38
|
-
|
39
|
-
expect{ @slave.query('') }.to raise_error(ModBus::Errors::ModBusTimeout, "Timed out during read attempt")
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
it 'should return only data from PDU' do
|
44
|
-
request = "\x3\x0\x6b\x0\x3"
|
45
|
-
response = "\x3\x6\x2\x2b\x0\x0\x0\x64"
|
46
|
-
@adu = @slave.transaction.next.to_word + "\x0\x0\x0\x9" + @uid.chr + request
|
47
|
-
@sock.should_receive(:write).with(@adu[0,4] + "\0\6" + @uid.chr + request)
|
48
|
-
@sock.should_receive(:read).with(7).and_return(@adu[0,7])
|
49
|
-
@sock.should_receive(:read).with(8).and_return(response)
|
50
|
-
|
51
|
-
@slave.query(request).should == response[2..-1]
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'should sugar connect method' do
|
55
|
-
ipaddr, port = '127.0.0.1', 502
|
56
|
-
TCPSocket.should_receive(:new).with(ipaddr, port).and_return(@sock)
|
57
|
-
@sock.should_receive(:closed?).and_return(false)
|
58
|
-
@sock.should_receive(:close)
|
59
|
-
ModBus::TCPClient.connect(ipaddr, port) do |cl|
|
60
|
-
cl.ipaddr.should == ipaddr
|
61
|
-
cl.port.should == port
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'should have closed? method' do
|
66
|
-
@sock.should_receive(:closed?).and_return(false)
|
67
|
-
@cl.closed?.should == false
|
68
|
-
|
69
|
-
@sock.should_receive(:closed?).and_return(false)
|
70
|
-
@sock.should_receive(:close)
|
71
|
-
|
72
|
-
@cl.close
|
73
|
-
|
74
|
-
@sock.should_receive(:closed?).and_return(true)
|
75
|
-
@cl.closed?.should == true
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'should give slave object in block' do
|
79
|
-
@cl.with_slave(1) do |slave|
|
80
|
-
slave.uid = 1
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
it "should tune connection timeout" do
|
86
|
-
lambda { ModBus::TCPClient.new('81.123.231.11', 1999, :connect_timeout => 0.001) }.should raise_error(ModBus::Errors::ModBusTimeout)
|
87
|
-
end
|
88
|
-
end
|
data/spec/tcp_server_spec.rb
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
# -*- coding: ascii
|
2
|
-
require "rmodbus"
|
3
|
-
|
4
|
-
describe ModBus::TCPServer do
|
5
|
-
before :all do
|
6
|
-
unit_ids = (1..247).to_a.shuffle
|
7
|
-
valid_unit_id = unit_ids.first
|
8
|
-
@invalid_unit_id = unit_ids.last
|
9
|
-
@server = ModBus::TCPServer.new(8502, valid_unit_id)
|
10
|
-
@server.coils = [1,0,1,1]
|
11
|
-
@server.discrete_inputs = [1,1,0,0]
|
12
|
-
@server.holding_registers = [1,2,3,4]
|
13
|
-
@server.input_registers = [1,2,3,4]
|
14
|
-
@server.start
|
15
|
-
@cl = ModBus::TCPClient.new('127.0.0.1', 8502)
|
16
|
-
@cl.read_retries = 1
|
17
|
-
@slave = @cl.with_slave(valid_unit_id)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should succeed if UID is broadcast" do
|
21
|
-
@cl.with_slave(0).read_coils(1,3)
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should fail if UID is mismatched" do
|
25
|
-
lambda { @cl.with_slave(@invalid_unit_id).read_coils(1,3) }.should raise_exception(
|
26
|
-
ModBus::Errors::ModBusTimeout
|
27
|
-
)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should send exception if function not supported" do
|
31
|
-
lambda { @slave.query('0x43') }.should raise_exception(
|
32
|
-
ModBus::Errors::IllegalFunction,
|
33
|
-
"The function code received in the query is not an allowable action for the server"
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should send exception if quanity of registers are more than 0x7d" do
|
38
|
-
lambda { @slave.read_holding_registers(0, 0x7e) }.should raise_exception(
|
39
|
-
ModBus::Errors::IllegalDataValue,
|
40
|
-
"A value contained in the query data field is not an allowable value for server"
|
41
|
-
)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "shouldn't send exception if quanity of coils are more than 0x7d0" do
|
45
|
-
lambda { @slave.read_coils(0, 0x7d1) }.should raise_exception(
|
46
|
-
ModBus::Errors::IllegalDataValue,
|
47
|
-
"A value contained in the query data field is not an allowable value for server"
|
48
|
-
)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should send exception if addr not valid" do
|
52
|
-
lambda { @slave.read_coils(2, 8) }.should raise_exception(
|
53
|
-
ModBus::Errors::IllegalDataAddress,
|
54
|
-
"The data address received in the query is not an allowable address for the server"
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should calc a many requests" do
|
59
|
-
@slave.read_coils(1,2)
|
60
|
-
@slave.write_multiple_registers(0,[9,9,9,])
|
61
|
-
@slave.read_holding_registers(0,3).should == [9,9,9]
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should supported function 'read coils'" do
|
65
|
-
@slave.read_coils(0,3).should == @server.coils[0,3]
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should supported function 'read coils' with more than 125 in one request" do
|
69
|
-
@server.coils = Array.new( 1900, 1 )
|
70
|
-
@slave.read_coils(0,1900).should == @server.coils[0,1900]
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should supported function 'read discrete inputs'" do
|
74
|
-
@slave.read_discrete_inputs(1,3).should == @server.discrete_inputs[1,3]
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should supported function 'read holding registers'" do
|
78
|
-
@slave.read_holding_registers(0,3).should == @server.holding_registers[0,3]
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should supported function 'read input registers'" do
|
82
|
-
@slave.read_input_registers(2,2).should == @server.input_registers[2,2]
|
83
|
-
end
|
84
|
-
|
85
|
-
it "should supported function 'write single coil'" do
|
86
|
-
@server.coils[3] = 0
|
87
|
-
@slave.write_single_coil(3,1)
|
88
|
-
@server.coils[3].should == 1
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should supported function 'write single register'" do
|
92
|
-
@server.holding_registers[3] = 25
|
93
|
-
@slave.write_single_register(3,35)
|
94
|
-
@server.holding_registers[3].should == 35
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should supported function 'write multiple coils'" do
|
98
|
-
@server.coils = [1,1,1,0, 0,0,0,0, 0,0,0,0, 0,1,1,1]
|
99
|
-
@slave.write_multiple_coils(3, [1, 0,1,0,1, 0,1,0,1])
|
100
|
-
@server.coils.should == [1,1,1,1, 0,1,0,1, 0,1,0,1, 0,1,1,1]
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should supported function 'write multiple registers'" do
|
104
|
-
@server.holding_registers = [1,2,3,4,5,6,7,8,9]
|
105
|
-
@slave.write_multiple_registers(3,[1,2,3,4,5])
|
106
|
-
@server.holding_registers.should == [1,2,3,1,2,3,4,5,9]
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should have options :host" do
|
110
|
-
host = '192.168.0.1'
|
111
|
-
srv = ModBus::TCPServer.new(1010, 1, :host => '192.168.0.1')
|
112
|
-
srv.host.should eql(host)
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should have options :max_connection" do
|
116
|
-
max_conn = 5
|
117
|
-
srv = ModBus::TCPServer.new(1010, 1, :max_connection => 5)
|
118
|
-
srv.maxConnections.should eql(max_conn)
|
119
|
-
end
|
120
|
-
|
121
|
-
after :all do
|
122
|
-
@cl.close unless @cl.closed?
|
123
|
-
@server.stop unless @server.stopped?
|
124
|
-
while GServer.in_service?(8502)
|
125
|
-
sleep(0.01)
|
126
|
-
end
|
127
|
-
@server.stop
|
128
|
-
end
|
129
|
-
end
|