rmodbus 1.3.2 → 2.1.2

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 (51) hide show
  1. checksums.yaml +5 -5
  2. data/NEWS.md +19 -0
  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 +333 -0
  11. data/lib/rmodbus/client.rb +15 -10
  12. data/lib/rmodbus/debug.rb +12 -15
  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 +89 -125
  18. data/lib/rmodbus/rtu_client.rb +22 -2
  19. data/lib/rmodbus/rtu_server.rb +16 -12
  20. data/lib/rmodbus/rtu_slave.rb +26 -3
  21. data/lib/rmodbus/rtu_via_tcp_server.rb +12 -19
  22. data/lib/rmodbus/server/slave.rb +18 -0
  23. data/lib/rmodbus/server.rb +227 -84
  24. data/lib/rmodbus/sp.rb +10 -12
  25. data/lib/rmodbus/tcp.rb +9 -10
  26. data/lib/rmodbus/tcp_client.rb +3 -0
  27. data/lib/rmodbus/tcp_server.rb +41 -35
  28. data/lib/rmodbus/tcp_slave.rb +19 -18
  29. data/lib/rmodbus/version.rb +3 -2
  30. data/lib/rmodbus.rb +20 -21
  31. metadata +63 -50
  32. data/Rakefile +0 -29
  33. data/examples/simple-xpca-gateway.rb +0 -84
  34. data/lib/rmodbus/rtu_via_tcp_client.rb +0 -26
  35. data/lib/rmodbus/rtu_via_tcp_slave.rb +0 -29
  36. data/lib/rmodbus/slave.rb +0 -308
  37. data/spec/client_spec.rb +0 -88
  38. data/spec/exception_spec.rb +0 -119
  39. data/spec/ext_spec.rb +0 -52
  40. data/spec/logging_spec.rb +0 -89
  41. data/spec/proxy_spec.rb +0 -74
  42. data/spec/read_rtu_response_spec.rb +0 -92
  43. data/spec/response_mismach_spec.rb +0 -163
  44. data/spec/rtu_client_spec.rb +0 -86
  45. data/spec/rtu_server_spec.rb +0 -30
  46. data/spec/rtu_via_tcp_client_spec.rb +0 -76
  47. data/spec/rtu_via_tcp_server_spec.rb +0 -16
  48. data/spec/slave_spec.rb +0 -55
  49. data/spec/spec_helper.rb +0 -54
  50. data/spec/tcp_client_spec.rb +0 -88
  51. data/spec/tcp_server_spec.rb +0 -129
data/lib/rmodbus/slave.rb DELETED
@@ -1,308 +0,0 @@
1
- module ModBus
2
- class Slave
3
- include Errors
4
- include Debug
5
- include Options
6
- # Number of times to retry on read and read timeouts
7
- attr_accessor :uid
8
- Exceptions = {
9
- 1 => IllegalFunction.new("The function code received in the query is not an allowable action for the server"),
10
- 2 => IllegalDataAddress.new("The data address received in the query is not an allowable address for the server"),
11
- 3 => IllegalDataValue.new("A value contained in the query data field is not an allowable value for server"),
12
- 4 => SlaveDeviceFailure.new("An unrecoverable error occurred while the server was attempting to perform the requested action"),
13
- 5 => Acknowledge.new("The server has accepted the request and is processing it, but a long duration of time will be required to do so"),
14
- 6 => SlaveDeviceBus.new("The server is engaged in processing a long duration program command"),
15
- 8 => MemoryParityError.new("The extended file area failed to pass a consistency check")
16
- }
17
- def initialize(uid, io)
18
- @uid = uid
19
- @io = io
20
- end
21
-
22
- # Returns a ModBus::ReadWriteProxy hash interface for coils
23
- #
24
- # @example
25
- # coils[addr] => [1]
26
- # coils[addr1..addr2] => [1, 0, ..]
27
- # coils[addr] = 0 => [0]
28
- # coils[addr1..addr2] = [1, 0, ..] => [1, 0, ..]
29
- #
30
- # @return [ReadWriteProxy] proxy object
31
- def coils
32
- ModBus::ReadWriteProxy.new(self, :coil)
33
- end
34
-
35
- # Read coils
36
- #
37
- # @example
38
- # read_coils(addr, ncoils) => [1, 0, ..]
39
- #
40
- # @param [Integer] addr address first coil
41
- # @param [Integer] ncoils number coils
42
- # @return [Array] coils
43
- def read_coils(addr, ncoils)
44
- query("\x1" + addr.to_word + ncoils.to_word).unpack_bits[0..ncoils-1]
45
- end
46
- alias_method :read_coil, :read_coils
47
-
48
- # Write a single coil
49
- #
50
- # @example
51
- # write_single_coil(1, 0) => self
52
- #
53
- # @param [Integer] addr address coil
54
- # @param [Integer] val value coil (0 or other)
55
- # @return self
56
- def write_single_coil(addr, val)
57
- if val == 0
58
- query("\x5" + addr.to_word + 0.to_word)
59
- else
60
- query("\x5" + addr.to_word + 0xff00.to_word)
61
- end
62
- self
63
- end
64
- alias_method :write_coil, :write_single_coil
65
-
66
- # Write multiple coils
67
- #
68
- # @example
69
- # write_multiple_coils(1, [0,1,0,1]) => self
70
- #
71
- # @param [Integer] addr address first coil
72
- # @param [Array] vals written coils
73
- def write_multiple_coils(addr, vals)
74
- nbyte = ((vals.size-1) >> 3) + 1
75
- sum = 0
76
- (vals.size - 1).downto(0) do |i|
77
- sum = sum << 1
78
- sum |= 1 if vals[i] > 0
79
- end
80
-
81
- s_val = ""
82
- nbyte.times do
83
- s_val << (sum & 0xff).chr
84
- sum >>= 8
85
- end
86
-
87
- query("\xf" + addr.to_word + vals.size.to_word + nbyte.chr + s_val)
88
- self
89
- end
90
- alias_method :write_coils, :write_multiple_coils
91
-
92
- # Returns a ModBus::ReadOnlyProxy hash interface for discrete inputs
93
- #
94
- # @example
95
- # discrete_inputs[addr] => [1]
96
- # discrete_inputs[addr1..addr2] => [1, 0, ..]
97
- #
98
- # @return [ReadOnlyProxy] proxy object
99
- def discrete_inputs
100
- ModBus::ReadOnlyProxy.new(self, :discrete_input)
101
- end
102
-
103
- # Read discrete inputs
104
- #
105
- # @example
106
- # read_discrete_inputs(addr, ninputs) => [1, 0, ..]
107
- #
108
- # @param [Integer] addr address first input
109
- # @param[Integer] ninputs number inputs
110
- # @return [Array] inputs
111
- def read_discrete_inputs(addr, ninputs)
112
- query("\x2" + addr.to_word + ninputs.to_word).unpack_bits[0..ninputs-1]
113
- end
114
- alias_method :read_discrete_input, :read_discrete_inputs
115
-
116
- # Returns a read/write ModBus::ReadOnlyProxy hash interface for coils
117
- #
118
- # @example
119
- # input_registers[addr] => [1]
120
- # input_registers[addr1..addr2] => [1, 0, ..]
121
- #
122
- # @return [ReadOnlyProxy] proxy object
123
- def input_registers
124
- ModBus::ReadOnlyProxy.new(self, :input_register)
125
- end
126
-
127
- # Read input registers
128
- #
129
- # @example
130
- # read_input_registers(1, 5) => [1, 0, ..]
131
- #
132
- # @param [Integer] addr address first registers
133
- # @param [Integer] nregs number registers
134
- # @return [Array] registers
135
- def read_input_registers(addr, nregs)
136
- query("\x4" + addr.to_word + nregs.to_word).unpack('n*')
137
- end
138
- alias_method :read_input_register, :read_input_registers
139
-
140
- # Returns a ModBus::ReadWriteProxy hash interface for holding registers
141
- #
142
- # @example
143
- # holding_registers[addr] => [123]
144
- # holding_registers[addr1..addr2] => [123, 234, ..]
145
- # holding_registers[addr] = 123 => 123
146
- # holding_registers[addr1..addr2] = [234, 345, ..] => [234, 345, ..]
147
- #
148
- # @return [ReadWriteProxy] proxy object
149
- def holding_registers
150
- ModBus::ReadWriteProxy.new(self, :holding_register)
151
- end
152
-
153
- # Read holding registers
154
- #
155
- # @example
156
- # read_holding_registers(1, 5) => [1, 0, ..]
157
- #
158
- # @param [Integer] addr address first registers
159
- # @param [Integer] nregs number registers
160
- # @return [Array] registers
161
- def read_holding_registers(addr, nregs)
162
- query("\x3" + addr.to_word + nregs.to_word).unpack('n*')
163
- end
164
- alias_method :read_holding_register, :read_holding_registers
165
-
166
- # Write a single holding register
167
- #
168
- # @example
169
- # write_single_register(1, 0xaa) => self
170
- #
171
- # @param [Integer] addr address registers
172
- # @param [Integer] val written to register
173
- # @return self
174
- def write_single_register(addr, val)
175
- query("\x6" + addr.to_word + val.to_word)
176
- self
177
- end
178
- alias_method :write_holding_register, :write_single_register
179
-
180
-
181
- # Write multiple holding registers
182
- #
183
- # @example
184
- # write_multiple_registers(1, [0xaa, 0]) => self
185
- #
186
- # @param [Integer] addr address first registers
187
- # @param [Array] val written registers
188
- # @return self
189
- def write_multiple_registers(addr, vals)
190
- s_val = ""
191
- vals.each do |reg|
192
- s_val << reg.to_word
193
- end
194
-
195
- query("\x10" + addr.to_word + vals.size.to_word + (vals.size * 2).chr + s_val)
196
- self
197
- end
198
- alias_method :write_holding_registers, :write_multiple_registers
199
-
200
- # Mask a holding register
201
- #
202
- # @example
203
- # mask_write_register(1, 0xAAAA, 0x00FF) => self
204
- # @param [Integer] addr address registers
205
- # @param [Integer] and_mask mask for AND operation
206
- # @param [Integer] or_mask mask for OR operation
207
- def mask_write_register(addr, and_mask, or_mask)
208
- query("\x16" + addr.to_word + and_mask.to_word + or_mask.to_word)
209
- self
210
- end
211
-
212
- # Request pdu to slave device
213
- #
214
- # @param [String] pdu request to slave
215
- # @return [String] received data
216
- #
217
- # @raise [ResponseMismatch] the received echo response differs from the request
218
- # @raise [ModBusTimeout] timed out during read attempt
219
- # @raise [ModBusException] unknown error
220
- # @raise [IllegalFunction] function code received in the query is not an allowable action for the server
221
- # @raise [IllegalDataAddress] data address received in the query is not an allowable address for the server
222
- # @raise [IllegalDataValue] value contained in the query data field is not an allowable value for server
223
- # @raise [SlaveDeviceFailure] unrecoverable error occurred while the server was attempting to perform the requested action
224
- # @raise [Acknowledge] server has accepted the request and is processing it, but a long duration of time will be required to do so
225
- # @raise [SlaveDeviceBus] server is engaged in processing a long duration program command
226
- # @raise [MemoryParityError] extended file area failed to pass a consistency check
227
- def query(request)
228
- tried = 0
229
- response = ""
230
- begin
231
- ::Timeout.timeout(@read_retry_timeout, ModBusTimeout) do
232
- send_pdu(request)
233
- response = read_pdu
234
- end
235
- rescue ModBusTimeout => err
236
- log "Timeout of read operation: (#{@read_retries - tried})"
237
- tried += 1
238
- retry unless tried >= @read_retries
239
- raise ModBusTimeout.new, "Timed out during read attempt"
240
- end
241
-
242
- return nil if response.size == 0
243
-
244
- read_func = response.getbyte(0)
245
- if read_func >= 0x80
246
- exc_id = response.getbyte(1)
247
- raise Exceptions[exc_id] unless Exceptions[exc_id].nil?
248
-
249
- raise ModBusException.new, "Unknown error"
250
- end
251
-
252
- check_response_mismatch(request, response) if raise_exception_on_mismatch
253
- response[2..-1]
254
- end
255
-
256
- private
257
- def check_response_mismatch(request, response)
258
- read_func = response.getbyte(0)
259
- data = response[2..-1]
260
- #Mismatch functional code
261
- send_func = request.getbyte(0)
262
- if read_func != send_func
263
- msg = "Function code is mismatch (expected #{send_func}, got #{read_func})"
264
- end
265
-
266
- case read_func
267
- when 1,2
268
- bc = request.getword(3)/8 + 1
269
- if data.size != bc
270
- msg = "Byte count is mismatch (expected #{bc}, got #{data.size} bytes)"
271
- end
272
- when 3,4
273
- rc = request.getword(3)
274
- if data.size/2 != rc
275
- msg = "Register count is mismatch (expected #{rc}, got #{data.size/2} regs)"
276
- end
277
- when 5,6
278
- exp_addr = request.getword(1)
279
- got_addr = response.getword(1)
280
- if exp_addr != got_addr
281
- msg = "Address is mismatch (expected #{exp_addr}, got #{got_addr})"
282
- end
283
-
284
- exp_val = request.getword(3)
285
- got_val = response.getword(3)
286
- if exp_val != got_val
287
- msg = "Value is mismatch (expected 0x#{exp_val.to_s(16)}, got 0x#{got_val.to_s(16)})"
288
- end
289
- when 15,16
290
- exp_addr = request.getword(1)
291
- got_addr = response.getword(1)
292
- if exp_addr != got_addr
293
- msg = "Address is mismatch (expected #{exp_addr}, got #{got_addr})"
294
- end
295
-
296
- exp_quant = request.getword(3)
297
- got_quant = response.getword(3)
298
- if exp_quant != got_quant
299
- msg = "Quantity is mismatch (expected #{exp_quant}, got #{got_quant})"
300
- end
301
- else
302
- warn "Fuiction (#{read_func}) is not supported raising response mismatch"
303
- end
304
-
305
- raise ResponseMismatch.new(msg, request, response) if msg
306
- end
307
- end
308
- end
data/spec/client_spec.rb DELETED
@@ -1,88 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- describe ModBus::Client do
5
- before do
6
- @cl = ModBus::Client.new
7
- end
8
-
9
- it "should give object provider for slave" do
10
- slave = @cl.with_slave(1)
11
- slave.uid.should eq(1)
12
- end
13
-
14
- it "should give object provider for slave in block" do
15
- @cl.with_slave(1) do |slave|
16
- slave.uid.should eq(1)
17
- end
18
- end
19
-
20
- it "should connect with TCP server" do
21
- ModBus::Client.connect do |cl|
22
- cl.should be_instance_of(ModBus::Client)
23
- end
24
- end
25
-
26
- it ":new alias :connect" do
27
- ModBus::Client.new do |cl|
28
- cl.should be_instance_of(ModBus::Client)
29
- end
30
- end
31
-
32
- it "should close the connection when an exception is raised in the given block" do
33
- expect {
34
- ModBus::Client.new do |client|
35
- client.should_receive(:close)
36
- raise
37
- end
38
- }.to raise_error
39
- end
40
-
41
- it 'should common for all slaves :debug flag' do
42
- @cl.debug = true
43
- @cl.with_slave(1) do |slave_1|
44
- slave_1.debug.should be_truthy
45
- end
46
- @cl.with_slave(2) do |slave_2|
47
- slave_2.debug = false
48
- slave_2.debug.should be_falsey
49
- end
50
- end
51
-
52
- it 'should common for all slaves :raise_exception_on_mismatch flag' do
53
- @cl.raise_exception_on_mismatch = true
54
- @cl.with_slave(1) do |slave_1|
55
- slave_1.raise_exception_on_mismatch.should be_truthy
56
- end
57
-
58
- @cl.with_slave(2) do |slave_2|
59
- slave_2.raise_exception_on_mismatch = false
60
- slave_2.raise_exception_on_mismatch.should be_falsey
61
- end
62
- end
63
-
64
- it 'should common for all slaves :read_retries options' do
65
- @cl.read_retries = 5
66
- @cl.with_slave(1) do |slave_1|
67
- slave_1.read_retries.should eql(5)
68
- end
69
-
70
- @cl.with_slave(2) do |slave_2|
71
- slave_2.read_retries = 15
72
- slave_2.read_retries.should eql(15)
73
- end
74
- end
75
-
76
- it 'should common for all slaves :read_retry_timeout options' do
77
- @cl.read_retry_timeout = 5
78
- @cl.with_slave(1) do |slave_1|
79
- slave_1.read_retry_timeout.should eql(5)
80
- end
81
-
82
- @cl.with_slave(2) do |slave_2|
83
- slave_2.read_retry_timeout = 15
84
- slave_2.read_retry_timeout.should eql(15)
85
- end
86
- end
87
-
88
- end
@@ -1,119 +0,0 @@
1
- # -*- coding: ascii
2
- require 'rmodbus'
3
-
4
- describe ModBus::TCPClient do
5
- before(:all) do
6
- @srv = ModBus::TCPServer.new(1502, 1)
7
- @srv.coils = [0] * 8
8
- @srv.discrete_inputs = [0] * 8
9
- @srv.holding_registers = [0] * 8
10
- @srv.input_registers = [0] * 8
11
- @srv.start
12
-
13
- @cl = ModBus::TCPClient.new('127.0.0.1', 1502)
14
- @slave = @cl.with_slave(1)
15
- end
16
-
17
- it "should raise ProxException" do
18
- lambda { @slave.holding_registers[0..2] = [0,0] }.should raise_error(ModBus::Errors::ProxyException)
19
- end
20
-
21
- # Read coil status
22
- it "should read coil status" do
23
- @slave.read_coils(0, 4).should == [0] * 4
24
- end
25
-
26
- it "should raise exception if illegal data address" do
27
- lambda { @slave.read_coils(501, 34) }.should raise_error(ModBus::Errors::IllegalDataAddress)
28
- end
29
-
30
- it "should raise exception if too many data" do
31
- lambda { @slave.read_coils(0, 0x07D1) }.should raise_error(ModBus::Errors::IllegalDataValue)
32
- end
33
-
34
- # Read input status
35
- it "should read discrete inputs" do
36
- @slave.read_discrete_inputs(0, 4).should == [0] * 4
37
- end
38
-
39
- it "should raise exception if illegal data address" do
40
- lambda { @slave.read_discrete_inputs(50, 23) }.should raise_error(ModBus::Errors::IllegalDataAddress)
41
- end
42
-
43
- it "should raise exception if too many data" do
44
- lambda { @slave.read_discrete_inputs(0, 0x07D1) }.should raise_error(ModBus::Errors::IllegalDataValue)
45
- end
46
-
47
- # Read holding registers
48
- it "should read discrete inputs" do
49
- @slave.read_holding_registers(0, 4).should == [0, 0, 0, 0]
50
- end
51
-
52
- it "should raise exception if illegal data address" do
53
- lambda { @slave.read_holding_registers(402, 99) }.should raise_error(ModBus::Errors::IllegalDataAddress)
54
- end
55
-
56
-
57
- it "should raise exception if too many data" do
58
- lambda { @slave.read_holding_registers(0, 0x007E) }.should raise_error(ModBus::Errors::IllegalDataValue)
59
- end
60
-
61
- # Read input registers
62
- it "should read discrete inputs" do
63
- @slave.read_input_registers(0, 4).should == [0, 0, 0, 0]
64
- end
65
-
66
- it "should raise exception if illegal data address" do
67
- lambda { @slave.read_input_registers(402, 9) }.should raise_error(ModBus::Errors::IllegalDataAddress)
68
- end
69
-
70
- it "should raise exception if too many data" do
71
- lambda { @slave.read_input_registers(0, 0x007E) }.should raise_error(ModBus::Errors::IllegalDataValue)
72
- end
73
-
74
- # Force single coil
75
- it "should force single coil" do
76
- @slave.write_single_coil(4, 1).should == @slave
77
- @slave.read_coils(4, 4).should == [1, 0, 0, 0]
78
- end
79
-
80
- it "should raise exception if illegal data address" do
81
- lambda { @slave.write_single_coil(501, true) }.should raise_error(ModBus::Errors::IllegalDataAddress)
82
- end
83
-
84
- # Preset single register
85
- it "should preset single register" do
86
- @slave.write_single_register(4, 0x0AA0).should == @slave
87
- @slave.read_holding_registers(4, 1).should == [0x0AA0]
88
- end
89
-
90
- it "should raise exception if illegal data address" do
91
- lambda { @slave.write_single_register(501, 0x0AA0) }.should raise_error(ModBus::Errors::IllegalDataAddress)
92
- end
93
-
94
- # Force multiple coils
95
- it "should force multiple coils" do
96
- @slave.write_multiple_coils(4, [0,1,0,1]).should == @slave
97
- @slave.read_coils(3, 5).should == [0,0,1,0,1]
98
- end
99
-
100
- it "should raise exception if illegal data address" do
101
- lambda { @slave.write_multiple_coils(501, [1,0]) }.should raise_error(ModBus::Errors::IllegalDataAddress)
102
- end
103
-
104
- # Preset multiple registers
105
- it "should preset multiple registers" do
106
- @slave.write_multiple_registers(4, [1, 2, 3, 0xAACC]).should == @slave
107
- @slave.read_holding_registers(3, 5).should == [0, 1, 2, 3, 0xAACC]
108
- end
109
-
110
- it "should raise exception if illegal data address" do
111
- lambda { @slave.write_multiple_registers(501, [1, 2]) }.should raise_error(ModBus::Errors::IllegalDataAddress)
112
- end
113
-
114
- after(:all) do
115
- @cl.close unless @cl.closed?
116
- @srv.stop
117
- end
118
-
119
- 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
- TCPSocket.should_receive(:new).with('127.0.0.1', 1502).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