class Modbus::Transaction::Server

Public Class Methods

recv_adu(buffer, conn) click to toggle source

Try to decode a response ADU from some recevied bytes and handle the ADU if decoding was successful.

@param buffer [String] The bytes received from the network. @param conn [Modbus::Connection::TCPServer] An EM connection object to work on. @return [true, false] True, if there where enough bytes in the buffer and decoding was successful.

# File lib/modbus/transaction/server.rb, line 17
def self.recv_adu(buffer, conn)
  adu = Modbus::TCPADU.new

  if adu.decode :request, buffer, conn
    transaction = self.new conn
    transaction.handle_request adu
    return true
  else
    return false
  end
end

Public Instance Methods

handle_read_holding_registers() click to toggle source
# File lib/modbus/transaction/server.rb, line 68
def handle_read_holding_registers
  read_registers 40001, PDU::ReadHoldingRegistersResponse
end
handle_read_input_registers() click to toggle source
# File lib/modbus/transaction/server.rb, line 63
def handle_read_input_registers
  read_registers 30001, PDU::ReadInputRegistersResponse
end
handle_request(adu) click to toggle source

Handles a recevied ADU and calls the relevant callback. The corresponding request ADU is matched and cleaned up.

@param adu [Modbus::ADU] The ADU to handle.

# File lib/modbus/transaction/server.rb, line 48
def handle_request(adu)
  @request_adu = adu

  transaction = TRANSACTIONS.find { |t| adu.pdu.is_a? t[:request] }
  fail IllegalFunction,     "Unknown PDU #{adu.pdu.inspect}" unless transaction
  fail ServerDeviceFailure, "Unexpected last sent PDU: #{@request_adu.pdu.inspect}" unless @request_adu.pdu.is_a? transaction[:request]

  pdu = send transaction[:handler]
  send_pdu pdu

rescue ModbusError => error
  send_pdu PDU::Exception.create(adu.pdu.func_code, error)
end
handle_write_multiple_registers() click to toggle source
# File lib/modbus/transaction/server.rb, line 81
def handle_write_multiple_registers
  reg_count      = @conn.write_registers 40001 + @request_adu.pdu.start_addr, @request_adu.pdu.reg_values
  pdu            = PDU::WriteMultipleRegistersResponse.new
  pdu.start_addr = @request_adu.pdu.start_addr
  pdu.reg_count  = reg_count
  pdu
end
read_registers(offset, response_class) click to toggle source
# File lib/modbus/transaction/server.rb, line 73
def read_registers(offset, response_class)
  reg_values     = @conn.read_registers offset + @request_adu.pdu.start_addr, @request_adu.pdu.reg_count
  pdu            = response_class.new
  pdu.reg_values = reg_values
  pdu
end
send_pdu(pdu) click to toggle source

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.

@param pdu [Modbus::PDU] The PDU to send. @return [Modbus::TCPADU] The sent ADU.

# File lib/modbus/transaction/server.rb, line 36
def send_pdu(pdu)
  @response_adu = TCPADU.new pdu, @request_adu.transaction_ident
  @conn.send_data @response_adu.encode
  self
end