Class: VoltronicDeviceOperation
- Inherits:
-
Object
- Object
- VoltronicDeviceOperation
- Defined in:
- lib/voltronic_device_operation.rb
Overview
A convenient immutable object to encapsulate the logic of a Voltronic Device operation consisting of: Command, parameter validation and result parser
@author: Johan van der Vyver
Defined Under Namespace
Classes: NAKReceivedError, RS232ParseError
Instance Method Summary collapse
-
#command(*args) ⇒ Object
Create an VoltronicRS232 object containing a command and optional parameter to execute on the device.
-
#initialize(input, &blk) ⇒ VoltronicDeviceOperation
constructor
A new instance of VoltronicDeviceOperation.
-
#inspect ⇒ Object
:nodoc:.
-
#issue_command(serial, *args) ⇒ Object
Issue a command to the device and parse the output result.
-
#parse_result(result) ⇒ Object
Parse the command output returned from the Voltronic device.
-
#to_s ⇒ Object
:nodoc:.
Constructor Details
#initialize(input, &blk) ⇒ VoltronicDeviceOperation
Returns a new instance of VoltronicDeviceOperation.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/voltronic_device_operation.rb', line 11 def initialize(input, &blk) input = {}.merge(input) rescue (raise ::ArgumentError.new("Expected an input hash")) @command = begin as_lambda(input.fetch(:command)) rescue ::StandardError => err err = "#{err.class.name.to_s} thrown; #{err..to_s}" raise ::ArgumentError.new("Expected :command to be a String with a device command or Proc (#{err})") end @error_on_nak = (true == input.fetch(:error_on_nak, true)) @parser = begin as_lambda(input.fetch(:parser)) rescue ::StandardError => err err = "#{err.class.name.to_s} thrown; #{err..to_s}" raise ::ArgumentError.new("Expected :parser to be a Proc or Lambda (#{err})") end @read_timeout = Integer(input.fetch(:serial_read_timeout_seconds, 2)) @retry_timeout = Integer(input.fetch(:serial_retry_timeout_milliseconds, 50)) @termination_character = begin parse = input.fetch(:serial_termination_character, "\r").to_s raise ::ArgumentError.new("Expected :serial_termination_character to be a single character") unless (parse.length == 1) parse.freeze end freeze end |
Instance Method Details
#command(*args) ⇒ Object
Create an VoltronicRS232 object containing a command and optional parameter to execute on the device
70 71 72 |
# File 'lib/voltronic_device_operation.rb', line 70 def command(*args) RS232_PROTO.new(@command.yield(*args)) end |
#inspect ⇒ Object
:nodoc:
92 93 94 |
# File 'lib/voltronic_device_operation.rb', line 92 def inspect # :nodoc: self.to_s end |
#issue_command(serial, *args) ⇒ Object
Issue a command to the device and parse the output result
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/voltronic_device_operation.rb', line 44 def issue_command(serial, *args) serial.read_timeout = -1 rescue nil # Prevent locking on serial serial.write(command(*args).bytes) result = begin parse = '' read_timeout = ::Time.now.to_i + @read_timeout # 2 seconds while(true) ch = serial.getc # Retrieve a single character from Serial port if ch.nil? raise ::IOError.new("Read timeout reached on serial port, giving up") if (Time.now.to_i > read_timeout) sleep (@retry_timeout/1000.0) # Pause before polling again next end parse += ch break if (@termination_character == ch) end parse end parse_result(result[0..-4]) end |
#parse_result(result) ⇒ Object
Parse the command output returned from the Voltronic device
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/voltronic_device_operation.rb', line 76 def parse_result(result) result = RS232_PROTO.new(result) if (@error_on_nak && ('(NAK' == result.data.upcase)) raise NAKReceivedError.new("Received NAK from device, this usually means an error occured, an invalid value was supplied or the command is not supported") end @parser.yield(result) rescue ::StandardError, ::ScriptError => err raise err if err.is_a?(NAKReceivedError) err = "#{err.class.name.to_s} thrown; #{err..to_s}" raise RS232ParseError.new("Could not parse the result, the output format may have changed (#{err})") end |
#to_s ⇒ Object
:nodoc:
88 89 90 |
# File 'lib/voltronic_device_operation.rb', line 88 def to_s # :nodoc: "#{self.class.name.to_s.split('::').last}" end |