rmodbus 1.2.6 → 1.2.7
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 +4 -4
- data/NEWS.md +7 -0
- data/README.md +11 -7
- data/lib/rmodbus/rtu.rb +7 -3
- data/lib/rmodbus/tcp_server.rb +24 -15
- data/lib/rmodbus/version.rb +2 -2
- data/spec/client_spec.rb +4 -4
- data/spec/logging_spec.rb +12 -7
- data/spec/proxy_spec.rb +1 -1
- data/spec/rtu_client_spec.rb +7 -3
- data/spec/rtu_server_spec.rb +2 -2
- data/spec/rtu_via_tcp_client_spec.rb +3 -3
- data/spec/slave_spec.rb +1 -1
- data/spec/tcp_client_spec.rb +4 -4
- data/spec/tcp_server_spec.rb +14 -9
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72ada248b0d55d8dfecb8cb022e30e0dbd4e50b3
|
4
|
+
data.tar.gz: 8de3ae040a26b173faa3bb1eca98b6d9bdba37c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52ba64f23e37297732981cfb7a21f0633b4959b813a20005903148539cb341086250135ff7607c68d7c204e5c71d93be428ea6bf78253409ef7bce153d1e1008
|
7
|
+
data.tar.gz: acc3b11d3b438c2af0ed52dcb2126f1e7360523efb6135ecd933999550869b57a5820d034ee6907277a0ca6b879084f7b0bdf5b0b04d4ebc26deab72edad18af
|
data/NEWS.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
###2015-07-30 Release 1.2.7
|
2
|
+
|
3
|
+
1. RTUServer doesn't stop serving when there is no RTU messages. Pull request [#37](https://github.com/flipback/rmodbus/pull/37).
|
4
|
+
2. Fixed a bug with flushing buffer in RTUviaTCPClient.
|
5
|
+
3. Added validation for UDI in TCPServer. See request [#38](https://github.com/flipback/rmodbus/pull/38).
|
6
|
+
4. Added a warning message to ask use UID=255 for TCP Server according to the protocol specification.
|
7
|
+
|
1
8
|
###2015-03-21 Release 1.2.6
|
2
9
|
|
3
10
|
1. Fixed issue [#35](https://github.com/flipback/rmodbus/issues/35).
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
RModBus [](http://travis-ci.org/flipback/rmodbus)
|
2
2
|
==========================
|
3
3
|
|
4
|
-
**RModBus** - free implementation of
|
4
|
+
**RModBus** - free implementation of ModBus protocol in pure Ruby.
|
5
5
|
|
6
6
|
Features
|
7
7
|
---------------------------
|
@@ -25,9 +25,11 @@ Support functions
|
|
25
25
|
Installation
|
26
26
|
------------------------------------
|
27
27
|
|
28
|
-
Download and install RModBus with the following
|
28
|
+
Download and install RModBus with the following:
|
29
29
|
|
30
|
-
|
30
|
+
```
|
31
|
+
gem install rmodbus
|
32
|
+
```
|
31
33
|
|
32
34
|
Example
|
33
35
|
------------------------------------
|
@@ -55,15 +57,17 @@ Example
|
|
55
57
|
GitHub
|
56
58
|
----------------------------------
|
57
59
|
|
58
|
-
You can checkout source code from GitHub
|
60
|
+
You can checkout source code from GitHub repository:
|
59
61
|
|
60
|
-
|
62
|
+
```
|
63
|
+
git clone git://github.com/flipback/RModBus.git
|
64
|
+
```
|
61
65
|
|
62
66
|
Reference
|
63
67
|
----------------------------------
|
64
68
|
|
65
69
|
Home page: http://rmodbus.flipback.net
|
66
70
|
|
67
|
-
|
71
|
+
RModBus on GitHub: http://github.com/flipback/RModBus
|
68
72
|
|
69
|
-
ModBus
|
73
|
+
ModBus specifications: http://www.modbus.org/specs.php
|
data/lib/rmodbus/rtu.rb
CHANGED
@@ -46,7 +46,11 @@ module ModBus
|
|
46
46
|
|
47
47
|
def clean_input_buff
|
48
48
|
# empty the input buffer
|
49
|
-
@io.flush_input
|
49
|
+
if @io.class.public_method_defined? :flush_input
|
50
|
+
@io.flush_input
|
51
|
+
else
|
52
|
+
@io.flush
|
53
|
+
end
|
50
54
|
end
|
51
55
|
|
52
56
|
def send_rtu_pdu(pdu)
|
@@ -105,8 +109,8 @@ module ModBus
|
|
105
109
|
loop do
|
106
110
|
# read the RTU message
|
107
111
|
msg = read_rtu_request(io)
|
108
|
-
|
109
|
-
|
112
|
+
|
113
|
+
next if msg.nil?
|
110
114
|
|
111
115
|
if msg.getbyte(0) == @uid and msg[-2,2].unpack('n')[0] == crc16(msg[0..-3])
|
112
116
|
pdu = yield msg
|
data/lib/rmodbus/tcp_server.rb
CHANGED
@@ -25,8 +25,8 @@ module ModBus
|
|
25
25
|
# srv.start
|
26
26
|
class TCPServer < GServer
|
27
27
|
include Debug
|
28
|
-
include Server
|
29
|
-
|
28
|
+
include Server
|
29
|
+
|
30
30
|
# Init server
|
31
31
|
# @param [Integer] port listen port
|
32
32
|
# @param [Integer] uid slave device
|
@@ -35,6 +35,9 @@ module ModBus
|
|
35
35
|
# @option opts [Float, Integer] :max_connection max of TCP connection with server default 4
|
36
36
|
def initialize(port = 502, uid = 1, opts = {})
|
37
37
|
@uid = uid
|
38
|
+
|
39
|
+
warn "[WARNING] Please, use UID = 255. It will be fixed in the next release." if @uid != 0xff
|
40
|
+
|
38
41
|
opts[:host] = DEFAULT_HOST unless opts[:host]
|
39
42
|
opts[:max_connection] = 4 unless opts[:max_connection]
|
40
43
|
super(port, host = opts[:host], maxConnection = opts[:max_connection])
|
@@ -42,22 +45,28 @@ module ModBus
|
|
42
45
|
|
43
46
|
# Serve requests
|
44
47
|
# @param [TCPSocket] io socket
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def serve(io)
|
49
|
+
while not stopped?
|
50
|
+
header = io.read(7)
|
51
|
+
tx_id = header[0,2]
|
52
|
+
proto_id = header[2,2]
|
53
|
+
len = header[4,2].unpack('n')[0]
|
54
|
+
unit_id = header.getbyte(6)
|
55
|
+
if proto_id == "\x00\x00"
|
51
56
|
req = io.read(len - 1)
|
52
|
-
|
57
|
+
if unit_id == @uid || unit_id == 0
|
58
|
+
log "Server RX (#{req.size} bytes): #{logging_bytes(req)}"
|
53
59
|
|
54
|
-
|
60
|
+
pdu = exec_req(req, @coils, @discrete_inputs, @holding_registers, @input_registers)
|
55
61
|
|
56
|
-
|
57
|
-
|
58
|
-
|
62
|
+
resp = tx_id + "\0\0" + (pdu.size + 1).to_word + @uid.chr + pdu
|
63
|
+
log "Server TX (#{resp.size} bytes): #{logging_bytes(resp)}"
|
64
|
+
io.write resp
|
65
|
+
else
|
66
|
+
log "Ignored server RX (invalid unit ID #{unit_id}, #{req.size} bytes): #{logging_bytes(req)}"
|
67
|
+
end
|
59
68
|
end
|
60
|
-
|
61
|
-
|
69
|
+
end
|
70
|
+
end
|
62
71
|
end
|
63
72
|
end
|
data/lib/rmodbus/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# RModBus - free implementation of ModBus protocol on Ruby.
|
2
2
|
#
|
3
|
-
# Copyright (C) 2012 Timin Aleksey
|
3
|
+
# Copyright (C) 2012-2015 Timin Aleksey
|
4
4
|
#
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
@@ -13,5 +13,5 @@
|
|
13
13
|
# GNU General Public License for more details.
|
14
14
|
module ModBus
|
15
15
|
# Package version
|
16
|
-
VERSION = '1.2.
|
16
|
+
VERSION = '1.2.7'
|
17
17
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -41,23 +41,23 @@ describe ModBus::Client do
|
|
41
41
|
it 'should common for all slaves :debug flag' do
|
42
42
|
@cl.debug = true
|
43
43
|
@cl.with_slave(1) do |slave_1|
|
44
|
-
slave_1.debug.should
|
44
|
+
slave_1.debug.should be_truthy
|
45
45
|
end
|
46
46
|
@cl.with_slave(2) do |slave_2|
|
47
47
|
slave_2.debug = false
|
48
|
-
slave_2.debug.should
|
48
|
+
slave_2.debug.should be_falsey
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'should common for all slaves :raise_exception_on_mismatch flag' do
|
53
53
|
@cl.raise_exception_on_mismatch = true
|
54
54
|
@cl.with_slave(1) do |slave_1|
|
55
|
-
slave_1.raise_exception_on_mismatch.should
|
55
|
+
slave_1.raise_exception_on_mismatch.should be_truthy
|
56
56
|
end
|
57
57
|
|
58
58
|
@cl.with_slave(2) do |slave_2|
|
59
59
|
slave_2.raise_exception_on_mismatch = false
|
60
|
-
slave_2.raise_exception_on_mismatch.should
|
60
|
+
slave_2.raise_exception_on_mismatch.should be_falsey
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
data/spec/logging_spec.rb
CHANGED
@@ -4,11 +4,11 @@ require 'rmodbus'
|
|
4
4
|
describe ModBus::TCPClient do
|
5
5
|
before(:each) do
|
6
6
|
@uid = 1
|
7
|
-
@sock =
|
7
|
+
@sock = double('Socket')
|
8
8
|
@adu = "\000\001\000\000\000\001\001"
|
9
9
|
|
10
10
|
TCPSocket.should_receive(:new).with('127.0.0.1', 1502).and_return(@sock)
|
11
|
-
@sock.stub
|
11
|
+
@sock.stub(:read).with(0).and_return('')
|
12
12
|
|
13
13
|
@slave = ModBus::TCPClient.new('127.0.0.1', 1502).with_slave(@uid)
|
14
14
|
@slave.debug = true
|
@@ -55,14 +55,19 @@ begin
|
|
55
55
|
require "serialport"
|
56
56
|
describe ModBus::RTUClient do
|
57
57
|
before do
|
58
|
-
@sp =
|
59
|
-
|
60
|
-
|
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)
|
61
64
|
@sp.should_receive(:flow_control=).with(SerialPort::NONE)
|
62
|
-
@sp.stub
|
63
|
-
|
65
|
+
@sp.stub(:read_timeout=)
|
66
|
+
@sp.stub(:flush_input)
|
67
|
+
|
64
68
|
@slave = ModBus::RTUClient.new("/dev/port1", 9600, :data_bits => 7, :stop_bits => 2, :parity => SerialPort::ODD).with_slave(1)
|
65
69
|
@slave.read_retries = 0
|
70
|
+
|
66
71
|
end
|
67
72
|
|
68
73
|
it 'should log rec\send bytes' do
|
data/spec/proxy_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'rmodbus'
|
|
3
3
|
|
4
4
|
describe Array do
|
5
5
|
before do
|
6
|
-
@slave =
|
6
|
+
@slave = double('ModBus Slave')
|
7
7
|
@coil_proxy = ModBus::ReadWriteProxy.new(@slave, :coil)
|
8
8
|
@discrete_input_proxy = ModBus::ReadOnlyProxy.new(@slave, :discrete_input)
|
9
9
|
@holding_register_proxy = ModBus::ReadWriteProxy.new(@slave, :holding_register)
|
data/spec/rtu_client_spec.rb
CHANGED
@@ -3,11 +3,15 @@ require 'rmodbus'
|
|
3
3
|
|
4
4
|
describe ModBus::RTUClient do
|
5
5
|
before do
|
6
|
-
@sp =
|
6
|
+
@sp = double('Serial port')
|
7
|
+
|
7
8
|
SerialPort.should_receive(:new).with("/dev/port1", 9600, 8, 1, 0).and_return(@sp)
|
8
|
-
|
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)
|
9
13
|
@sp.should_receive(:flow_control=).with(SerialPort::NONE)
|
10
|
-
@sp.stub
|
14
|
+
@sp.stub(:flush_input)
|
11
15
|
|
12
16
|
@cl = ModBus::RTUClient.new("/dev/port1", 9600, :data_bits => 8, :stop_bits => 1, :parity => SerialPort::NONE)
|
13
17
|
@slave = @cl.with_slave(1)
|
data/spec/rtu_server_spec.rb
CHANGED
@@ -3,9 +3,9 @@ require 'rmodbus'
|
|
3
3
|
|
4
4
|
describe ModBus::RTUServer do
|
5
5
|
before do
|
6
|
-
@sp =
|
6
|
+
@sp = double('SerialPort')
|
7
7
|
SerialPort.should_receive(:new).with('/dev/ttyS0', 4800, 7, 2, SerialPort::NONE).and_return(@sp)
|
8
|
-
@sp.stub
|
8
|
+
@sp.stub(:read_timeout=)
|
9
9
|
@sp.should_receive(:flow_control=).with(SerialPort::NONE)
|
10
10
|
|
11
11
|
@server = ModBus::RTUServer.new('/dev/ttyS0', 4800, 1, :data_bits => 7, :stop_bits => 2)
|
@@ -4,10 +4,10 @@ require 'rmodbus'
|
|
4
4
|
describe ModBus::RTUViaTCPClient do
|
5
5
|
describe "method 'query'" do
|
6
6
|
before do
|
7
|
-
@sock =
|
7
|
+
@sock = double('Socket')
|
8
8
|
TCPSocket.should_receive(:new).with("127.0.0.1", 10002).and_return(@sock)
|
9
|
-
@sock.stub
|
10
|
-
@sock.stub
|
9
|
+
@sock.stub(:read_timeout=)
|
10
|
+
@sock.stub(:flush)
|
11
11
|
|
12
12
|
@cl = ModBus::RTUViaTCPClient.new("127.0.0.1")
|
13
13
|
@slave = @cl.with_slave(1)
|
data/spec/slave_spec.rb
CHANGED
data/spec/tcp_client_spec.rb
CHANGED
@@ -5,11 +5,11 @@ describe ModBus::TCPClient do
|
|
5
5
|
describe "method 'query'" do
|
6
6
|
before(:each) do
|
7
7
|
@uid = 1
|
8
|
-
@sock =
|
8
|
+
@sock = double('Socket')
|
9
9
|
@adu = "\000\001\000\000\000\001\001"
|
10
10
|
|
11
11
|
TCPSocket.should_receive(:new).with('127.0.0.1', 1502).and_return(@sock)
|
12
|
-
@sock.stub
|
12
|
+
@sock.stub(:read).with(0).and_return('')
|
13
13
|
@cl = ModBus::TCPClient.new('127.0.0.1', 1502)
|
14
14
|
@slave = @cl.with_slave(@uid)
|
15
15
|
end
|
@@ -33,8 +33,8 @@ describe ModBus::TCPClient do
|
|
33
33
|
it 'should throw timeout exception if do not get own transaction' do
|
34
34
|
@slave.read_retries = 2
|
35
35
|
@adu[0,2] = @slave.transaction.next.to_word
|
36
|
-
@sock.should_receive(:write).
|
37
|
-
@sock.should_receive(:read).
|
36
|
+
@sock.should_receive(:write).at_least(1).times.with(/\.*/)
|
37
|
+
@sock.should_receive(:read).at_least(1).times.with(7).and_return("\000\x3\000\000\000\001" + @uid.chr)
|
38
38
|
|
39
39
|
expect{ @slave.query('') }.to raise_error(ModBus::Errors::ModBusTimeout, "Timed out during read attempt")
|
40
40
|
end
|
data/spec/tcp_server_spec.rb
CHANGED
@@ -3,23 +3,28 @@ require "rmodbus"
|
|
3
3
|
|
4
4
|
describe ModBus::TCPServer do
|
5
5
|
before :all do
|
6
|
-
|
6
|
+
unit_ids = (1..247).to_a.shuffle
|
7
|
+
valid_unit_id = unit_ids.first
|
8
|
+
@invalid_unit_id = unit_ids.last
|
9
|
+
@server = ModBus::TCPServer.new(8502, valid_unit_id)
|
7
10
|
@server.coils = [1,0,1,1]
|
8
11
|
@server.discrete_inputs = [1,1,0,0]
|
9
12
|
@server.holding_registers = [1,2,3,4]
|
10
13
|
@server.input_registers = [1,2,3,4]
|
11
14
|
@server.start
|
12
15
|
@cl = ModBus::TCPClient.new('127.0.0.1', 8502)
|
13
|
-
@
|
14
|
-
@slave
|
16
|
+
@cl.read_retries = 1
|
17
|
+
@slave = @cl.with_slave(valid_unit_id)
|
15
18
|
end
|
16
19
|
|
17
|
-
it "should
|
18
|
-
@cl.with_slave(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
it "should succeed if UID is broadcast" do
|
21
|
+
@cl.with_slave(0).read_coils(1,3)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should fail if UID is mismatched" do
|
25
|
+
lambda { @cl.with_slave(@invalid_unit_id).read_coils(1,3) }.should raise_exception(
|
26
|
+
ModBus::Errors::ModBusTimeout
|
27
|
+
)
|
23
28
|
end
|
24
29
|
|
25
30
|
it "should send exception if function not supported" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rmodbus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- A.Timin, J. Sanders, K. Reynolds
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2.
|
47
|
+
version: '2.99'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '2.
|
54
|
+
version: '2.99'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: guard-rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|