rmodbus-ccutrer 2.0.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
-