Remove Connection and Device classes

They are now functions that return instances of Adaptors and Drivers
respectively.
This commit is contained in:
Andrew Stewart 2014-11-10 15:56:25 -08:00
parent aac7bd0de8
commit e67ae19882
9 changed files with 80 additions and 197 deletions

View File

@ -23,7 +23,33 @@ var Adaptor = module.exports = function Adaptor(opts) {
opts = opts || {}; opts = opts || {};
this.name = opts.name; this.name = opts.name;
this.connection = opts.connection;
// the Robot the adaptor belongs to
this.robot = opts.robot;
// some default options
this.host = opts.host;
this.port = opts.port;
// misc. details provided in args hash
this.details = {};
for (var opt in opts) {
if (['robot', 'name', 'adaptor'].indexOf(opt) < 0) {
this.details[opt] = opts[opt];
}
}
}; };
Utils.subclass(Adaptor, Basestar); Utils.subclass(Adaptor, Basestar);
// Public: Expresses the Connection in JSON format
//
// Returns an Object containing Connection data
Adaptor.prototype.toJSON = function() {
return {
name: this.name,
adaptor: this.constructor.name || this.name,
details: this.details
};
};

View File

@ -42,7 +42,7 @@ var load = function load(req, res, next) {
}; };
router.get("/", function(req, res) { router.get("/", function(req, res) {
res.json({ MCP: Cylon }); res.json({ MCP: Cylon.toJSON() });
}); });
router.get("/commands", function(req, res) { router.get("/commands", function(req, res) {
@ -102,12 +102,12 @@ router.get("/robots/:robot/devices/:device/events/:event", load, function(req, r
}); });
router.get("/robots/:robot/devices/:device/commands", load, function(req, res) { router.get("/robots/:robot/devices/:device/commands", load, function(req, res) {
res.json({ commands: Object.keys(req.device.driver.commands) }); res.json({ commands: Object.keys(req.device.commands) });
}); });
router.all("/robots/:robot/devices/:device/commands/:command", load, function(req, res) { router.all("/robots/:robot/devices/:device/commands/:command", load, function(req, res) {
var command = req.device.driver.commands[req.params.command]; var command = req.device.commands[req.params.command];
var result = command.apply(req.device.driver, req.commandParams); var result = command.apply(req.device, req.commandParams);
res.json({ result: result }); res.json({ result: result });
}); });

View File

@ -69,24 +69,23 @@ Basestar.prototype.defineEvent = function(opts) {
// Public: Creates an event handler that proxies events from an adaptor's // Public: Creates an event handler that proxies events from an adaptor's
// 'connector' (reference to whatever module is actually talking to the hw) // 'connector' (reference to whatever module is actually talking to the hw)
// to the adaptor's associated connection. // to the adaptor
// //
// opts - hash of opts to be passed to defineEvent() // opts - hash of opts to be passed to defineEvent()
// //
// Returns this.connector // Returns this.connector
Basestar.prototype.defineAdaptorEvent = function(opts) { Basestar.prototype.defineAdaptorEvent = function(opts) {
return this._proxyEvents(opts, this.connector, this.connection); return this._proxyEvents(opts, this.connector, this);
}; };
// Public: Creates an event handler that proxies events from an device's // Public: Creates an event handler that proxies events from an driver's
// 'connector' (reference to whatever module is actually talking to the hw) // adaptor to the driver
// to the device's associated connection.
// //
// opts - hash of opts to be passed to defineEvent() // opts - hash of opts to be passed to defineEvent()
// //
// Returns this.connection // Returns this.connection
Basestar.prototype.defineDriverEvent = function(opts) { Basestar.prototype.defineDriverEvent = function(opts) {
return this._proxyEvents(opts, this.connection, this.device); return this._proxyEvents(opts, this.adaptor, this);
}; };
Basestar.prototype._proxyEvents = function(opts, source, target) { Basestar.prototype._proxyEvents = function(opts, source, target) {

View File

@ -8,18 +8,15 @@
'use strict'; 'use strict';
var EventEmitter = require('events').EventEmitter;
var Registry = require('./registry'), var Registry = require('./registry'),
Config = require('./config'), Config = require('./config'),
Logger = require('./logger'), Logger = require('./logger');
Utils = require('./utils');
var testMode = function() { var testMode = function() {
return process.env.NODE_ENV === 'test' && Config.testMode; return process.env.NODE_ENV === 'test' && Config.testMode;
}; };
// Public: Creates a new Connection // Public: Creates a new Adaptor and returns it.
// //
// opts - hash of acceptable params: // opts - hash of acceptable params:
// robot - Robot the Connection belongs to // robot - Robot the Connection belongs to
@ -28,81 +25,17 @@ var testMode = function() {
// port - string port to use for the Connection // port - string port to use for the Connection
// //
// Returns the newly set-up connection // Returns the newly set-up connection
var Connection = module.exports = function Connection(opts) { module.exports = function Connection(opts) {
opts = opts || {};
this.connect = this.connect.bind(this);
this.robot = opts.robot;
this.name = opts.name;
this.port = opts.port;
this.adaptor = this.initAdaptor(opts);
this.details = {};
for (var opt in opts) {
if (['robot', 'name', 'adaptor', 'connection'].indexOf(opt) < 0) {
this.details[opt] = opts[opt];
}
}
};
Utils.subclass(Connection, EventEmitter);
// Public: Expresses the Connection in JSON format
//
// Returns an Object containing Connection data
Connection.prototype.toJSON = function() {
return {
name: this.name,
adaptor: this.adaptor.constructor.name || this.adaptor.name,
details: this.details
};
};
// Public: Connect the adaptor's connection
//
// callback - callback function to run when the adaptor is connected
//
// Returns nothing
Connection.prototype.connect = function(callback) {
var msg = this._logstring("Connecting to");
Logger.info(msg);
this.adaptor.connect(function() {
Utils.proxyFunctions(this.adaptor, this)
callback.apply(this, arguments);
}.bind(this));
};
// Public: Disconnect the adaptor's connection
//
// callback - function to be triggered then the adaptor has disconnected
//
// Returns nothing
Connection.prototype.disconnect = function(callback) {
var msg = this._logstring("Disconnecting from");
Logger.info(msg);
this.removeAllListeners();
this.adaptor.disconnect(callback);
};
// Public: sets up adaptor with @robot
//
// opts - options for adaptor being initialized
// adaptor - name of the adaptor
//
// Returns the set-up adaptor
Connection.prototype.initAdaptor = function(opts) {
var module; var module;
opts = opts || {};
if (opts.module) { if (opts.module) {
module = Registry.register(opts.module); module = Registry.register(opts.module);
} else { } else {
module = Registry.findByAdaptor(opts.adaptor); module = Registry.findByAdaptor(opts.adaptor);
} }
opts.connection = this;
if (!module) { if (!module) {
Registry.register('cylon-' + opts.adaptor); Registry.register('cylon-' + opts.adaptor);
module = Registry.findByAdaptor(opts.adaptor); module = Registry.findByAdaptor(opts.adaptor);
@ -124,15 +57,3 @@ Connection.prototype.initAdaptor = function(opts) {
return adaptor; return adaptor;
}; };
Connection.prototype._logstring = function _logstring(action) {
var msg = action + " '" + this.name + "'";
if (this.port != null) {
msg += " on port " + this.port;
}
msg += ".";
return msg;
};

View File

@ -133,7 +133,7 @@ Cylon.toJSON = function() {
var robots = []; var robots = [];
for (var bot in this.robots) { for (var bot in this.robots) {
robots.push(this.robots[bot]); robots.push(this.robots[bot].toJSON());
} }
return { return {

View File

@ -8,12 +8,8 @@
'use strict'; 'use strict';
var EventEmitter = require('events').EventEmitter;
var Registry = require('./registry'), var Registry = require('./registry'),
Config = require('./config'), Config = require('./config');
Logger = require('./logger'),
Utils = require('./utils');
var testMode = function() { var testMode = function() {
return process.env.NODE_ENV === 'test' && Config.testMode; return process.env.NODE_ENV === 'test' && Config.testMode;
@ -29,83 +25,7 @@ var testMode = function() {
// driver - string name of the module the device driver logic lives in // driver - string name of the module the device driver logic lives in
// //
// Returns a new Device // Returns a new Device
var Device = module.exports = function Device(opts) { module.exports = function Device(opts) {
if (opts == null) {
opts = {};
}
this.halt = this.halt.bind(this);
this.start = this.start.bind(this);
this.robot = opts.robot;
this.name = opts.name;
this.pin = opts.pin;
this.connection = opts.connection;
this.driver = this.initDriver(opts);
this.details = {};
for (var opt in opts) {
if (['robot', 'name', 'connection', 'driver', 'device', 'adaptor'].indexOf(opt) < 0) {
this.details[opt] = opts[opt];
}
}
};
Utils.subclass(Device, EventEmitter);
// Public: Starts the device driver
//
// callback - callback function to be executed by the driver start
//
// Returns nothing
Device.prototype.start = function(callback) {
var msg = "Starting device '" + this.name + "'";
if (this.pin != null) {
msg += " on pin " + this.pin;
}
msg += ".";
Logger.info(msg);
this.driver.start(function() {
Utils.proxyFunctions(this.driver, this)
callback.apply(this, arguments);
}.bind(this));
};
// Public: Halt the device driver
//
// callback - function to trigger when the device has been halted
//
// Returns nothing
Device.prototype.halt = function(callback) {
Logger.info("Halting device '" + this.name + "'.");
this.removeAllListeners();
this.driver.halt(callback);
};
// Public: Expresses the Device in JSON format
//
// Returns an Object containing Connection data
Device.prototype.toJSON = function() {
return {
name: this.name,
driver: this.driver.constructor.name || this.driver.name,
connection: this.connection.name,
commands: Object.keys(this.driver.commands),
details: this.details
};
};
// Public: sets up driver with @robot
//
// opts - object containing options when initializing driver
// driver - name of the driver to intt()
//
// Returns the set-up driver
Device.prototype.initDriver = function(opts) {
var module; var module;
if (opts.module) { if (opts.module) {

View File

@ -23,21 +23,30 @@ var Driver = module.exports = function Driver(opts) {
opts = opts || {}; opts = opts || {};
this.name = opts.name; this.name = opts.name;
this.robot = opts.robot
this.device = opts.device; this.adaptor = opts.adaptor
this.connection = opts.device.connection;
this.adaptor = this.connection.adaptor;
this.interval = opts.interval || 10;
this.commands = {}; this.commands = {};
// some default options
this.pin = opts.pin;
this.interval = opts.interval || 10;
this.details = {};
for (var opt in opts) {
if (['robot', 'name', 'adaptor', 'driver'].indexOf(opt) < 0) {
this.details[opt] = opts[opt];
}
}
}; };
Utils.subclass(Driver, Basestar); Utils.subclass(Driver, Basestar);
Driver.prototype.setupCommands = function(commands, proxy) { Driver.prototype.setupCommands = function(commands, proxy) {
if (proxy == null) { if (proxy == null) {
proxy = this.connection; proxy = this.adaptor;
} }
this.proxyMethods(commands, proxy, this); this.proxyMethods(commands, proxy, this);
@ -58,3 +67,13 @@ Driver.prototype.setupCommands = function(commands, proxy) {
this.commands[snake_case] = this[command]; this.commands[snake_case] = this[command];
} }
} }
Driver.prototype.toJSON = function() {
return {
name: this.name,
driver: this.constructor.name || this.name,
connection: this.adaptor.name,
commands: Object.keys(this.commands),
details: this.details
};
};

View File

@ -139,11 +139,11 @@ Robot.prototype.toJSON = function() {
n; n;
for (n in this.connections) { for (n in this.connections) {
connections.push(this.connections[n]); connections.push(this.connections[n].toJSON());
} }
for (n in this.devices) { for (n in this.devices) {
devices.push(this.devices[n]); devices.push(this.devices[n].toJSON());
} }
return { return {
@ -173,7 +173,7 @@ Robot.prototype.initConnections = function(opts) {
Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'"); Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'");
} }
this.connections[conn.name] = new Connection(conn); this.connections[conn.name] = Connection(conn);
}.bind(this); }.bind(this);
if (opts.connection == null && opts.connections == null) { if (opts.connection == null && opts.connections == null) {
@ -229,15 +229,15 @@ Robot.prototype.initDevices = function(opts) {
process.emit('SIGINT'); process.emit('SIGINT');
} }
device.connection = this.connections[device.connection]; device.adaptor = this.connections[device.connection];
} else { } else {
for (var conn in this.connections) { for (var conn in this.connections) {
device.connection = this.connections[conn]; device.adaptor = this.connections[conn];
break; break;
} }
} }
this.devices[device.name] = new Device(device); this.devices[device.name] = Device(device);
}.bind(this); }.bind(this);
if (opts.device == null && opts.devices == null) { if (opts.device == null && opts.devices == null) {
@ -334,9 +334,8 @@ Robot.prototype.startConnections = function(callback) {
Logger.info("Starting connections."); Logger.info("Starting connections.");
for (var n in this.connections) { for (var n in this.connections) {
var connection = this.connections[n]; this[n] = this.connections[n];
this[n] = connection; starters[n] = this.connections[n].connect;
starters[n] = connection.connect;
} }
return Async.parallel(starters, callback); return Async.parallel(starters, callback);
@ -353,9 +352,8 @@ Robot.prototype.startDevices = function(callback) {
Logger.info("Starting devices."); Logger.info("Starting devices.");
for (var n in this.devices) { for (var n in this.devices) {
var device = this.devices[n]; this[n] = this.devices[n];
this[n] = device; starters[n] = this.devices[n].start;
starters[n] = device.start;
} }
return Async.parallel(starters, callback); return Async.parallel(starters, callback);

View File

@ -22,7 +22,7 @@ var Ping = module.exports = function Ping() {
Utils.subclass(Ping, Driver); Utils.subclass(Ping, Driver);
Ping.prototype.ping = function() { Ping.prototype.ping = function() {
this.device.emit('ping', 'ping'); this.emit('ping', 'ping');
return "pong"; return "pong";
}; };