rmodbus-ccutrer 2.0.0 → 2.1.1

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +14 -7
  3. data/README.md +8 -8
  4. data/examples/perfomance_rtu.rb +55 -56
  5. data/examples/perfomance_rtu_via_tcp.rb +54 -55
  6. data/examples/perfomance_tcp.rb +54 -55
  7. data/examples/simple_xpca_gateway.rb +85 -0
  8. data/examples/use_rtu_via_tcp_modbus.rb +14 -11
  9. data/examples/use_tcp_modbus.rb +14 -11
  10. data/lib/rmodbus/client/slave.rb +58 -70
  11. data/lib/rmodbus/client.rb +13 -10
  12. data/lib/rmodbus/debug.rb +10 -6
  13. data/lib/rmodbus/errors.rb +26 -2
  14. data/lib/rmodbus/ext.rb +72 -51
  15. data/lib/rmodbus/options.rb +4 -1
  16. data/lib/rmodbus/proxy.rb +14 -9
  17. data/lib/rmodbus/rtu.rb +38 -32
  18. data/lib/rmodbus/rtu_client.rb +5 -2
  19. data/lib/rmodbus/rtu_server.rb +9 -7
  20. data/lib/rmodbus/rtu_slave.rb +6 -2
  21. data/lib/rmodbus/rtu_via_tcp_server.rb +7 -5
  22. data/lib/rmodbus/server/slave.rb +4 -2
  23. data/lib/rmodbus/server.rb +97 -73
  24. data/lib/rmodbus/sp.rb +10 -12
  25. data/lib/rmodbus/tcp.rb +5 -2
  26. data/lib/rmodbus/tcp_client.rb +3 -0
  27. data/lib/rmodbus/tcp_server.rb +28 -26
  28. data/lib/rmodbus/tcp_slave.rb +17 -16
  29. data/lib/rmodbus/version.rb +3 -1
  30. data/lib/rmodbus.rb +20 -18
  31. metadata +50 -49
  32. data/Rakefile +0 -29
  33. data/examples/simple-xpca-gateway.rb +0 -84
  34. data/spec/client_spec.rb +0 -88
  35. data/spec/exception_spec.rb +0 -120
  36. data/spec/ext_spec.rb +0 -52
  37. data/spec/logging_spec.rb +0 -89
  38. data/spec/proxy_spec.rb +0 -74
  39. data/spec/read_rtu_response_spec.rb +0 -92
  40. data/spec/response_mismach_spec.rb +0 -163
  41. data/spec/rtu_client_spec.rb +0 -86
  42. data/spec/rtu_server_spec.rb +0 -31
  43. data/spec/rtu_via_tcp_client_spec.rb +0 -76
  44. data/spec/rtu_via_tcp_server_spec.rb +0 -89
  45. data/spec/slave_spec.rb +0 -55
  46. data/spec/spec_helper.rb +0 -54
  47. data/spec/tcp_client_spec.rb +0 -88
  48. data/spec/tcp_server_spec.rb +0 -158
@@ -1,120 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- describe ModBus::TCPClient do
5
- before(:all) do
6
- @srv = ModBus::TCPServer.new(1502)
7
- srv_slave = @srv.with_slave(1)
8
- srv_slave.coils = [0] * 8
9
- srv_slave.discrete_inputs = [0] * 8
10
- srv_slave.holding_registers = [0] * 8
11
- srv_slave.input_registers = [0] * 8
12
- @srv.start
13
-
14
- @cl = ModBus::TCPClient.new('127.0.0.1', 1502)
15
- @slave = @cl.with_slave(1)
16
- end
17
-
18
- it "should raise ProxException" do
19
- lambda { @slave.holding_registers[0..2] = [0,0] }.should raise_error(ModBus::Errors::ProxyException)
20
- end
21
-
22
- # Read coil status
23
- it "should read coil status" do
24
- @slave.read_coils(0, 4).should == [0] * 4
25
- end
26
-
27
- it "should raise exception if illegal data address" do
28
- lambda { @slave.read_coils(501, 34) }.should raise_error(ModBus::Errors::IllegalDataAddress)
29
- end
30
-
31
- it "should raise exception if too many data" do
32
- lambda { @slave.read_coils(0, 0x07D1) }.should raise_error(ModBus::Errors::IllegalDataValue)
33
- end
34
-
35
- # Read input status
36
- it "should read discrete inputs" do
37
- @slave.read_discrete_inputs(0, 4).should == [0] * 4
38
- end
39
-
40
- it "should raise exception if illegal data address" do
41
- lambda { @slave.read_discrete_inputs(50, 23) }.should raise_error(ModBus::Errors::IllegalDataAddress)
42
- end
43
-
44
- it "should raise exception if too many data" do
45
- lambda { @slave.read_discrete_inputs(0, 0x07D1) }.should raise_error(ModBus::Errors::IllegalDataValue)
46
- end
47
-
48
- # Read holding registers
49
- it "should read discrete inputs" do
50
- @slave.read_holding_registers(0, 4).should == [0, 0, 0, 0]
51
- end
52
-
53
- it "should raise exception if illegal data address" do
54
- lambda { @slave.read_holding_registers(402, 99) }.should raise_error(ModBus::Errors::IllegalDataAddress)
55
- end
56
-
57
-
58
- it "should raise exception if too many data" do
59
- lambda { @slave.read_holding_registers(0, 0x007E) }.should raise_error(ModBus::Errors::IllegalDataValue)
60
- end
61
-
62
- # Read input registers
63
- it "should read discrete inputs" do
64
- @slave.read_input_registers(0, 4).should == [0, 0, 0, 0]
65
- end
66
-
67
- it "should raise exception if illegal data address" do
68
- lambda { @slave.read_input_registers(402, 9) }.should raise_error(ModBus::Errors::IllegalDataAddress)
69
- end
70
-
71
- it "should raise exception if too many data" do
72
- lambda { @slave.read_input_registers(0, 0x007E) }.should raise_error(ModBus::Errors::IllegalDataValue)
73
- end
74
-
75
- # Force single coil
76
- it "should force single coil" do
77
- @slave.write_single_coil(4, 1).should == @slave
78
- @slave.read_coils(4, 4).should == [1, 0, 0, 0]
79
- end
80
-
81
- it "should raise exception if illegal data address" do
82
- lambda { @slave.write_single_coil(501, true) }.should raise_error(ModBus::Errors::IllegalDataAddress)
83
- end
84
-
85
- # Preset single register
86
- it "should preset single register" do
87
- @slave.write_single_register(4, 0x0AA0).should == @slave
88
- @slave.read_holding_registers(4, 1).should == [0x0AA0]
89
- end
90
-
91
- it "should raise exception if illegal data address" do
92
- lambda { @slave.write_single_register(501, 0x0AA0) }.should raise_error(ModBus::Errors::IllegalDataAddress)
93
- end
94
-
95
- # Force multiple coils
96
- it "should force multiple coils" do
97
- @slave.write_multiple_coils(4, [0,1,0,1]).should == @slave
98
- @slave.read_coils(3, 5).should == [0,0,1,0,1]
99
- end
100
-
101
- it "should raise exception if illegal data address" do
102
- lambda { @slave.write_multiple_coils(501, [1,0]) }.should raise_error(ModBus::Errors::IllegalDataAddress)
103
- end
104
-
105
- # Preset multiple registers
106
- it "should preset multiple registers" do
107
- @slave.write_multiple_registers(4, [1, 2, 3, 0xAACC]).should == @slave
108
- @slave.read_holding_registers(3, 5).should == [0, 1, 2, 3, 0xAACC]
109
- end
110
-
111
- it "should raise exception if illegal data address" do
112
- lambda { @slave.write_multiple_registers(501, [1, 2]) }.should raise_error(ModBus::Errors::IllegalDataAddress)
113
- end
114
-
115
- after(:all) do
116
- @cl.close unless @cl.closed?
117
- @srv.stop
118
- end
119
-
120
- end
data/spec/ext_spec.rb DELETED
@@ -1,52 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- describe Array do
5
- before do
6
- @arr = [1,0,1,1, 0,0,1,1, 1,1,0,1, 0,1,1,0, 1,0,1]
7
- @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]
8
- end
9
-
10
- it "should return string reprisent 16bit" do
11
- @arr.pack_to_word.should == "\xcd\x6b\x5"
12
- end
13
-
14
- it "fixed bug for divisible 8 data " do
15
- ([0] * 8).pack_to_word.should == "\x00"
16
- end
17
-
18
- it "should unpack to @test" do
19
- "test".unpack_bits == @test
20
- end
21
-
22
- it "should turn an array into 32b ints" do
23
- [20342, 17344].to_32i.should == [1136676726]
24
- [20342, 17344, 20342, 17344].to_32i.size.should == 2
25
- end
26
-
27
- it "should turn an array into 32b floats big endian" do
28
- [20342, 17344].to_32f[0].should be_within(0.1).of(384.620788574219)
29
- [20342, 17344, 20342, 17344].to_32f.size.should == 2
30
- end
31
-
32
- it "should turn a an array into 32b floats (little endian)" do
33
- [17344, 20342].to_32f_le[0].should be_within(0.1).of(384.620788574219)
34
- [17344, 20342, 17344, 20342].to_32f_le.size.should == 2
35
- end
36
-
37
- it "should turn an array from 32b ints into 16b ints, big endian" do
38
- [1136676726].from_32i.should == [20342, 17344]
39
- [1136676726, 1136676725].from_32i.should == [20342, 17344, 20341, 17344]
40
- end
41
-
42
- it "should turn an array from 32b floats into 16b ints, big endian" do
43
- [384.620788].from_32f.should == [20342, 17344]
44
- [384.620788, 384.620788].from_32f.should == [20342, 17344, 20342, 17344]
45
- end
46
-
47
- it "should raise exception if uneven number of elements" do
48
- lambda { [20342, 17344, 123].to_32f }.should raise_error(StandardError)
49
- lambda { [20342, 17344, 123].to_32i }.should raise_error(StandardError)
50
- end
51
- end
52
-
data/spec/logging_spec.rb DELETED
@@ -1,89 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- describe ModBus::TCPClient do
5
- before(:each) do
6
- @uid = 1
7
- @sock = double('Socket')
8
- @adu = "\000\001\000\000\000\001\001"
9
-
10
- Socket.should_receive(:tcp).with('127.0.0.1', 1502, nil, nil, hash_including(:connect_timeout)).and_return(@sock)
11
- @sock.stub(:read).with(0).and_return('')
12
-
13
- @slave = ModBus::TCPClient.new('127.0.0.1', 1502).with_slave(@uid)
14
- @slave.debug = true
15
- end
16
-
17
- it 'should log rec\send bytes' do
18
- request, response = "\x3\x0\x6b\x0\x3", "\x3\x6\x2\x2b\x0\x0\x0\x64"
19
- mock_query(request,response)
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
- @slave.debug = false
27
- request, response = "\x3\x0\x6b\x0\x3", "\x3\x6\x2\x2b\x0\x0\x0\x64"
28
- mock_query(request,response)
29
- @slave.query(request)
30
- end
31
-
32
- it "should log warn message if transaction mismatch" do
33
- @adu[0,2] = @slave.transaction.next.to_word
34
- @sock.should_receive(:write).with(@adu)
35
- @sock.should_receive(:read).with(7).and_return("\000\002\000\000\000\001" + @uid.chr)
36
- @sock.should_receive(:read).with(7).and_return("\000\001\000\000\000\001" + @uid.chr)
37
-
38
- $stdout.should_receive(:puts).with("Tx (7 bytes): [00][01][00][00][00][01][01]")
39
- $stdout.should_receive(:puts).with("Rx (7 bytes): [00][02][00][00][00][01][01]")
40
- $stdout.should_receive(:puts).with("Transaction number mismatch. A packet is ignored.")
41
- $stdout.should_receive(:puts).with("Rx (7 bytes): [00][01][00][00][00][01][01]")
42
-
43
- @slave.query('')
44
- end
45
-
46
- def mock_query(request, response)
47
- @adu = @slave.transaction.next.to_word + "\x0\x0\x0\x9" + @uid.chr + request
48
- @sock.should_receive(:write).with(@adu[0,4] + "\0\6" + @uid.chr + request)
49
- @sock.should_receive(:read).with(7).and_return(@adu[0,7])
50
- @sock.should_receive(:read).with(8).and_return(response)
51
- end
52
- end
53
-
54
- begin
55
- require "serialport"
56
- describe ModBus::RTUClient do
57
- before do
58
- @sp = double('Serial port')
59
-
60
- SerialPort.should_receive(:new).with("/dev/port1", 9600, 7, 2, SerialPort::ODD).and_return(@sp)
61
- SerialPort.stub(:public_method_defined?).with(:flush_input).and_return(true)
62
-
63
- @sp.stub(:class).and_return(SerialPort)
64
- @sp.should_receive(:flow_control=).with(SerialPort::NONE)
65
- @sp.stub(:read_timeout=)
66
- @sp.stub(:flush_input)
67
-
68
- @slave = ModBus::RTUClient.new("/dev/port1", 9600, :data_bits => 7, :stop_bits => 2, :parity => SerialPort::ODD).with_slave(1)
69
- @slave.read_retries = 0
70
-
71
- end
72
-
73
- it 'should log rec\send bytes' do
74
- request = "\x3\x0\x1\x0\x1"
75
- @sp.should_receive(:write).with("\1#{request}\xd5\xca")
76
- @sp.should_receive(:flush_input) # Clean a garbage
77
- @sp.should_receive(:read).with(2).and_return("\x1\x3")
78
- @sp.should_receive(:read).with(1).and_return("\x2")
79
- @sp.should_receive(:read).with(4).and_return("\xff\xff\xb9\xf4")
80
-
81
- @slave.debug = true
82
- $stdout.should_receive(:puts).with("Tx (8 bytes): [01][03][00][01][00][01][d5][ca]")
83
- $stdout.should_receive(:puts).with("Rx (7 bytes): [01][03][02][ff][ff][b9][f4]")
84
-
85
- @slave.query(request).should == "\xff\xff"
86
- end
87
- end
88
- rescue LoadError
89
- end
data/spec/proxy_spec.rb DELETED
@@ -1,74 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- describe Array do
5
- before do
6
- @slave = double('ModBus Slave')
7
- @coil_proxy = ModBus::ReadWriteProxy.new(@slave, :coil)
8
- @discrete_input_proxy = ModBus::ReadOnlyProxy.new(@slave, :discrete_input)
9
- @holding_register_proxy = ModBus::ReadWriteProxy.new(@slave, :holding_register)
10
- @input_register_proxy = ModBus::ReadOnlyProxy.new(@slave, :input_register)
11
- end
12
-
13
- # Handle all of the coil methods
14
- it "should call read_coil" do
15
- @slave.should_receive(:read_coil).with(0, 1)
16
- @coil_proxy[0]
17
- end
18
- it "should call read_coils" do
19
- @slave.should_receive(:read_coils).with(0, 2)
20
- @coil_proxy[0..1]
21
- end
22
- it "should call write_coil" do
23
- @slave.should_receive(:write_coil).with(0, 1)
24
- @coil_proxy[0] = 1
25
- end
26
- it "should call write_coils" do
27
- @slave.should_receive(:write_coils).with(0, [0, 0])
28
- @coil_proxy[0..1] = [0, 0]
29
- end
30
-
31
-
32
- # Discrete input tests
33
- it "should call read_discrete_input" do
34
- @slave.should_receive(:read_discrete_input).with(0, 1)
35
- @discrete_input_proxy[0]
36
- end
37
-
38
- it "should call read_discrete_inputs" do
39
- @slave.should_receive(:read_discrete_inputs).with(0, 2)
40
- @discrete_input_proxy[0..1]
41
- end
42
-
43
-
44
- # Holding Register Tess
45
- it "should call read_holding_register" do
46
- @slave.should_receive(:read_holding_register).with(0, 1)
47
- @holding_register_proxy[0]
48
- end
49
- it "should call read_holding_registers" do
50
- @slave.should_receive(:read_holding_registers).with(0, 2)
51
- @holding_register_proxy[0..1]
52
- end
53
- it "should call write_holding_register" do
54
- @slave.should_receive(:write_holding_register).with(0, 1)
55
- @holding_register_proxy[0] = 1
56
- end
57
- it "should call write_holding_registers" do
58
- @slave.should_receive(:write_holding_registers).with(0, [0, 0])
59
- @holding_register_proxy[0..1] = [0, 0]
60
- end
61
-
62
-
63
- # Input Register Tests
64
- it "should call read_discrete_input" do
65
- @slave.should_receive(:read_input_register).with(0, 1)
66
- @input_register_proxy[0]
67
- end
68
-
69
- it "should call read_discrete_inputs" do
70
- @slave.should_receive(:read_input_registers).with(0, 2)
71
- @input_register_proxy[0..1]
72
- end
73
- end
74
-
@@ -1,92 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- #Use public wrap method
5
- class ModBus::Client
6
- include ModBus::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 = ModBus::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("\x1f\x0\x1\x0\x2")
83
- lambda{ @cl_mb.test_read_method(resp)}.should raise_error {
84
- ModBus::Errors::IllegalFunction
85
- }
86
- end
87
-
88
- def make_resp(msg)
89
- "\x1" + msg + "\x2\x2" # slave + msg + mock_crc
90
- end
91
- end
92
-
@@ -1,163 +0,0 @@
1
- # -*- coding: ascii
2
- require "spec_helper"
3
-
4
- describe "response mismach" do
5
- include RaiseResponseMatcher
6
- before(:each) do
7
- @slave = ModBus::Client::Slave.new(1, nil)
8
- @slave.raise_exception_on_mismatch = true
9
- end
10
-
11
- it "should raise error if function code is mismatch" do
12
- request = "\x1\x0\x13\x0\x12"
13
- response = "\x2\x3\xcd\xb6\x5"
14
- mock_query!(request, response)
15
-
16
- lambda{ @slave.read_coils(0x13,0x12) }.should raise_response_mismatch(
17
- "Function code is mismatch (expected 1, got 2)",
18
- request, response)
19
- end
20
-
21
- describe "read coils" do
22
- it "should raise error if count of byte is mismatch" do
23
- request = "\x1\x0\x13\x0\x12"
24
- response = "\x1\x2\xcd\xb6"
25
- mock_query!(request, response)
26
-
27
- lambda{ @slave.read_coils(0x13,0x12) }.should raise_response_mismatch(
28
- "Byte count is mismatch (expected 3, got 2 bytes)",
29
- request, response)
30
- end
31
- end
32
-
33
- describe "read discrete inputs" do
34
- it "should raise error if count of byte is mismatch" do
35
- request = "\x2\x0\x13\x0\x12"
36
- response = "\x2\x2\xcd\xb6"
37
- mock_query!(request, response)
38
-
39
- lambda{ @slave.read_discrete_inputs(0x13,0x12) }.should raise_response_mismatch(
40
- "Byte count is mismatch (expected 3, got 2 bytes)",
41
- request, response)
42
- end
43
- end
44
-
45
- describe "read holding registesrs" do
46
- it "should raise error if count of registers is mismatch" do
47
- request = "\x3\x0\x8\x0\x1"
48
- response = "\x3\x4\x0\xa\x0\xb"
49
- mock_query!(request, response)
50
-
51
- lambda{ @slave.read_holding_registers(0x8,0x1) }.should raise_response_mismatch(
52
- "Register count is mismatch (expected 1, got 2 regs)",
53
- request, response)
54
- end
55
- end
56
-
57
- describe "read input registesrs" do
58
- it "should raise error if count of registers is mismatch" do
59
- request = "\x4\x0\x8\x0\x2"
60
- response = "\x4\x2\xa\x0"
61
- mock_query!(request, response)
62
-
63
- lambda{ @slave.read_input_registers(0x8,0x2) }.should raise_response_mismatch(
64
- "Register count is mismatch (expected 2, got 1 regs)",
65
- request, response)
66
- end
67
- end
68
-
69
- describe "write single coil" do
70
- it "should raise error if address of coil is mismatch" do
71
- request = "\x5\x0\x8\xff\x0"
72
- response = "\x5\x0\x9\xff\x0"
73
- mock_query!(request, response)
74
-
75
- lambda{ @slave.write_coil(8,true) }.should raise_response_mismatch(
76
- "Address is mismatch (expected 8, got 9)",
77
- request, response)
78
- end
79
-
80
- it "should raise error if value of coil is mismatch" do
81
- request = "\x5\x0\x8\xff\x0"
82
- response = "\x5\x0\x8\x0\x0"
83
- mock_query!(request, response)
84
-
85
- lambda{ @slave.write_coil(8,true) }.should raise_response_mismatch(
86
- "Value is mismatch (expected 0xff00, got 0x0)",
87
- request, response)
88
- end
89
- end
90
-
91
- describe "write single register" do
92
- it "should raise error if address of register is mismatch" do
93
- request = "\x6\x0\x8\xa\xb"
94
- response = "\x6\x0\x9\xa\xb"
95
- mock_query!(request, response)
96
-
97
- lambda{ @slave.write_single_register(8,0x0a0b) }.should raise_response_mismatch(
98
- "Address is mismatch (expected 8, got 9)",
99
- request, response)
100
- end
101
-
102
- it "should raise error if value of register is mismatch" do
103
- request = "\x6\x0\x8\xa\xb"
104
- response = "\x6\x0\x8\x9\xb"
105
- mock_query!(request, response)
106
-
107
- lambda{ @slave.write_single_register(8,0x0a0b) }.should raise_response_mismatch(
108
- "Value is mismatch (expected 0xa0b, got 0x90b)",
109
- request, response)
110
- end
111
- end
112
-
113
- describe "write multiple coils" do
114
- it "should raise error if address of first coil is mismatch" do
115
- request = "\xf\x0\x13\x0\xa\2\xcd\x01"
116
- response = "\xf\x0\x14\x0\xa"
117
- mock_query!(request, response)
118
-
119
- lambda{ @slave.write_coils(0x13,[1,0,1,1, 0,0,1,1, 1,0]) }.should raise_response_mismatch(
120
- "Address is mismatch (expected 19, got 20)",
121
- request, response)
122
- end
123
-
124
- it "should raise error if quantity of coils is mismatch" do
125
- request = "\xf\x0\x13\x0\xa\2\xcd\x01"
126
- response = "\xf\x0\x13\x0\x9"
127
- mock_query!(request, response)
128
-
129
- lambda{ @slave.write_coils(0x13,[1,0,1,1, 0,0,1,1, 1,0]) }.should raise_response_mismatch(
130
- "Quantity is mismatch (expected 10, got 9)",
131
- request, response)
132
- end
133
- end
134
-
135
- describe "write multiple registers" do
136
- it "should raise error if address of first register is mismatch" do
137
- request = "\x10\x0\x1\x0\x2\x4\x0\xa\x1\x2"
138
- response = "\x10\x0\x2\x0\x2"
139
- mock_query!(request, response)
140
-
141
- lambda{ @slave.write_holding_registers(0x1,[0xa,0x102]) }.should raise_response_mismatch(
142
- "Address is mismatch (expected 1, got 2)",
143
- request, response)
144
- end
145
-
146
- it "should raise error if quantity of registers is mismatch" do
147
- request = "\x10\x0\x1\x0\x2\x4\x0\xa\x1\x2"
148
- response = "\x10\x0\x2\x0\x1"
149
- mock_query!(request, response)
150
-
151
- lambda{ @slave.write_holding_registers(0x1,[0xa,0x102]) }.should raise_response_mismatch(
152
- "Quantity is mismatch (expected 2, got 1)",
153
- request, response)
154
- end
155
- end
156
-
157
-
158
- private
159
- def mock_query!(request, response)
160
- @slave.should_receive(:send_pdu).with(request)
161
- @slave.should_receive(:read_pdu).and_return(response)
162
- end
163
- end
@@ -1,86 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- describe ModBus::RTUClient do
5
- before do
6
- @sp = double('Serial port')
7
-
8
- SerialPort.should_receive(:new).with("/dev/port1", 9600, 8, 1, 0).and_return(@sp)
9
- SerialPort.stub(:public_method_defined?).with(:flush_input).and_return(true)
10
-
11
- @sp.stub(:read_timeout=)
12
- @sp.stub(:class).and_return(SerialPort)
13
- @sp.should_receive(:flow_control=).with(SerialPort::NONE)
14
- @sp.stub(:flush_input)
15
-
16
- @cl = ModBus::RTUClient.new("/dev/port1", 9600, :data_bits => 8, :stop_bits => 1, :parity => SerialPort::NONE)
17
- @slave = @cl.with_slave(1)
18
- @slave.read_retries = 1
19
- end
20
-
21
- it "should ignore frame with other UID" do
22
- request = "\x10\x0\x1\x0\x1\x2\xff\xff"
23
- @sp.should_receive(:write).with("\1#{request}\xA6\x31")
24
- @sp.should_receive(:read).with(2).and_return("\x2\x10")
25
- @sp.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
26
- lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
27
- end
28
-
29
- it "should ignored frame with incorrect CRC" do
30
- request = "\x10\x0\x1\x0\x1\x2\xff\xff"
31
- @sp.should_receive(:write).with("\1#{request}\xA6\x31")
32
- @sp.should_receive(:read).with(2).and_return("\x2\x10")
33
- @sp.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
34
- lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
35
- end
36
-
37
- it "should return value of registers"do
38
- request = stab_valid_request
39
- @slave.query(request).should == "\xff\xff"
40
- end
41
-
42
- it 'should sugar connect method' do
43
- port, baud = "/dev/port1", 4800
44
- SerialPort.should_receive(:new).with(port, baud, 8, 1, SerialPort::NONE).and_return(@sp)
45
- @sp.should_receive(:closed?).and_return(false)
46
- @sp.should_receive(:close)
47
- @sp.should_receive(:flow_control=).with(SerialPort::NONE)
48
- ModBus::RTUClient.connect(port, baud) do |cl|
49
- cl.port.should == port
50
- cl.baud.should == baud
51
- cl.data_bits.should == 8
52
- cl.stop_bits.should == 1
53
- cl.parity.should == SerialPort::NONE
54
- end
55
- end
56
-
57
- it 'should have closed? method' do
58
- @sp.should_receive(:closed?).and_return(false)
59
- @cl.closed?.should == false
60
-
61
- @sp.should_receive(:closed?).and_return(false)
62
- @sp.should_receive(:close)
63
-
64
- @cl.close
65
-
66
- @sp.should_receive(:closed?).and_return(true)
67
- @cl.closed?.should == true
68
- end
69
-
70
- it 'should give slave object in block' do
71
- @cl.with_slave(1) do |slave|
72
- slave.uid = 1
73
- end
74
- end
75
-
76
- def stab_valid_request
77
- request = "\x3\x0\x1\x0\x1"
78
- @sp.should_receive(:write).with("\1#{request}\xd5\xca")
79
- @sp.should_receive(:read).with(2).and_return("\x1\x3")
80
- @sp.should_receive(:read).with(1).and_return("\x2")
81
- @sp.should_receive(:read).with(4).and_return("\xff\xff\xb9\xf4")
82
-
83
- request
84
- end
85
- end
86
-