rmodbus 1.3.3 → 2.1.3

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