rmodbus 0.5.0 → 1.0.0
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.
- data/NEWS.md +52 -0
- data/README.md +87 -0
- data/Rakefile +22 -36
- data/examples/perfomance_rtu.rb +35 -37
- data/examples/perfomance_tcp.rb +36 -38
- data/examples/use_rtu_via_tcp_modbus.rb +8 -5
- data/examples/use_tcp_modbus.rb +10 -6
- data/lib/rmodbus/client.rb +52 -174
- data/lib/rmodbus/common.rb +45 -18
- data/lib/rmodbus/{exceptions.rb → errors.rb} +3 -0
- data/lib/rmodbus/ext.rb +25 -2
- data/lib/rmodbus/proxy.rb +54 -0
- data/lib/rmodbus/{crc16.rb → rtu.rb} +73 -2
- data/lib/rmodbus/rtu_client.rb +20 -116
- data/lib/rmodbus/rtu_server.rb +28 -57
- data/lib/rmodbus/rtu_slave.rb +59 -0
- data/lib/rmodbus/rtu_via_tcp_client.rb +22 -86
- data/lib/rmodbus/rtu_via_tcp_server.rb +31 -95
- data/lib/rmodbus/rtu_via_tcp_slave.rb +58 -0
- data/lib/rmodbus/{parsers.rb → server.rb} +24 -15
- data/lib/rmodbus/slave.rb +268 -0
- data/lib/rmodbus/sp.rb +45 -0
- data/lib/rmodbus/tcp.rb +49 -0
- data/lib/rmodbus/tcp_client.rb +19 -88
- data/lib/rmodbus/tcp_server.rb +16 -19
- data/lib/rmodbus/tcp_slave.rb +64 -0
- data/lib/rmodbus/version.rb +17 -0
- data/lib/rmodbus.rb +20 -4
- data/spec/client_spec.rb +19 -45
- data/spec/exception_spec.rb +26 -27
- data/spec/ext_spec.rb +24 -1
- data/spec/logging_spec.rb +31 -37
- data/spec/proxy_spec.rb +73 -0
- data/spec/read_rtu_response_spec.rb +2 -4
- data/spec/rtu_client_spec.rb +17 -19
- data/spec/rtu_server_spec.rb +1 -3
- data/spec/rtu_via_tcp_client_spec.rb +69 -63
- data/spec/slave_spec.rb +55 -0
- data/spec/tcp_client_spec.rb +77 -69
- data/spec/tcp_server_spec.rb +34 -49
- metadata +123 -37
- data/AUTHORS +0 -3
- data/ChangeLog +0 -82
- data/LICENSE +0 -675
- data/README +0 -53
- data/examples/add_new_function.rb +0 -19
@@ -1,72 +1,78 @@
|
|
1
|
-
begin
|
2
|
-
require 'rubygems'
|
3
|
-
rescue
|
4
|
-
end
|
5
1
|
require 'rmodbus'
|
6
|
-
|
7
2
|
include ModBus
|
8
3
|
|
9
4
|
describe RTUViaTCPClient do
|
5
|
+
describe "method 'query'" do
|
6
|
+
before do
|
7
|
+
@sock = mock('Socked')
|
8
|
+
TCPSocket.should_receive(:new).with("127.0.0.1", 10002).and_return(@sock)
|
9
|
+
@sock.stub!(:read_timeout=)
|
10
|
+
@sock.stub!(:read)
|
11
|
+
|
12
|
+
@cl = RTUViaTCPClient.new("127.0.0.1")
|
13
|
+
@slave = @cl.with_slave(1)
|
14
|
+
@slave.read_retries = 0
|
15
|
+
end
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
17
|
+
it "should ignore frame with other UID" do
|
18
|
+
request = "\x10\x0\x1\x0\x1\x2\xff\xff"
|
19
|
+
@sock.should_receive(:write).with("\1#{request}\xA6\x31")
|
20
|
+
@sock.should_receive(:read).with(2).and_return("\x2\x10")
|
21
|
+
@sock.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
|
22
|
+
lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should ignored frame with incorrect CRC" do
|
26
|
+
request = "\x10\x0\x1\x0\x1\x2\xff\xff"
|
27
|
+
@sock.should_receive(:write).with("\1#{request}\xA6\x31")
|
28
|
+
@sock.should_receive(:read).with(2).and_return("\x2\x10")
|
29
|
+
@sock.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
|
30
|
+
lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return value of registers"do
|
34
|
+
request = "\x3\x0\x1\x0\x1"
|
35
|
+
@sock.should_receive(:write).with("\1#{request}\xd5\xca")
|
36
|
+
@sock.should_receive(:read).with(2).and_return("\x1\x3")
|
37
|
+
@sock.should_receive(:read).with(1).and_return("\x2")
|
38
|
+
@sock.should_receive(:read).with(4).and_return("\xff\xff\xb9\xf4")
|
39
|
+
@slave.query(request).should == "\xff\xff"
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should sugar connect method' do
|
43
|
+
ipaddr, port = '127.0.0.1', 502
|
44
|
+
TCPSocket.should_receive(:new).with(ipaddr, port).and_return(@sock)
|
45
|
+
@sock.should_receive(:closed?).and_return(false)
|
46
|
+
@sock.should_receive(:close)
|
47
|
+
RTUViaTCPClient.connect(ipaddr, port) do |cl|
|
48
|
+
cl.ipaddr.should == ipaddr
|
49
|
+
cl.port.should == port
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should have closed? method' do
|
54
|
+
@sock.should_receive(:closed?).and_return(false)
|
55
|
+
@cl.closed?.should == false
|
56
|
+
|
57
|
+
@sock.should_receive(:closed?).and_return(false)
|
58
|
+
@sock.should_receive(:close)
|
59
|
+
|
60
|
+
@cl.close
|
61
|
+
|
62
|
+
@sock.should_receive(:closed?).and_return(true)
|
63
|
+
@cl.closed?.should == true
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should give slave object in block' do
|
67
|
+
@cl.with_slave(1) do |slave|
|
68
|
+
slave.uid = 1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
36
72
|
|
37
|
-
it "should
|
38
|
-
|
39
|
-
|
40
|
-
@sock.should_receive(:read).with(2).and_return("\x1\x3")
|
41
|
-
@sock.should_receive(:read).with(1).and_return("\x2")
|
42
|
-
@sock.should_receive(:read).with(4).and_return("\xff\xff\xb9\xf4")
|
43
|
-
@mb_client.query(request).should == "\xff\xff"
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should sugar connect method' do
|
47
|
-
ipaddr, port, slave = '127.0.0.1', 502, 3
|
48
|
-
TCPSocket.should_receive(:new).with(ipaddr, port).and_return(@sock)
|
49
|
-
@sock.should_receive(:closed?).and_return(false)
|
50
|
-
@sock.should_receive(:close)
|
51
|
-
RTUViaTCPClient.connect(ipaddr, port, slave) do |cl|
|
52
|
-
cl.ipaddr.should == ipaddr
|
53
|
-
cl.port.should == port
|
54
|
-
cl.slave.should == slave
|
73
|
+
it "should tune connection timeout" do
|
74
|
+
timeout(0.5) do
|
75
|
+
lambda { RTUViaTCPClient.new('81.123.231.11', 1999, :connect_timeout => 0.1) }.should raise_error(ModBusTimeout)
|
55
76
|
end
|
56
77
|
end
|
57
|
-
|
58
|
-
it 'should have closed? method' do
|
59
|
-
@sock.should_receive(:closed?).and_return(false)
|
60
|
-
@mb_client.closed?.should == false
|
61
|
-
|
62
|
-
@sock.should_receive(:closed?).and_return(false)
|
63
|
-
@sock.should_receive(:close)
|
64
|
-
|
65
|
-
@mb_client.close
|
66
|
-
|
67
|
-
@sock.should_receive(:closed?).and_return(true)
|
68
|
-
@mb_client.closed?.should == true
|
69
|
-
end
|
70
|
-
|
71
78
|
end
|
72
|
-
|
data/spec/slave_spec.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rmodbus'
|
2
|
+
include ModBus
|
3
|
+
|
4
|
+
describe Slave do
|
5
|
+
before do
|
6
|
+
@slave = Client.new.with_slave(1)
|
7
|
+
|
8
|
+
@slave.stub!(:query).and_return('')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should support function 'read coils'" do
|
12
|
+
@slave.should_receive(:query).with("\x1\x0\x13\x0\x13").and_return("\xcd\x6b\x5")
|
13
|
+
@slave.read_coils(0x13,0x13).should == [1,0,1,1, 0,0,1,1, 1,1,0,1, 0,1,1,0, 1,0,1]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should support function 'read discrete inputs'" do
|
17
|
+
@slave.should_receive(:query).with("\x2\x0\xc4\x0\x16").and_return("\xac\xdb\x35")
|
18
|
+
@slave.read_discrete_inputs(0xc4,0x16).should == [0,0,1,1, 0,1,0,1, 1,1,0,1, 1,0,1,1, 1,0,1,0, 1,1]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should support function 'read holding registers'" do
|
22
|
+
@slave.should_receive(:query).with("\x3\x0\x6b\x0\x3").and_return("\x2\x2b\x0\x0\x0\x64")
|
23
|
+
@slave.read_holding_registers(0x6b,0x3).should == [0x022b, 0x0000, 0x0064]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should support function 'read input registers'" do
|
27
|
+
@slave.should_receive(:query).with("\x4\x0\x8\x0\x1").and_return("\x0\xa")
|
28
|
+
@slave.read_input_registers(0x8,0x1).should == [0x000a]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should support function 'write single coil'" do
|
32
|
+
@slave.should_receive(:query).with("\x5\x0\xac\xff\x0").and_return("\xac\xff\x00")
|
33
|
+
@slave.write_single_coil(0xac,0x1).should == @slave
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should support function 'write single register'" do
|
37
|
+
@slave.should_receive(:query).with("\x6\x0\x1\x0\x3").and_return("\x1\x0\x3")
|
38
|
+
@slave.write_single_register(0x1,0x3).should == @slave
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should support function 'write multiple coils'" do
|
42
|
+
@slave.should_receive(:query).with("\xf\x0\x13\x0\xa\x2\xcd\x1").and_return("\x13\x0\xa")
|
43
|
+
@slave.write_multiple_coils(0x13,[1,0,1,1, 0,0,1,1, 1,0]).should == @slave
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should support function 'write multiple registers'" do
|
47
|
+
@slave.should_receive(:query).with("\x10\x0\x1\x0\x3\x6\x0\xa\x1\x2\xf\xf").and_return("\x1\x0\x3")
|
48
|
+
@slave.write_multiple_registers(0x1,[0x000a,0x0102, 0xf0f]).should == @slave
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should support function 'mask write register'" do
|
52
|
+
@slave.should_receive(:query).with("\x16\x0\x4\x0\xf2\x0\2").and_return("\x4\x0\xf2\x0\x2")
|
53
|
+
@slave.mask_write_register(0x4, 0xf2, 0x2).should == @slave
|
54
|
+
end
|
55
|
+
end
|
data/spec/tcp_client_spec.rb
CHANGED
@@ -1,73 +1,81 @@
|
|
1
|
-
require 'rmodbus
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@sock.stub!(:read).with(0).and_return('')
|
15
|
-
|
16
|
-
@mb_client = TCPClient.new('127.0.0.1', 1502)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should send valid MBAP Header' do
|
20
|
-
@adu[0,2] = @mb_client.transaction.next.to_word
|
21
|
-
@sock.should_receive(:write).with(@adu)
|
22
|
-
@sock.should_receive(:read).with(7).and_return(@adu)
|
23
|
-
@mb_client.query('').should == nil
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'should throw exception if get other transaction' do
|
27
|
-
@adu[0,2] = @mb_client.transaction.next.to_word
|
28
|
-
@sock.should_receive(:write).with(@adu)
|
29
|
-
@sock.should_receive(:read).with(7).and_return("\000\002\000\000\000\001" + UID.chr)
|
30
|
-
begin
|
31
|
-
@mb_client.query('').should == nil
|
32
|
-
rescue Exception => ex
|
33
|
-
ex.class.should == Errors::ModBusException
|
1
|
+
require 'rmodbus'
|
2
|
+
|
3
|
+
describe TCPClient do
|
4
|
+
describe "method 'query'" do
|
5
|
+
before(:each) do
|
6
|
+
@uid = 1
|
7
|
+
@sock = mock("Socket")
|
8
|
+
@adu = "\000\001\000\000\000\001\001"
|
9
|
+
|
10
|
+
TCPSocket.should_receive(:new).with('127.0.0.1', 1502).and_return(@sock)
|
11
|
+
@sock.stub!(:read).with(0).and_return('')
|
12
|
+
@cl = ModBus::TCPClient.new('127.0.0.1', 1502)
|
13
|
+
@slave = @cl.with_slave(@uid)
|
34
14
|
end
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
15
|
+
|
16
|
+
it 'should send valid MBAP Header' do
|
17
|
+
@adu[0,2] = @slave.transaction.next.to_word
|
18
|
+
@sock.should_receive(:write).with(@adu)
|
19
|
+
@sock.should_receive(:read).with(7).and_return(@adu)
|
20
|
+
@slave.query('').should == nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should throw exception if get other transaction' do
|
24
|
+
@adu[0,2] = @slave.transaction.next.to_word
|
25
|
+
@sock.should_receive(:write).with(@adu)
|
26
|
+
@sock.should_receive(:read).with(7).and_return("\000\002\000\000\000\001" + @uid.chr)
|
27
|
+
begin
|
28
|
+
@slave.query('').should == nil
|
29
|
+
rescue Exception => ex
|
30
|
+
ex.class.should == Errors::ModBusException
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should return only data from PDU' do
|
35
|
+
request = "\x3\x0\x6b\x0\x3"
|
36
|
+
response = "\x3\x6\x2\x2b\x0\x0\x0\x64"
|
37
|
+
@adu = @slave.transaction.next.to_word + "\x0\x0\x0\x9" + @uid.chr + request
|
38
|
+
@sock.should_receive(:write).with(@adu[0,4] + "\0\6" + @uid.chr + request)
|
39
|
+
@sock.should_receive(:read).with(7).and_return(@adu[0,7])
|
40
|
+
@sock.should_receive(:read).with(8).and_return(response)
|
41
|
+
|
42
|
+
@slave.query(request).should == response[2..-1]
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should sugar connect method' do
|
46
|
+
ipaddr, port = '127.0.0.1', 502
|
47
|
+
TCPSocket.should_receive(:new).with(ipaddr, port).and_return(@sock)
|
48
|
+
@sock.should_receive(:closed?).and_return(false)
|
49
|
+
@sock.should_receive(:close)
|
50
|
+
TCPClient.connect(ipaddr, port) do |cl|
|
51
|
+
cl.ipaddr.should == ipaddr
|
52
|
+
cl.port.should == port
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should have closed? method' do
|
57
|
+
@sock.should_receive(:closed?).and_return(false)
|
58
|
+
@cl.closed?.should == false
|
59
|
+
|
60
|
+
@sock.should_receive(:closed?).and_return(false)
|
61
|
+
@sock.should_receive(:close)
|
62
|
+
|
63
|
+
@cl.close
|
64
|
+
|
65
|
+
@sock.should_receive(:closed?).and_return(true)
|
66
|
+
@cl.closed?.should == true
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should give slave object in block' do
|
70
|
+
@cl.with_slave(1) do |slave|
|
71
|
+
slave.uid = 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should tune connection timeout" do
|
77
|
+
timeout(0.5) do
|
78
|
+
lambda { ModBus::TCPClient.new('81.123.231.11', 1999, :connect_timeout => 0.1) }.should raise_error(ModBusTimeout)
|
57
79
|
end
|
58
80
|
end
|
59
|
-
|
60
|
-
it 'should have closed? method' do
|
61
|
-
@sock.should_receive(:closed?).and_return(false)
|
62
|
-
@mb_client.closed?.should == false
|
63
|
-
|
64
|
-
@sock.should_receive(:closed?).and_return(false)
|
65
|
-
@sock.should_receive(:close)
|
66
|
-
|
67
|
-
@mb_client.close
|
68
|
-
|
69
|
-
@sock.should_receive(:closed?).and_return(true)
|
70
|
-
@mb_client.closed?.should == true
|
71
|
-
end
|
72
|
-
|
73
81
|
end
|
data/spec/tcp_server_spec.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'rmodbus'
|
2
2
|
|
3
3
|
describe TCPServer do
|
4
|
-
|
5
4
|
before do
|
6
5
|
@server = ModBus::TCPServer.new(8502,1)
|
7
6
|
@server.coils = [1,0,1,1]
|
@@ -9,104 +8,90 @@ describe TCPServer do
|
|
9
8
|
@server.holding_registers = [1,2,3,4]
|
10
9
|
@server.input_registers = [1,2,3,4]
|
11
10
|
@server.start
|
12
|
-
@
|
13
|
-
@
|
11
|
+
@cl = ModBus::TCPClient.new('127.0.0.1', 8502)
|
12
|
+
@slave = @cl.with_slave(1)
|
13
|
+
@slave.read_retries = 0
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should silent if UID has mismatched" do
|
17
|
-
@
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
@cl.close
|
18
|
+
ModBus::TCPClient.connect('127.0.0.1', 8502) do |cl|
|
19
|
+
lambda { cl.with_slave(2).read_coils(1,3) }.should raise_exception(
|
20
|
+
ModBus::Errors::ModBusException,
|
21
|
+
"Server did not respond"
|
22
|
+
)
|
23
23
|
end
|
24
|
-
client.close
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should silent if protocol identifer has mismatched" do
|
28
|
-
@client.close
|
29
|
-
client = TCPSocket.new('127.0.0.1', 8502)
|
30
|
-
begin
|
31
|
-
client.write "\0\0\1\0\0\6\1"
|
32
|
-
rescue ModBus::Errors::ModBusException => ex
|
33
|
-
ex.message.should == "Server did not respond"
|
34
|
-
end
|
35
|
-
client.close
|
36
24
|
end
|
37
25
|
|
38
26
|
it "should send exception if function not supported" do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
27
|
+
lambda { @slave.query('0x43') }.should raise_exception(
|
28
|
+
ModBus::Errors::IllegalFunction,
|
29
|
+
"The function code received in the query is not an allowable action for the server"
|
30
|
+
)
|
44
31
|
end
|
45
32
|
|
46
33
|
it "should send exception if quanity of out more 0x7d" do
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
34
|
+
lambda { @slave.read_coils(0, 0x7e) }.should raise_exception(
|
35
|
+
ModBus::Errors::IllegalDataValue,
|
36
|
+
"A value contained in the query data field is not an allowable value for server"
|
37
|
+
)
|
52
38
|
end
|
53
39
|
|
54
40
|
it "should send exception if addr not valid" do
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
41
|
+
lambda { @slave.read_coils(2, 8) }.should raise_exception(
|
42
|
+
ModBus::Errors::IllegalDataAddress,
|
43
|
+
"The data address received in the query is not an allowable address for the server"
|
44
|
+
)
|
60
45
|
end
|
61
46
|
|
62
47
|
it "should calc a many requests" do
|
63
|
-
@
|
64
|
-
@
|
65
|
-
@
|
48
|
+
@slave.read_coils(1,2)
|
49
|
+
@slave.write_multiple_registers(0,[9,9,9,])
|
50
|
+
@slave.read_holding_registers(0,3).should == [9,9,9]
|
66
51
|
end
|
67
52
|
|
68
53
|
it "should supported function 'read coils'" do
|
69
|
-
@
|
54
|
+
@slave.read_coils(0,3).should == @server.coils[0,3]
|
70
55
|
end
|
71
56
|
|
72
57
|
it "should supported function 'read discrete inputs'" do
|
73
|
-
@
|
58
|
+
@slave.read_discrete_inputs(1,3).should == @server.discrete_inputs[1,3]
|
74
59
|
end
|
75
60
|
|
76
61
|
it "should supported function 'read holding registers'" do
|
77
|
-
@
|
62
|
+
@slave.read_holding_registers(0,3).should == @server.holding_registers[0,3]
|
78
63
|
end
|
79
64
|
|
80
65
|
it "should supported function 'read input registers'" do
|
81
|
-
@
|
66
|
+
@slave.read_input_registers(2,2).should == @server.input_registers[2,2]
|
82
67
|
end
|
83
68
|
|
84
69
|
it "should supported function 'write single coil'" do
|
85
70
|
@server.coils[3] = 0
|
86
|
-
@
|
71
|
+
@slave.write_single_coil(3,1)
|
87
72
|
@server.coils[3].should == 1
|
88
73
|
end
|
89
74
|
|
90
75
|
it "should supported function 'write single register'" do
|
91
76
|
@server.holding_registers[3] = 25
|
92
|
-
@
|
77
|
+
@slave.write_single_register(3,35)
|
93
78
|
@server.holding_registers[3].should == 35
|
94
79
|
end
|
95
80
|
|
96
81
|
it "should supported function 'write multiple coils'" do
|
97
82
|
@server.coils = [1,1,1,0, 0,0,0,0, 0,0,0,0, 0,1,1,1]
|
98
|
-
@
|
83
|
+
@slave.write_multiple_coils(3, [1, 0,1,0,1, 0,1,0,1])
|
99
84
|
@server.coils.should == [1,1,1,1, 0,1,0,1, 0,1,0,1, 0,1,1,1]
|
100
85
|
end
|
101
86
|
|
102
87
|
it "should supported function 'write multiple registers'" do
|
103
88
|
@server.holding_registers = [1,2,3,4,5,6,7,8,9]
|
104
|
-
@
|
89
|
+
@slave.write_multiple_registers(3,[1,2,3,4,5])
|
105
90
|
@server.holding_registers.should == [1,2,3,1,2,3,4,5,9]
|
106
91
|
end
|
107
92
|
|
108
93
|
after do
|
109
|
-
@
|
94
|
+
@cl.close
|
110
95
|
@server.stop unless @server.stopped?
|
111
96
|
while GServer.in_service?(8502)
|
112
97
|
end
|