class Lignite::Ev3Tool

Implements the `ev3tool` command line interface

Constants

EV3TOOL_HOME

The VM current working directory is /home/root/lms2012/sys which is not very useful. A better default is /home/root/lms2012/prjs which is displayed on the 2nd tab of the brick UI.

Public Class Methods

exit_on_failure?() click to toggle source
# File lib/lignite/ev3_tool.rb, line 16
def self.exit_on_failure?
  true
end

Public Instance Methods

asm(ruby_fn, rbf_fn) click to toggle source
# File lib/lignite/ev3_tool.rb, line 60
def asm(ruby_fn, rbf_fn)
  a = Assembler.new
  a.assemble(ruby_fn, rbf_fn)
end
assisted_connection() click to toggle source
# File lib/lignite/ev3_tool.rb, line 137
      def assisted_connection
        c = Lignite::Connection.create
        # When invoking via Thor we can't get at the instance otherwise :-/
        ObjectSpace.define_finalizer(self, ->(_id) { close })
        c
      rescue StandardError => e
        fn = Lignite::Connection::Bluetooth.config_filename
        $stderr.puts <<MSG
Could not connect to EV3.
Use a USB cable or configure a Bluetooth address in #{fn.inspect}.
Details:
  #{e.message}
MSG

        try_config_from_template(fn, Lignite::Connection::Bluetooth.template_config_filename)
        raise Thor::Error, ""
      end
close() click to toggle source
# File lib/lignite/ev3_tool.rb, line 176
def close
  @conn.close if @conn
  @conn = nil
end
conn() click to toggle source
# File lib/lignite/ev3_tool.rb, line 172
def conn
  @conn ||= assisted_connection
end
dc() click to toggle source
# File lib/lignite/ev3_tool.rb, line 167
def dc
  return @dc if @dc
  @dc = Lignite::DirectCommands.new(conn)
end
download(brick_filename, local_filename = nil) click to toggle source
# File lib/lignite/ev3_tool.rb, line 34
def download(brick_filename, local_filename = nil)
  chunk_size = 1000 # 2000 stalls, 4096 goes out of sync in our code
  local_filename ||= File.basename(brick_filename)
  fsize, handle, data = sc.begin_upload(chunk_size, brick_filename)
  File.open(local_filename, "w") do |f|
    loop do
      f.write(data)
      fsize -= data.bytesize
      break if fsize.zero?
      handle, data = sc.continue_upload(handle, chunk_size)
    end
  end
end
file_exist?(name) click to toggle source
# File lib/lignite/ev3_tool.rb, line 130
def file_exist?(name)
  dirname = File.dirname(name)
  filename = File.basename(name)
  files = raw_ls(dirname) || []
  files.include?(filename)
end
list_files(name) click to toggle source
# File lib/lignite/ev3_tool.rb, line 50
def list_files(name)
  puts raw_list_files(name)
end
ls(name) click to toggle source
# File lib/lignite/ev3_tool.rb, line 55
def ls(name)
  puts raw_ls(name)
end
raw_list_files(name) click to toggle source
# File lib/lignite/ev3_tool.rb, line 66
def raw_list_files(name)
  name ||= EV3TOOL_HOME
  name = "#{EV3TOOL_HOME}/#{name}" unless name.start_with?("/")

  result = ""
  fsize, handle, data = sc.list_files(4096, name)
  loop do
    result += data
    fsize -= data.bytesize
    break if fsize.zero?
    handle, data = sc.continue_list_files(handle, 4096)
  end
  result
rescue Lignite::VMError
  nil
end
raw_ls(name) click to toggle source
# File lib/lignite/ev3_tool.rb, line 83
def raw_ls(name)
  raw = raw_list_files(name)
  return nil if raw.nil?

  raw.lines.map do |l|
    l = l.chomp
    next nil if ["./", "../"].include?(l)
    next l if l.end_with?("/")
    # skip checksum + space + size + space
    l[32 + 1 + 8 + 1..-1]
  end.compact
end
runnable_name(name) click to toggle source
# File lib/lignite/ev3_tool.rb, line 96
def runnable_name(name)
  if name.start_with?("/")
    name
  elsif name.include?("/")
    "#{EV3TOOL_HOME}/#{name}"
  else
    "#{EV3TOOL_HOME}/#{name}/#{name}.rbf"
  end
end
sc() click to toggle source
# File lib/lignite/ev3_tool.rb, line 162
def sc
  return @sc if @sc
  @sc = Lignite::SystemCommands.new(conn)
end
start(name) click to toggle source
# File lib/lignite/ev3_tool.rb, line 108
def start(name)
  name = runnable_name(name)

  raise Thor::Error, "File #{name.inspect} not found on the brick" unless file_exist?(name)

  slot = Lignite::USER_SLOT
  no_debug = 0
  dc.block do
    # these are local variables
    data32 :size
    data32 :ip
    file_load_image(slot, name, :size, :ip)
    program_start(slot, :size, :ip, no_debug)
  end
end
stop() click to toggle source
# File lib/lignite/ev3_tool.rb, line 125
def stop
  dc.program_stop(Lignite::USER_SLOT)
end
try_config_from_template(config_fn, template_fn) click to toggle source
# File lib/lignite/ev3_tool.rb, line 155
def try_config_from_template(config_fn, template_fn)
  return unless !File.exist?(config_fn) && File.exist?(template_fn)
  FileUtils.mkdir_p(File.dirname(config_fn))
  FileUtils.install(template_fn, config_fn)
  $stderr.puts "(A template config file has been copied for your convenience)"
end
upload(local_filename, brick_filename = nil) click to toggle source
# File lib/lignite/ev3_tool.rb, line 22
def upload(local_filename, brick_filename = nil)
  data = File.read(local_filename, encoding: Encoding::BINARY)
  unless brick_filename
    prj = File.basename(local_filename, ".rbf")
    brick_filename = "#{EV3TOOL_HOME}/#{prj}/#{prj}.rbf"
  end
  handle = sc.begin_download(data.bytesize, brick_filename)
  sc.continue_download(handle, data)
end