rmodbus 1.0.0-java

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.
@@ -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