Merge pull request #238 from hybridgroup/change/specifying-multiple-connections-or-devices
Support providing connections/devices as an object
This commit is contained in:
commit
aac7bd0de8
|
@ -84,16 +84,16 @@ Cylon.robot({
|
|||
var Cylon = require('cylon');
|
||||
|
||||
Cylon.robot({
|
||||
connections: [
|
||||
{ name: 'digispark', adaptor: 'digispark'},
|
||||
{ name: 'leapmotion', adaptor: 'leapmotion' }
|
||||
],
|
||||
connections: {
|
||||
digispark: { adaptor: 'digispark' },
|
||||
leapmotion: { adaptor: 'leapmotion' }
|
||||
},
|
||||
|
||||
devices: [
|
||||
{ name: 'servo1', driver: 'servo', pin: 0, connection: 'digispark' },
|
||||
{ name: 'servo2', driver: 'servo', pin: 1, connection: 'digispark' },
|
||||
{ name: 'leapmotion', driver: 'leapmotion', connection: 'leapmotion' }
|
||||
],
|
||||
devices: {
|
||||
servo1: { driver: 'servo', pin: 0, connection: 'digispark' },
|
||||
servo2: { driver: 'servo', pin: 1, connection: 'digispark' },
|
||||
leapmotion: { driver: 'leapmotion', connection: 'leapmotion' }
|
||||
},
|
||||
|
||||
work: function(my) {
|
||||
my.x = 90;
|
||||
|
|
|
@ -15,11 +15,12 @@ Arduino = (function(){
|
|||
})();
|
||||
|
||||
skynet = {
|
||||
connections: [
|
||||
{ name: 'skynet',
|
||||
adaptor: 'skynet',
|
||||
uuid: "96630051-a3dc-11e3-8442-5bf31d98c912", token: "2s67o7ek98pycik98f43reqr90t6s9k9" }
|
||||
],
|
||||
connection: {
|
||||
name: 'skynet',
|
||||
adaptor: 'skynet',
|
||||
uuid: "96630051-a3dc-11e3-8442-5bf31d98c912",
|
||||
token: "2s67o7ek98pycik98f43reqr90t6s9k9"
|
||||
},
|
||||
|
||||
work: function(my) {
|
||||
console.log("Skynet is listening...");
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
var Cylon = require('../..');
|
||||
|
||||
Cylon.robot({
|
||||
connections: [
|
||||
{ name: 'digispark', adaptor: 'digispark'},
|
||||
{ name: 'leapmotion', adaptor: 'leapmotion' }
|
||||
],
|
||||
connections: {
|
||||
digispark: { adaptor: 'digispark' },
|
||||
leapmotion: { adaptor: 'leapmotion' }
|
||||
},
|
||||
|
||||
devices: [
|
||||
{name: 'servo1', driver: 'servo', pin: 0, connection: 'digispark'},
|
||||
{name: 'servo2', driver: 'servo', pin: 1, connection: 'digispark'},
|
||||
{name: 'leapmotion', driver: 'leapmotion', connection: 'leapmotion'}
|
||||
],
|
||||
devices: {
|
||||
servo1: { driver: 'servo', pin: 0, connection: 'digispark' },
|
||||
servo2: { driver: 'servo', pin: 1, connection: 'digispark' },
|
||||
leapmotion: { driver: 'leapmotion', connection: 'leapmotion' }
|
||||
},
|
||||
|
||||
work: function(my) {
|
||||
my['x'] = 90;
|
||||
|
|
|
@ -10,16 +10,16 @@ Now that we have Cylon imported, we can start defining our robot
|
|||
|
||||
Let's define the connections and devices:
|
||||
|
||||
connections: [
|
||||
{ name: 'digispark', adaptor: 'digispark'},
|
||||
{ name: 'leapmotion', adaptor: 'leapmotion' }
|
||||
],
|
||||
connections: {
|
||||
digispark: { adaptor: 'digispark' },
|
||||
leapmotion: { adaptor: 'leapmotion' }
|
||||
},
|
||||
|
||||
devices: [
|
||||
{name: 'servo1', driver: 'servo', pin: 0, connection: 'digispark'},
|
||||
{name: 'servo2', driver: 'servo', pin: 1, connection: 'digispark'},
|
||||
{name: 'leapmotion', driver: 'leapmotion', connection: 'leapmotion'}
|
||||
],
|
||||
devices: {
|
||||
servo1: { driver: 'servo', pin: 0, connection: 'digispark' },
|
||||
servo2: { driver: 'servo', pin: 1, connection: 'digispark' },
|
||||
leapmotion: { driver: 'leapmotion', connection: 'leapmotion' }
|
||||
},
|
||||
|
||||
Now that Cylon knows about the necessary hardware we're going to be using, we'll
|
||||
tell it what work we want to do:
|
||||
|
|
|
@ -25,17 +25,17 @@ var handStartPosition = [],
|
|||
var handWasClosedInLastFrame = false;
|
||||
|
||||
Cylon.robot({
|
||||
connections: [
|
||||
{ name: 'leapmotion', adaptor: 'leapmotion' },
|
||||
{ name: 'ardrone', adaptor: 'ardrone', port: '192.168.1.1' },
|
||||
{ name: 'keyboard', adaptor: 'keyboard' }
|
||||
],
|
||||
connections: {
|
||||
leapmotion: { adaptor: 'leapmotion' },
|
||||
ardrone: { adaptor: 'ardrone', port: '192.168.1.1' },
|
||||
keyboard: { adaptor: 'keyboard' }
|
||||
},
|
||||
|
||||
devices: [
|
||||
{ name: 'drone', driver: 'ardrone', connection: 'ardrone' },
|
||||
{ name: 'leapmotion', driver: 'leapmotion', connection: 'leapmotion' },
|
||||
{ name: 'keyboard', driver: 'keyboard', connection: 'keyboard'}
|
||||
],
|
||||
devices: {
|
||||
drone: { driver: 'ardrone', connection:'ardrone' },
|
||||
leapmotion: { driver: 'leapmotion', connection:'leapmotion' },
|
||||
keyboard: { driver: 'keyboard', connection:'keyboard' }
|
||||
},
|
||||
|
||||
work: function(my) {
|
||||
my.keyboard.on('right', my.drone.rightFlip);
|
||||
|
|
|
@ -12,16 +12,17 @@ Now that we have Cylon imported, we can start defining our robot
|
|||
|
||||
Let's define the connections and devices:
|
||||
|
||||
connections: [
|
||||
{ name: 'leapmotion', adaptor: 'leapmotion' },
|
||||
{ name: 'ardrone', adaptor: 'ardrone', port: '192.168.1.1' },
|
||||
{ name: 'keyboard', adaptor: 'keyboard' }
|
||||
],
|
||||
devices: [
|
||||
{ name: 'drone', driver: 'ardrone', connection:'ardrone' },
|
||||
{ name: 'leapmotion', driver: 'leapmotion', connection:'leapmotion' },
|
||||
{ name: 'keyboard', driver: 'keyboard', connection:'keyboard'}
|
||||
],
|
||||
connections: {
|
||||
leapmotion: { adaptor: 'leapmotion' },
|
||||
ardrone: { adaptor: 'ardrone', port: '192.168.1.1' },
|
||||
keyboard: { adaptor: 'keyboard' }
|
||||
},
|
||||
|
||||
devices: {
|
||||
drone: { driver: 'ardrone', connection:'ardrone' },
|
||||
leapmotion: { driver: 'leapmotion', connection:'leapmotion' },
|
||||
keyboard: { driver: 'keyboard', connection:'keyboard' }
|
||||
},
|
||||
|
||||
Now that Cylon knows about the necessary hardware we're going to be using, we'll
|
||||
tell it what work we want to do:
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
var Cylon = require('../..');
|
||||
|
||||
Cylon.robot({
|
||||
connections: [{ name: 'leapmotion', adaptor: 'leapmotion' },
|
||||
{ name: 'arduino', adaptor: 'firmata', port: '/dev/ttyACM0' }],
|
||||
connections: {
|
||||
arduino: { adaptor: 'firmata', port: '/dev/ttyACM0' }
|
||||
leapmotion: { adaptor: 'leapmotion' },
|
||||
},
|
||||
|
||||
devices: [{ name: 'leapmotion', driver: 'leapmotion', connection: 'leapmotion' },
|
||||
{ name: 'led', driver: 'led', pin: 13, connection: 'arduino' }],
|
||||
devices: {
|
||||
led: { driver: 'led', pin: 13, connection: 'arduino' }
|
||||
leapmotion: { driver: 'leapmotion', connection: 'leapmotion' },
|
||||
},
|
||||
|
||||
work: function(my) {
|
||||
my.leapmotion.on('frame', function(frame) {
|
||||
|
|
|
@ -10,15 +10,15 @@ Now that we have Cylon imported, we can start defining our robot
|
|||
|
||||
Let's define the connections and devices:
|
||||
|
||||
connections: [
|
||||
{ name: 'leapmotion', adaptor: 'leapmotion' },
|
||||
{ name: 'arduino', adaptor: 'firmata', port: '/dev/ttyACM0' }
|
||||
],
|
||||
connections: {
|
||||
leapmotion: { adaptor: 'leapmotion' },
|
||||
arduino: { adaptor: 'firmata', port: '/dev/ttyACM0' }
|
||||
},
|
||||
|
||||
devices: [
|
||||
{ name: 'leapmotion', driver: 'leapmotion', connection: 'leapmotion' },
|
||||
{ name: 'led', driver: 'led', pin: 13, connection: 'arduino' }
|
||||
],
|
||||
devices: {
|
||||
leapmotion: { driver: 'leapmotion', connection: 'leapmotion' },
|
||||
led: { driver: 'led', pin: 13, connection: 'arduino' }
|
||||
},
|
||||
|
||||
Now that Cylon knows about the necessary hardware we're going to be using, we'll
|
||||
tell it what work we want to do:
|
||||
|
|
|
@ -2,8 +2,10 @@ var Cylon = require('../..');
|
|||
|
||||
Cylon.robot({
|
||||
connection: { name: 'arduino', adaptor: 'firmata', port: '/dev/ttyUSB0' },
|
||||
devices: [{name: 'led', driver: 'led', pin: 17},
|
||||
{ name: 'servo', driver: 'servo', pin: 2, range: { min: 30, max: 150 } }],
|
||||
devices: {
|
||||
led: { driver: 'led', pin: 17 },
|
||||
servo: { driver: 'servo', pin: 2, range: { min: 30, max: 150 } }
|
||||
},
|
||||
|
||||
work: function(my) {
|
||||
my.led.turnOn();
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
var Cylon = require('../..');
|
||||
|
||||
Cylon.robot({
|
||||
connections: [
|
||||
{ name: 'arduino', adaptor: 'firmata', port: '/dev/ttyACM0' },
|
||||
{ name: 'skynet', adaptor: 'skynet',
|
||||
uuid: "96630051-a3dc-11e3-8442-5bf31d98c912", token: "2s67o7ek98pycik98f43reqr90t6s9k9" }
|
||||
],
|
||||
connections: {
|
||||
arduino: { adaptor: 'firmata', port: '/dev/ttyACM0' },
|
||||
skynet: {
|
||||
adaptor: 'skynet',
|
||||
uuid: "96630051-a3dc-11e3-8442-5bf31d98c912",
|
||||
token: "2s67o7ek98pycik98f43reqr90t6s9k9"
|
||||
}
|
||||
},
|
||||
|
||||
device: { name: 'led13', driver: 'led', pin: 13, connection: 'arduino' },
|
||||
|
||||
|
|
|
@ -10,19 +10,14 @@ Now that we have Cylon imported, we can start defining our robot
|
|||
|
||||
Let's define the connections and devices:
|
||||
|
||||
connections: [
|
||||
{
|
||||
name: 'arduino',
|
||||
adaptor: 'firmata',
|
||||
port: '/dev/ttyACM0'
|
||||
},
|
||||
{
|
||||
name: 'skynet',
|
||||
connections: {
|
||||
arduino: { adaptor: 'firmata', port: '/dev/ttyACM0' },
|
||||
skynet: {
|
||||
adaptor: 'skynet',
|
||||
uuid: "96630051-a3dc-11e3-8442-5bf31d98c912",
|
||||
token: "2s67o7ek98pycik98f43reqr90t6s9k9"
|
||||
}
|
||||
],
|
||||
},
|
||||
|
||||
device: { name: 'led13', driver: 'led', pin: 13, connection: 'arduino' },
|
||||
|
||||
|
|
95
lib/robot.js
95
lib/robot.js
|
@ -78,8 +78,8 @@ var Robot = module.exports = function Robot(opts) {
|
|||
this.work = function() { Logger.debug("No work yet."); };
|
||||
}
|
||||
|
||||
this.initConnections(opts.connection || opts.connections);
|
||||
this.initDevices(opts.device || opts.devices);
|
||||
this.initConnections(opts);
|
||||
this.initDevices(opts);
|
||||
|
||||
for (var n in opts) {
|
||||
var opt = opts[n];
|
||||
|
@ -156,19 +156,15 @@ Robot.prototype.toJSON = function() {
|
|||
|
||||
// Public: Initializes all connections for the robot
|
||||
//
|
||||
// connections - connections to initialize
|
||||
// opts - options array passed to constructor
|
||||
//
|
||||
// Returns initialized connections
|
||||
Robot.prototype.initConnections = function(connections) {
|
||||
Robot.prototype.initConnections = function(opts) {
|
||||
Logger.info("Initializing connections.");
|
||||
|
||||
if (connections == null) {
|
||||
return;
|
||||
}
|
||||
var isArray = Array.isArray;
|
||||
|
||||
connections = [].concat(connections);
|
||||
|
||||
connections.forEach(function(conn) {
|
||||
var addConnection = function(conn) {
|
||||
conn.robot = this;
|
||||
|
||||
if (this.connections[conn.name]) {
|
||||
|
@ -177,34 +173,47 @@ Robot.prototype.initConnections = function(connections) {
|
|||
Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'");
|
||||
}
|
||||
|
||||
Logger.info("Initializing connection '" + conn.name + "'.");
|
||||
|
||||
this.connections[conn.name] = new Connection(conn);
|
||||
}.bind(this));
|
||||
}.bind(this);
|
||||
|
||||
if (opts.connection == null && opts.connections == null) {
|
||||
return this.connections;
|
||||
}
|
||||
|
||||
if (opts.connection) {
|
||||
addConnection(opts.connection);
|
||||
return this.connections;
|
||||
}
|
||||
|
||||
if (typeof opts.connections == 'object' && !isArray(opts.connections)) {
|
||||
for (var name in opts.connections) {
|
||||
var conn = opts.connections[name];
|
||||
conn.name = name;
|
||||
addConnection(conn);
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray(opts.connections)) {
|
||||
Logger.warn("Specifying connections as an array is deprecated, and will be removed in 1.0.0.");
|
||||
opts.connections.forEach(function(conn) {
|
||||
addConnection(conn);
|
||||
});
|
||||
}
|
||||
|
||||
return this.connections;
|
||||
};
|
||||
|
||||
// Public: Initializes all devices for the robot
|
||||
//
|
||||
// devices - devices to initialize
|
||||
// opts - options array passed to constructor
|
||||
//
|
||||
// Returns initialized devices
|
||||
Robot.prototype.initDevices = function(devices) {
|
||||
Robot.prototype.initDevices = function(opts) {
|
||||
Logger.info("Initializing devices.");
|
||||
|
||||
if (devices == null) {
|
||||
return;
|
||||
}
|
||||
var isArray = Array.isArray;
|
||||
|
||||
// check that there are connections to use
|
||||
if (!Object.keys(this.connections).length) {
|
||||
throw new Error("No connections specified")
|
||||
}
|
||||
|
||||
devices = [].concat(devices);
|
||||
|
||||
devices.forEach(function(device) {
|
||||
var addDevice = function(device) {
|
||||
device.robot = this;
|
||||
|
||||
if (this.devices[device.name]) {
|
||||
|
@ -228,11 +237,37 @@ Robot.prototype.initDevices = function(devices) {
|
|||
}
|
||||
}
|
||||
|
||||
device.adaptor = device.connection.adaptor;
|
||||
|
||||
Logger.info("Initializing device '" + device.name + "'.");
|
||||
this.devices[device.name] = new Device(device);
|
||||
}.bind(this));
|
||||
}.bind(this);
|
||||
|
||||
if (opts.device == null && opts.devices == null) {
|
||||
return this.devices;
|
||||
}
|
||||
|
||||
// check that there are connections to use
|
||||
if (!Object.keys(this.connections).length) {
|
||||
throw new Error("No connections specified")
|
||||
}
|
||||
|
||||
if (opts.device) {
|
||||
addDevice(opts.device);
|
||||
return this.devices;
|
||||
}
|
||||
|
||||
if (typeof opts.devices == 'object' && !isArray(opts.devices)) {
|
||||
for (var name in opts.devices) {
|
||||
var device = opts.devices[name];
|
||||
device.name = name;
|
||||
addDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray(opts.devices)) {
|
||||
Logger.warn("Specifying devices as an array is deprecated, and will be removed in 1.0.0.");
|
||||
opts.devices.forEach(function(device) {
|
||||
addDevice(device);
|
||||
});
|
||||
}
|
||||
|
||||
return this.devices;
|
||||
};
|
||||
|
|
|
@ -233,15 +233,16 @@ describe("Robot", function() {
|
|||
});
|
||||
|
||||
context("when not passed anything", function() {
|
||||
it("returns immediately", function() {
|
||||
expect(bot.initConnections()).to.be.eql(undefined);
|
||||
it("does not modify the bot's connections", function() {
|
||||
bot.initConnections({});
|
||||
expect(bot.connections).to.be.eql({});
|
||||
});
|
||||
});
|
||||
|
||||
context("when passed a connection object", function() {
|
||||
it("instantiates a new connection with the provided object", function() {
|
||||
var connection = { name: 'loopback', adaptor: 'loopback' };
|
||||
bot.initConnections(connection);
|
||||
bot.initConnections({ connection: connection });
|
||||
expect(bot.connections['loopback']).to.be.instanceOf(Connection);
|
||||
});
|
||||
});
|
||||
|
@ -249,15 +250,19 @@ describe("Robot", function() {
|
|||
context("when passed an array of connection objects", function() {
|
||||
it("instantiates a new connection with each of the provided objects", function() {
|
||||
var connections = [{ name: 'loopback', adaptor: 'loopback' }]
|
||||
bot.initConnections(connections);
|
||||
bot.initConnections({ connections: connections });
|
||||
expect(bot.connections['loopback']).to.be.instanceOf(Connection);
|
||||
});
|
||||
|
||||
it("avoids name collisions collisions", function() {
|
||||
bot.initConnections([
|
||||
{ name: 'loopback', adaptor: 'loopback' },
|
||||
{ name: 'loopback', adaptor: 'loopback' }
|
||||
]);
|
||||
it("avoids name collisions", function() {
|
||||
var opts = {
|
||||
connections: [
|
||||
{ name: 'loopback', adaptor: 'loopback' },
|
||||
{ name: 'loopback', adaptor: 'loopback' }
|
||||
]
|
||||
};
|
||||
|
||||
bot.initConnections(opts);
|
||||
|
||||
var keys = Object.keys(bot.connections);
|
||||
expect(keys).to.be.eql(["loopback", "loopback-1"]);
|
||||
|
@ -275,36 +280,35 @@ describe("Robot", function() {
|
|||
});
|
||||
|
||||
context("when not passed anything", function() {
|
||||
it("returns immediately", function() {
|
||||
expect(bot.initDevices()).to.be.eql(undefined);
|
||||
it("does not modify the bot's devices", function() {
|
||||
bot.initDevices({});
|
||||
expect(bot.devices).to.be.eql({});
|
||||
});
|
||||
});
|
||||
|
||||
context("when passed a connection object", function() {
|
||||
afterEach(function() { bot.devices = {}; });
|
||||
|
||||
context("when passed a devicw object", function() {
|
||||
it("instantiates a new device with the provided object", function() {
|
||||
var device = { name: 'ping', driver: 'ping' };
|
||||
bot.initDevices(device);
|
||||
bot.initDevices({ device: device });
|
||||
expect(bot.devices['ping']).to.be.instanceOf(Device);
|
||||
});
|
||||
});
|
||||
|
||||
context("when passed an array of device objects", function() {
|
||||
afterEach(function() { bot.devices = {}; });
|
||||
|
||||
it("instantiates a new device with each of the provided objects", function() {
|
||||
var devices = [{ name: 'ping', driver: 'ping' }]
|
||||
bot.initDevices(devices);
|
||||
bot.initDevices({ devices: devices});
|
||||
|
||||
expect(bot.devices['ping']).to.be.instanceOf(Device);
|
||||
});
|
||||
|
||||
it("avoids name collisions collisions", function() {
|
||||
bot.initDevices([
|
||||
{ name: 'ping', driver: 'ping' },
|
||||
{ name: 'ping', driver: 'ping' }
|
||||
]);
|
||||
bot.initDevices({
|
||||
devices: [
|
||||
{ name: 'ping', driver: 'ping' },
|
||||
{ name: 'ping', driver: 'ping' }
|
||||
]
|
||||
});
|
||||
|
||||
var keys = Object.keys(bot.devices);
|
||||
expect(keys).to.be.eql(["ping", "ping-1"]);
|
||||
|
@ -353,10 +357,10 @@ describe("Robot", function() {
|
|||
|
||||
beforeEach(function() {
|
||||
bot = new Robot({
|
||||
connections: [
|
||||
{ name: 'alpha', adaptor: 'loopback' },
|
||||
{ name: 'bravo', adaptor: 'loopback' }
|
||||
]
|
||||
connections: {
|
||||
alpha: { adaptor: 'loopback' },
|
||||
bravo: { adaptor: 'loopback' }
|
||||
}
|
||||
});
|
||||
|
||||
stub(bot.connections.alpha, 'connect').returns(true);
|
||||
|
@ -376,11 +380,11 @@ describe("Robot", function() {
|
|||
|
||||
beforeEach(function() {
|
||||
bot = new Robot({
|
||||
connection: [{ name: 'loopback', adaptor: 'loopback' }],
|
||||
devices: [
|
||||
{ name: 'alpha', driver: 'ping' },
|
||||
{ name: 'bravo', driver: 'ping' }
|
||||
]
|
||||
connection: { name: 'loopback', adaptor: 'loopback' },
|
||||
devices: {
|
||||
alpha: { driver: 'ping' },
|
||||
bravo: { driver: 'ping' }
|
||||
}
|
||||
});
|
||||
|
||||
stub(bot.devices.alpha, 'start').returns(true);
|
||||
|
|
Loading…
Reference in New Issue