rmodbus 1.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,116 @@
1
+ require 'rmodbus'
2
+
3
+ include ModBus::Errors
4
+
5
+ describe ModBus::TCPClient do
6
+ before(:all) do
7
+ @srv = ModBus::TCPServer.new(1502, 1)
8
+ @srv.coils = [0] * 8
9
+ @srv.discrete_inputs = [0] * 8
10
+ @srv.holding_registers = [0] * 8
11
+ @srv.input_registers = [0] * 8
12
+ @srv.start
13
+
14
+ @cl = TCPClient.new('127.0.0.1', 1502)
15
+ @slave = @cl.with_slave(1)
16
+ end
17
+
18
+ # Read coil status
19
+ it "should read coil status" do
20
+ @slave.read_coils(0, 4).should == [0] * 4
21
+ end
22
+
23
+ it "should raise exception if illegal data address" do
24
+ lambda { @slave.read_coils(501, 34) }.should raise_error(IllegalDataAddress)
25
+ end
26
+
27
+ it "should raise exception if too many data" do
28
+ lambda { @slave.read_coils(0, 0x07D1) }.should raise_error(IllegalDataValue)
29
+ end
30
+
31
+ # Read input status
32
+ it "should read discrete inputs" do
33
+ @slave.read_discrete_inputs(0, 4).should == [0] * 4
34
+ end
35
+
36
+ it "should raise exception if illegal data address" do
37
+ lambda { @slave.read_discrete_inputs(50, 23) }.should raise_error(IllegalDataAddress)
38
+ end
39
+
40
+ it "should raise exception if too many data" do
41
+ lambda { @slave.read_discrete_inputs(0, 0x07D1) }.should raise_error(IllegalDataValue)
42
+ end
43
+
44
+ # Read holding registers
45
+ it "should read discrete inputs" do
46
+ @slave.read_holding_registers(0, 4).should == [0, 0, 0, 0]
47
+ end
48
+
49
+ it "should raise exception if illegal data address" do
50
+ lambda { @slave.read_holding_registers(402, 99) }.should raise_error(IllegalDataAddress)
51
+ end
52
+
53
+
54
+ it "should raise exception if too many data" do
55
+ lambda { @slave.read_holding_registers(0, 0x007E) }.should raise_error(IllegalDataValue)
56
+ end
57
+
58
+ # Read input registers
59
+ it "should read discrete inputs" do
60
+ @slave.read_input_registers(0, 4).should == [0, 0, 0, 0]
61
+ end
62
+
63
+ it "should raise exception if illegal data address" do
64
+ lambda { @slave.read_input_registers(402, 9) }.should raise_error(IllegalDataAddress)
65
+ end
66
+
67
+ it "should raise exception if too many data" do
68
+ lambda { @slave.read_input_registers(0, 0x007E) }.should raise_error(IllegalDataValue)
69
+ end
70
+
71
+ # Force single coil
72
+ it "should force single coil" do
73
+ @slave.write_single_coil(4, 1).should == @slave
74
+ @slave.read_coils(4, 4).should == [1, 0, 0, 0]
75
+ end
76
+
77
+ it "should raise exception if illegal data address" do
78
+ lambda { @slave.write_single_coil(501, true) }.should raise_error(IllegalDataAddress)
79
+ end
80
+
81
+ # Preset single register
82
+ it "should preset single register" do
83
+ @slave.write_single_register(4, 0x0AA0).should == @slave
84
+ @slave.read_holding_registers(4, 1).should == [0x0AA0]
85
+ end
86
+
87
+ it "should raise exception if illegal data address" do
88
+ lambda { @slave.write_single_register(501, 0x0AA0) }.should raise_error(IllegalDataAddress)
89
+ end
90
+
91
+ # Force multiple coils
92
+ it "should force multiple coils" do
93
+ @slave.write_multiple_coils(4, [0,1,0,1]).should == @slave
94
+ @slave.read_coils(3, 5).should == [0,0,1,0,1]
95
+ end
96
+
97
+ it "should raise exception if illegal data address" do
98
+ lambda { @slave.write_multiple_coils(501, [1,0]) }.should raise_error(IllegalDataAddress)
99
+ end
100
+
101
+ # Preset multiple registers
102
+ it "should preset multiple registers" do
103
+ @slave.write_multiple_registers(4, [1, 2, 3, 0xAACC]).should == @slave
104
+ @slave.read_holding_registers(3, 5).should == [0, 1, 2, 3, 0xAACC]
105
+ end
106
+
107
+ it "should raise exception if illegal data address" do
108
+ lambda { @slave.write_multiple_registers(501, [1, 2]) }.should raise_error(IllegalDataAddress)
109
+ end
110
+
111
+ after(:all) do
112
+ @cl.close unless @cl.closed?
113
+ @srv.stop
114
+ end
115
+
116
+ end
data/spec/ext_spec.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'rmodbus'
2
+
3
+ describe Array do
4
+ before do
5
+ @arr = [1,0,1,1, 0,0,1,1, 1,1,0,1, 0,1,1,0, 1,0,1]
6
+ @test = [0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0]
7
+ end
8
+
9
+ it "should return string reprisent 16bit" do
10
+ @arr.pack_to_word.should == "\xcd\x6b\x5"
11
+ end
12
+
13
+ it "fixed bug for divisible 8 data " do
14
+ ([0] * 8).pack_to_word.should == "\x00"
15
+ end
16
+
17
+ it "should unpack to @test" do
18
+ "test".unpack_bits == @test
19
+ end
20
+
21
+ it "should turn an array into 32b ints" do
22
+ [20342, 17344].to_32i.should == [1136676726]
23
+ [20342, 17344, 20342, 17344].to_32i.size.should == 2
24
+ end
25
+
26
+ it "should turn an array into 32b floats" do
27
+ [20342, 17344].to_32f[0].should be_within(0.1).of(384.620788574219)
28
+ [20342, 17344, 20342, 17344].to_32f.size.should == 2
29
+ end
30
+
31
+ it "should turn an array from 32b ints into 16b ints, big endian" do
32
+ [1136676726].from_32i.should == [20342, 17344]
33
+ [1136676726, 1136676725].from_32i.should == [20342, 17344, 20341, 17344]
34
+ end
35
+
36
+ it "should turn an array from 32b floats into 16b ints, big endian" do
37
+ [384.620788].from_32f.should == [20342, 17344]
38
+ [384.620788, 384.620788].from_32f.should == [20342, 17344, 20342, 17344]
39
+ end
40
+
41
+ it "should raise exception if uneven number of elements" do
42
+ lambda { [20342, 17344, 123].to_32f }.should raise_error(StandardError)
43
+ lambda { [20342, 17344, 123].to_32i }.should raise_error(StandardError)
44
+ end
45
+ end
46
+
@@ -0,0 +1,65 @@
1
+ require 'rmodbus'
2
+ include ModBus
3
+
4
+ describe TCPClient 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
+
13
+ @slave = TCPClient.new('127.0.0.1', 1502).with_slave(@uid)
14
+ end
15
+
16
+ it 'should log rec\send bytes' do
17
+ request, response = "\x3\x0\x6b\x0\x3", "\x3\x6\x2\x2b\x0\x0\x0\x64"
18
+ mock_query(request,response)
19
+ @slave.debug = true
20
+ $stdout.should_receive(:puts).with("Tx (12 bytes): [00][01][00][00][00][06][01][03][00][6b][00][03]")
21
+ $stdout.should_receive(:puts).with("Rx (15 bytes): [00][01][00][00][00][09][01][03][06][02][2b][00][00][00][64]")
22
+ @slave.query(request)
23
+ end
24
+
25
+ it "should don't logging if debug disable" do
26
+ request, response = "\x3\x0\x6b\x0\x3", "\x3\x6\x2\x2b\x0\x0\x0\x64"
27
+ mock_query(request,response)
28
+ @slave.query(request)
29
+ end
30
+
31
+ def mock_query(request, response)
32
+ @adu = @slave.transaction.next.to_word + "\x0\x0\x0\x9" + @uid.chr + request
33
+ @sock.should_receive(:write).with(@adu[0,4] + "\0\6" + @uid.chr + request)
34
+ @sock.should_receive(:read).with(7).and_return(@adu[0,7])
35
+ @sock.should_receive(:read).with(8).and_return(response)
36
+ end
37
+ end
38
+
39
+ unless RUBY_PLATFORM == "java"
40
+ describe RTUClient do
41
+ before do
42
+ @sp = mock('Serial port')
43
+ SerialPort.should_receive(:new).with("/dev/port1", 9600, 7, 2, SerialPort::ODD).and_return(@sp)
44
+
45
+ @sp.stub!(:read_timeout=)
46
+
47
+ @slave = RTUClient.new("/dev/port1", 9600, :data_bits => 7, :stop_bits => 2, :parity => SerialPort::ODD).with_slave(1)
48
+ @slave.read_retries = 0
49
+ end
50
+
51
+ it 'should log rec\send bytes' do
52
+ request = "\x3\x0\x1\x0\x1"
53
+ @sp.should_receive(:write).with("\1#{request}\xd5\xca")
54
+ @sp.should_receive(:read).with(2).and_return("\x1\x3")
55
+ @sp.should_receive(:read).with(1).and_return("\x2")
56
+ @sp.should_receive(:read).with(4).and_return("\xff\xff\xb9\xf4")
57
+
58
+ @slave.debug = true
59
+ $stdout.should_receive(:puts).with("Tx (8 bytes): [01][03][00][01][00][01][d5][ca]")
60
+ $stdout.should_receive(:puts).with("Rx (7 bytes): [01][03][02][ff][ff][b9][f4]")
61
+
62
+ @slave.query(request).should == "\xff\xff"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,73 @@
1
+ require 'rmodbus'
2
+
3
+ describe Array do
4
+ before do
5
+ @slave = mock('ModBus Slave')
6
+ @coil_proxy = ModBus::ReadWriteProxy.new(@slave, :coil)
7
+ @discrete_input_proxy = ModBus::ReadOnlyProxy.new(@slave, :discrete_input)
8
+ @holding_register_proxy = ModBus::ReadWriteProxy.new(@slave, :holding_register)
9
+ @input_register_proxy = ModBus::ReadOnlyProxy.new(@slave, :input_register)
10
+ end
11
+
12
+ # Handle all of the coil methods
13
+ it "should call read_coil" do
14
+ @slave.should_receive(:read_coil).with(0, 1)
15
+ @coil_proxy[0]
16
+ end
17
+ it "should call read_coils" do
18
+ @slave.should_receive(:read_coils).with(0, 2)
19
+ @coil_proxy[0..1]
20
+ end
21
+ it "should call write_coil" do
22
+ @slave.should_receive(:write_coil).with(0, 1)
23
+ @coil_proxy[0] = 1
24
+ end
25
+ it "should call write_coils" do
26
+ @slave.should_receive(:write_coils).with(0, [0, 0])
27
+ @coil_proxy[0..1] = [0, 0]
28
+ end
29
+
30
+
31
+ # Discrete input tests
32
+ it "should call read_discrete_input" do
33
+ @slave.should_receive(:read_discrete_input).with(0, 1)
34
+ @discrete_input_proxy[0]
35
+ end
36
+
37
+ it "should call read_discrete_inputs" do
38
+ @slave.should_receive(:read_discrete_inputs).with(0, 2)
39
+ @discrete_input_proxy[0..1]
40
+ end
41
+
42
+
43
+ # Holding Register Tess
44
+ it "should call read_holding_register" do
45
+ @slave.should_receive(:read_holding_register).with(0, 1)
46
+ @holding_register_proxy[0]
47
+ end
48
+ it "should call read_holding_registers" do
49
+ @slave.should_receive(:read_holding_registers).with(0, 2)
50
+ @holding_register_proxy[0..1]
51
+ end
52
+ it "should call write_holding_register" do
53
+ @slave.should_receive(:write_holding_register).with(0, 1)
54
+ @holding_register_proxy[0] = 1
55
+ end
56
+ it "should call write_holding_registers" do
57
+ @slave.should_receive(:write_holding_registers).with(0, [0, 0])
58
+ @holding_register_proxy[0..1] = [0, 0]
59
+ end
60
+
61
+
62
+ # Input Register Tests
63
+ it "should call read_discrete_input" do
64
+ @slave.should_receive(:read_input_register).with(0, 1)
65
+ @input_register_proxy[0]
66
+ end
67
+
68
+ it "should call read_discrete_inputs" do
69
+ @slave.should_receive(:read_input_registers).with(0, 2)
70
+ @input_register_proxy[0..1]
71
+ end
72
+ end
73
+
@@ -0,0 +1,91 @@
1
+ require 'rmodbus'
2
+ include ModBus
3
+
4
+ #Use public wrap method
5
+ class Client
6
+ include RTU
7
+ def test_read_method(msg)
8
+ io = TestIO.new(msg)
9
+ read_rtu_response(io)
10
+ end
11
+
12
+ end
13
+
14
+ class TestIO
15
+ def initialize(msg)
16
+ @msg = msg
17
+ end
18
+
19
+ def read(num)
20
+ result = @msg[0,num]
21
+ @msg = @msg[num..-1]
22
+ result
23
+ end
24
+ end
25
+
26
+ describe "#read_rtu_response" do
27
+ before do
28
+ @cl_mb = Client.new
29
+ end
30
+
31
+ it "should read response for 'read coils'" do
32
+ resp = make_resp("\x1\x3\xcd\x6b\x05")
33
+ @cl_mb.test_read_method(resp).should == resp
34
+ end
35
+
36
+ it "should read response for 'read discrete inputs'" do
37
+ resp = make_resp("\x2\x3\xac\xdb\x35")
38
+ @cl_mb.test_read_method(resp).should == resp
39
+ end
40
+
41
+ it "should read response for 'read holding registers'" do
42
+ resp = make_resp("\x3\x6\x2\x2b\x0\x0\x0\x64")
43
+ @cl_mb.test_read_method(resp).should == resp
44
+ end
45
+
46
+ it "should read response for 'read input registers'" do
47
+ resp = make_resp("\x4\x2\x0\xa")
48
+ @cl_mb.test_read_method(resp).should == resp
49
+ end
50
+
51
+ it "should read response for 'write single coil'" do
52
+ resp = make_resp("\x5\x0\xac\xff\x0")
53
+ @cl_mb.test_read_method(resp).should == resp
54
+ end
55
+
56
+ it "should read response for 'write single register'" do
57
+ resp = make_resp("\x6\x0\x1\x0\x3")
58
+ @cl_mb.test_read_method(resp).should == resp
59
+ end
60
+
61
+ it "should read response for 'write multiple coils'" do
62
+ resp = make_resp("\xf\x0\x13\x0\xa")
63
+ @cl_mb.test_read_method(resp).should == resp
64
+ end
65
+
66
+ it "should read response for 'write multiple registers'" do
67
+ resp = make_resp("\x10\x0\x1\x0\x2")
68
+ @cl_mb.test_read_method(resp).should == resp
69
+ end
70
+
71
+ it "should read response 'mask write register'" do
72
+ resp = make_resp("\x16\x0\x4\x0\xf2\x0\x25")
73
+ @cl_mb.test_read_method(resp).should == resp
74
+ end
75
+
76
+ it "should read exception codes" do
77
+ resp = make_resp("\x84\x3")
78
+ @cl_mb.test_read_method(resp).should == resp
79
+ end
80
+
81
+ it "should raise exception if function is illegal" do
82
+ resp = make_resp("\xff\x0\x1\x0\x2").should raise_error {
83
+ ModBus::Errors::IllegalFunction
84
+ }
85
+ end
86
+
87
+ def make_resp(msg)
88
+ "\x1" + msg + "\x2\x2" # slave + msg + mock_crc
89
+ end
90
+ end
91
+
@@ -0,0 +1,74 @@
1
+ require 'rmodbus'
2
+ include ModBus
3
+
4
+ describe RTUClient do
5
+ before do
6
+ @sp = mock('Serial port')
7
+ SerialPort.should_receive(:new).with("/dev/port1", 9600, 8, 1, 0).and_return(@sp)
8
+ @sp.stub!(:read_timeout=)
9
+ @sp.stub!(:read)
10
+
11
+ @cl = RTUClient.new("/dev/port1", 9600, :data_bits => 8, :stop_bits => 1, :parity => SerialPort::NONE)
12
+ @slave = @cl.with_slave(1)
13
+ @slave.read_retries = 0
14
+ end
15
+
16
+ it "should ignore frame with other UID" do
17
+ request = "\x10\x0\x1\x0\x1\x2\xff\xff"
18
+ @sp.should_receive(:write).with("\1#{request}\xA6\x31")
19
+ @sp.should_receive(:read).with(2).and_return("\x2\x10")
20
+ @sp.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
21
+ lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
22
+ end
23
+
24
+ it "should ignored frame with incorrect CRC" do
25
+ request = "\x10\x0\x1\x0\x1\x2\xff\xff"
26
+ @sp.should_receive(:write).with("\1#{request}\xA6\x31")
27
+ @sp.should_receive(:read).with(2).and_return("\x2\x10")
28
+ @sp.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
29
+ lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
30
+ end
31
+
32
+ it "should return value of registers"do
33
+ request = "\x3\x0\x1\x0\x1"
34
+ @sp.should_receive(:write).with("\1#{request}\xd5\xca")
35
+ @sp.should_receive(:read).with(2).and_return("\x1\x3")
36
+ @sp.should_receive(:read).with(1).and_return("\x2")
37
+ @sp.should_receive(:read).with(4).and_return("\xff\xff\xb9\xf4")
38
+ @slave.query(request).should == "\xff\xff"
39
+ end
40
+
41
+ it 'should sugar connect method' do
42
+ port, baud = "/dev/port1", 4800
43
+ SerialPort.should_receive(:new).with(port, baud, 8, 1, SerialPort::NONE).and_return(@sp)
44
+ @sp.should_receive(:closed?).and_return(false)
45
+ @sp.should_receive(:close)
46
+ RTUClient.connect(port, baud) do |cl|
47
+ cl.port.should == port
48
+ cl.baud.should == baud
49
+ cl.data_bits.should == 8
50
+ cl.stop_bits.should == 1
51
+ cl.parity.should == SerialPort::NONE
52
+ end
53
+ end
54
+
55
+ it 'should have closed? method' do
56
+ @sp.should_receive(:closed?).and_return(false)
57
+ @cl.closed?.should == false
58
+
59
+ @sp.should_receive(:closed?).and_return(false)
60
+ @sp.should_receive(:close)
61
+
62
+ @cl.close
63
+
64
+ @sp.should_receive(:closed?).and_return(true)
65
+ @cl.closed?.should == true
66
+ end
67
+
68
+ it 'should give slave object in block' do
69
+ @cl.with_slave(1) do |slave|
70
+ slave.uid = 1
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,29 @@
1
+ require 'rmodbus'
2
+ include ModBus
3
+
4
+ describe RTUServer do
5
+ before do
6
+ @sp = mock "SerialPort"
7
+ SerialPort.should_receive(:new).with('/dev/ttyS0', 4800, 7, 2, SerialPort::NONE).and_return(@sp)
8
+ @sp.stub!(:read_timeout=)
9
+
10
+ @server = RTUServer.new('/dev/ttyS0', 4800, 1, :data_bits => 7, :stop_bits => 2)
11
+ @server.coils = [1,0,1,1]
12
+ @server.discrete_inputs = [1,1,0,0]
13
+ @server.holding_registers = [1,2,3,4]
14
+ @server.input_registers = [1,2,3,4]
15
+ end
16
+
17
+ it "should be valid initialized " do
18
+ @server.coils.should == [1,0,1,1]
19
+ @server.discrete_inputs.should == [1,1,0,0]
20
+ @server.holding_registers.should == [1,2,3,4]
21
+ @server.input_registers.should == [1,2,3,4]
22
+
23
+ @server.port.should == '/dev/ttyS0'
24
+ @server.baud.should == 4800
25
+ @server.data_bits.should == 7
26
+ @server.stop_bits.should == 2
27
+ @server.parity.should == SerialPort::NONE
28
+ end
29
+ end
@@ -0,0 +1,78 @@
1
+ require 'rmodbus'
2
+ include ModBus
3
+
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
16
+
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
72
+
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)
76
+ end
77
+ end
78
+ end
@@ -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