var path = require('path'); var fs = require('fs'); var uuid = require("hap-nodejs").uuid; var Bridge = require("hap-nodejs").Bridge; var Accessory = require("hap-nodejs").Accessory; var Service = require("hap-nodejs").Service; var Characteristic = require("hap-nodejs").Characteristic; var Plugin = require('./plugin').Plugin; var User = require('./user').User; 'use strict'; module.exports = { Server: Server } function Server() { this._accessories = {}; // this._accessories[name] = accessory constructor this._platforms = {}; // this._platforms[name] = platform constructor this._plugins = this._loadPlugins(this._accessories, this._platforms); // plugins[name] = plugin this._config = this._loadConfig(); this._bridge = this._createBridge(); } Server.prototype.run = function() { // keep track of async calls we're waiting for callbacks on before we can start up this._asyncCalls = 0; this._asyncWait = true; if (this._config.platforms) this._loadPlatforms(); if (this._config.accessories) this._loadAccessories(); this._asyncWait = false; // publish now unless we're waiting on anyone if (this._asyncCalls == 0) this._publish(); } Server.prototype._publish = function() { // pull out our custom Bridge settings from config.json, if any var bridgeConfig = this._config.bridge || {}; this._printPin(bridgeConfig.pin); this._bridge.publish({ username: bridgeConfig.username || "CC:22:3D:E3:CE:30", port: bridgeConfig.port || 51826, pincode: bridgeConfig.pin || "031-45-154", category: Accessory.Categories.OTHER }); } Server.prototype._loadPlugins = function(accessories, platforms) { var plugins = {}; // load and validate plugins - check for valid package.json, etc. Plugin.installed().forEach(function(plugin) { // attempt to load it try { plugin.load(); } catch (err) { console.error(err); plugin.loadError = err; } // add it to our dict for easy lookup later plugins[plugin.name()] = plugin; console.log("Loaded plugin: " + plugin.name()); if (plugin.accessories) { var sep = "" var line = "Accessories: ["; for (var name in plugin.accessories) { if (accessories[name]) throw new Error("Plugin " + plugin.name() + " wants to publish an accessory '" + name + "' which has already been published by another plugin!"); accessories[name] = plugin.accessories[name]; // copy to global dict line += sep + name; sep = ","; } line += "]"; if (sep) console.log(line); } if (plugin.platforms) { var sep = "" var line = "Platforms: ["; for (var name in plugin.platforms) { if (plugin.platforms[name]) throw new Error("Plugin " + plugin.name() + " wants to publish a platform '" + name + "' which has already been published by another plugin!"); platforms[name] = plugin.platforms[name]; // copy to global dict line += sep + name; sep = ","; } line += "]"; if (sep) console.log(line); } console.log("---"); }.bind(this)); return plugins; } Server.prototype._loadConfig = function() { // Look for the configuration file var configPath = User.configPath(); // Complain and exit if it doesn't exist yet if (!fs.existsSync(configPath)) { console.log("Couldn't find a config.json file in the same directory as app.js. Look at config-sample.json for examples of how to format your config.js and add your home accessories."); process.exit(1); } // Load up the configuration file var config; try { config = JSON.parse(fs.readFileSync(configPath)); } catch (err) { console.log("There was a problem reading your config.json file."); console.log("Please try pasting your config.json file here to validate it: http://jsonlint.com"); console.log(""); throw err; } var accessoryCount = (config.accessories && config.accessories.length) || 0; var platformCount = (config.platforms && config.platforms.length) || 0; console.log("Loaded config.json with %s accessories and %s platforms.", accessoryCount, platformCount); console.log("---"); return config; } Server.prototype._createBridge = function() { // pull out our custom Bridge settings from config.json, if any var bridgeConfig = this._config.bridge || {}; // Create our Bridge which will host all loaded Accessories return new Bridge(bridgeConfig.name || 'Homebridge', uuid.generate("HomeBridge")); } Server.prototype._loadAccessories = function() { // Instantiate all accessories in the config console.log("Loading " + this._config.accessories.length + " accessories..."); for (var i=0; i