rmodbus 1.3.2 → 2.1.2
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 +5 -5
 - data/NEWS.md +19 -0
 - 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 +333 -0
 - data/lib/rmodbus/client.rb +15 -10
 - data/lib/rmodbus/debug.rb +12 -15
 - 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 +89 -125
 - data/lib/rmodbus/rtu_client.rb +22 -2
 - data/lib/rmodbus/rtu_server.rb +16 -12
 - data/lib/rmodbus/rtu_slave.rb +26 -3
 - data/lib/rmodbus/rtu_via_tcp_server.rb +12 -19
 - data/lib/rmodbus/server/slave.rb +18 -0
 - data/lib/rmodbus/server.rb +227 -84
 - data/lib/rmodbus/sp.rb +10 -12
 - data/lib/rmodbus/tcp.rb +9 -10
 - data/lib/rmodbus/tcp_client.rb +3 -0
 - data/lib/rmodbus/tcp_server.rb +41 -35
 - data/lib/rmodbus/tcp_slave.rb +19 -18
 - data/lib/rmodbus/version.rb +3 -2
 - data/lib/rmodbus.rb +20 -21
 - metadata +63 -50
 - data/Rakefile +0 -29
 - data/examples/simple-xpca-gateway.rb +0 -84
 - data/lib/rmodbus/rtu_via_tcp_client.rb +0 -26
 - data/lib/rmodbus/rtu_via_tcp_slave.rb +0 -29
 - data/lib/rmodbus/slave.rb +0 -308
 - data/spec/client_spec.rb +0 -88
 - data/spec/exception_spec.rb +0 -119
 - 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 -30
 - data/spec/rtu_via_tcp_client_spec.rb +0 -76
 - data/spec/rtu_via_tcp_server_spec.rb +0 -16
 - 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 -129
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 1aea47814577228ffdc9f2cb1bba67bf52b5cdb76d8e911c8a06125ceb80b7ad
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: be1e6031671b722d4c96a510eeab66191d3c8a79e854c97d3e16cd7f242e38e3
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 392b5ad4164e0675bbbba1d1c62e5374a432e2c2e4a83e79cfa1a68cd05a4e3a64d9a4438bd49e073b2f1437849a14c3fc2face1139765985a4c8247ee2c862e
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 95e198118db64019335403b4092f637b1e3cbe49f6a5303abb913bf3f3fbab2e2486b70f2a84d8fa6bb4fca47b0105f22ba5724d86d6ba162439de27ffac7032
         
     | 
    
        data/NEWS.md
    CHANGED
    
    | 
         @@ -1,3 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ###2024-08-20 Release 2.1.1
         
     | 
| 
      
 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 
     | 
    
         
            +
            4. [BREAKING] to/from_32* use big endian order. if you want little endian order for the 
         
     | 
| 
      
 7 
     | 
    
         
            +
               constituent 16-bit registers, use `wordswap` before/after conversion as appropriate.
         
     | 
| 
      
 8 
     | 
    
         
            +
            5. [BREAKING] to/from_32i works with _signed_ integers. If you want unsigned, use 32u
         
     | 
| 
      
 9 
     | 
    
         
            +
            6. Don't time out waiting to read a response that will never come from broadcast commands
         
     | 
| 
      
 10 
     | 
    
         
            +
            7. Don't send responses to broadcast commands as a server
         
     | 
| 
      
 11 
     | 
    
         
            +
            8. Properly function as a server in an environment with multiple RTU slaves
         
     | 
| 
      
 12 
     | 
    
         
            +
            9. Server now supports promiscuous mode to dump the conversation happening between a master and other slaves.
         
     | 
| 
      
 13 
     | 
    
         
            +
            10. Add read/write multiple registers function (server and client)
         
     | 
| 
      
 14 
     | 
    
         
            +
            11. Add mask write register function to server
         
     | 
| 
      
 15 
     | 
    
         
            +
            12. Log to a logger object, not $stderr
         
     | 
| 
      
 16 
     | 
    
         
            +
            13. Improve RTU read resiliency with partial reads
         
     | 
| 
      
 17 
     | 
    
         
            +
            14. Callbacks in server to implement additional custom processing
         
     | 
| 
      
 18 
     | 
    
         
            +
            15. Ability to use any IO (including a proxy you've set up) with RTUClient
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       1 
20 
     | 
    
         
             
            ###2017-03-30 Release 1.3.2
         
     | 
| 
       2 
21 
     | 
    
         | 
| 
       3 
22 
     | 
    
         
             
            1. Fix Fixnum warning on Ruby 2.4
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,16 +1,16 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RModBus [](http://badge.fury.io/rb/rmodbus)
         
     | 
| 
       2 
2 
     | 
    
         
             
            ==========================
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            **RModBus** - free implementation of ModBus protocol in pure Ruby.
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            Features
         
     | 
| 
       7 
7 
     | 
    
         
             
            ---------------------------
         
     | 
| 
       8 
     | 
    
         
            -
              - Ruby 2. 
     | 
| 
      
 8 
     | 
    
         
            +
              - Ruby 2.5+ and JRuby (without serial ModBus RTU)
         
     | 
| 
       9 
9 
     | 
    
         
             
              - TCP, RTU, RTU over TCP protocols
         
     | 
| 
       10 
10 
     | 
    
         
             
              - Client(master) and server(slave)
         
     | 
| 
       11 
     | 
    
         
            -
              - 16, 32 
     | 
| 
      
 11 
     | 
    
         
            +
              - 16, 32-bit and floating point registers
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
            Supported functions
         
     | 
| 
       14 
14 
     | 
    
         
             
            ---------------------------
         
     | 
| 
       15 
15 
     | 
    
         
             
              * Read Coils (0x01)
         
     | 
| 
       16 
16 
     | 
    
         
             
              * Read Discrete Inputs (0x02)
         
     | 
| 
         @@ -19,7 +19,7 @@ Support functions 
     | 
|
| 
       19 
19 
     | 
    
         
             
              * Write Single Coil (0x05)
         
     | 
| 
       20 
20 
     | 
    
         
             
              * Write Single Register (0x06)
         
     | 
| 
       21 
21 
     | 
    
         
             
              * Write Multiple Coils (0x0F)
         
     | 
| 
       22 
     | 
    
         
            -
              * Write Multiple  
     | 
| 
      
 22 
     | 
    
         
            +
              * Write Multiple Registers (0x10)
         
     | 
| 
       23 
23 
     | 
    
         
             
              * Mask Write register (0x16)
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
            Installation
         
     | 
| 
         @@ -37,14 +37,14 @@ Or if you are using bundler, add to your Gemfile: 
     | 
|
| 
       37 
37 
     | 
    
         
             
            gem 'rmodbus'
         
     | 
| 
       38 
38 
     | 
    
         
             
            ```
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
            If you want to use ModBus over serial, you will also need to install the 'serialport' gem.
         
     | 
| 
      
 40 
     | 
    
         
            +
            If you want to use ModBus over serial, you will also need to install the 'ccutrer-serialport' gem.
         
     | 
| 
       41 
41 
     | 
    
         
             
            If you are using bundler, add to your Gemfile:
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
            ```
         
     | 
| 
       44 
     | 
    
         
            -
            gem 'serialport'
         
     | 
| 
      
 44 
     | 
    
         
            +
            gem 'ccutrer-serialport'
         
     | 
| 
       45 
45 
     | 
    
         
             
            ```
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
            If you want to use ModBus::TCPServer or ModBus::RTUViaTCPServer 
     | 
| 
      
 47 
     | 
    
         
            +
            If you want to use ModBus::TCPServer or ModBus::RTUViaTCPServer,
         
     | 
| 
       48 
48 
     | 
    
         
             
            you will also need to install the 'gserver' gem. If you are using bundler, add to your Gemfile:
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
            ```
         
     | 
    
        data/examples/perfomance_rtu.rb
    CHANGED
    
    | 
         @@ -1,56 +1,55 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            BAUD = 9600 
     | 
| 
       9 
     | 
    
         
            -
            TIMES = 100
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            srv = RTUServer.new  
     | 
| 
       12 
     | 
    
         
            -
            srv.coils = [0,1] 
     | 
| 
       13 
     | 
    
         
            -
            srv.discrete_inputs = [1,0] 
     | 
| 
       14 
     | 
    
         
            -
            srv.holding_registers = [0,1,2,3,4,5,6,7,8,9] 
     | 
| 
       15 
     | 
    
         
            -
            srv.input_registers = [0,1,2,3,4,5,6,7,8,9] 
     | 
| 
       16 
     | 
    
         
            -
            srv.start
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            cl 
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
            cl.close
         
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem "rmodbus"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "rmodbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "benchmark"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            BAUD = 9600
         
     | 
| 
      
 9 
     | 
    
         
            +
            TIMES = 100
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            srv = ModBus::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 
     | 
    
         
            +
            cl = ModBus::RTUClient.new("com4", BAUD)
         
     | 
| 
      
 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 
     | 
    
         
            +
            srv.stop
         
     | 
| 
      
 55 
     | 
    
         
            +
            cl.close
         
     | 
| 
         @@ -1,55 +1,54 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            TIMES = 1000
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
            srv = ModBus::RTUViaTCPServer.new 1502 
     | 
| 
       11 
     | 
    
         
            -
            srv.coils = [0,1] 
     | 
| 
       12 
     | 
    
         
            -
            srv.discrete_inputs = [1,0] 
     | 
| 
       13 
     | 
    
         
            -
            srv.holding_registers = [0,1,2,3,4,5,6,7,8,9] 
     | 
| 
       14 
     | 
    
         
            -
            srv.input_registers = [0,1,2,3,4,5,6,7,8,9] 
     | 
| 
       15 
     | 
    
         
            -
            srv.start
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            cl 
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            srv.stop
         
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem "rmodbus"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "rmodbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "benchmark"
         
     | 
| 
      
 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 
     | 
    
         
            +
            cl = ModBus::RTUClient.new("127.0.0.1", 1502)
         
     | 
| 
      
 18 
     | 
    
         
            +
            cl.with_slave(1) do |slave|
         
     | 
| 
      
 19 
     | 
    
         
            +
              Benchmark.bmbm do |x|
         
     | 
| 
      
 20 
     | 
    
         
            +
                x.report("Read coils") do
         
     | 
| 
      
 21 
     | 
    
         
            +
                  TIMES.times { slave.read_coils 0, 100 }
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                x.report("Read discrete inputs") do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  TIMES.times { slave.read_discrete_inputs 0, 100 }
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                x.report("Read holding registers") do
         
     | 
| 
      
 29 
     | 
    
         
            +
                  TIMES.times { slave.read_holding_registers 0, 100 }
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                x.report("Read input registers") do
         
     | 
| 
      
 33 
     | 
    
         
            +
                  TIMES.times { slave.read_input_registers 0, 100 }
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                x.report("Write single coil") do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  TIMES.times { slave.write_single_coil 0, 1 }
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                x.report("Write single register") do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  TIMES.times { slave.write_single_register 100, 0xAAAA }
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                x.report("Write multiple coils") do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  TIMES.times { slave.write_multiple_coils 0, [1, 0] * 50 }
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                x.report("Write multiple registers") do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  TIMES.times { slave.write_multiple_registers 0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * 10 }
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
      
 53 
     | 
    
         
            +
            cl.close
         
     | 
| 
      
 54 
     | 
    
         
            +
            srv.stop
         
     | 
    
        data/examples/perfomance_tcp.rb
    CHANGED
    
    | 
         @@ -1,55 +1,54 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            TIMES = 1000
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
            srv = ModBus::TCPServer.new 1502 
     | 
| 
       11 
     | 
    
         
            -
            srv.coils = [0,1] 
     | 
| 
       12 
     | 
    
         
            -
            srv.discrete_inputs = [1,0] 
     | 
| 
       13 
     | 
    
         
            -
            srv.holding_registers = [0,1,2,3,4,5,6,7,8,9] 
     | 
| 
       14 
     | 
    
         
            -
            srv.input_registers = [0,1,2,3,4,5,6,7,8,9] 
     | 
| 
       15 
     | 
    
         
            -
            srv.start
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            cl 
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            srv.stop
         
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem "rmodbus"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "rmodbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "benchmark"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            TIMES = 1000
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            srv = ModBus::TCPServer.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 
     | 
    
         
            +
            cl = ModBus::TCPClient.new("127.0.0.1", 1502)
         
     | 
| 
      
 18 
     | 
    
         
            +
            cl.with_slave(1) do |slave|
         
     | 
| 
      
 19 
     | 
    
         
            +
              Benchmark.bmbm do |x|
         
     | 
| 
      
 20 
     | 
    
         
            +
                x.report("Read coils") do
         
     | 
| 
      
 21 
     | 
    
         
            +
                  TIMES.times { slave.read_coils 0, 100 }
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                x.report("Read discrete inputs") do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  TIMES.times { slave.read_discrete_inputs 0, 100 }
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                x.report("Read holding registers") do
         
     | 
| 
      
 29 
     | 
    
         
            +
                  TIMES.times { slave.read_holding_registers 0, 100 }
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                x.report("Read input registers") do
         
     | 
| 
      
 33 
     | 
    
         
            +
                  TIMES.times { slave.read_input_registers 0, 100 }
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                x.report("Write single coil") do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  TIMES.times { slave.write_single_coil 0, 1 }
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                x.report("Write single register") do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  TIMES.times { slave.write_single_register 100, 0xAAAA }
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                x.report("Write multiple coils") do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  TIMES.times { slave.write_multiple_coils 0, [1, 0] * 50 }
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                x.report("Write multiple registers") do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  TIMES.times { slave.write_multiple_registers 0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * 10 }
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
      
 53 
     | 
    
         
            +
            cl.close
         
     | 
| 
      
 54 
     | 
    
         
            +
            srv.stop
         
     | 
| 
         @@ -0,0 +1,85 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # It's very simple example of implementation XPCA gateway (see http://www.xpca.org)
         
     | 
| 
      
 4 
     | 
    
         
            +
            # for communication with TCP ModBus devices
         
     | 
| 
      
 5 
     | 
    
         
            +
            # It receives  REST requests (e.g http://127.0.0.1:4567/mb/127.0.0.1/8502/1/coils/6/17 )
         
     | 
| 
      
 6 
     | 
    
         
            +
            # and returns data in JSON format addr : data:
         
     | 
| 
      
 7 
     | 
    
         
            +
            # {"coils": {
         
     | 
| 
      
 8 
     | 
    
         
            +
            #   "6":{
         
     | 
| 
      
 9 
     | 
    
         
            +
            #     "value":0,
         
     | 
| 
      
 10 
     | 
    
         
            +
            #     "timestamp":"2011-07-12 18:11:03 +0000",
         
     | 
| 
      
 11 
     | 
    
         
            +
            #     "quality":"good"
         
     | 
| 
      
 12 
     | 
    
         
            +
            #   },
         
     | 
| 
      
 13 
     | 
    
         
            +
            #   "7":{
         
     | 
| 
      
 14 
     | 
    
         
            +
            #     "value":0,
         
     | 
| 
      
 15 
     | 
    
         
            +
            #     "timestamp":"2011-07-12 18:11:03 +0000",
         
     | 
| 
      
 16 
     | 
    
         
            +
            #     "quality":"good"
         
     | 
| 
      
 17 
     | 
    
         
            +
            #     }
         
     | 
| 
      
 18 
     | 
    
         
            +
            #   ...
         
     | 
| 
      
 19 
     | 
    
         
            +
            # }
         
     | 
| 
      
 20 
     | 
    
         
            +
            #
         
     | 
| 
      
 21 
     | 
    
         
            +
            # This code requies gems: rmodbus, sinatra and json
         
     | 
| 
      
 22 
     | 
    
         
            +
            # 2011 (c) Aleksey Timin
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            gem "rmodbus"
         
     | 
| 
      
 25 
     | 
    
         
            +
            gem "sinatra"
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            require "rmodbus"
         
     | 
| 
      
 28 
     | 
    
         
            +
            require "sinatra"
         
     | 
| 
      
 29 
     | 
    
         
            +
            require "json"
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            # Launche TCP ModBus server for test
         
     | 
| 
      
 32 
     | 
    
         
            +
            IP = "127.0.0.1"
         
     | 
| 
      
 33 
     | 
    
         
            +
            PORT = 8502
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            @srv = ModBus::TCPServer.new(PORT, 1)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            @srv.holding_registers = Array.new(100) { |i| i + 1 }
         
     | 
| 
      
 38 
     | 
    
         
            +
            @srv.input_registers = Array.new(100) { |i| i + 1 }
         
     | 
| 
      
 39 
     | 
    
         
            +
            @srv.coils = Array.new(100) { 0 }
         
     | 
| 
      
 40 
     | 
    
         
            +
            @srv.discrete_inputs = Array.new(100) { 0 }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            @srv.start
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            # Calc a GET request
         
     | 
| 
      
 45 
     | 
    
         
            +
            # @example
         
     | 
| 
      
 46 
     | 
    
         
            +
            # http://127.0.0.1:4567/mb/127.0.0.1/8502/1/coils/6/17
         
     | 
| 
      
 47 
     | 
    
         
            +
            #
         
     | 
| 
      
 48 
     | 
    
         
            +
            # HTTP route: GET http://localhost/mb/:ip/:port/:slave/:dataplace/:firstaddr/:lastaddr
         
     | 
| 
      
 49 
     | 
    
         
            +
            #
         
     | 
| 
      
 50 
     | 
    
         
            +
            # :ip - ip addr of ModBus TCP Server
         
     | 
| 
      
 51 
     | 
    
         
            +
            # :port - port of ModBUs TCP Server
         
     | 
| 
      
 52 
     | 
    
         
            +
            # :slave - id of slave device
         
     | 
| 
      
 53 
     | 
    
         
            +
            # :dataplace - valid values: coils, discrete_inputs, input_registers, holding_registers
         
     | 
| 
      
 54 
     | 
    
         
            +
            # :firstaddr - first addr of registers(contacts)
         
     | 
| 
      
 55 
     | 
    
         
            +
            # :lastaddr - last addr of registers(contacts)
         
     | 
| 
      
 56 
     | 
    
         
            +
            get "/mb/:ip/:port/:slave/:dataplace/:firstaddr/:lastaddr" do
         
     | 
| 
      
 57 
     | 
    
         
            +
              resp = {}
         
     | 
| 
      
 58 
     | 
    
         
            +
              begin
         
     | 
| 
      
 59 
     | 
    
         
            +
                data = []
         
     | 
| 
      
 60 
     | 
    
         
            +
                ModBus::TCPClient.new(params[:ip].to_s, params[:port].to_i) do |cl|
         
     | 
| 
      
 61 
     | 
    
         
            +
                  cl.with_slave(params[:slave].to_i) do |slave|
         
     | 
| 
      
 62 
     | 
    
         
            +
                    slave.debug = true
         
     | 
| 
      
 63 
     | 
    
         
            +
                    dataplace = slave.send params[:dataplace]
         
     | 
| 
      
 64 
     | 
    
         
            +
                    data = dataplace[params[:firstaddr].to_i..params[:lastaddr].to_i]
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                resp = { params[:dataplace] => {} }
         
     | 
| 
      
 69 
     | 
    
         
            +
                data.each_with_index do |v, i|
         
     | 
| 
      
 70 
     | 
    
         
            +
                  resp[params[:dataplace]][params[:firstaddr].to_i + i] = {
         
     | 
| 
      
 71 
     | 
    
         
            +
                    value: v,
         
     | 
| 
      
 72 
     | 
    
         
            +
                    timestamp: Time.now.utc.strftime("%Y-%m-%d %H:%M:%S %z"),
         
     | 
| 
      
 73 
     | 
    
         
            +
                    quality: "good"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  }
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
              rescue => e
         
     | 
| 
      
 77 
     | 
    
         
            +
                resp = { error: {
         
     | 
| 
      
 78 
     | 
    
         
            +
                  type: e.class,
         
     | 
| 
      
 79 
     | 
    
         
            +
                  message: e.message
         
     | 
| 
      
 80 
     | 
    
         
            +
                } }
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              content_type "application/json"
         
     | 
| 
      
 84 
     | 
    
         
            +
              resp.to_json
         
     | 
| 
      
 85 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,21 +1,24 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
            require 'rmodbus'
         
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            srv 
     | 
| 
      
 3 
     | 
    
         
            +
            gem "rmodbus"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "rmodbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            srv = ModBus::RTUViaTCPServer.new(10_002, 1)
         
     | 
| 
      
 8 
     | 
    
         
            +
            srv.coils = [1, 0, 1, 1]
         
     | 
| 
      
 9 
     | 
    
         
            +
            srv.discrete_inputs = [1, 1, 0, 0]
         
     | 
| 
      
 10 
     | 
    
         
            +
            srv.holding_registers = [1, 2, 3, 4]
         
     | 
| 
      
 11 
     | 
    
         
            +
            srv.input_registers = [1, 2, 3, 4]
         
     | 
| 
       9 
12 
     | 
    
         
             
            srv.debug = true
         
     | 
| 
       10 
13 
     | 
    
         
             
            srv.start
         
     | 
| 
       11 
14 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            ModBus:: 
     | 
| 
      
 15 
     | 
    
         
            +
            ModBus::RTUClient.connect("127.0.0.1", 10_002) do |cl|
         
     | 
| 
       13 
16 
     | 
    
         
             
              cl.with_slave(1) do |slave|
         
     | 
| 
       14 
17 
     | 
    
         
             
                slave.debug = true
         
     | 
| 
       15 
18 
     | 
    
         
             
                regs = slave.holding_registers
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
                puts regs[0..3]
         
     | 
| 
      
 20 
     | 
    
         
            +
                regs[0..3] = [2, 0, 1, 1]
         
     | 
| 
      
 21 
     | 
    
         
            +
                puts regs[0..3]
         
     | 
| 
       19 
22 
     | 
    
         
             
              end
         
     | 
| 
       20 
23 
     | 
    
         
             
            end
         
     | 
| 
       21 
24 
     | 
    
         | 
    
        data/examples/use_tcp_modbus.rb
    CHANGED
    
    | 
         @@ -1,22 +1,25 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
            require 'rmodbus'
         
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            srv 
     | 
| 
      
 3 
     | 
    
         
            +
            gem "rmodbus"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "rmodbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            srv = ModBus::TCPServer.new(8502, 1)
         
     | 
| 
      
 8 
     | 
    
         
            +
            srv.coils = [1, 0, 1, 1]
         
     | 
| 
      
 9 
     | 
    
         
            +
            srv.discrete_inputs = [1, 1, 0, 0]
         
     | 
| 
      
 10 
     | 
    
         
            +
            srv.holding_registers = [1, 2, 3, 4]
         
     | 
| 
      
 11 
     | 
    
         
            +
            srv.input_registers = [1, 2, 3, 4]
         
     | 
| 
       9 
12 
     | 
    
         
             
            srv.debug = true
         
     | 
| 
       10 
13 
     | 
    
         
             
            srv.audit = true
         
     | 
| 
       11 
14 
     | 
    
         
             
            srv.start
         
     | 
| 
       12 
15 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
            ModBus::TCPClient.connect( 
     | 
| 
      
 16 
     | 
    
         
            +
            ModBus::TCPClient.connect("127.0.0.1", 8502) do |cl|
         
     | 
| 
       14 
17 
     | 
    
         
             
              cl.with_slave(1) do |slave|
         
     | 
| 
       15 
18 
     | 
    
         
             
                slave.debug = true
         
     | 
| 
       16 
19 
     | 
    
         
             
                regs = slave.holding_registers
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
      
 20 
     | 
    
         
            +
                puts regs[0..3]
         
     | 
| 
      
 21 
     | 
    
         
            +
                regs[0..3] = [2, 0, 1, 1]
         
     | 
| 
      
 22 
     | 
    
         
            +
                puts regs[0..3]
         
     | 
| 
       20 
23 
     | 
    
         
             
              end
         
     | 
| 
       21 
24 
     | 
    
         
             
            end
         
     | 
| 
       22 
25 
     | 
    
         |