lib/artoo/api/api.rb
require 'reel'
require 'artoo/api/route_helpers'
require 'artoo/api/device_event_client'
module Artoo
module Api
# Artoo API Server provides an interface to communicate with
# master class and retrieve information about robots being
# controlled
class Server < Reel::Server::HTTP
include RouteHelpers
# Create new API server
# @param [String] host
# @param [Int] port
def initialize(host = "127.0.0.1", port = 3000)
super(host, port, &method(:on_connection))
end
# Dispatches connection requests
def on_connection(connection)
while !connection.current_request && request = connection.request
dispatch!(connection, request)
end
end
# Retrieve api index
# @return [JSON] MCP index
get '/api' do
robots = master.robots.collect { |r| r.to_hash }
response = {MCP: {robots: robots, commands: master.commands}}
MultiJson.dump(response)
end
# Retrieve list of master commands
# @return [JSON] commands
get '/api/commands' do
MultiJson.dump({commands: master.commands})
end
# Execute master command
# @return [JSON] result
any '/api/commands/:commandid' do
result = master.command(@params['commandid'], *command_params)
MultiJson.dump({result: result})
end
# Retrieve list of robots
# @return [JSON] robots
get '/api/robots' do
robots = master.robots.collect {|r|r.to_hash}
response = {robots: robots}
MultiJson.dump(response)
end
# Retrieve robot by id
# @return [JSON] robot
get '/api/robots/:robotid' do
validate_params!
MultiJson.dump({robot: @robot.to_hash})
end
# Retrieve robot commands
# @return [JSON] commands
get '/api/robots/:robotid/commands' do
validate_params!
MultiJson.dump({commands: @robot.commands})
end
# Execute robot command
# @return [JSON] command
any '/api/robots/:robotid/commands/:commandid' do
validate_params!
result = @robot.command(@params['commandid'], *command_params)
return MultiJson.dump({'result' => result})
end
# Retrieve robot devices
# @return [JSON] devices
get '/api/robots/:robotid/devices' do
validate_params!
devices = @robot.devices.each_value.collect {|d| d.to_hash}
MultiJson.dump({devices: devices})
end
# Retrieve robot device
# @return [JSON] device
get '/api/robots/:robotid/devices/:deviceid' do
validate_params!
MultiJson.dump({device: @device.to_hash})
end
# Retrieve robot commands
# @return [JSON] commands
get '/api/robots/:robotid/devices/:deviceid/commands' do
validate_params!
MultiJson.dump({commands: @device.commands})
end
# Execute robot command
# @return [JSON] command
any '/api/robots/:robotid/devices/:deviceid/commands/:commandid' do
validate_params!
result = @device.command(@params['commandid'], *command_params)
return MultiJson.dump({'result' => result})
end
# Subscribe to robot device events
# @return [nil]
get '/api/robots/:robotid/devices/:deviceid/events/:eventid' do
validate_params!
topic = @device.event_topic_name(@params['eventid'])
DeviceEventClient.new(@connection, topic)
return
end
# Retrieve robot connections
# @return [JSON] connections
get '/api/robots/:robotid/connections' do
validate_params!
connections = @robot.connections.each_value.collect {|c| c.to_hash}
MultiJson.dump({connections: connections})
end
# Retrieve robot connection
# @return [JSON] connection
get '/api/robots/:robotid/connections/:connectionid' do
validate_params!
MultiJson.dump({connection: @conn.to_hash})
end
protected
def master
Actor[:master]
end
def device(robot_id, device_id)
master.robot_device(robot_id, device_id)
end
def validate_params!
robot = @params['robotid']
device = @params['deviceid']
connection = @params['connectionid']
if robot
@robot = master.robot(robot)
unless @robot
@error = "No Robot found with the name #{robot}"
raise RobotNotFound
end
end
if device
@device = @robot.devices[device.intern]
unless @device
@error = "No device found with the name #{device}"
raise RobotNotFound
end
end
if connection
@conn = @robot.connections[connection.intern]
unless @conn
@error = "No connection found with the name #{connection}"
raise RobotNotFound
end
end
end
def command_params
if @req.body.to_s != ""
data = MultiJson.load(@req.body.to_s, :symbolize_keys => true)
data.values
end
end
end
end
end