class MovingsignApi::Sign

Manipulates a Movingsign attached to a serial port

@example Construct a sign

require 'movingsign_api'

sign = MovingsignApi::Sign.new('/dev/ttyUSB0')

@example Show Text

sign.show_text('Hello World!')

@example Turn Sound Off

sign.set_sound false

Attributes

device_path[RW]

Serial port device path (ie: /dev/ttyUSB0)

Public Class Methods

new(device_path) click to toggle source

@param device_path [String] the serial port device path (ie: /dev/ttyUSB0, different depending on platform)

# File lib/movingsign_api/sign.rb, line 22
def initialize(device_path)
  @device_path = device_path
end

Public Instance Methods

send_command(command) click to toggle source

Sends the specified Movingsign command to this sign's serial port

@param [MovingsignApi::Command] command subclass to send

@return [self]

# File lib/movingsign_api/sign.rb, line 70
def send_command(command)
  SerialPort.open(self.device_path, 9600, 8, 1) do |port|
    # flush anything existing on the port
    port.flush
    flush_read_buffer(port)

    byte_string = command.to_bytes.pack('C*')

    begin
      while byte_string && byte_string.length != 0
        count = port.write_nonblock(byte_string)
        byte_string = byte_string[count,-1]

        port.flush
      end
    rescue IO::WaitWritable
      if IO.select([], [port], [], 5)
        retry
      else
        raise IOError, "Timeout writing command to #{self.device_path}"
      end
    end

    # wait for expected confirmation signals
    got_eot = false
    got_soh = false
    loop do
      begin
        c = port.read_nonblock(1)

        case c
          when "\x04"
            if ! got_eot
              got_eot = true
            else
              raise IOError, "Got EOT reply twice from #{self.device_path}"
            end
          when "\x01"
            if got_eot
              if ! got_soh
                got_soh = true

                break
              else
                raise IOError, "Got SOH twice from #{self.device_path}"
              end
            else
              raise IOError, "Got SOH before EOT from #{self.device_path}"
            end
        end
      rescue IO::WaitReadable
        if IO.select([port], [], [], 3)
          retry
        else
          raise IOError, "Timeout waiting for command reply from #{self.device_path}.  EOT:#{got_eot} SOH:#{got_soh}"
        end
      end
    end
  end

  self
end
set_sound(on) click to toggle source

Turns on/off sound when the sign receives a command

This is a shorthand for {SetSoundCommand}

@param on [Boolean] true to turn sound on, false otherwise

@return [self]

# File lib/movingsign_api/sign.rb, line 59
def set_sound(on)
  cmd = SetSoundCommand.new on

  send_command cmd
end
show_identity() click to toggle source

Show the {#device_path} value on the display (useful for diagnostics)

# File lib/movingsign_api/sign.rb, line 27
def show_identity
  cmd = WriteTextCommand.new
  cmd.text = self.device_path

  send_command cmd
end
show_text(text, options = {}) click to toggle source

Displays the given text on the board.

This is short-hand for the {WriteTextCommand}

@param text [String] the text to display on the sign @param options [Hash] options for {WriteTextCommand} @option options [Integer] :display_pause (2) Time to pause (in seconds) between pages of text. See {WriteTextCommand#display_pause}

@return [self]

# File lib/movingsign_api/sign.rb, line 43
def show_text(text, options = {})
  cmd = WriteTextCommand.new
  cmd.display_pause = options[:display_pause] if options[:display_pause]
  cmd.text = text

  send_command cmd
end
Also aliased as: write_text
write_text(text, options = {})
Alias for: show_text

Private Instance Methods

flush_read_buffer(port) click to toggle source
# File lib/movingsign_api/sign.rb, line 135
def flush_read_buffer(port)
  begin
    while true
      port.read_nonblock(1024)
    end
  rescue IO::WaitReadable
  end
end