mirror of
https://github.com/mtan93/homebridge.git
synced 2026-04-05 22:04:31 +01:00
Merge pull request #94 from nfarina/use-hap-refactor
Use WIP version of HAP-NodeJS refactor
This commit is contained in:
@@ -68,7 +68,7 @@ WeMoAccessory.prototype = {
|
|||||||
if (!err) {
|
if (!err) {
|
||||||
var binaryState = parseInt(result)
|
var binaryState = parseInt(result)
|
||||||
that.log("power state for " + that.wemoName + " is: " + binaryState)
|
that.log("power state for " + that.wemoName + " is: " + binaryState)
|
||||||
callback(binaryState)
|
callback(binaryState > 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
that.log(err)
|
that.log(err)
|
||||||
|
|||||||
186
app.js
186
app.js
@@ -1,7 +1,11 @@
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var storage = require('node-persist');
|
var storage = require('node-persist');
|
||||||
var crypto = require('crypto');
|
var hap = require('HAP-NodeJS');
|
||||||
|
var uuid = require('HAP-NodeJS').uuid;
|
||||||
|
var Bridge = require('HAP-NodeJS').Bridge;
|
||||||
|
var Accessory = require('HAP-NodeJS').Accessory;
|
||||||
|
var accessoryLoader = require('HAP-NodeJS').AccessoryLoader;
|
||||||
|
|
||||||
console.log("Starting HomeBridge server...");
|
console.log("Starting HomeBridge server...");
|
||||||
|
|
||||||
@@ -14,24 +18,36 @@ if (!fs.existsSync(configPath)) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize persistent storage
|
// Initialize HAP-NodeJS
|
||||||
storage.initSync();
|
hap.init();
|
||||||
|
|
||||||
|
// Start by creating our Bridge which will host all loaded Accessories
|
||||||
|
var bridge = new Bridge('HomeBridge', uuid.generate("HomeBridge"));
|
||||||
|
|
||||||
// Load up the configuration file
|
// Load up the configuration file
|
||||||
var config = JSON.parse(fs.readFileSync(configPath));
|
var config = JSON.parse(fs.readFileSync(configPath));
|
||||||
|
|
||||||
// Just to prevent them getting garbage collected
|
// keep track of async calls we're waiting for callbacks on before we can start up
|
||||||
var accessories = [];
|
// this is hacky but this is all going away once we build proper plugin support
|
||||||
|
var asyncCalls = 0;
|
||||||
|
var asyncWait = false;
|
||||||
|
|
||||||
function startup() {
|
function startup() {
|
||||||
|
asyncWait = true;
|
||||||
if (config.platforms) loadPlatforms();
|
if (config.platforms) loadPlatforms();
|
||||||
if (config.accessories) loadAccessories();
|
if (config.accessories) loadAccessories();
|
||||||
|
asyncWait = false;
|
||||||
|
|
||||||
|
// publish now unless we're waiting on anyone
|
||||||
|
if (asyncCalls == 0)
|
||||||
|
publish();
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAccessories() {
|
function loadAccessories() {
|
||||||
|
|
||||||
// Instantiate all accessories in the config
|
// Instantiate all accessories in the config
|
||||||
console.log("Loading " + config.accessories.length + " accessories...");
|
console.log("Loading " + config.accessories.length + " accessories...");
|
||||||
|
|
||||||
for (var i=0; i<config.accessories.length; i++) {
|
for (var i=0; i<config.accessories.length; i++) {
|
||||||
|
|
||||||
var accessoryConfig = config.accessories[i];
|
var accessoryConfig = config.accessories[i];
|
||||||
@@ -46,21 +62,28 @@ function loadAccessories() {
|
|||||||
var log = function(name) { return function(s) { console.log("[" + name + "] " + s); }; }(name);
|
var log = function(name) { return function(s) { console.log("[" + name + "] " + s); }; }(name);
|
||||||
|
|
||||||
log("Initializing " + accessoryName + " accessory...");
|
log("Initializing " + accessoryName + " accessory...");
|
||||||
var accessory = new accessoryConstructor(log, accessoryConfig);
|
|
||||||
accessories.push(accessory);
|
var accessoryInstance = new accessoryConstructor(log, accessoryConfig);
|
||||||
|
|
||||||
// Extract the raw "services" for this accessory which is a big array of objects describing the various
|
// Extract the raw "services" for this accessory which is a big array of objects describing the various
|
||||||
// hooks in and out of HomeKit for the HAP-NodeJS server.
|
// hooks in and out of HomeKit for the HAP-NodeJS server.
|
||||||
var services = accessory.getServices();
|
var services = accessoryInstance.getServices();
|
||||||
|
|
||||||
|
// Create the actual HAP-NodeJS "Accessory" instance
|
||||||
|
var accessory = accessoryLoader.parseAccessoryJSON({
|
||||||
|
displayName: name,
|
||||||
|
services: services
|
||||||
|
});
|
||||||
|
|
||||||
// Create the HAP server for this accessory
|
// add it to the bridge
|
||||||
createHAPServer(name, services, accessory.transportCategory);
|
bridge.addBridgedAccessory(accessory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadPlatforms() {
|
function loadPlatforms() {
|
||||||
|
|
||||||
console.log("Loading " + config.platforms.length + " platforms...");
|
console.log("Loading " + config.platforms.length + " platforms...");
|
||||||
|
|
||||||
for (var i=0; i<config.platforms.length; i++) {
|
for (var i=0; i<config.platforms.length; i++) {
|
||||||
|
|
||||||
var platformConfig = config.platforms[i];
|
var platformConfig = config.platforms[i];
|
||||||
@@ -76,114 +99,51 @@ function loadPlatforms() {
|
|||||||
|
|
||||||
log("Initializing " + platformName + " platform...");
|
log("Initializing " + platformName + " platform...");
|
||||||
|
|
||||||
var platform = new platformConstructor(log, platformConfig);
|
var platformInstance = new platformConstructor(log, platformConfig);
|
||||||
|
|
||||||
|
// wrap name and log in a closure so they don't change in the callback
|
||||||
|
function getAccessories(name, log) {
|
||||||
|
asyncCalls++;
|
||||||
|
platformInstance.accessories(function(foundAccessories){
|
||||||
|
asyncCalls--;
|
||||||
|
// loop through accessories adding them to the list and registering them
|
||||||
|
for (var i = 0; i < foundAccessories.length; i++) {
|
||||||
|
var accessoryInstance = foundAccessories[i];
|
||||||
|
|
||||||
|
log("Initializing device with name " + accessoryInstance.name + "...")
|
||||||
|
|
||||||
|
// Extract the raw "services" for this accessory which is a big array of objects describing the various
|
||||||
|
// hooks in and out of HomeKit for the HAP-NodeJS server.
|
||||||
|
var services = accessoryInstance.getServices();
|
||||||
|
|
||||||
|
// Create the actual HAP-NodeJS "Accessory" instance
|
||||||
|
var accessory = accessoryLoader.parseAccessoryJSON({
|
||||||
|
displayName: name,
|
||||||
|
services: services
|
||||||
|
});
|
||||||
|
|
||||||
|
// add it to the bridge
|
||||||
|
bridge.addBridgedAccessory(accessory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// were we the last callback?
|
||||||
|
if (asyncCalls === 0 && !asyncWait)
|
||||||
|
publish();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// query for devices
|
// query for devices
|
||||||
platform.accessories(function(foundAccessories){
|
getAccessories(name, log);
|
||||||
// loop through accessories adding them to the list and registering them
|
|
||||||
for (var i = 0; i < foundAccessories.length; i++) {
|
|
||||||
accessory = foundAccessories[i]
|
|
||||||
accessories.push(accessory);
|
|
||||||
log("Initializing device with name " + accessory.name + "...")
|
|
||||||
// Extract the raw "services" for this accessory which is a big array of objects describing the various
|
|
||||||
// hooks in and out of HomeKit for the HAP-NodeJS server.
|
|
||||||
var services = accessory.getServices();
|
|
||||||
// Create the HAP server for this accessory
|
|
||||||
createHAPServer(accessory.name, services, accessory.transportCategory);
|
|
||||||
}
|
|
||||||
accessories.push.apply(accessories, foundAccessories);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
function publish() {
|
||||||
// Creates the actual HAP servers which listen on different sockets
|
bridge.publish({
|
||||||
//
|
username: "CC:22:3D:E3:CE:27",
|
||||||
|
port: 51826,
|
||||||
// Pull in required HAP-NodeJS stuff
|
pincode: "031-45-154",
|
||||||
var accessory_Factor = new require("HAP-NodeJS/Accessory.js");
|
category: Accessory.Categories.OTHER
|
||||||
var accessoryController_Factor = new require("HAP-NodeJS/AccessoryController.js");
|
});
|
||||||
var service_Factor = new require("HAP-NodeJS/Service.js");
|
|
||||||
var characteristic_Factor = new require("HAP-NodeJS/Characteristic.js");
|
|
||||||
|
|
||||||
// Each accessory has its own little server. We'll need to allocate some ports for these servers
|
|
||||||
var nextPort = 51826;
|
|
||||||
var nextServer = 0;
|
|
||||||
var accessoryServers = [];
|
|
||||||
var accessoryControllers = [];
|
|
||||||
var usernames = {};
|
|
||||||
|
|
||||||
function createHAPServer(name, services, transportCategory) {
|
|
||||||
var accessoryController = new accessoryController_Factor.AccessoryController();
|
|
||||||
|
|
||||||
//loop through services
|
|
||||||
for (var j = 0; j < services.length; j++) {
|
|
||||||
var service = new service_Factor.Service(services[j].sType);
|
|
||||||
|
|
||||||
//loop through characteristics
|
|
||||||
for (var k = 0; k < services[j].characteristics.length; k++) {
|
|
||||||
var options = {
|
|
||||||
onRead: services[j].characteristics[k].onRead,
|
|
||||||
onRegister: services[j].characteristics[k].onRegister,
|
|
||||||
type: services[j].characteristics[k].cType,
|
|
||||||
perms: services[j].characteristics[k].perms,
|
|
||||||
format: services[j].characteristics[k].format,
|
|
||||||
initialValue: services[j].characteristics[k].initialValue,
|
|
||||||
supportEvents: services[j].characteristics[k].supportEvents,
|
|
||||||
supportBonjour: services[j].characteristics[k].supportBonjour,
|
|
||||||
manfDescription: services[j].characteristics[k].manfDescription,
|
|
||||||
designedMaxLength: services[j].characteristics[k].designedMaxLength,
|
|
||||||
designedMinValue: services[j].characteristics[k].designedMinValue,
|
|
||||||
designedMaxValue: services[j].characteristics[k].designedMaxValue,
|
|
||||||
designedMinStep: services[j].characteristics[k].designedMinStep,
|
|
||||||
unit: services[j].characteristics[k].unit
|
|
||||||
};
|
|
||||||
|
|
||||||
var characteristic = new characteristic_Factor.Characteristic(options, services[j].characteristics[k].onUpdate);
|
|
||||||
|
|
||||||
service.addCharacteristic(characteristic);
|
|
||||||
}
|
|
||||||
accessoryController.addService(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a unique "username" for this accessory based on the default display name
|
|
||||||
var username = createUsername(name);
|
|
||||||
|
|
||||||
if (usernames[username]) {
|
|
||||||
console.log("Cannot create another accessory with the same name '" + name + "'. The 'name' property must be unique for each accessory.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember that we used this name already
|
|
||||||
usernames[username] = name;
|
|
||||||
|
|
||||||
// increment ports for each accessory
|
|
||||||
nextPort = nextPort + (nextServer*2);
|
|
||||||
|
|
||||||
// hardcode the PIN to something random (same PIN as HAP-NodeJS sample accessories)
|
|
||||||
var pincode = "031-45-154";
|
|
||||||
|
|
||||||
var accessory = new accessory_Factor.Accessory(name, username, storage, parseInt(nextPort), pincode, accessoryController, transportCategory);
|
|
||||||
accessoryServers[nextServer] = accessory;
|
|
||||||
accessoryControllers[nextServer] = accessoryController;
|
|
||||||
accessory.publishAccessory();
|
|
||||||
|
|
||||||
nextServer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a unique "username" for HomeKit from a hash of the given string
|
|
||||||
function createUsername(str) {
|
|
||||||
|
|
||||||
// Hash str into something like "098F6BCD4621D373CADE4E832627B4F6"
|
|
||||||
var hash = crypto.createHash('md5').update(str).digest("hex").toUpperCase();
|
|
||||||
|
|
||||||
// Turn it into a MAC-address-looking "username" for HomeKit
|
|
||||||
return hash[0] + hash[1] + ":" +
|
|
||||||
hash[2] + hash[3] + ":" +
|
|
||||||
hash[4] + hash[5] + ":" +
|
|
||||||
hash[6] + hash[7] + ":" +
|
|
||||||
hash[8] + hash[9] + ":" +
|
|
||||||
hash[10] + hash[11];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startup();
|
startup();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"carwingsjs": "0.0.x",
|
"carwingsjs": "0.0.x",
|
||||||
"color": "0.10.x",
|
"color": "0.10.x",
|
||||||
"elkington": "kevinohara80/elkington",
|
"elkington": "kevinohara80/elkington",
|
||||||
"hap-nodejs": "git+https://github.com/khaost/HAP-NodeJS#2a1bc8d99a2009317ab5da93faebea34c89f197c",
|
"hap-nodejs": "git+https://github.com/KhaosT/HAP-NodeJS#b237a56de3299fba82b1c5d988a1ac665bc44a6a",
|
||||||
"harmonyhubjs-client": "^1.1.4",
|
"harmonyhubjs-client": "^1.1.4",
|
||||||
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",
|
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",
|
||||||
"mdns": "^2.2.4",
|
"mdns": "^2.2.4",
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ SonosPlatform.prototype = {
|
|||||||
|
|
||||||
device.deviceDescription(function (err, description) {
|
device.deviceDescription(function (err, description) {
|
||||||
if (description["zoneType"] != '11' && description["zoneType"] != '8') { // 8 is the Sonos SUB
|
if (description["zoneType"] != '11' && description["zoneType"] != '8') { // 8 is the Sonos SUB
|
||||||
|
|
||||||
var roomName = description["roomName"];
|
var roomName = description["roomName"];
|
||||||
|
|
||||||
if (!roomNamesFound[roomName]) {
|
if (!roomNamesFound[roomName]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user