rmodbus-ccutrer 2.0.0
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.
- checksums.yaml +7 -0
- data/NEWS.md +180 -0
- data/README.md +115 -0
- data/Rakefile +29 -0
- data/examples/perfomance_rtu.rb +56 -0
- data/examples/perfomance_rtu_via_tcp.rb +55 -0
- data/examples/perfomance_tcp.rb +55 -0
- data/examples/simple-xpca-gateway.rb +84 -0
- data/examples/use_rtu_via_tcp_modbus.rb +22 -0
- data/examples/use_tcp_modbus.rb +23 -0
- data/lib/rmodbus.rb +21 -0
- data/lib/rmodbus/client.rb +94 -0
- data/lib/rmodbus/client/slave.rb +345 -0
- data/lib/rmodbus/debug.rb +25 -0
- data/lib/rmodbus/errors.rb +42 -0
- data/lib/rmodbus/ext.rb +85 -0
- data/lib/rmodbus/options.rb +6 -0
- data/lib/rmodbus/proxy.rb +41 -0
- data/lib/rmodbus/rtu.rb +122 -0
- data/lib/rmodbus/rtu_client.rb +43 -0
- data/lib/rmodbus/rtu_server.rb +48 -0
- data/lib/rmodbus/rtu_slave.rb +48 -0
- data/lib/rmodbus/rtu_via_tcp_server.rb +35 -0
- data/lib/rmodbus/server.rb +246 -0
- data/lib/rmodbus/server/slave.rb +16 -0
- data/lib/rmodbus/sp.rb +36 -0
- data/lib/rmodbus/tcp.rb +31 -0
- data/lib/rmodbus/tcp_client.rb +25 -0
- data/lib/rmodbus/tcp_server.rb +67 -0
- data/lib/rmodbus/tcp_slave.rb +55 -0
- data/lib/rmodbus/version.rb +3 -0
- data/spec/client_spec.rb +88 -0
- data/spec/exception_spec.rb +120 -0
- data/spec/ext_spec.rb +52 -0
- data/spec/logging_spec.rb +89 -0
- data/spec/proxy_spec.rb +74 -0
- data/spec/read_rtu_response_spec.rb +92 -0
- data/spec/response_mismach_spec.rb +163 -0
- data/spec/rtu_client_spec.rb +86 -0
- data/spec/rtu_server_spec.rb +31 -0
- data/spec/rtu_via_tcp_client_spec.rb +76 -0
- data/spec/rtu_via_tcp_server_spec.rb +89 -0
- data/spec/slave_spec.rb +55 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/tcp_client_spec.rb +88 -0
- data/spec/tcp_server_spec.rb +158 -0
- metadata +206 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '06318cd10a9aca4e65b4c15d4f153ef13d976054429f8343ac3b5cc1304063bc'
|
4
|
+
data.tar.gz: 16fb3bfccd80ac8dd02b5c5dda1ab0aeafa9d06b59b8cf53e5938de5f07fcf34
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af77c4b113a51dc669c6d1127d1613ea3b21ac6b93efee52f02f7cdf4f898e9b7bd5ad0f39a7372f7f4a9a7064de522469ec73f1af94ac27cb7df2d27b6021d6
|
7
|
+
data.tar.gz: 5586969c9caf0269c8408f4a9c79faa089fe29fbb204523238f2541d36ce84d5606596e6086f4b983d1d8eaaf45d0bbcbce75a95a305039345aff00ae66b89f2
|
data/NEWS.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
###UPCOMING
|
2
|
+
|
3
|
+
1. [BREAKING] Servers now support publishing multiple slaves
|
4
|
+
2. [BREAKING] RTUViaTCPClient/RTUViaTCPSlave are gone. Please just use RTUClient directly
|
5
|
+
3. [BREAKING] Proxy collections no longer return an array when requesting a single item.
|
6
|
+
3. Don't time out waiting to read a response that will never come from broadcast commands
|
7
|
+
4. Don't send responses to broadcast commands as a server
|
8
|
+
5. Properly function as a server in an environment with multiple RTU slaves
|
9
|
+
6. Server now supports promiscuous mode to dump the conversation happening between a master and other slaves.
|
10
|
+
7. Add read/write multiple registers function (server and client)
|
11
|
+
8. Add mask write register function to server
|
12
|
+
|
13
|
+
###2017-03-30 Release 1.3.2
|
14
|
+
|
15
|
+
1. Fix Fixnum warning on Ruby 2.4
|
16
|
+
2. Add extension method to support unpacking 32-bit Int using little-endian order
|
17
|
+
|
18
|
+
###2016-10-18 Release 1.3.0
|
19
|
+
|
20
|
+
1. Turn the following dependencies optional: serialport, gserver
|
21
|
+
|
22
|
+
###2016-09-20 Release 1.2.8
|
23
|
+
|
24
|
+
1. Fix warning on ruby 2.3 when calling Timeout.timeout
|
25
|
+
|
26
|
+
###2015-07-30 Release 1.2.7
|
27
|
+
|
28
|
+
1. RTUServer doesn't stop serving when there is no RTU messages. Pull request [#37](https://github.com/flipback/rmodbus/pull/37).
|
29
|
+
2. Fixed a bug with flushing buffer in RTUviaTCPClient.
|
30
|
+
3. Added validation for UDI in TCPServer. See request [#38](https://github.com/flipback/rmodbus/pull/38).
|
31
|
+
4. Added a warning message to ask use UID=255 for TCP Server according to the protocol specification.
|
32
|
+
|
33
|
+
###2015-03-21 Release 1.2.6
|
34
|
+
|
35
|
+
1. Fixed issue [#35](https://github.com/flipback/rmodbus/issues/35).
|
36
|
+
|
37
|
+
###2015-03-12 Release 1.2.5
|
38
|
+
|
39
|
+
1. Fixed issue [#34](https://github.com/flipback/rmodbus/issues/34).
|
40
|
+
|
41
|
+
###2015-01-29 Release 1.2.4
|
42
|
+
|
43
|
+
1. Added ruby-2.2 compatibility
|
44
|
+
|
45
|
+
###2015-01-29 Release 1.2.3
|
46
|
+
|
47
|
+
1. Fixed bug [#30](https://github.com/flipback/rmodbus/pull/30) in parsing command 'write_register' for server implementation part.
|
48
|
+
|
49
|
+
###2013-10-28 Release 1.2.2
|
50
|
+
|
51
|
+
1. Fixed issue [#29](https://github.com/flipback/rmodbus/pull/29). The server part supports 2000 of coils/discrete inputs for reading instead of 125.
|
52
|
+
|
53
|
+
###2013-06-28 Release 1.2.1
|
54
|
+
|
55
|
+
1. Fixed issue [#27](https://github.com/flipback/rmodbus/issues/27) for read_nonblock error on Windows
|
56
|
+
|
57
|
+
###2013-03-12 Release 1.2.0
|
58
|
+
|
59
|
+
1. Transaction number mismatch doesn't throw exception in TCPSlave#query method.
|
60
|
+
Now this method will wait correct transaction until timeout breaks waiting.
|
61
|
+
2. Added ruby-2.0 experimental compatibility
|
62
|
+
|
63
|
+
###2012-07-17 Release 1.1.5
|
64
|
+
|
65
|
+
1. Fixed issue [#24](https://github.com/flipback/rmodbus/issues/24) for RTUClient.
|
66
|
+
|
67
|
+
###2012-06-28 Release 1.1.4
|
68
|
+
|
69
|
+
1. Fixed issue [#23](https://github.com/flipback/rmodbus/issues/23).
|
70
|
+
2. Improved speed of the RTU\RTUViaTCP part.
|
71
|
+
|
72
|
+
###2012-06-06 Release 1.1.3
|
73
|
+
|
74
|
+
1. Fixed issue [#22](https://github.com/flipback/rmodbus/issues/22)
|
75
|
+
|
76
|
+
###2012-05-12 Release 1.1.2
|
77
|
+
|
78
|
+
1. Fixed issue [#20](https://github.com/flipback/rmodbus/issues/20)
|
79
|
+
|
80
|
+
###2012-04-12 Release 1.1.1
|
81
|
+
|
82
|
+
1. Fixed issue [#15](https://github.com/flipback/rmodbus/issues/15)
|
83
|
+
|
84
|
+
2011-10-29 Release 1.1.0
|
85
|
+
===================================
|
86
|
+
1. Fixed issue [#12](https://github.com/flipback/rmodbus/issues/12). Added option Slave#raise_exception_on_mismatch to turn to check response and raise exception
|
87
|
+
if it's mismatch.
|
88
|
+
2. Added pass options :debug, :raise_exception_on_mismatch, :read_retry_timeout, :read_retries from clients to slaves
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
@cl.debug = true
|
92
|
+
|
93
|
+
@cl.with_slave(1) do |slave_1|
|
94
|
+
slave_1.debug #=> true
|
95
|
+
end
|
96
|
+
|
97
|
+
@cl.with_slave(2) do |slave_2|
|
98
|
+
slave_2.debug = false
|
99
|
+
slave_2.debug #=> false
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
3. Deleted dependency with `serialport` gem. Install it manual for using RTU
|
104
|
+
|
105
|
+
###2011-08-10 Release 1.0.4
|
106
|
+
|
107
|
+
1. Fixed issue [#11](https://github.com/flipback/rmodbus/issues/11)
|
108
|
+
|
109
|
+
|
110
|
+
###2011-07-17 Release 1.0.3
|
111
|
+
|
112
|
+
1. Fixed issue #10
|
113
|
+
2. Added new options for TCPServer#new and RTUViaTCPServer#new
|
114
|
+
:host - ip of host server (default 127.0.0.1)
|
115
|
+
:max_connection - maximum (client default 4)
|
116
|
+
|
117
|
+
###2011-07-1 Release 1.0.2
|
118
|
+
|
119
|
+
1. Fixed issue #9
|
120
|
+
|
121
|
+
###2011-06-30 Release 1.0.1
|
122
|
+
|
123
|
+
1. Fixed issue #8
|
124
|
+
|
125
|
+
2011-06-27 Release 1.0.0
|
126
|
+
=====================================
|
127
|
+
New API for client part of library
|
128
|
+
---------------------------------------
|
129
|
+
|
130
|
+
Example:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
require 'rmodbus'
|
134
|
+
|
135
|
+
ModBus::TCPClient.new('127.0.0.1', 8502) do |cl|
|
136
|
+
cl.with_slave(1) do |slave|
|
137
|
+
# Read a single holding register at address 16
|
138
|
+
slave.holding_registers[16]
|
139
|
+
|
140
|
+
# Write a single holding register at address 16
|
141
|
+
slave.holding_registers[16] = 123
|
142
|
+
|
143
|
+
# Read holding registers 16 through 20
|
144
|
+
slave.holding_registers[16..20]
|
145
|
+
|
146
|
+
# Write holding registers 16 through 20 with some values
|
147
|
+
slave.holding_registers[16..20] = [1, 2, 3, 4, 5]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
for more information [see](http://rdoc.info/gems/rmodbus/1.0.0/frames)
|
153
|
+
|
154
|
+
Conversion to/from 32bit registers
|
155
|
+
-----------------------------------
|
156
|
+
|
157
|
+
Some modbus devices use two registers to store 32bit values.
|
158
|
+
RModbus provides some helper functions to go back and forth between these two things when reading/writing.
|
159
|
+
The built-in examples assume registers in a particular order but it's trivial to change.
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
# Reading values in multiple registers (you can read more than 2 and convert them all so long as they are in multiples of 2)
|
163
|
+
res = slave.holding_registers[0..1]
|
164
|
+
res.inspect => [20342, 17344]
|
165
|
+
res.to_32i => [1136676726]
|
166
|
+
res.to_32f => [384.620788574219]
|
167
|
+
|
168
|
+
# Writing 32b values to multiple registers
|
169
|
+
cl.holding_registers[0..1] = [1136676726].from_32i
|
170
|
+
cl.holding_registers[0..1] => [20342, 17344]
|
171
|
+
cl.holding_registers[2..3] = [384.620788574219].from_32f
|
172
|
+
cl.holding_registers[2..3] => [20342, 17344]
|
173
|
+
```
|
174
|
+
|
175
|
+
Support JRuby
|
176
|
+
--------------------------------------
|
177
|
+
Now you could use RModBus on JRuby without RTU implementation.
|
178
|
+
|
179
|
+
RTU classes requires gem [serialport](https://github.com/hparra/ruby-serialport) which
|
180
|
+
currently not compatible with JRuby
|
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
RModBus [](http://travis-ci.org/rmodbus/rmodbus) [](http://badge.fury.io/rb/rmodbus)
|
2
|
+
==========================
|
3
|
+
|
4
|
+
**RModBus** - free implementation of ModBus protocol in pure Ruby.
|
5
|
+
|
6
|
+
Features
|
7
|
+
---------------------------
|
8
|
+
- Ruby 2.2, 2.3 and JRuby (without serial ModBus RTU)
|
9
|
+
- TCP, RTU, RTU over TCP protocols
|
10
|
+
- Client(master) and server(slave)
|
11
|
+
- 16, 32 -bit and float registers
|
12
|
+
|
13
|
+
Support functions
|
14
|
+
---------------------------
|
15
|
+
* Read Coils (0x01)
|
16
|
+
* Read Discrete Inputs (0x02)
|
17
|
+
* Read Holding Registers (0x03)
|
18
|
+
* Read Input Registers (0x04)
|
19
|
+
* Write Single Coil (0x05)
|
20
|
+
* Write Single Register (0x06)
|
21
|
+
* Write Multiple Coils (0x0F)
|
22
|
+
* Write Multiple registers (0x10)
|
23
|
+
* Mask Write register (0x16)
|
24
|
+
|
25
|
+
Installation
|
26
|
+
------------------------------------
|
27
|
+
|
28
|
+
Download and install RModBus with the following:
|
29
|
+
|
30
|
+
```
|
31
|
+
gem install rmodbus
|
32
|
+
```
|
33
|
+
|
34
|
+
Or if you are using bundler, add to your Gemfile:
|
35
|
+
|
36
|
+
```
|
37
|
+
gem 'rmodbus'
|
38
|
+
```
|
39
|
+
|
40
|
+
If you want to use ModBus over serial, you will also need to install the 'serialport' gem.
|
41
|
+
If you are using bundler, add to your Gemfile:
|
42
|
+
|
43
|
+
```
|
44
|
+
gem 'serialport'
|
45
|
+
```
|
46
|
+
|
47
|
+
If you want to use ModBus::TCPServer or ModBus::RTUViaTCPServer and are using Ruby >= 2.2,
|
48
|
+
you will also need to install the 'gserver' gem. If you are using bundler, add to your Gemfile:
|
49
|
+
|
50
|
+
```
|
51
|
+
gem 'gserver'
|
52
|
+
```
|
53
|
+
|
54
|
+
Please note that GServer is deprecated, and I'm looking for a better solution.
|
55
|
+
Contributions are welcome!
|
56
|
+
|
57
|
+
Example
|
58
|
+
------------------------------------
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
require 'rmodbus'
|
62
|
+
|
63
|
+
ModBus::TCPClient.new('127.0.0.1', 8502) do |cl|
|
64
|
+
cl.with_slave(1) do |slave|
|
65
|
+
# Read a single holding register at address 16
|
66
|
+
slave.holding_registers[16]
|
67
|
+
|
68
|
+
# Write a single holding register at address 16
|
69
|
+
slave.holding_registers[16] = 123
|
70
|
+
|
71
|
+
# Read holding registers 16 through 20
|
72
|
+
slave.holding_registers[16..20]
|
73
|
+
|
74
|
+
# Write holding registers 16 through 20 with some values
|
75
|
+
slave.holding_registers[16..20] = [1, 2, 3, 4, 5]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
Versioning
|
81
|
+
----------------------------------
|
82
|
+
|
83
|
+
This project will follow http://semver.org/
|
84
|
+
|
85
|
+
```
|
86
|
+
Given a version number MAJOR.MINOR.PATCH, increment the:
|
87
|
+
|
88
|
+
MAJOR version when you make incompatible API changes,
|
89
|
+
MINOR version when you add functionality in a backwards-compatible manner, and
|
90
|
+
PATCH version when you make backwards-compatible bug fixes.
|
91
|
+
```
|
92
|
+
|
93
|
+
Contributing
|
94
|
+
----------------------------------
|
95
|
+
|
96
|
+
See [CONTRIBUTING](CONTRIBUTING.md).
|
97
|
+
|
98
|
+
Reference
|
99
|
+
----------------------------------
|
100
|
+
|
101
|
+
RModBus on GitHub: http://github.com/rmodbus/rmodbus
|
102
|
+
|
103
|
+
Documentation: http://www.rubydoc.info/github/rmodbus/rmodbus
|
104
|
+
|
105
|
+
ModBus specifications: http://www.modbus.org/specs.php
|
106
|
+
|
107
|
+
License
|
108
|
+
----------------------------------
|
109
|
+
|
110
|
+
BSD-3-Clause
|
111
|
+
|
112
|
+
Credits
|
113
|
+
----------------------------------
|
114
|
+
|
115
|
+
Aleksey Timin - original author
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rake'
|
14
|
+
require 'rspec/core'
|
15
|
+
require 'rspec/core/rake_task'
|
16
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
17
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
18
|
+
begin
|
19
|
+
require 'serialport'
|
20
|
+
rescue LoadError => e
|
21
|
+
spec.pattern.exclude("spec/rtu_client_spec.rb", "spec/rtu_server_spec.rb")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
task :default => :spec
|
26
|
+
|
27
|
+
task :pry do
|
28
|
+
sh "bundle exec pry -r ./lib/rmodbus.rb"
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'../lib')
|
2
|
+
|
3
|
+
require 'rmodbus'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
include ModBus
|
7
|
+
|
8
|
+
BAUD = 9600
|
9
|
+
TIMES = 100
|
10
|
+
|
11
|
+
srv = RTUServer.new 'com3', BAUD
|
12
|
+
srv.coils = [0,1] * 50
|
13
|
+
srv.discrete_inputs = [1,0] * 50
|
14
|
+
srv.holding_registers = [0,1,2,3,4,5,6,7,8,9] * 10
|
15
|
+
srv.input_registers = [0,1,2,3,4,5,6,7,8,9] * 10
|
16
|
+
srv.start
|
17
|
+
|
18
|
+
|
19
|
+
cl = RTUClient.new('com4', BAUD)
|
20
|
+
cl.with_slave(1) do |slave|
|
21
|
+
Benchmark.bmbm do |x|
|
22
|
+
x.report('Read coils') do
|
23
|
+
TIMES.times { slave.read_coils 0, 100 }
|
24
|
+
end
|
25
|
+
|
26
|
+
x.report('Read discrete inputs') do
|
27
|
+
TIMES.times { slave.read_discrete_inputs 0, 100 }
|
28
|
+
end
|
29
|
+
|
30
|
+
x.report('Read holding registers') do
|
31
|
+
TIMES.times { slave.read_holding_registers 0, 100 }
|
32
|
+
end
|
33
|
+
|
34
|
+
x.report('Read input registers') do
|
35
|
+
TIMES.times { slave.read_input_registers 0, 100 }
|
36
|
+
end
|
37
|
+
|
38
|
+
x.report('Write single coil') do
|
39
|
+
TIMES.times { slave.write_single_coil 0, 1 }
|
40
|
+
end
|
41
|
+
|
42
|
+
x.report('Write single register') do
|
43
|
+
TIMES.times { slave.write_single_register 100, 0xAAAA }
|
44
|
+
end
|
45
|
+
|
46
|
+
x.report('Write multiple coils') do
|
47
|
+
TIMES.times { slave.write_multiple_coils 0, [1,0] * 50 }
|
48
|
+
end
|
49
|
+
|
50
|
+
x.report('Write multiple registers') do
|
51
|
+
TIMES.times { slave.write_multiple_registers 0, [0,1,2,3,4,5,6,7,8,9] * 10 }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
srv.stop
|
56
|
+
cl.close
|
@@ -0,0 +1,55 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'../lib')
|
2
|
+
|
3
|
+
require 'rmodbus'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
include ModBus
|
7
|
+
|
8
|
+
TIMES = 1000
|
9
|
+
|
10
|
+
srv = ModBus::RTUViaTCPServer.new 1502
|
11
|
+
srv.coils = [0,1] * 50
|
12
|
+
srv.discrete_inputs = [1,0] * 50
|
13
|
+
srv.holding_registers = [0,1,2,3,4,5,6,7,8,9] * 10
|
14
|
+
srv.input_registers = [0,1,2,3,4,5,6,7,8,9] * 10
|
15
|
+
srv.start
|
16
|
+
|
17
|
+
|
18
|
+
cl = RTUClient.new('127.0.0.1', 1502)
|
19
|
+
cl.with_slave(1) do |slave|
|
20
|
+
Benchmark.bmbm do |x|
|
21
|
+
x.report('Read coils') do
|
22
|
+
TIMES.times { slave.read_coils 0, 100 }
|
23
|
+
end
|
24
|
+
|
25
|
+
x.report('Read discrete inputs') do
|
26
|
+
TIMES.times { slave.read_discrete_inputs 0, 100 }
|
27
|
+
end
|
28
|
+
|
29
|
+
x.report('Read holding registers') do
|
30
|
+
TIMES.times { slave.read_holding_registers 0, 100 }
|
31
|
+
end
|
32
|
+
|
33
|
+
x.report('Read input registers') do
|
34
|
+
TIMES.times { slave.read_input_registers 0, 100 }
|
35
|
+
end
|
36
|
+
|
37
|
+
x.report('Write single coil') do
|
38
|
+
TIMES.times { slave.write_single_coil 0, 1 }
|
39
|
+
end
|
40
|
+
|
41
|
+
x.report('Write single register') do
|
42
|
+
TIMES.times { slave.write_single_register 100, 0xAAAA }
|
43
|
+
end
|
44
|
+
|
45
|
+
x.report('Write multiple coils') do
|
46
|
+
TIMES.times { slave.write_multiple_coils 0, [1,0] * 50 }
|
47
|
+
end
|
48
|
+
|
49
|
+
x.report('Write multiple registers') do
|
50
|
+
TIMES.times { slave.write_multiple_registers 0, [0,1,2,3,4,5,6,7,8,9] * 10 }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
cl.close
|
55
|
+
srv.stop
|