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
@@ -0,0 +1,55 @@
|
|
1
|
+
module ModBus
|
2
|
+
# TCP slave implementation
|
3
|
+
# @example
|
4
|
+
# TCP.connect('127.0.0.1', 10002) do |cl|
|
5
|
+
# cl.with_slave(uid) do |slave|
|
6
|
+
# slave.holding_registers[0..100]
|
7
|
+
# end
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# @see TCP#open_tcp_connection
|
11
|
+
# @see Client#with_slave
|
12
|
+
# @see Slave
|
13
|
+
class TCPSlave < Client::Slave
|
14
|
+
attr_reader :transaction
|
15
|
+
|
16
|
+
# @see Slave::initialize
|
17
|
+
def initialize(uid, io)
|
18
|
+
@transaction = 0
|
19
|
+
super(uid, io)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
# overide method for RTU over TCP implamentaion
|
24
|
+
# @see Slave#query
|
25
|
+
def send_pdu(pdu)
|
26
|
+
@transaction = 0 if @transaction.next > 65535
|
27
|
+
@transaction += 1
|
28
|
+
msg = @transaction.to_word + "\0\0" + (pdu.size + 1).to_word + @uid.chr + pdu
|
29
|
+
@io.write msg
|
30
|
+
|
31
|
+
log "Tx (#{msg.size} bytes): " + logging_bytes(msg)
|
32
|
+
end
|
33
|
+
|
34
|
+
# overide method for RTU over TCP implamentaion
|
35
|
+
# @see Slave#query
|
36
|
+
def read_pdu
|
37
|
+
loop do
|
38
|
+
header = @io.read(7)
|
39
|
+
if header
|
40
|
+
trn = header[0,2].unpack('n')[0]
|
41
|
+
len = header[4,2].unpack('n')[0]
|
42
|
+
msg = @io.read(len-1)
|
43
|
+
|
44
|
+
log "Rx (#{(header + msg).size} bytes): " + logging_bytes(header + msg)
|
45
|
+
|
46
|
+
if trn == @transaction
|
47
|
+
return msg
|
48
|
+
else
|
49
|
+
log "Transaction number mismatch. A packet is ignored."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,88 @@
|
|
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
|
@@ -0,0 +1,120 @@
|
|
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
ADDED
@@ -0,0 +1,52 @@
|
|
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
|
+
|
@@ -0,0 +1,89 @@
|
|
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
ADDED
@@ -0,0 +1,74 @@
|
|
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
|
+
|