Class: Modbus::Transaction::Client
- Includes:
- EM::Deferrable
- Defined in:
- lib/modbus/transaction/client.rb
Class Method Summary collapse
-
.recv_adu(buffer, conn) ⇒ true, false
Try to decode a response ADU from some recevied bytes and handle the ADU if decoding was successful.
Instance Method Summary collapse
- #handle_read_bits ⇒ Object
- #handle_read_registers ⇒ Object
-
#handle_response(adu) ⇒ Object
Handles a recevied ADU and calls the relevant callback.
- #handle_write_multiple_registers ⇒ Object
- #handle_write_single_coil ⇒ Object
-
#initialize(conn, timeout) ⇒ Client
constructor
A new instance of Client.
-
#read_coils(start_addr, bit_count) ⇒ Object
Sends a request for the modbus function 1 “read coils” asynchronusly.
-
#read_holding_registers(start_addr, reg_count) ⇒ Object
Sends a request for the modbus function “read holding registers” asynchronusly.
-
#read_input_registers(start_addr, reg_count) ⇒ Object
Sends a request for the modbus function 4 “read input registers” asynchronusly.
-
#read_input_status(start_addr, bit_count) ⇒ Object
Sends a request for the modbus function 2 “read input status” asynchronusly.
-
#send_pdu(pdu) ⇒ Modbus::TCPADU
Constructs a ADU using a PDU and send it asynchronusly to the server.
-
#transaction_ident ⇒ Integer
Returns the transaction ident of this transaction which is consistent to the ident of the request PDU.
-
#transaction_time ⇒ Float
Returns the duration of a transaction.
-
#write_multiple_registers(start_addr, reg_values) ⇒ Object
Sends a request for the modbus function “write mutliple registers” asynchronusly.
-
#write_single_coil(start_addr, value) ⇒ Object
Sends a request for the modbus function 5 “write single coil” asynchronusly.
Constructor Details
#initialize(conn, timeout) ⇒ Client
Returns a new instance of Client.
14 15 16 17 |
# File 'lib/modbus/transaction/client.rb', line 14 def initialize(conn, timeout) super conn @timeout = timeout end |
Class Method Details
.recv_adu(buffer, conn) ⇒ true, false
Try to decode a response ADU from some recevied bytes and handle the ADU if decoding was successful.
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/modbus/transaction/client.rb', line 26 def self.recv_adu(buffer, conn) adu = Modbus::TCPADU.new if adu.decode :response, buffer, conn transaction = conn.pick_pending_transaction adu.transaction_ident fail ClientError, "Transaction ident #{adu.transaction_ident} not found!" unless transaction transaction.handle_response adu return true else return false end end |
Instance Method Details
#handle_read_bits ⇒ Object
166 167 168 |
# File 'lib/modbus/transaction/client.rb', line 166 def handle_read_bits @response_adu.pdu.bit_values end |
#handle_read_registers ⇒ Object
176 177 178 |
# File 'lib/modbus/transaction/client.rb', line 176 def handle_read_registers @response_adu.pdu.reg_values end |
#handle_response(adu) ⇒ Object
Handles a recevied ADU and calls the relevant callback. The corresponding request ADU is matched and cleaned up.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/modbus/transaction/client.rb', line 149 def handle_response(adu) @response_adu = adu fail Modbus.find_exception(@response_adu.pdu.exception_code), "Request PDU: #{@request_adu.pdu.inspect}" if @response_adu.pdu.is_a? PDU::Exception transaction = TRANSACTIONS.find { |t| @response_adu.pdu.is_a? t[:response] } fail "Unknown PDU #{@response_adu.pdu.inspect}" unless transaction fail "Unexpected last sent PDU: #{@request_adu.pdu.inspect}" unless @request_adu.pdu.is_a? transaction[:request] value = send transaction[:handler] EM.cancel_timer @timeout_timer set_deferred_success @request_adu.pdu.start_addr, value rescue => e set_deferred_failure "#{e.class} - #{e.}" end |
#handle_write_multiple_registers ⇒ Object
181 182 183 |
# File 'lib/modbus/transaction/client.rb', line 181 def handle_write_multiple_registers @response_adu.pdu.reg_count end |
#handle_write_single_coil ⇒ Object
171 172 173 |
# File 'lib/modbus/transaction/client.rb', line 171 def handle_write_single_coil @response_adu.pdu.value end |
#read_coils(start_addr, bit_count) ⇒ Object
Sends a request for the modbus function 1 “read coils” asynchronusly. This method is non-blocking.
45 46 47 48 49 50 51 |
# File 'lib/modbus/transaction/client.rb', line 45 def read_coils(start_addr, bit_count) pdu = PDU::ReadCoilsRequest.new pdu.start_addr = start_addr pdu.bit_count = bit_count send_pdu pdu end |
#read_holding_registers(start_addr, reg_count) ⇒ Object
Sends a request for the modbus function “read holding registers” asynchronusly. This method is non-blocking.
101 102 103 104 105 106 107 |
# File 'lib/modbus/transaction/client.rb', line 101 def read_holding_registers(start_addr, reg_count) pdu = PDU::ReadHoldingRegistersRequest.new pdu.start_addr = start_addr pdu.reg_count = reg_count send_pdu pdu end |
#read_input_registers(start_addr, reg_count) ⇒ Object
Sends a request for the modbus function 4 “read input registers” asynchronusly. This method is non-blocking.
87 88 89 90 91 92 93 |
# File 'lib/modbus/transaction/client.rb', line 87 def read_input_registers(start_addr, reg_count) pdu = PDU::ReadInputRegistersRequest.new pdu.start_addr = start_addr pdu.reg_count = reg_count send_pdu pdu end |
#read_input_status(start_addr, bit_count) ⇒ Object
Sends a request for the modbus function 2 “read input status” asynchronusly. This method is non-blocking.
59 60 61 62 63 64 65 |
# File 'lib/modbus/transaction/client.rb', line 59 def read_input_status(start_addr, bit_count) pdu = PDU::ReadInputStatusRequest.new pdu.start_addr = start_addr pdu.bit_count = bit_count send_pdu pdu end |
#send_pdu(pdu) ⇒ Modbus::TCPADU
Constructs a ADU using a PDU and send it asynchronusly to the server. The created ADU is stored internally and is matched to the response when the response is available.
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/modbus/transaction/client.rb', line 130 def send_pdu(pdu) @request_adu = TCPADU.new pdu, @conn.next_transaction_ident @conn.track_transaction self @conn.send_data @request_adu.encode @timeout_timer = EM.add_timer @timeout do @conn.pick_pending_transaction @request_adu.transaction_ident set_deferred_failure "Timeout #{@timeout}s expired" end self end |
#transaction_ident ⇒ Integer
Returns the transaction ident of this transaction which is consistent to the ident of the request PDU.
190 191 192 |
# File 'lib/modbus/transaction/client.rb', line 190 def transaction_ident @request_adu.transaction_ident end |
#transaction_time ⇒ Float
Returns the duration of a transaction.
199 200 201 202 |
# File 'lib/modbus/transaction/client.rb', line 199 def transaction_time fail ClientError, 'Response ADU unknown. Can not calcluate transaction time.' unless @response_adu ((@response_adu.pdu.creation_time - @request_adu.pdu.creation_time) * 1000).round end |
#write_multiple_registers(start_addr, reg_values) ⇒ Object
Sends a request for the modbus function “write mutliple registers” asynchronusly. This method is non-blocking.
115 116 117 118 119 120 121 |
# File 'lib/modbus/transaction/client.rb', line 115 def write_multiple_registers(start_addr, reg_values) pdu = PDU::WriteMultipleRegistersRequest.new pdu.start_addr = start_addr pdu.reg_values = reg_values send_pdu pdu end |
#write_single_coil(start_addr, value) ⇒ Object
Sends a request for the modbus function 5 “write single coil” asynchronusly. This method is non-blocking.
73 74 75 76 77 78 79 |
# File 'lib/modbus/transaction/client.rb', line 73 def write_single_coil(start_addr, value) pdu = PDU::WriteSingleCoilRequest.new pdu.start_addr = start_addr pdu.value = value send_pdu pdu end |