mirror of
https://github.com/mtan93/homebridge.git
synced 2026-03-08 05:31:55 +00:00
Init Plugin 2.0
This commit is contained in:
243
lib/server.js
243
lib/server.js
@@ -1,6 +1,7 @@
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var uuid = require("hap-nodejs").uuid;
|
||||
var accessoryStorage = require('node-persist').create();
|
||||
var Bridge = require("hap-nodejs").Bridge;
|
||||
var Accessory = require("hap-nodejs").Accessory;
|
||||
var Service = require("hap-nodejs").Service;
|
||||
@@ -10,6 +11,8 @@ var once = require("hap-nodejs/lib/util/once").once;
|
||||
var Plugin = require('./plugin').Plugin;
|
||||
var User = require('./user').User;
|
||||
var API = require('./api').API;
|
||||
var PlatformAccessory = require("./platformAccessory").PlatformAccessory;
|
||||
var BridgeSetupManager = require("./bridgeSetupManager").BridgeSetupManager;
|
||||
var log = require("./logger")._system;
|
||||
var Logger = require('./logger').Logger;
|
||||
|
||||
@@ -20,10 +23,32 @@ module.exports = {
|
||||
}
|
||||
|
||||
function Server() {
|
||||
// Setup Accessory Cache Storage
|
||||
accessoryStorage.initSync({ dir: User.cachedAccessoryPath() });
|
||||
|
||||
this._api = new API(); // object we feed to Plugins
|
||||
|
||||
this._api.on('registerPlatformAccessories', function(accessories) {
|
||||
this._handleRegisterPlatformAccessories(accessories);
|
||||
}.bind(this));
|
||||
|
||||
this._api.on('unregisterPlatformAccessories', function(accessories) {
|
||||
this._handleUnregisterPlatformAccessories(accessories);
|
||||
}.bind(this));
|
||||
|
||||
this._plugins = this._loadPlugins(); // plugins[name] = Plugin instance
|
||||
this._config = this._loadConfig();
|
||||
this._config = this._loadConfig();
|
||||
this._cachedPlatformAccessories = this._loadCachedPlatformAccessories();
|
||||
this._bridge = this._createBridge();
|
||||
|
||||
this._activeDynamicPlugins = {};
|
||||
this._configurablePlatformPlugins = {};
|
||||
this._setupManager = new BridgeSetupManager();
|
||||
this._setupManager.on('newConfig', this._handleNewConfig.bind(this));
|
||||
|
||||
this._setupManager.on('requestCurrentConfig', function(callback) {
|
||||
callback(this._config);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
Server.prototype.run = function() {
|
||||
@@ -34,12 +59,18 @@ Server.prototype.run = function() {
|
||||
|
||||
if (this._config.platforms) this._loadPlatforms();
|
||||
if (this._config.accessories) this._loadAccessories();
|
||||
this._loadDynamicPlatforms();
|
||||
this._configCachedPlatformAccessories();
|
||||
this._setupManager.configurablePlatformPlugins = this._configurablePlatformPlugins;
|
||||
this._bridge.addService(this._setupManager.service);
|
||||
|
||||
this._asyncWait = false;
|
||||
|
||||
// publish now unless we're waiting on anyone
|
||||
if (this._asyncCalls == 0)
|
||||
this._publish();
|
||||
|
||||
this._api.emit('didFinishLaunching');
|
||||
}
|
||||
|
||||
Server.prototype._publish = function() {
|
||||
@@ -108,8 +139,18 @@ Server.prototype._loadConfig = function() {
|
||||
|
||||
// Complain and exit if it doesn't exist yet
|
||||
if (!fs.existsSync(configPath)) {
|
||||
log.error("Couldn't find a config.json file at '"+configPath+"'. Look at config-sample.json for examples of how to format your config.js and add your home accessories.");
|
||||
process.exit(1);
|
||||
var config = {};
|
||||
|
||||
config.bridge = {
|
||||
"name": "Homebridge",
|
||||
"username": "CC:22:3D:E3:CE:30",
|
||||
"port": 51826,
|
||||
"pin": "031-45-154"
|
||||
};
|
||||
|
||||
return config;
|
||||
// log.error("Couldn't find a config.json file at '"+configPath+"'. 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
|
||||
@@ -142,6 +183,23 @@ Server.prototype._loadConfig = function() {
|
||||
return config;
|
||||
}
|
||||
|
||||
Server.prototype._loadCachedPlatformAccessories = function() {
|
||||
var cachedAccessories = accessoryStorage.getItem("cachedAccessories");
|
||||
var platformAccessories = [];
|
||||
|
||||
if (cachedAccessories) {
|
||||
for (var index in cachedAccessories) {
|
||||
var serializedAccessory = cachedAccessories[index];
|
||||
var platformAccessory = new PlatformAccessory(serializedAccessory.displayName, serializedAccessory.UUID, serializedAccessory.category);
|
||||
platformAccessory._configFromData(serializedAccessory);
|
||||
|
||||
platformAccessories.push(platformAccessory);
|
||||
}
|
||||
}
|
||||
|
||||
return platformAccessories;
|
||||
}
|
||||
|
||||
Server.prototype._createBridge = function() {
|
||||
// pull out our custom Bridge settings from config.json, if any
|
||||
var bridgeConfig = this._config.bridge || {};
|
||||
@@ -201,11 +259,64 @@ Server.prototype._loadPlatforms = function() {
|
||||
|
||||
platformLogger("Initializing %s platform...", platformType);
|
||||
|
||||
var platformInstance = new platformConstructor(platformLogger, platformConfig);
|
||||
this._loadPlatformAccessories(platformInstance, platformLogger, platformType);
|
||||
var platformInstance = new platformConstructor(platformLogger, platformConfig, this._api);
|
||||
|
||||
if (platformInstance.configureAccessory == undefined) {
|
||||
// Plugin 1.0, load accessories
|
||||
this._loadPlatformAccessories(platformInstance, platformLogger, platformType);
|
||||
} else {
|
||||
this._activeDynamicPlugins[platformType] = platformInstance;
|
||||
}
|
||||
|
||||
if (platformInstance.configurationRequestHandler != undefined) {
|
||||
this._configurablePlatformPlugins[platformType] = platformInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Server.prototype._loadDynamicPlatforms = function() {
|
||||
for (var dynamicPluginName in this._api._dynamicPlatforms) {
|
||||
if (!this._activeDynamicPlugins[dynamicPluginName] && !this._activeDynamicPlugins[dynamicPluginName.split(".")[1]]) {
|
||||
console.log("Load " + dynamicPluginName);
|
||||
var platformConstructor = this._api._dynamicPlatforms[dynamicPluginName];
|
||||
var platformLogger = Logger.withPrefix(dynamicPluginName);
|
||||
var platformInstance = new platformConstructor(platformLogger, null, this._api);
|
||||
this._activeDynamicPlugins[dynamicPluginName] = platformInstance;
|
||||
|
||||
if (platformInstance.configurationRequestHandler != undefined) {
|
||||
this._configurablePlatformPlugins[dynamicPluginName] = platformInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Server.prototype._configCachedPlatformAccessories = function() {
|
||||
for (var index in this._cachedPlatformAccessories) {
|
||||
var accessory = this._cachedPlatformAccessories[index];
|
||||
|
||||
if (!(accessory instanceof PlatformAccessory)) {
|
||||
console.log("Unexpected Accessory!");
|
||||
continue;
|
||||
}
|
||||
|
||||
var fullName = accessory._associatedPlugin + "." + accessory._associatedPlatform;
|
||||
var platformInstance = this._activeDynamicPlugins[fullName];
|
||||
|
||||
if (!platformInstance) {
|
||||
platformInstance = this._activeDynamicPlugins[accessory._associatedPlatform];
|
||||
}
|
||||
|
||||
if (platformInstance) {
|
||||
platformInstance.configureAccessory(accessory);
|
||||
} else {
|
||||
console.log("Failed to find plugin to handle accessory " + accessory.displayName);
|
||||
}
|
||||
|
||||
accessory._prepareAssociatedHAPAccessory();
|
||||
this._bridge.addBridgedAccessory(accessory._associatedHAPAccessory);
|
||||
}
|
||||
}
|
||||
|
||||
Server.prototype._loadPlatformAccessories = function(platformInstance, log, platformType) {
|
||||
this._asyncCalls++;
|
||||
platformInstance.accessories(once(function(foundAccessories){
|
||||
@@ -280,6 +391,128 @@ Server.prototype._createAccessory = function(accessoryInstance, displayName, acc
|
||||
}
|
||||
}
|
||||
|
||||
Server.prototype._handleRegisterPlatformAccessories = function(accessories) {
|
||||
var hapAccessories = [];
|
||||
for (var index in accessories) {
|
||||
var accessory = accessories[index];
|
||||
|
||||
accessory._prepareAssociatedHAPAccessory();
|
||||
hapAccessories.push(accessory._associatedHAPAccessory);
|
||||
|
||||
this._cachedPlatformAccessories.push(accessory);
|
||||
}
|
||||
|
||||
this._bridge.addBridgedAccessories(hapAccessories);
|
||||
this._updateCachedAccessories();
|
||||
}
|
||||
|
||||
Server.prototype._handleUnregisterPlatformAccessories = function(accessories) {
|
||||
var hapAccessories = [];
|
||||
for (var index in accessories) {
|
||||
var accessory = accessories[index];
|
||||
|
||||
if (accessory._associatedHAPAccessory) {
|
||||
hapAccessories.push(accessory._associatedHAPAccessory);
|
||||
}
|
||||
|
||||
for (var targetIndex in this._cachedPlatformAccessories) {
|
||||
var existing = this._cachedPlatformAccessories[targetIndex];
|
||||
if (existing.UUID === accessory.UUID) {
|
||||
this._cachedPlatformAccessories.splice(targetIndex, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._bridge.removeBridgedAccessories(hapAccessories);
|
||||
this._updateCachedAccessories();
|
||||
}
|
||||
|
||||
Server.prototype._updateCachedAccessories = function() {
|
||||
var serializedAccessories = [];
|
||||
|
||||
for (var index in this._cachedPlatformAccessories) {
|
||||
var accessory = this._cachedPlatformAccessories[index];
|
||||
serializedAccessories.push(accessory._dictionaryPresentation());
|
||||
}
|
||||
|
||||
accessoryStorage.setItemSync("cachedAccessories", serializedAccessories);
|
||||
}
|
||||
|
||||
Server.prototype._handleNewConfig = function(type, name, replace, config) {
|
||||
if (type === "accessory") {
|
||||
// TODO: Load new accessory
|
||||
if (!this._config.accessories) {
|
||||
this._config.accessories = [];
|
||||
}
|
||||
|
||||
if (!replace) {
|
||||
this._config.accessories.push(config);
|
||||
} else {
|
||||
var targetName;
|
||||
if (name.indexOf('.') == -1) {
|
||||
targetName = name.split(".")[1];
|
||||
}
|
||||
var found = false;
|
||||
for (var index in this._config.accessories) {
|
||||
var accessoryConfig = this._config.accessories[index];
|
||||
if (accessoryConfig.accessory === name) {
|
||||
this._config.accessories[index] = config;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetName && (accessoryConfig.accessory === targetName)) {
|
||||
this._config.accessories[index] = config;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
this._config.accessories.push(config);
|
||||
}
|
||||
}
|
||||
} else if (type === "platform") {
|
||||
if (!this._config.platforms) {
|
||||
this._config.platforms = [];
|
||||
}
|
||||
|
||||
if (!replace) {
|
||||
this._config.platforms.push(config);
|
||||
} else {
|
||||
var targetName;
|
||||
if (name.indexOf('.') == -1) {
|
||||
targetName = name.split(".")[1];
|
||||
}
|
||||
|
||||
var found = false;
|
||||
for (var index in this._config.platforms) {
|
||||
var platformConfig = this._config.platforms[index];
|
||||
if (platformConfig.platform === name) {
|
||||
this._config.platforms[index] = config;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetName && (platformConfig.platform === targetName)) {
|
||||
this._config.platforms[index] = config;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
this._config.platforms.push(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var serializedConfig = JSON.stringify(this._config, null, ' ');
|
||||
var configPath = User.configPath();
|
||||
fs.writeFileSync(configPath, serializedConfig, 'utf8');
|
||||
}
|
||||
|
||||
// Returns the setup code in a scannable format.
|
||||
Server.prototype._printPin = function(pin) {
|
||||
console.log("Scan this code with your HomeKit App on your iOS device to pair with Homebridge:");
|
||||
|
||||
Reference in New Issue
Block a user