Class: ProconBypassMan::ExternalInput::Channels::SerialPortChannel
- Defined in:
- lib/procon_bypass_man/external_input/channels/serial_port_channel.rb
Instance Attribute Summary collapse
-
#serial_port ⇒ Object
readonly
Returns the value of attribute serial_port.
Instance Method Summary collapse
- #display_name_for_boot_message ⇒ Object
-
#initialize(device_path:, baud_rate: 9600) ⇒ SerialPortChannel
constructor
A new instance of SerialPortChannel.
-
#read ⇒ String, NilClass
NOTE: この実装では、::IO::EAGAINWaitReadableを実質的な終端として扱っているので、高速に書き込みがされると取りこぼす可能性がある.
- #shutdown ⇒ Object
Constructor Details
#initialize(device_path:, baud_rate: 9600) ⇒ SerialPortChannel
Returns a new instance of SerialPortChannel.
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/procon_bypass_man/external_input/channels/serial_port_channel.rb', line 9 def initialize(device_path: , baud_rate: 9600) require 'serialport' super() # data_bitsあたりは必要があれば設定ができるようにしたいがよくわからないのでとりあえずnilを入れる data_bits = 8 stop_bits = 1 parity = SerialPort::NONE @serial_port = SerialPort.new(device_path, baud_rate, data_bits, stop_bits, parity) end |
Instance Attribute Details
#serial_port ⇒ Object (readonly)
Returns the value of attribute serial_port.
5 6 7 |
# File 'lib/procon_bypass_man/external_input/channels/serial_port_channel.rb', line 5 def serial_port @serial_port end |
Instance Method Details
#display_name_for_boot_message ⇒ Object
50 51 52 |
# File 'lib/procon_bypass_man/external_input/channels/serial_port_channel.rb', line 50 def 'SerialPort' end |
#read ⇒ String, NilClass
NOTE: この実装では、::IO::EAGAINWaitReadableを実質的な終端として扱っているので、高速に書き込みがされると取りこぼす可能性がある. NOTE: read_nonblockでバッファから読み出すとき、バッファが空になるまでは::IO::EAGAINWaitReadableが起きない前提で実装している. NOTE: 取りこぼししないよう精度を上げるには、終端文字が来るまで1文字ずつ読む必要があるがパフォーマンスが犠牲になってしまう. この対策をするには、bypass処理の開始で非同期に1文字ずつ読み込むことをすると多少マシになるはず
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/procon_bypass_man/external_input/channels/serial_port_channel.rb', line 24 def read buffer = '' loop do begin buffer += @serial_port.read_nonblock(1024) || '' rescue ::IO::EAGAINWaitReadable break end end return nil if buffer.empty? # NOTE: 高速に書き込まれた場合、複数のチャンクを含む可能性があるので、最初だけを切り取る chunks = buffer.split("\n") if(chunks.size > 1) ProconBypassMan::SendErrorCommand.execute( error: "[ExternalInput] シリアルポートから読み込んだchunkが複数あります. 高い書き込み頻度に耐えられていないので実装を見直してください。 (chunks.size: #{chunks.size})" ) end chunks.first end |
#shutdown ⇒ Object
46 47 48 |
# File 'lib/procon_bypass_man/external_input/channels/serial_port_channel.rb', line 46 def shutdown # no-op end |