rmodbus-ccutrer 2.0.0 → 2.1.1
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 +14 -7
- data/README.md +8 -8
- data/examples/perfomance_rtu.rb +55 -56
- data/examples/perfomance_rtu_via_tcp.rb +54 -55
- data/examples/perfomance_tcp.rb +54 -55
- data/examples/simple_xpca_gateway.rb +85 -0
- data/examples/use_rtu_via_tcp_modbus.rb +14 -11
- data/examples/use_tcp_modbus.rb +14 -11
- data/lib/rmodbus/client/slave.rb +58 -70
- data/lib/rmodbus/client.rb +13 -10
- data/lib/rmodbus/debug.rb +10 -6
- data/lib/rmodbus/errors.rb +26 -2
- data/lib/rmodbus/ext.rb +72 -51
- data/lib/rmodbus/options.rb +4 -1
- data/lib/rmodbus/proxy.rb +14 -9
- data/lib/rmodbus/rtu.rb +38 -32
- data/lib/rmodbus/rtu_client.rb +5 -2
- data/lib/rmodbus/rtu_server.rb +9 -7
- data/lib/rmodbus/rtu_slave.rb +6 -2
- data/lib/rmodbus/rtu_via_tcp_server.rb +7 -5
- data/lib/rmodbus/server/slave.rb +4 -2
- data/lib/rmodbus/server.rb +97 -73
- data/lib/rmodbus/sp.rb +10 -12
- data/lib/rmodbus/tcp.rb +5 -2
- data/lib/rmodbus/tcp_client.rb +3 -0
- data/lib/rmodbus/tcp_server.rb +28 -26
- data/lib/rmodbus/tcp_slave.rb +17 -16
- data/lib/rmodbus/version.rb +3 -1
- data/lib/rmodbus.rb +20 -18
- metadata +50 -49
- data/Rakefile +0 -29
- data/examples/simple-xpca-gateway.rb +0 -84
- data/spec/client_spec.rb +0 -88
- data/spec/exception_spec.rb +0 -120
- data/spec/ext_spec.rb +0 -52
- data/spec/logging_spec.rb +0 -89
- data/spec/proxy_spec.rb +0 -74
- data/spec/read_rtu_response_spec.rb +0 -92
- data/spec/response_mismach_spec.rb +0 -163
- data/spec/rtu_client_spec.rb +0 -86
- data/spec/rtu_server_spec.rb +0 -31
- data/spec/rtu_via_tcp_client_spec.rb +0 -76
- data/spec/rtu_via_tcp_server_spec.rb +0 -89
- data/spec/slave_spec.rb +0 -55
- data/spec/spec_helper.rb +0 -54
- data/spec/tcp_client_spec.rb +0 -88
- data/spec/tcp_server_spec.rb +0 -158
    
        data/spec/rtu_server_spec.rb
    DELETED
    
    | @@ -1,31 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: ascii
         | 
| 2 | 
            -
            require 'rmodbus'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe ModBus::RTUServer do
         | 
| 5 | 
            -
              before do
         | 
| 6 | 
            -
                @sp = double('SerialPort')
         | 
| 7 | 
            -
                SerialPort.should_receive(:new).with('/dev/ttyS0', 4800, 7, 2, SerialPort::NONE).and_return(@sp)
         | 
| 8 | 
            -
                @sp.stub(:read_timeout=)
         | 
| 9 | 
            -
                @sp.should_receive(:flow_control=).with(SerialPort::NONE)
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                @server = ModBus::RTUServer.new('/dev/ttyS0', 4800, :data_bits => 7, :stop_bits => 2)
         | 
| 12 | 
            -
                @slave = @server.with_slave(1)
         | 
| 13 | 
            -
                @slave.coils = [1,0,1,1]
         | 
| 14 | 
            -
                @slave.discrete_inputs = [1,1,0,0]
         | 
| 15 | 
            -
                @slave.holding_registers = [1,2,3,4]
         | 
| 16 | 
            -
                @slave.input_registers = [1,2,3,4]
         | 
| 17 | 
            -
              end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              it "should be valid initialized " do
         | 
| 20 | 
            -
                @slave.coils.should == [1,0,1,1]
         | 
| 21 | 
            -
                @slave.discrete_inputs.should == [1,1,0,0]
         | 
| 22 | 
            -
                @slave.holding_registers.should == [1,2,3,4]
         | 
| 23 | 
            -
                @slave.input_registers.should == [1,2,3,4]
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                @server.port.should == '/dev/ttyS0'
         | 
| 26 | 
            -
                @server.baud.should == 4800
         | 
| 27 | 
            -
                @server.data_bits.should == 7
         | 
| 28 | 
            -
                @server.stop_bits.should == 2
         | 
| 29 | 
            -
                @server.parity.should == SerialPort::NONE
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
            end
         | 
| @@ -1,76 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: ascii
         | 
| 2 | 
            -
            require 'rmodbus'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe ModBus::RTUClient do
         | 
| 5 | 
            -
              describe "method 'query'" do
         | 
| 6 | 
            -
                before do
         | 
| 7 | 
            -
                  @sock = double('Socket')
         | 
| 8 | 
            -
                  Socket.should_receive(:tcp).with("127.0.0.1", 10002, nil, nil, hash_including(:connect_timeout)).and_return(@sock)
         | 
| 9 | 
            -
                  @sock.stub(:read_timeout=)
         | 
| 10 | 
            -
                  @sock.stub(:flush)
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  @cl = ModBus::RTUClient.new("127.0.0.1")
         | 
| 13 | 
            -
                  @slave = @cl.with_slave(1)
         | 
| 14 | 
            -
                  @slave.read_retries = 1
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                it "should ignore frame with other UID" do
         | 
| 18 | 
            -
                  request = "\x10\x0\x1\x0\x1\x2\xff\xff"
         | 
| 19 | 
            -
                  @sock.should_receive(:write).with("\1#{request}\xA6\x31")
         | 
| 20 | 
            -
                  @sock.should_receive(:read).with(2).and_return("\x2\x10")
         | 
| 21 | 
            -
                  @sock.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
         | 
| 22 | 
            -
                  lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                it "should ignored frame with incorrect CRC" do
         | 
| 26 | 
            -
                  request = "\x10\x0\x1\x0\x1\x2\xff\xff"
         | 
| 27 | 
            -
                  @sock.should_receive(:write).with("\1#{request}\xA6\x31")
         | 
| 28 | 
            -
                  @sock.should_receive(:read).with(2).and_return("\x2\x10")
         | 
| 29 | 
            -
                  @sock.should_receive(:read).with(6).and_return("\x0\x1\x0\x1\x1C\x08")
         | 
| 30 | 
            -
                  lambda {@slave.query(request)}.should raise_error(ModBus::Errors::ModBusTimeout)
         | 
| 31 | 
            -
                end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                it "should return value of registers"do
         | 
| 34 | 
            -
                  request = "\x3\x0\x1\x0\x1"
         | 
| 35 | 
            -
                  @sock.should_receive(:write).with("\1#{request}\xd5\xca")
         | 
| 36 | 
            -
                  @sock.should_receive(:read).with(2).and_return("\x1\x3")
         | 
| 37 | 
            -
                  @sock.should_receive(:read).with(1).and_return("\x2")
         | 
| 38 | 
            -
                  @sock.should_receive(:read).with(4).and_return("\xff\xff\xb9\xf4")
         | 
| 39 | 
            -
                  @slave.query(request).should == "\xff\xff"
         | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                it 'should sugar connect method' do
         | 
| 43 | 
            -
                  ipaddr, port = '127.0.0.1', 502
         | 
| 44 | 
            -
                  Socket.should_receive(:tcp).with(ipaddr, port, nil, nil, hash_including(:connect_timeout)).and_return(@sock)
         | 
| 45 | 
            -
                  @sock.should_receive(:closed?).and_return(false)
         | 
| 46 | 
            -
                  @sock.should_receive(:close)
         | 
| 47 | 
            -
                  ModBus::RTUClient.connect(ipaddr, port) do |cl|
         | 
| 48 | 
            -
                    cl.ipaddr.should == ipaddr
         | 
| 49 | 
            -
                    cl.port.should == port
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
                end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                it 'should have closed? method' do
         | 
| 54 | 
            -
                  @sock.should_receive(:closed?).and_return(false)
         | 
| 55 | 
            -
                  @cl.closed?.should == false
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                  @sock.should_receive(:closed?).and_return(false)
         | 
| 58 | 
            -
                  @sock.should_receive(:close)
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                  @cl.close
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                  @sock.should_receive(:closed?).and_return(true)
         | 
| 63 | 
            -
                  @cl.closed?.should == true
         | 
| 64 | 
            -
                end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                it 'should give slave object in block' do
         | 
| 67 | 
            -
                  @cl.with_slave(1) do |slave|
         | 
| 68 | 
            -
                    slave.uid = 1
         | 
| 69 | 
            -
                  end
         | 
| 70 | 
            -
                end
         | 
| 71 | 
            -
              end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
              it "should tune connection timeout" do
         | 
| 74 | 
            -
                lambda { ModBus::RTUClient.new('81.123.231.11', 1999, :connect_timeout => 0.001) }.should raise_error(ModBus::Errors::ModBusTimeout)
         | 
| 75 | 
            -
              end
         | 
| 76 | 
            -
            end
         | 
| @@ -1,89 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: ascii
         | 
| 2 | 
            -
            require "rmodbus"
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe ModBus::RTUViaTCPServer do
         | 
| 5 | 
            -
              before :all do
         | 
| 6 | 
            -
                @port = 8502
         | 
| 7 | 
            -
                begin
         | 
| 8 | 
            -
                  @server = ModBus::RTUViaTCPServer.new(@port)
         | 
| 9 | 
            -
                  @server_slave = @server.with_slave(1)
         | 
| 10 | 
            -
                  @server_slave.coils = [1,0,1,1]
         | 
| 11 | 
            -
                  @server_slave.discrete_inputs = [1,1,0,0]
         | 
| 12 | 
            -
                  @server_slave.holding_registers = [1,2,3,4]
         | 
| 13 | 
            -
                  @server_slave.input_registers = [1,2,3,4]
         | 
| 14 | 
            -
                  @server.promiscuous = true
         | 
| 15 | 
            -
                  @server.start
         | 
| 16 | 
            -
                rescue Errno::EADDRINUSE
         | 
| 17 | 
            -
                  @port += 1
         | 
| 18 | 
            -
                  retry
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
                @cl = ModBus::RTUClient.new('127.0.0.1', @port)
         | 
| 21 | 
            -
                @cl.read_retries = 1
         | 
| 22 | 
            -
                @slave = @cl.with_slave(1)
         | 
| 23 | 
            -
                # pretend this is a serialport and we're just someone else on the same bus
         | 
| 24 | 
            -
                @io = @cl.instance_variable_get(:@io)
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
              before do
         | 
| 28 | 
            -
                @server.debug = false
         | 
| 29 | 
            -
              end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
              it "should have options :host" do
         | 
| 32 | 
            -
                host = '192.168.0.1'
         | 
| 33 | 
            -
                srv = ModBus::RTUViaTCPServer.new(1010, :host => '192.168.0.1')
         | 
| 34 | 
            -
                srv.host.should eql(host)
         | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
              it "should have options :max_connection" do
         | 
| 38 | 
            -
                max_conn = 5
         | 
| 39 | 
            -
                srv = ModBus::RTUViaTCPServer.new(1010, :max_connection => 5)
         | 
| 40 | 
            -
                srv.maxConnections.should eql(max_conn)
         | 
| 41 | 
            -
              end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
              it "should properly ignore responses from other slaves" do
         | 
| 44 | 
            -
                request = "\x10\x03\x0\x1\x0\x1\xd6\x8b"
         | 
| 45 | 
            -
                response = "\x10\x83\x1\xd0\xf5"
         | 
| 46 | 
            -
                @server.debug = true
         | 
| 47 | 
            -
                @server.should receive(:log).ordered.with("Server RX (8 bytes): [10][03][00][01][00][01][d6][8b]")
         | 
| 48 | 
            -
                @server.should receive(:log).ordered.with("Server RX function 3 to 16: {:quant=>1, :addr=>1}")
         | 
| 49 | 
            -
                @server.should receive(:log).ordered.with("Server RX (5 bytes): [10][83][01][d0][f5]")
         | 
| 50 | 
            -
                @server.should receive(:log).ordered.with("Server RX response 3 from 16: {:err=>1}")
         | 
| 51 | 
            -
                @server.should receive(:log).ordered.with("Server RX (8 bytes): [01][01][00][00][00][01][fd][ca]")
         | 
| 52 | 
            -
                @server.should receive(:log).ordered.with("Server RX function 1 to 1: {:quant=>1, :addr=>0}")
         | 
| 53 | 
            -
                @server.should receive(:log).ordered.with("Server TX (6 bytes): [01][01][01][01][90][48]")
         | 
| 54 | 
            -
                @io.write(request)
         | 
| 55 | 
            -
                @io.write(response)
         | 
| 56 | 
            -
                # just to prove the server can still handle subsequent requests
         | 
| 57 | 
            -
                @slave.read_coils(0, 1).should == [1]
         | 
| 58 | 
            -
              end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
              it "should properly ignore functions from other slaves that it doesn't understand" do
         | 
| 61 | 
            -
                request = "\x10\x41\x0\x1\x0\x1\x0\x5\x0\x1\xb1\x00"
         | 
| 62 | 
            -
                response = "\x10\xc1\x1\xe0\x55"
         | 
| 63 | 
            -
                @io.write(request)
         | 
| 64 | 
            -
                @io.write(response)
         | 
| 65 | 
            -
                # just to prove the server can still handle subsequent requests
         | 
| 66 | 
            -
                @slave.read_coils(0, 1).should == [1]
         | 
| 67 | 
            -
              end
         | 
| 68 | 
            -
             | 
| 69 | 
            -
              it "should properly ignore utter garbage on the line from starting up halfway through a conversation" do
         | 
| 70 | 
            -
                response = "garbage" * 50 + "\x1\x55\xe0"
         | 
| 71 | 
            -
                @io.write(response)
         | 
| 72 | 
            -
                # just to prove the server can still handle subsequent requests
         | 
| 73 | 
            -
                @slave.read_coils(0, 1).should == [1]
         | 
| 74 | 
            -
              end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
              it "should send exception if request is malformed" do
         | 
| 77 | 
            -
                lambda { @slave.query("\x01\x01") }.should raise_exception(
         | 
| 78 | 
            -
                                                               ModBus::Errors::ModBusTimeout)
         | 
| 79 | 
            -
              end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
              after :all do
         | 
| 82 | 
            -
                @cl.close unless @cl.closed?
         | 
| 83 | 
            -
                @server.stop unless @server.stopped?
         | 
| 84 | 
            -
                while GServer.in_service?(@port)
         | 
| 85 | 
            -
                  sleep(0.01)
         | 
| 86 | 
            -
                end
         | 
| 87 | 
            -
                @server.stop
         | 
| 88 | 
            -
              end
         | 
| 89 | 
            -
            end
         | 
    
        data/spec/slave_spec.rb
    DELETED
    
    | @@ -1,55 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: ascii
         | 
| 2 | 
            -
            require 'rmodbus'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe ModBus::Client::Slave do
         | 
| 5 | 
            -
              before do
         | 
| 6 | 
            -
                @slave = ModBus::Client.new.with_slave(1)
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                @slave.stub(:query).and_return('')
         | 
| 9 | 
            -
              end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
              it "should support function 'read coils'" do
         | 
| 12 | 
            -
                @slave.should_receive(:query).with("\x1\x0\x13\x0\x13").and_return("\xcd\x6b\x5")    
         | 
| 13 | 
            -
                @slave.read_coils(0x13,0x13).should == [1,0,1,1, 0,0,1,1, 1,1,0,1, 0,1,1,0,  1,0,1]
         | 
| 14 | 
            -
              end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              it "should support function 'read discrete inputs'" do
         | 
| 17 | 
            -
                @slave.should_receive(:query).with("\x2\x0\xc4\x0\x16").and_return("\xac\xdb\x35")    
         | 
| 18 | 
            -
                @slave.read_discrete_inputs(0xc4,0x16).should == [0,0,1,1, 0,1,0,1, 1,1,0,1, 1,0,1,1, 1,0,1,0, 1,1]
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
              it "should support function 'read holding registers'" do
         | 
| 22 | 
            -
                @slave.should_receive(:query).with("\x3\x0\x6b\x0\x3").and_return("\x2\x2b\x0\x0\x0\x64")    
         | 
| 23 | 
            -
                @slave.read_holding_registers(0x6b,0x3).should == [0x022b, 0x0000, 0x0064]
         | 
| 24 | 
            -
              end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
              it "should support function 'read input registers'" do
         | 
| 27 | 
            -
                @slave.should_receive(:query).with("\x4\x0\x8\x0\x1").and_return("\x0\xa")    
         | 
| 28 | 
            -
                @slave.read_input_registers(0x8,0x1).should == [0x000a]
         | 
| 29 | 
            -
              end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
              it "should support function 'write single coil'" do
         | 
| 32 | 
            -
                @slave.should_receive(:query).with("\x5\x0\xac\xff\x0").and_return("\xac\xff\x00")    
         | 
| 33 | 
            -
                @slave.write_single_coil(0xac,0x1).should == @slave
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
              it "should support function 'write single register'" do
         | 
| 37 | 
            -
                @slave.should_receive(:query).with("\x6\x0\x1\x0\x3").and_return("\x1\x0\x3")    
         | 
| 38 | 
            -
                @slave.write_single_register(0x1,0x3).should == @slave
         | 
| 39 | 
            -
              end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
              it "should support function 'write multiple coils'" do
         | 
| 42 | 
            -
                @slave.should_receive(:query).with("\xf\x0\x13\x0\xa\x2\xcd\x1").and_return("\x13\x0\xa")    
         | 
| 43 | 
            -
                @slave.write_multiple_coils(0x13,[1,0,1,1, 0,0,1,1, 1,0]).should == @slave
         | 
| 44 | 
            -
              end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
              it "should support function 'write multiple registers'" do
         | 
| 47 | 
            -
                @slave.should_receive(:query).with("\x10\x0\x1\x0\x3\x6\x0\xa\x1\x2\xf\xf").and_return("\x1\x0\x3")    
         | 
| 48 | 
            -
                @slave.write_multiple_registers(0x1,[0x000a,0x0102, 0xf0f]).should == @slave
         | 
| 49 | 
            -
              end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
              it "should support function 'mask write register'" do
         | 
| 52 | 
            -
                @slave.should_receive(:query).with("\x16\x0\x4\x0\xf2\x0\2").and_return("\x4\x0\xf2\x0\x2")
         | 
| 53 | 
            -
                @slave.mask_write_register(0x4, 0xf2, 0x2).should == @slave
         | 
| 54 | 
            -
              end
         | 
| 55 | 
            -
            end
         | 
    
        data/spec/spec_helper.rb
    DELETED
    
    | @@ -1,54 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: ascii
         | 
| 2 | 
            -
            require "rmodbus"
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            class RaiseResponseMismatch
         | 
| 5 | 
            -
              def initialize(message, request, response)
         | 
| 6 | 
            -
                @expected_message, @expected_request, @expected_response = message, request, response
         | 
| 7 | 
            -
              end
         | 
| 8 | 
            -
             | 
| 9 | 
            -
              def matches?(given_block)
         | 
| 10 | 
            -
                begin
         | 
| 11 | 
            -
                  given_block.call
         | 
| 12 | 
            -
                rescue ModBus::Errors::ResponseMismatch => e
         | 
| 13 | 
            -
                  @actual_message = e.message
         | 
| 14 | 
            -
                  @actual_request = e.request
         | 
| 15 | 
            -
                  @actual_response = e.response
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  @with_expected_message = verify_message
         | 
| 18 | 
            -
                  @with_expected_request = @expected_request == @actual_request
         | 
| 19 | 
            -
                  @with_expected_response = @expected_response == @actual_response
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
                @with_expected_message & @with_expected_request & @with_expected_response
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
              def failure_message
         | 
| 25 | 
            -
                unless @with_expected_message
         | 
| 26 | 
            -
                  return "Expected message '#{@expected_message}', got '#{@actual_message}'"
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                unless @with_expected_request
         | 
| 30 | 
            -
                  return "Expected request #{logging_bytes @expected_request}, got #{logging_bytes @actual_request}"
         | 
| 31 | 
            -
                end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                unless @with_expected_response
         | 
| 34 | 
            -
                  return "Expected response #{logging_bytes @expected_response}, got #{logging_bytes @actual_response}"
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
              end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
              def verify_message
         | 
| 39 | 
            -
                case  @expected_message
         | 
| 40 | 
            -
                  when nil
         | 
| 41 | 
            -
                    true
         | 
| 42 | 
            -
                  when Regexp
         | 
| 43 | 
            -
                     @expected_message =~ @actual_message
         | 
| 44 | 
            -
                  else
         | 
| 45 | 
            -
                     @expected_message == @actual_message
         | 
| 46 | 
            -
                end
         | 
| 47 | 
            -
              end
         | 
| 48 | 
            -
            end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
            module RaiseResponseMatcher
         | 
| 51 | 
            -
              def raise_response_mismatch(message, request, response)
         | 
| 52 | 
            -
                RaiseResponseMismatch.new(message, request, response)
         | 
| 53 | 
            -
              end
         | 
| 54 | 
            -
            end
         | 
    
        data/spec/tcp_client_spec.rb
    DELETED
    
    | @@ -1,88 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: ascii
         | 
| 2 | 
            -
            require 'rmodbus'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe ModBus::TCPClient do
         | 
| 5 | 
            -
              describe "method 'query'" do    
         | 
| 6 | 
            -
                before(:each) do
         | 
| 7 | 
            -
                  @uid = 1
         | 
| 8 | 
            -
                  @sock = double('Socket')
         | 
| 9 | 
            -
                  @adu = "\000\001\000\000\000\001\001"
         | 
| 10 | 
            -
              
         | 
| 11 | 
            -
                  Socket.should_receive(:tcp).with('127.0.0.1', 1502, nil, nil, hash_including(:connect_timeout)).and_return(@sock)
         | 
| 12 | 
            -
                  @sock.stub(:read).with(0).and_return('')
         | 
| 13 | 
            -
                  @cl = ModBus::TCPClient.new('127.0.0.1', 1502)
         | 
| 14 | 
            -
                  @slave = @cl.with_slave(@uid)
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
                
         | 
| 17 | 
            -
                it 'should send valid MBAP Header' do
         | 
| 18 | 
            -
                  @adu[0,2] = @slave.transaction.next.to_word
         | 
| 19 | 
            -
                  @sock.should_receive(:write).with(@adu)
         | 
| 20 | 
            -
                  @sock.should_receive(:read).with(7).and_return(@adu)
         | 
| 21 | 
            -
                  @slave.query('').should == nil
         | 
| 22 | 
            -
                end
         | 
| 23 | 
            -
                
         | 
| 24 | 
            -
                it 'should not throw exception and white next packet if get other transaction' do
         | 
| 25 | 
            -
                  @adu[0,2] = @slave.transaction.next.to_word
         | 
| 26 | 
            -
                  @sock.should_receive(:write).with(@adu)
         | 
| 27 | 
            -
                  @sock.should_receive(:read).with(7).and_return("\000\002\000\000\000\001" + @uid.chr)
         | 
| 28 | 
            -
                  @sock.should_receive(:read).with(7).and_return("\000\001\000\000\000\001" + @uid.chr)
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                  expect{ @slave.query('') }.to_not raise_error
         | 
| 31 | 
            -
                end
         | 
| 32 | 
            -
                
         | 
| 33 | 
            -
                it 'should throw timeout exception if do not get own transaction' do
         | 
| 34 | 
            -
                  @slave.read_retries = 2
         | 
| 35 | 
            -
                  @adu[0,2] = @slave.transaction.next.to_word
         | 
| 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 | 
            -
             | 
| 39 | 
            -
                  expect{ @slave.query('') }.to raise_error(ModBus::Errors::ModBusTimeout, "Timed out during read attempt")
         | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                
         | 
| 43 | 
            -
                it 'should return only data from PDU' do
         | 
| 44 | 
            -
                  request = "\x3\x0\x6b\x0\x3"
         | 
| 45 | 
            -
                  response = "\x3\x6\x2\x2b\x0\x0\x0\x64"
         | 
| 46 | 
            -
                  @adu = @slave.transaction.next.to_word + "\x0\x0\x0\x9" + @uid.chr + request
         | 
| 47 | 
            -
                  @sock.should_receive(:write).with(@adu[0,4] + "\0\6" + @uid.chr + request)
         | 
| 48 | 
            -
                  @sock.should_receive(:read).with(7).and_return(@adu[0,7])
         | 
| 49 | 
            -
                  @sock.should_receive(:read).with(8).and_return(response)
         | 
| 50 | 
            -
              
         | 
| 51 | 
            -
                  @slave.query(request).should == response[2..-1]
         | 
| 52 | 
            -
                end
         | 
| 53 | 
            -
                
         | 
| 54 | 
            -
                it 'should sugar connect method' do
         | 
| 55 | 
            -
                    ipaddr, port = '127.0.0.1', 502
         | 
| 56 | 
            -
                    Socket.should_receive(:tcp).with(ipaddr, port, nil, nil, hash_including(:connect_timeout)).and_return(@sock)
         | 
| 57 | 
            -
                    @sock.should_receive(:closed?).and_return(false)
         | 
| 58 | 
            -
                    @sock.should_receive(:close)
         | 
| 59 | 
            -
                    ModBus::TCPClient.connect(ipaddr, port) do |cl|
         | 
| 60 | 
            -
                      cl.ipaddr.should == ipaddr
         | 
| 61 | 
            -
                      cl.port.should == port
         | 
| 62 | 
            -
                    end
         | 
| 63 | 
            -
                  end
         | 
| 64 | 
            -
                
         | 
| 65 | 
            -
                it 'should have closed? method' do
         | 
| 66 | 
            -
                  @sock.should_receive(:closed?).and_return(false)
         | 
| 67 | 
            -
                  @cl.closed?.should == false
         | 
| 68 | 
            -
              
         | 
| 69 | 
            -
                  @sock.should_receive(:closed?).and_return(false)
         | 
| 70 | 
            -
                  @sock.should_receive(:close)
         | 
| 71 | 
            -
              
         | 
| 72 | 
            -
                  @cl.close
         | 
| 73 | 
            -
              
         | 
| 74 | 
            -
                  @sock.should_receive(:closed?).and_return(true)
         | 
| 75 | 
            -
                  @cl.closed?.should == true
         | 
| 76 | 
            -
                end 
         | 
| 77 | 
            -
                
         | 
| 78 | 
            -
                it 'should give slave object in block' do
         | 
| 79 | 
            -
                  @cl.with_slave(1) do |slave|
         | 
| 80 | 
            -
                    slave.uid = 1
         | 
| 81 | 
            -
                  end
         | 
| 82 | 
            -
                end
         | 
| 83 | 
            -
              end  
         | 
| 84 | 
            -
              
         | 
| 85 | 
            -
              it "should tune connection timeout" do
         | 
| 86 | 
            -
                lambda { ModBus::TCPClient.new('81.123.231.11', 1999, :connect_timeout => 0.001) }.should raise_error(ModBus::Errors::ModBusTimeout)
         | 
| 87 | 
            -
              end
         | 
| 88 | 
            -
            end
         | 
    
        data/spec/tcp_server_spec.rb
    DELETED
    
    | @@ -1,158 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: ascii
         | 
| 2 | 
            -
            require "rmodbus"
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe ModBus::TCPServer do
         | 
| 5 | 
            -
              before :all do
         | 
| 6 | 
            -
                unit_ids = (1..247).to_a.shuffle
         | 
| 7 | 
            -
                valid_unit_id = unit_ids.first
         | 
| 8 | 
            -
                @invalid_unit_id = unit_ids.last
         | 
| 9 | 
            -
                @port = 8502
         | 
| 10 | 
            -
                begin
         | 
| 11 | 
            -
                  @server = ModBus::TCPServer.new(@port)
         | 
| 12 | 
            -
                  @server_slave = @server.with_slave(valid_unit_id)
         | 
| 13 | 
            -
                  @server_slave.coils = [1,0,1,1]
         | 
| 14 | 
            -
                  @server_slave.discrete_inputs = [1,1,0,0]
         | 
| 15 | 
            -
                  @server_slave.holding_registers = [1,2,3,4]
         | 
| 16 | 
            -
                  @server_slave.input_registers = [1,2,3,4]
         | 
| 17 | 
            -
                  @server.start
         | 
| 18 | 
            -
                rescue Errno::EADDRINUSE
         | 
| 19 | 
            -
                  @port += 1
         | 
| 20 | 
            -
                  retry
         | 
| 21 | 
            -
                end
         | 
| 22 | 
            -
                @cl = ModBus::TCPClient.new('127.0.0.1', @port)
         | 
| 23 | 
            -
                @cl.read_retries = 1
         | 
| 24 | 
            -
                @slave = @cl.with_slave(valid_unit_id)
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
              it "should succeed if UID is broadcast" do
         | 
| 28 | 
            -
                @cl.with_slave(0).write_coil(1,1)
         | 
| 29 | 
            -
                # have to wait for the server to process it
         | 
| 30 | 
            -
                sleep 1
         | 
| 31 | 
            -
                @server_slave.coils[1].should == 1
         | 
| 32 | 
            -
              end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              it "should fail if UID is mismatched" do
         | 
| 35 | 
            -
                lambda { @cl.with_slave(@invalid_unit_id).read_coils(1,3) }.should raise_exception(
         | 
| 36 | 
            -
                  ModBus::Errors::ModBusTimeout
         | 
| 37 | 
            -
                )
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
              it "should send exception if function not supported" do
         | 
| 41 | 
            -
                lambda { @slave.query('0x43') }.should raise_exception(
         | 
| 42 | 
            -
                  ModBus::Errors::IllegalFunction,
         | 
| 43 | 
            -
                  "The function code received in the query is not an allowable action for the server"
         | 
| 44 | 
            -
                )
         | 
| 45 | 
            -
              end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
              it "should send exception if quanity of registers are more than 0x7d" do
         | 
| 48 | 
            -
                lambda { @slave.read_holding_registers(0, 0x7e) }.should raise_exception(
         | 
| 49 | 
            -
                  ModBus::Errors::IllegalDataValue,
         | 
| 50 | 
            -
                  "A value contained in the query data field is not an allowable value for server"
         | 
| 51 | 
            -
                )
         | 
| 52 | 
            -
              end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
              it "shouldn't send exception if quanity of coils are more than 0x7d0" do
         | 
| 55 | 
            -
                lambda { @slave.read_coils(0, 0x7d1) }.should raise_exception(
         | 
| 56 | 
            -
                  ModBus::Errors::IllegalDataValue,
         | 
| 57 | 
            -
                  "A value contained in the query data field is not an allowable value for server"
         | 
| 58 | 
            -
                )
         | 
| 59 | 
            -
              end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
              it "should send exception if addr not valid" do
         | 
| 62 | 
            -
                lambda { @slave.read_coils(2, 8) }.should raise_exception(
         | 
| 63 | 
            -
                  ModBus::Errors::IllegalDataAddress,
         | 
| 64 | 
            -
                  "The data address received in the query is not an allowable address for the server"
         | 
| 65 | 
            -
                )
         | 
| 66 | 
            -
              end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
              it "should send exception if function not supported" do
         | 
| 69 | 
            -
                lambda { @slave.query('0x43') }.should raise_exception(
         | 
| 70 | 
            -
                                                           ModBus::Errors::IllegalFunction,
         | 
| 71 | 
            -
                                                           "The function code received in the query is not an allowable action for the server"
         | 
| 72 | 
            -
                                                       )
         | 
| 73 | 
            -
              end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
              it "should calc a many requests" do
         | 
| 76 | 
            -
                @slave.read_coils(1,2)
         | 
| 77 | 
            -
                @slave.write_multiple_registers(0,[9,9,9,])
         | 
| 78 | 
            -
                @slave.read_holding_registers(0,3).should == [9,9,9]
         | 
| 79 | 
            -
              end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
              it "should supported function 'read coils'" do
         | 
| 82 | 
            -
                @slave.read_coils(0,3).should == @server_slave.coils[0,3]
         | 
| 83 | 
            -
              end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              it "should supported function 'read coils' with more than 125 in one request" do
         | 
| 86 | 
            -
                @server_slave.coils = Array.new( 1900, 1 )
         | 
| 87 | 
            -
                @slave.read_coils(0,1900).should == @server_slave.coils[0,1900]
         | 
| 88 | 
            -
              end
         | 
| 89 | 
            -
             | 
| 90 | 
            -
              it "should supported function 'read discrete inputs'" do
         | 
| 91 | 
            -
                @slave.read_discrete_inputs(1,3).should == @server_slave.discrete_inputs[1,3]
         | 
| 92 | 
            -
              end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
              it "should supported function 'read holding registers'" do
         | 
| 95 | 
            -
                @slave.read_holding_registers(0,3).should == @server_slave.holding_registers[0,3]
         | 
| 96 | 
            -
              end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
              it "should supported function 'read input registers'" do
         | 
| 99 | 
            -
                @slave.read_input_registers(2,2).should == @server_slave.input_registers[2,2]
         | 
| 100 | 
            -
              end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
              it "should supported function 'write single coil'" do
         | 
| 103 | 
            -
                @server_slave.coils[3] = 0
         | 
| 104 | 
            -
                @slave.write_single_coil(3,1)
         | 
| 105 | 
            -
                @server_slave.coils[3].should == 1
         | 
| 106 | 
            -
              end
         | 
| 107 | 
            -
             | 
| 108 | 
            -
              it "should supported function 'write single register'" do
         | 
| 109 | 
            -
                @server_slave.holding_registers[3] = 25
         | 
| 110 | 
            -
                @slave.write_single_register(3,35)
         | 
| 111 | 
            -
                @server_slave.holding_registers[3].should == 35
         | 
| 112 | 
            -
              end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
              it "should supported function 'write multiple coils'" do
         | 
| 115 | 
            -
                @server_slave.coils = [1,1,1,0, 0,0,0,0, 0,0,0,0, 0,1,1,1]
         | 
| 116 | 
            -
                @slave.write_multiple_coils(3, [1, 0,1,0,1, 0,1,0,1])
         | 
| 117 | 
            -
                @server_slave.coils.should == [1,1,1,1, 0,1,0,1, 0,1,0,1, 0,1,1,1]
         | 
| 118 | 
            -
              end
         | 
| 119 | 
            -
             | 
| 120 | 
            -
              it "should supported function 'write multiple registers'" do
         | 
| 121 | 
            -
                @server_slave.holding_registers = [1,2,3,4,5,6,7,8,9]
         | 
| 122 | 
            -
                @slave.write_multiple_registers(3,[1,2,3,4,5])
         | 
| 123 | 
            -
                @server_slave.holding_registers.should == [1,2,3,1,2,3,4,5,9]
         | 
| 124 | 
            -
              end
         | 
| 125 | 
            -
             | 
| 126 | 
            -
              it "should support function 'mask_write_register'" do
         | 
| 127 | 
            -
                @server_slave.holding_registers = [0x12]
         | 
| 128 | 
            -
                @slave.mask_write_register(0, 0xf2, 0x25)
         | 
| 129 | 
            -
                @server_slave.holding_registers.should == [0x17]
         | 
| 130 | 
            -
              end
         | 
| 131 | 
            -
             | 
| 132 | 
            -
              it "should support function 'read_write_multiple_registers'" do
         | 
| 133 | 
            -
                @server_slave.holding_registers = [1,2,3,4,5,6,7,8,9]
         | 
| 134 | 
            -
                @slave.read_write_multiple_registers(0, 5, 4, [3,2,1]).should == [1,2,3,4,3]
         | 
| 135 | 
            -
                @server_slave.holding_registers.should == [1,2,3,4,3,2,1,8,9]
         | 
| 136 | 
            -
              end
         | 
| 137 | 
            -
             | 
| 138 | 
            -
              it "should have options :host" do
         | 
| 139 | 
            -
                host = '192.168.0.1'
         | 
| 140 | 
            -
                srv = ModBus::TCPServer.new(1010, :host => '192.168.0.1')
         | 
| 141 | 
            -
                srv.host.should eql(host)
         | 
| 142 | 
            -
              end
         | 
| 143 | 
            -
             | 
| 144 | 
            -
              it "should have options :max_connection" do
         | 
| 145 | 
            -
                max_conn = 5
         | 
| 146 | 
            -
                srv = ModBus::TCPServer.new(1010, :max_connection => 5)
         | 
| 147 | 
            -
                srv.maxConnections.should eql(max_conn)
         | 
| 148 | 
            -
              end
         | 
| 149 | 
            -
             | 
| 150 | 
            -
              after :all do
         | 
| 151 | 
            -
                @cl.close unless @cl.closed?
         | 
| 152 | 
            -
                @server.stop unless @server.stopped?
         | 
| 153 | 
            -
                while GServer.in_service?(@port)
         | 
| 154 | 
            -
                  sleep(0.01)
         | 
| 155 | 
            -
                end
         | 
| 156 | 
            -
                @server.stop
         | 
| 157 | 
            -
              end
         | 
| 158 | 
            -
            end
         |