Merge pull request #253 from hybridgroup/feature/cppp-io-updates
Add event listings to API
This commit is contained in:
commit
fe4c899f7f
|
@ -35,7 +35,7 @@ var Adaptor = module.exports = function Adaptor(opts) {
|
|||
this.details = {};
|
||||
|
||||
_.forEach(opts, function(opt, name) {
|
||||
if (_.include(["robot", "name", "adaptor"], name)) {
|
||||
if (_.include(["robot", "name", "adaptor", "events"], name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,12 @@ var Cylon = require("../cylon");
|
|||
|
||||
var router = module.exports = require("express").Router();
|
||||
|
||||
var eventHeaders = {
|
||||
"Content-Type": "text/event-stream",
|
||||
"Connection": "keep-alive",
|
||||
"Cache-Control": "no-cache"
|
||||
};
|
||||
|
||||
// Loads up the appropriate Robot/Device/Connection instances, if they are
|
||||
// present in the route params.
|
||||
var load = function load(req, res, next) {
|
||||
|
@ -55,6 +61,26 @@ router.get("/", function(req, res) {
|
|||
res.json({ MCP: Cylon.toJSON() });
|
||||
});
|
||||
|
||||
router.get("/events", function(req, res) {
|
||||
res.json({ events: Cylon.events });
|
||||
});
|
||||
|
||||
router.get("/events/:event", function(req, res) {
|
||||
var event = req.params.event;
|
||||
|
||||
res.writeHead(200, eventHeaders);
|
||||
|
||||
var writeData = function(data) {
|
||||
res.write("data: " + JSON.stringify(data) + "\n\n");
|
||||
};
|
||||
|
||||
Cylon.on(event, writeData);
|
||||
|
||||
res.on("close", function() {
|
||||
Cylon.removeListener(event, writeData);
|
||||
});
|
||||
});
|
||||
|
||||
router.get("/commands", function(req, res) {
|
||||
res.json({ commands: Object.keys(Cylon.commands) });
|
||||
});
|
||||
|
@ -81,6 +107,26 @@ router.all("/robots/:robot/commands/:command", load, function(req, res) {
|
|||
router.runCommand(req, res, req.robot, command);
|
||||
});
|
||||
|
||||
router.get("/robots/:robot/events", load, function(req, res) {
|
||||
res.json({ events: req.robot.events });
|
||||
});
|
||||
|
||||
router.all("/robots/:robot/events/:event", load, function(req, res) {
|
||||
var event = req.params.event;
|
||||
|
||||
res.writeHead(200, eventHeaders);
|
||||
|
||||
var writeData = function(data) {
|
||||
res.write("data: " + JSON.stringify(data) + "\n\n");
|
||||
};
|
||||
|
||||
req.robot.on(event, writeData);
|
||||
|
||||
res.on("close", function() {
|
||||
req.robot.removeListener(event, writeData);
|
||||
});
|
||||
});
|
||||
|
||||
router.get("/robots/:robot/devices", load, function(req, res) {
|
||||
res.json({ devices: req.robot.toJSON().devices });
|
||||
});
|
||||
|
@ -89,14 +135,14 @@ router.get("/robots/:robot/devices/:device", load, function(req, res) {
|
|||
res.json({ device: req.device });
|
||||
});
|
||||
|
||||
router.get("/robots/:robot/devices/:device/events", load, function(req, res) {
|
||||
res.json({ events: req.device.events });
|
||||
});
|
||||
|
||||
router.get("/robots/:robot/devices/:device/events/:event", load, function(req, res) {
|
||||
var event = req.params.event;
|
||||
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/event-stream",
|
||||
"Connection": "keep-alive",
|
||||
"Cache-Control": "no-cache"
|
||||
});
|
||||
res.writeHead(200, eventHeaders);
|
||||
|
||||
var writeData = function(data) {
|
||||
res.write("data: " + JSON.stringify(data) + "\n\n");
|
||||
|
|
33
lib/cylon.js
33
lib/cylon.js
|
@ -16,23 +16,27 @@ var Logger = require("./logger"),
|
|||
Utils = require("./utils"),
|
||||
_ = require("./lodash");
|
||||
|
||||
var Cylon = module.exports = {
|
||||
Logger: Logger,
|
||||
Driver: require("./driver"),
|
||||
Adaptor: require("./adaptor"),
|
||||
Utils: Utils,
|
||||
var EventEmitter = require("events").EventEmitter;
|
||||
|
||||
IO: {
|
||||
var Cylon = module.exports = new EventEmitter();
|
||||
|
||||
Cylon.Logger = Logger;
|
||||
Cylon.Driver = require("./driver");
|
||||
Cylon.Adaptor = require("./adaptor");
|
||||
Cylon.Utils = Utils;
|
||||
|
||||
Cylon.IO = {
|
||||
DigitalPin: require("./io/digital-pin"),
|
||||
Utils: require("./io/utils")
|
||||
},
|
||||
|
||||
api_instance: null,
|
||||
|
||||
robots: {},
|
||||
commands: {}
|
||||
};
|
||||
|
||||
Cylon.api_instance = null;
|
||||
|
||||
Cylon.robots = {};
|
||||
Cylon.commands = {};
|
||||
|
||||
Cylon.events = [ "robot_added", "robot_removed" ];
|
||||
|
||||
// Public: Creates a new Robot
|
||||
//
|
||||
// opts - hash of Robot attributes
|
||||
|
@ -61,6 +65,8 @@ Cylon.robot = function robot(opts) {
|
|||
|
||||
var bot = new Robot(opts);
|
||||
this.robots[bot.name] = bot;
|
||||
this.emit("robot_added", bot.name);
|
||||
|
||||
return bot;
|
||||
};
|
||||
|
||||
|
@ -134,7 +140,8 @@ Cylon.halt = function halt(callback) {
|
|||
Cylon.toJSON = function() {
|
||||
return {
|
||||
robots: _.invoke(this.robots, "toJSON"),
|
||||
commands: _.keys(this.commands)
|
||||
commands: _.keys(this.commands),
|
||||
events: this.events
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ var Driver = module.exports = function Driver(opts) {
|
|||
this.connection = opts.connection;
|
||||
|
||||
this.commands = {};
|
||||
this.events = [];
|
||||
|
||||
// some default options
|
||||
this.pin = opts.pin;
|
||||
|
@ -36,7 +37,7 @@ var Driver = module.exports = function Driver(opts) {
|
|||
this.details = {};
|
||||
|
||||
_.forEach(opts, function(opt, name) {
|
||||
if (_.include(["robot", "name", "connection", "driver"], name)) {
|
||||
if (_.include(["robot", "name", "connection", "driver", "events"], name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -74,6 +75,7 @@ Driver.prototype.toJSON = function() {
|
|||
driver: this.constructor.name || this.name,
|
||||
connection: this.connection.name,
|
||||
commands: _.keys(this.commands),
|
||||
events: this.events,
|
||||
details: this.details
|
||||
};
|
||||
};
|
||||
|
|
|
@ -120,7 +120,8 @@ Robot.prototype.toJSON = function() {
|
|||
name: this.name,
|
||||
connections: _.invoke(this.connections, "toJSON"),
|
||||
devices: _.invoke(this.devices, "toJSON"),
|
||||
commands: _.keys(this.commands)
|
||||
commands: _.keys(this.commands),
|
||||
events: _.isArray(this.events) ? this.events : []
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ var Ping = module.exports = function Ping() {
|
|||
this.commands = {
|
||||
ping: this.ping
|
||||
};
|
||||
|
||||
this.events = ["ping"];
|
||||
};
|
||||
|
||||
Utils.subclass(Ping, Driver);
|
||||
|
|
|
@ -181,5 +181,9 @@ describe("Cylon", function() {
|
|||
it("contains an array of MCP commands", function() {
|
||||
expect(json.commands).to.be.eql(["echo"]);
|
||||
});
|
||||
|
||||
it("contains an array of MCP events", function() {
|
||||
expect(json.events).to.be.eql(["robot_added", "robot_removed"]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -30,6 +30,10 @@ describe("Driver", function() {
|
|||
expect(driver.commands).to.be.eql({});
|
||||
});
|
||||
|
||||
it("sets @events to an empty array by default", function() {
|
||||
expect(driver.events).to.be.eql([]);
|
||||
});
|
||||
|
||||
it("sets @interval to 10ms by default, or the provided value", function() {
|
||||
expect(driver.interval).to.be.eql(10);
|
||||
|
||||
|
@ -43,6 +47,46 @@ describe("Driver", function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("#toJSON", function() {
|
||||
var driver, json;
|
||||
|
||||
beforeEach(function() {
|
||||
driver = new Driver({
|
||||
connection: { name: "conn" },
|
||||
name: "name",
|
||||
port: "3000"
|
||||
});
|
||||
|
||||
json = driver.toJSON();
|
||||
});
|
||||
|
||||
it("returns an object", function() {
|
||||
expect(json).to.be.a("object");
|
||||
});
|
||||
|
||||
it("contains the driver's name", function() {
|
||||
expect(json.name).to.eql("name");
|
||||
});
|
||||
|
||||
it("contains the driver's constructor name", function() {
|
||||
expect(json.driver).to.eql("Driver");
|
||||
});
|
||||
|
||||
it("contains the driver's connection name", function() {
|
||||
expect(json.connection).to.eql("conn");
|
||||
});
|
||||
|
||||
it("contains the driver's commands", function() {
|
||||
expect(json.commands).to.eql(Object.keys(driver.commands));
|
||||
});
|
||||
|
||||
it("contains the driver's events, or an empty array", function() {
|
||||
expect(json.events).to.eql([]);
|
||||
driver.events = ["hello", "world"];
|
||||
expect(driver.toJSON().events).to.be.eql(["hello", "world"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setupCommands", function() {
|
||||
beforeEach(function() {
|
||||
driver.proxyMethods = spy();
|
||||
|
|
|
@ -215,7 +215,9 @@ describe("Robot", function() {
|
|||
|
||||
devices: {
|
||||
ping: { driver: "ping" }
|
||||
}
|
||||
},
|
||||
|
||||
events: ["hello", "world"]
|
||||
});
|
||||
|
||||
var json = bot.toJSON();
|
||||
|
@ -239,6 +241,13 @@ describe("Robot", function() {
|
|||
it("contains the robot's connections", function() {
|
||||
expect(json.connections).to.eql([bot.connections.loopback.toJSON()]);
|
||||
});
|
||||
|
||||
it("contains the robot's events, or an empty array", function() {
|
||||
expect(json.events).to.eql(["hello", "world"]);
|
||||
|
||||
var bot = new Robot();
|
||||
expect(bot.toJSON().events).to.be.eql([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#connection", function() {
|
||||
|
|
Loading…
Reference in New Issue