Merge branch 'master' into literate
* master: Update to version 0.6.0 Execute robot commands from api Replace api.litcoffee with api.coffee Replace api.litcoffee with api.coffee Docs corrections Refactoring adaptor and driver initialization to simplify, and fix init overwrite error Conflicts: src/api.coffee
This commit is contained in:
commit
dbfa4f859e
|
@ -108,6 +108,8 @@ In lieu of a formal styleguide, take care to maintain the existing coding style.
|
|||
|
||||
[![NPM](https://nodei.co/npm/cylon.png?compact=true)](https://nodei.co/npm/cylon/)
|
||||
|
||||
Version 0.6.0 - API exposes robot commands, fixes issues in driver/adaptor init
|
||||
|
||||
Version 0.5.0 - Improve API, add GPIO support for reuse in adaptors
|
||||
|
||||
Version 0.4.0 - Refactor proxy in Cylon.Basestar, improve API
|
||||
|
|
|
@ -61,6 +61,32 @@
|
|||
return res.json(err ? err : robot.data());
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robotname/commands", function(req, res) {
|
||||
return master.findRobot(req.params.robotname, function(err, robot) {
|
||||
return res.json(err ? err : robot.data().commands);
|
||||
});
|
||||
});
|
||||
this.server.all("/robots/:robotname/commands/:commandname", function(req, res) {
|
||||
var key, params, value, _ref;
|
||||
params = [];
|
||||
if (typeof req.body === 'object') {
|
||||
_ref = req.body;
|
||||
for (key in _ref) {
|
||||
value = _ref[key];
|
||||
params.push(value);
|
||||
}
|
||||
}
|
||||
return master.findRobot(req.params.robotname, function(err, robot) {
|
||||
var result;
|
||||
if (err) {
|
||||
return res.json(err);
|
||||
}
|
||||
result = robot[req.params.commandname].apply(robot, params);
|
||||
return res.json({
|
||||
result: result
|
||||
});
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robotname/devices", function(req, res) {
|
||||
return master.findRobot(req.params.robotname, function(err, robot) {
|
||||
return res.json(err ? err : robot.data().devices);
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
this.robot = opts.robot;
|
||||
this.name = opts.name;
|
||||
this.connection_id = opts.id;
|
||||
this.adaptor = this.requireAdaptor(opts);
|
||||
this.adaptor = this.initAdaptor(opts);
|
||||
this.port = new Cylon.Port(opts.port);
|
||||
proxyFunctionsToObject(this.adaptor.commands(), this.adaptor, this.self);
|
||||
}
|
||||
|
@ -72,9 +72,9 @@
|
|||
return this.adaptor.disconnect();
|
||||
};
|
||||
|
||||
Connection.prototype.requireAdaptor = function(opts) {
|
||||
Connection.prototype.initAdaptor = function(opts) {
|
||||
Logger.debug("Loading adaptor '" + opts.adaptor + "'");
|
||||
return this.robot.requireAdaptor(opts.adaptor, this.self, opts);
|
||||
return this.robot.initAdaptor(opts.adaptor, this.self, opts);
|
||||
};
|
||||
|
||||
return Connection;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
this.name = opts.name;
|
||||
this.pin = opts.pin;
|
||||
this.connection = this.determineConnection(opts.connection) || this.defaultConnection();
|
||||
this.driver = this.requireDriver(opts);
|
||||
this.driver = this.initDriver(opts);
|
||||
proxyFunctionsToObject(this.driver.commands(), this.driver, this.self);
|
||||
}
|
||||
|
||||
|
@ -81,12 +81,12 @@
|
|||
return first;
|
||||
};
|
||||
|
||||
Device.prototype.requireDriver = function(opts) {
|
||||
Device.prototype.initDriver = function(opts) {
|
||||
if (opts == null) {
|
||||
opts = {};
|
||||
}
|
||||
Logger.debug("Loading driver '" + opts.driver + "'");
|
||||
return this.robot.requireDriver(opts.driver, this.self, opts);
|
||||
return this.robot.initDriver(opts.driver, this.self, opts);
|
||||
};
|
||||
|
||||
return Device;
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
opts = {};
|
||||
}
|
||||
this.registerDriver = __bind(this.registerDriver, this);
|
||||
this.requireDriver = __bind(this.requireDriver, this);
|
||||
this.registerAdaptor = __bind(this.registerAdaptor, this);
|
||||
this.requireAdaptor = __bind(this.requireAdaptor, this);
|
||||
this.stop = __bind(this.stop, this);
|
||||
this.startDevices = __bind(this.startDevices, this);
|
||||
this.startConnections = __bind(this.startConnections, this);
|
||||
|
@ -52,6 +55,7 @@
|
|||
this.devices = {};
|
||||
this.adaptors = {};
|
||||
this.drivers = {};
|
||||
this.commands = [];
|
||||
this.registerAdaptor("./loopback", "loopback");
|
||||
this.registerDriver("./ping", "ping");
|
||||
this.initConnections(opts.connection || opts.connections);
|
||||
|
@ -95,7 +99,8 @@
|
|||
_results.push(device.data());
|
||||
}
|
||||
return _results;
|
||||
}).call(this)
|
||||
}).call(this),
|
||||
commands: this.commands
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -182,64 +187,54 @@
|
|||
return _results;
|
||||
};
|
||||
|
||||
Robot.prototype.requireAdaptor = function(adaptorName, connection, opts) {
|
||||
Robot.prototype.initAdaptor = function(adaptorName, connection, opts) {
|
||||
if (opts == null) {
|
||||
opts = {};
|
||||
}
|
||||
if (this.robot.adaptors[adaptorName] != null) {
|
||||
if (typeof this.robot.adaptors[adaptorName] === 'string') {
|
||||
this.robot.adaptors[adaptorName] = require(this.robot.adaptors[adaptorName]).adaptor({
|
||||
name: adaptorName,
|
||||
connection: connection,
|
||||
extraParams: opts
|
||||
});
|
||||
}
|
||||
} else {
|
||||
require("cylon-" + adaptorName).register(this);
|
||||
this.robot.adaptors[adaptorName] = require("cylon-" + adaptorName).adaptor({
|
||||
name: adaptorName,
|
||||
connection: connection,
|
||||
extraParams: opts
|
||||
});
|
||||
return this.robot.requireAdaptor(adaptorName).adaptor({
|
||||
name: adaptorName,
|
||||
connection: connection,
|
||||
extraParams: opts
|
||||
});
|
||||
};
|
||||
|
||||
Robot.prototype.requireAdaptor = function(adaptorName) {
|
||||
if (this.robot.adaptors[adaptorName] == null) {
|
||||
this.robot.registerAdaptor("cylon-" + adaptorName, adaptorName);
|
||||
this.robot.adaptors[adaptorName].register(this);
|
||||
}
|
||||
return this.robot.adaptors[adaptorName];
|
||||
};
|
||||
|
||||
Robot.prototype.registerAdaptor = function(moduleName, adaptorName) {
|
||||
if (this.adaptors[adaptorName] != null) {
|
||||
return;
|
||||
if (this.adaptors[adaptorName] == null) {
|
||||
return this.adaptors[adaptorName] = require(moduleName);
|
||||
}
|
||||
return this.adaptors[adaptorName] = moduleName;
|
||||
};
|
||||
|
||||
Robot.prototype.requireDriver = function(driverName, device, opts) {
|
||||
Robot.prototype.initDriver = function(driverName, device, opts) {
|
||||
if (opts == null) {
|
||||
opts = {};
|
||||
}
|
||||
if (this.robot.drivers[driverName] != null) {
|
||||
if (typeof this.robot.drivers[driverName] === 'string') {
|
||||
this.robot.drivers[driverName] = require(this.robot.drivers[driverName]).driver({
|
||||
name: driverName,
|
||||
device: device,
|
||||
extraParams: opts
|
||||
});
|
||||
}
|
||||
} else {
|
||||
require("cylon-" + driverName).register(this);
|
||||
this.robot.drivers[driverName] = require("cylon-" + driverName).driver({
|
||||
name: driverName,
|
||||
device: device,
|
||||
extraParams: opts
|
||||
});
|
||||
return this.robot.requireDriver(driverName).driver({
|
||||
name: driverName,
|
||||
device: device,
|
||||
extraParams: opts
|
||||
});
|
||||
};
|
||||
|
||||
Robot.prototype.requireDriver = function(driverName) {
|
||||
if (this.robot.drivers[driverName] == null) {
|
||||
this.robot.registerDriver("cylon-" + driverName, driverName);
|
||||
this.robot.drivers[driverName].register(this);
|
||||
}
|
||||
return this.robot.drivers[driverName];
|
||||
};
|
||||
|
||||
Robot.prototype.registerDriver = function(moduleName, driverName) {
|
||||
if (this.drivers[driverName] != null) {
|
||||
return;
|
||||
if (this.drivers[driverName] == null) {
|
||||
return this.drivers[driverName] = require(moduleName);
|
||||
}
|
||||
return this.drivers[driverName] = moduleName;
|
||||
};
|
||||
|
||||
return Robot;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
Cylon = require '..'
|
||||
|
||||
Cylon.api host: '0.0.0.0', port: '8080'
|
||||
|
||||
class MyRobot
|
||||
commands:
|
||||
["relax"]
|
||||
|
||||
relax: ->
|
||||
return "#{this.name} says relax"
|
||||
|
||||
work: (me) ->
|
||||
every 1.seconds(), ->
|
||||
Logger.info me.name
|
||||
|
||||
robot = new MyRobot
|
||||
robot.name = "frankie"
|
||||
Cylon.robot robot
|
||||
|
||||
Cylon.start()
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cylon",
|
||||
"version": "0.5.0",
|
||||
"version": "0.6.0",
|
||||
"main": "dist/cylon.js",
|
||||
"description": "A JavaScript robotics framework using Node.js",
|
||||
"homepage": "http://cylonjs.com",
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace 'Cylon', ->
|
|||
@robot = opts.robot
|
||||
@name = opts.name
|
||||
@connection_id = opts.id
|
||||
@adaptor = @requireAdaptor opts
|
||||
@adaptor = @initAdaptor opts
|
||||
@port = new Cylon.Port opts.port
|
||||
proxyFunctionsToObject @adaptor.commands(), @adaptor, @self
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace 'Cylon', ->
|
|||
connection_id: @connection_id
|
||||
}
|
||||
|
||||
# Public: Creates the adaptor connection
|
||||
# Public: Connect the adaptor's connection
|
||||
#
|
||||
# callback - callback function to run when the adaptor is connected
|
||||
#
|
||||
|
@ -61,7 +61,7 @@ namespace 'Cylon', ->
|
|||
Logger.info msg
|
||||
@adaptor.connect(callback)
|
||||
|
||||
# Public: Closes the adaptor connection
|
||||
# Public: Disconnect the adaptor's connection
|
||||
#
|
||||
# Returns nothing
|
||||
disconnect: ->
|
||||
|
@ -72,11 +72,12 @@ namespace 'Cylon', ->
|
|||
|
||||
# Public: sets up adaptor with @robot
|
||||
#
|
||||
# adaptorName - module name of adaptor to require
|
||||
# opts - options for adaptor being initialized
|
||||
# adaptor - name of the adaptor
|
||||
#
|
||||
# Returns the set-up adaptor
|
||||
requireAdaptor: (opts) ->
|
||||
initAdaptor: (opts) ->
|
||||
Logger.debug "Loading adaptor '#{opts.adaptor}'"
|
||||
@robot.requireAdaptor(opts.adaptor, @self, opts)
|
||||
@robot.initAdaptor(opts.adaptor, @self, opts)
|
||||
|
||||
module.exports = Cylon.Connection
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace 'Cylon', ->
|
|||
@name = opts.name
|
||||
@pin = opts.pin
|
||||
@connection = @determineConnection(opts.connection) or @defaultConnection()
|
||||
@driver = @requireDriver(opts)
|
||||
@driver = @initDriver(opts)
|
||||
proxyFunctionsToObject @driver.commands(), @driver, @self
|
||||
|
||||
# Public: Starts the device driver
|
||||
|
@ -86,12 +86,12 @@ namespace 'Cylon', ->
|
|||
|
||||
# Public: sets up driver with @robot
|
||||
#
|
||||
# opts - object containing options when requiring driver
|
||||
# driver - name of the module to require()
|
||||
# opts - object containing options when initializing driver
|
||||
# driver - name of the driver to intt()
|
||||
#
|
||||
# Returns the set-up driver
|
||||
requireDriver: (opts = {}) ->
|
||||
initDriver: (opts = {}) ->
|
||||
Logger.debug "Loading driver '#{ opts.driver }'"
|
||||
@robot.requireDriver(opts.driver, @self, opts)
|
||||
@robot.initDriver(opts.driver, @self, opts)
|
||||
|
||||
module.exports = Cylon.Device
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace 'Cylon', ->
|
|||
@devices = {}
|
||||
@adaptors = {}
|
||||
@drivers = {}
|
||||
@commands = []
|
||||
|
||||
@registerAdaptor "./loopback", "loopback"
|
||||
@registerDriver "./ping", "ping"
|
||||
|
@ -81,6 +82,7 @@ namespace 'Cylon', ->
|
|||
name: @name
|
||||
connections: (connection.data() for n, connection of @connections)
|
||||
devices: (device.data() for n, device of @devices)
|
||||
commands: @commands
|
||||
}
|
||||
|
||||
# Public: Initializes all connections for the robot
|
||||
|
@ -162,31 +164,27 @@ namespace 'Cylon', ->
|
|||
for n, connection of @connections
|
||||
connection.disconnect()
|
||||
|
||||
# Public: Requires a hardware adaptor and adds it to @robot.adaptors
|
||||
# Public: Initialize an adaptor and adds it to @robot.adaptors
|
||||
#
|
||||
# adaptorName - module name of adaptor to require
|
||||
# connection - the Connection that requested the adaptor be required
|
||||
#
|
||||
# Returns the set-up adaptor
|
||||
requireAdaptor: (adaptorName, connection, opts = {}) ->
|
||||
if @robot.adaptors[adaptorName]?
|
||||
if typeof @robot.adaptors[adaptorName] is 'string'
|
||||
@robot.adaptors[adaptorName] = require(
|
||||
@robot.adaptors[adaptorName]
|
||||
).adaptor(
|
||||
name: adaptorName,
|
||||
connection: connection,
|
||||
extraParams: opts
|
||||
)
|
||||
else
|
||||
require("cylon-#{adaptorName}").register(this)
|
||||
@robot.adaptors[adaptorName] = require(
|
||||
"cylon-#{adaptorName}"
|
||||
).adaptor(
|
||||
name: adaptorName,
|
||||
connection: connection,
|
||||
extraParams: opts
|
||||
)
|
||||
# Returns the adaptor
|
||||
initAdaptor: (adaptorName, connection, opts = {}) ->
|
||||
@robot.requireAdaptor(adaptorName).adaptor
|
||||
name: adaptorName,
|
||||
connection: connection,
|
||||
extraParams: opts
|
||||
|
||||
# Public: Requires a hardware adaptor and adds it to @robot.adaptors
|
||||
#
|
||||
# adaptorName - module name of adaptor to require
|
||||
#
|
||||
# Returns the module for the adaptor
|
||||
requireAdaptor: (adaptorName) =>
|
||||
unless @robot.adaptors[adaptorName]?
|
||||
@robot.registerAdaptor "cylon-#{adaptorName}", adaptorName
|
||||
@robot.adaptors[adaptorName].register this
|
||||
|
||||
return @robot.adaptors[adaptorName]
|
||||
|
||||
|
@ -196,35 +194,31 @@ namespace 'Cylon', ->
|
|||
# adaptorName - name of the adaptor to register the moduleName under
|
||||
#
|
||||
# Returns the registered module name
|
||||
registerAdaptor: (moduleName, adaptorName) ->
|
||||
return if @adaptors[adaptorName]?
|
||||
@adaptors[adaptorName] = moduleName
|
||||
registerAdaptor: (moduleName, adaptorName) =>
|
||||
@adaptors[adaptorName] = require(moduleName) unless @adaptors[adaptorName]?
|
||||
|
||||
# Public: Requires a hardware driver and adds it to @robot.drivers
|
||||
# Public: Init a hardware driver
|
||||
#
|
||||
# driverName - driver name
|
||||
# device - the Device that requested the driver be initialized
|
||||
# opts - object containing options when initializing driver
|
||||
#
|
||||
# Returns the new driver
|
||||
initDriver: (driverName, device, opts = {}) ->
|
||||
@robot.requireDriver(driverName).driver
|
||||
name: driverName,
|
||||
device: device,
|
||||
extraParams: opts
|
||||
|
||||
# Public: Requires module for a driver and adds it to @robot.drivers
|
||||
#
|
||||
# driverName - module name of driver to require
|
||||
# connection - the Connection that requested the driver be required
|
||||
#
|
||||
# Returns the set-up driver
|
||||
requireDriver: (driverName, device, opts = {}) ->
|
||||
if @robot.drivers[driverName]?
|
||||
if typeof @robot.drivers[driverName] is 'string'
|
||||
@robot.drivers[driverName] = require(
|
||||
@robot.drivers[driverName]
|
||||
).driver(
|
||||
name: driverName,
|
||||
device: device,
|
||||
extraParams: opts
|
||||
)
|
||||
else
|
||||
require("cylon-#{driverName}").register(this)
|
||||
@robot.drivers[driverName] = require(
|
||||
"cylon-#{driverName}"
|
||||
).driver(
|
||||
name: driverName,
|
||||
device: device,
|
||||
extraParams: opts
|
||||
)
|
||||
# Returns the module for driver
|
||||
requireDriver: (driverName) =>
|
||||
unless @robot.drivers[driverName]?
|
||||
@robot.registerDriver "cylon-#{driverName}", driverName
|
||||
@robot.drivers[driverName].register this
|
||||
|
||||
return @robot.drivers[driverName]
|
||||
|
||||
|
@ -235,7 +229,6 @@ namespace 'Cylon', ->
|
|||
#
|
||||
# Returns the registered module name
|
||||
registerDriver: (moduleName, driverName) =>
|
||||
return if @drivers[driverName]?
|
||||
@drivers[driverName] = moduleName
|
||||
@drivers[driverName] = require(moduleName) unless @drivers[driverName]?
|
||||
|
||||
module.exports = Cylon.Robot
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
source("robot");
|
||||
|
||||
describe("Connection", function() {
|
||||
var adaptor, connection, requireAdaptor, robot;
|
||||
var adaptor, connection, initAdaptor, robot;
|
||||
robot = new Cylon.Robot({
|
||||
name: 'me'
|
||||
});
|
||||
adaptor = new Cylon.Adaptor({
|
||||
name: 'loopback'
|
||||
});
|
||||
requireAdaptor = sinon.stub(robot, 'requireAdaptor').returns(adaptor);
|
||||
initAdaptor = sinon.stub(robot, 'initAdaptor').returns(adaptor);
|
||||
connection = new Cylon.Connection({
|
||||
name: "connective",
|
||||
adaptor: "loopback",
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
source("test/driver");
|
||||
|
||||
describe("Device", function() {
|
||||
var device, driver, requireDriver, robot;
|
||||
var device, driver, initDriver, robot;
|
||||
robot = new Cylon.Robot({
|
||||
name: 'me'
|
||||
});
|
||||
driver = new Cylon.Driver({
|
||||
name: 'driving'
|
||||
});
|
||||
requireDriver = sinon.stub(robot, 'requireDriver').returns(driver);
|
||||
initDriver = sinon.stub(robot, 'initDriver').returns(driver);
|
||||
device = new Cylon.Device({
|
||||
name: "devisive",
|
||||
driver: 'driving',
|
||||
|
@ -28,8 +28,8 @@
|
|||
});
|
||||
it("should use default connection if none specified");
|
||||
it("should use connection if one is specified");
|
||||
return it("should require a driver", function() {
|
||||
return requireDriver.should.be.called;
|
||||
return it("should init a driver", function() {
|
||||
return initDriver.should.be.called;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ source "robot"
|
|||
describe "Connection", ->
|
||||
robot = new Cylon.Robot(name: 'me')
|
||||
adaptor = new Cylon.Adaptor(name: 'loopback')
|
||||
requireAdaptor = sinon.stub(robot, 'requireAdaptor').returns(adaptor)
|
||||
initAdaptor = sinon.stub(robot, 'initAdaptor').returns(adaptor)
|
||||
connection = new Cylon.Connection
|
||||
name: "connective"
|
||||
adaptor: "loopback"
|
||||
|
|
|
@ -7,7 +7,7 @@ source "test/driver"
|
|||
describe "Device", ->
|
||||
robot = new Cylon.Robot(name: 'me')
|
||||
driver = new Cylon.Driver(name: 'driving')
|
||||
requireDriver = sinon.stub(robot, 'requireDriver').returns(driver)
|
||||
initDriver = sinon.stub(robot, 'initDriver').returns(driver)
|
||||
device = new Cylon.Device(name: "devisive", driver: 'driving', robot: robot)
|
||||
|
||||
it "should belong to a robot", ->
|
||||
|
@ -19,5 +19,5 @@ describe "Device", ->
|
|||
it "should use default connection if none specified"
|
||||
it "should use connection if one is specified"
|
||||
|
||||
it "should require a driver", ->
|
||||
requireDriver.should.be.called
|
||||
it "should init a driver", ->
|
||||
initDriver.should.be.called
|
||||
|
|
Loading…
Reference in New Issue