cylon/lib/cylon.js

170 lines
3.6 KiB
JavaScript
Raw Normal View History

2013-10-25 05:25:42 +08:00
/*
* cylon
* cylonjs.com
*
* Copyright (c) 2013 The Hybrid Group
* Licensed under the Apache 2.0 license.
*/
2014-02-28 05:31:54 +08:00
"use strict";
2013-10-25 05:25:42 +08:00
2014-12-16 03:15:29 +08:00
var Async = require("async");
2014-12-16 03:15:29 +08:00
var Logger = require("./logger"),
Robot = require("./robot"),
Config = require("./config"),
Utils = require("./utils");
var Cylon = module.exports = {
2014-05-14 10:44:40 +08:00
Logger: Logger,
2014-12-16 03:15:29 +08:00
Driver: require("./driver"),
Adaptor: require("./adaptor"),
Utils: Utils,
IO: {
2014-12-16 03:15:29 +08:00
DigitalPin: require("./io/digital-pin"),
Utils: require("./io/utils")
},
api_instance: null,
2014-07-16 03:27:16 +08:00
robots: {},
commands: {}
};
// Public: Creates a new Robot
//
// opts - hash of Robot attributes
//
// Returns a shiny new Robot
// Examples:
// Cylon.robot
2014-12-16 03:15:29 +08:00
// connection: { name: "arduino", adaptor: "firmata" }
// device: { name: "led", driver: "led", pin: 13 }
//
// work: (me) ->
// me.led.toggle()
Cylon.robot = function robot(opts) {
opts = opts || {};
// check if a robot with the same name exists already
if (opts.name && this.robots[opts.name]) {
var original = opts.name;
opts.name = Utils.makeUnique(original, Object.keys(this.robots));
2014-12-16 03:15:29 +08:00
var str = "Robot names must be unique. Renaming '";
str += original + "' to '" + opts.name + "'";
Logger.warn(str);
}
2014-12-16 03:15:29 +08:00
var bot = new Robot(opts);
this.robots[bot.name] = bot;
return bot;
};
2014-06-05 02:37:15 +08:00
// Public: Creates a new API based on passed options
//
2014-06-05 02:37:15 +08:00
// Returns nothing
Cylon.api = function api(opts) {
2014-12-16 03:15:29 +08:00
if (typeof opts === "object") {
this.config({ api: opts });
}
2014-12-16 03:15:29 +08:00
var API = require("./api");
2014-02-28 05:31:54 +08:00
2014-12-16 03:15:29 +08:00
var config = Utils.fetch(Config, "api", {});
this.api_instance = new API(config);
2014-06-05 02:37:15 +08:00
this.api_instance.listen();
};
// Public: Starts up the API and the robots
//
// Returns nothing
Cylon.start = function start() {
2014-10-04 15:56:08 +08:00
var starters = [];
for (var bot in this.robots) {
2014-10-04 15:56:08 +08:00
starters.push(this.robots[bot].start);
2014-10-04 14:07:07 +08:00
}
2014-12-16 03:15:29 +08:00
Async.parallel(starters, function() {
var mode = Utils.fetch(Config, "workMode", "async");
if (mode === "sync") {
2014-10-04 15:56:08 +08:00
for (var bot in this.robots) {
this.robots[bot].startWork();
}
2014-12-16 03:15:29 +08:00
}
2014-10-04 15:56:08 +08:00
}.bind(this));
};
// Public: Sets the internal configuration, based on passed options
//
// opts - object containing configuration key/value pairs
//
2014-09-16 05:46:24 +08:00
// Returns the current config
Cylon.config = function(opts) {
var loggingChanged = (opts.logging && Config.logging !== opts.logging);
2014-12-16 03:15:29 +08:00
if (opts && typeof(opts) === "object" && !Array.isArray(opts)) {
2014-09-16 05:46:24 +08:00
for (var o in opts) {
Config[o] = opts[o];
}
}
if (loggingChanged) {
Logger.setup();
}
return Config;
};
// Public: Halts the API and the robots
//
// callback - callback to be triggered when Cylon is ready to shutdown
//
// Returns nothing
Cylon.halt = function halt(callback) {
2014-12-16 03:15:29 +08:00
callback = callback || function() {};
// if robots can"t shut down quickly enough, forcefully self-terminate
var timeout = Config.haltTimeout || 3000;
Utils.after(timeout, callback);
var fns = [];
for (var bot in this.robots) {
var robot = this.robots[bot];
fns.push(robot.halt.bind(robot));
}
Async.parallel(fns, callback);
};
2014-07-16 03:27:16 +08:00
Cylon.toJSON = function() {
var robots = [];
for (var bot in this.robots) {
robots.push(this.robots[bot].toJSON());
2014-07-16 03:27:16 +08:00
}
return {
robots: robots,
commands: Object.keys(this.commands)
2014-12-16 03:15:29 +08:00
};
2014-07-16 03:27:16 +08:00
};
if (process.platform === "win32") {
var readline = require("readline"),
io = { input: process.stdin, output: process.stdout };
readline.createInterface(io).on("SIGINT", function() {
process.emit("SIGINT");
});
2014-06-17 04:09:13 +08:00
}
process.on("SIGINT", function() {
Cylon.halt(function() {
process.kill(process.pid);
});
});