mirror of
https://github.com/mtan93/homebridge.git
synced 2026-03-08 05:31:55 +00:00
Merge branch 'nfarina/master' into z-way-server-2
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
var types = require("HAP-NodeJS/accessories/types.js");
|
||||
var Service = require("HAP-NodeJS").Service;
|
||||
var Characteristic = require("HAP-NodeJS").Characteristic;
|
||||
var request = require("request");
|
||||
|
||||
module.exports = {
|
||||
accessory: HttpAccessory
|
||||
}
|
||||
|
||||
function HttpAccessory(log, config) {
|
||||
this.log = log;
|
||||
|
||||
@@ -9,9 +14,6 @@ function HttpAccessory(log, config) {
|
||||
this.off_url = config["off_url"];
|
||||
this.brightness_url = config["brightness_url"];
|
||||
this.http_method = config["http_method"];
|
||||
|
||||
// device info
|
||||
this.name = config["name"];
|
||||
}
|
||||
|
||||
HttpAccessory.prototype = {
|
||||
@@ -26,135 +28,73 @@ HttpAccessory.prototype = {
|
||||
})
|
||||
},
|
||||
|
||||
setPowerState: function(powerOn) {
|
||||
setPowerState: function(powerOn, callback) {
|
||||
var url;
|
||||
|
||||
if (powerOn) {
|
||||
url = this.on_url
|
||||
this.log("Setting power state on the '"+this.name+"' to on");
|
||||
}else{
|
||||
url = this.off_url
|
||||
this.log("Setting power state on the '"+this.name+"' to off");
|
||||
url = this.on_url;
|
||||
this.log("Setting power state to on");
|
||||
}
|
||||
else {
|
||||
url = this.off_url;
|
||||
this.log("Setting power state to off");
|
||||
}
|
||||
|
||||
this.httpRequest(url, this.http_method, function(error, response, body){
|
||||
this.httpRequest(url, this.http_method, function(error, response, body) {
|
||||
if (error) {
|
||||
return console.error('http power function failed:', error);
|
||||
}else{
|
||||
return console.log('http power function succeeded!');
|
||||
this.log('HTTP power function failed: %s', error.message);
|
||||
callback(error);
|
||||
}
|
||||
});
|
||||
|
||||
else {
|
||||
this.log('HTTP power function succeeded!');
|
||||
callback();
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
setBrightness: function(level) {
|
||||
setBrightness: function(level, callback) {
|
||||
var url = this.brightness_url.replace("%b", level)
|
||||
|
||||
this.log("Setting brightness on the '"+this.name+"' to " + level);
|
||||
this.log("Setting brightness to %s", level);
|
||||
|
||||
this.httpRequest(url, this.http_method, function(error, response, body){
|
||||
this.httpRequest(url, this.http_method, function(error, response, body) {
|
||||
if (error) {
|
||||
return console.error('http brightness function failed:', error);
|
||||
}else{
|
||||
return console.log('http brightness function succeeded!');
|
||||
this.log('HTTP brightness function failed: %s', error);
|
||||
callback(error);
|
||||
}
|
||||
});
|
||||
|
||||
else {
|
||||
this.log('HTTP brightness function succeeded!');
|
||||
callback();
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
|
||||
identify: function(callback) {
|
||||
this.log("Identify requested!");
|
||||
callback(); // success
|
||||
},
|
||||
|
||||
getServices: function() {
|
||||
var that = this;
|
||||
return [{
|
||||
sType: types.ACCESSORY_INFORMATION_STYPE,
|
||||
characteristics: [{
|
||||
cType: types.NAME_CTYPE,
|
||||
onUpdate: null,
|
||||
perms: ["pr"],
|
||||
format: "string",
|
||||
initialValue: this.name,
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Name of the accessory",
|
||||
designedMaxLength: 255
|
||||
},{
|
||||
cType: types.MANUFACTURER_CTYPE,
|
||||
onUpdate: null,
|
||||
perms: ["pr"],
|
||||
format: "string",
|
||||
initialValue: "Http",
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Manufacturer",
|
||||
designedMaxLength: 255
|
||||
},{
|
||||
cType: types.MODEL_CTYPE,
|
||||
onUpdate: null,
|
||||
perms: ["pr"],
|
||||
format: "string",
|
||||
initialValue: "Rev-1",
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Model",
|
||||
designedMaxLength: 255
|
||||
},{
|
||||
cType: types.SERIAL_NUMBER_CTYPE,
|
||||
onUpdate: null,
|
||||
perms: ["pr"],
|
||||
format: "string",
|
||||
initialValue: "A1S2NASF88EW",
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "SN",
|
||||
designedMaxLength: 255
|
||||
},{
|
||||
cType: types.IDENTIFY_CTYPE,
|
||||
onUpdate: null,
|
||||
perms: ["pw"],
|
||||
format: "bool",
|
||||
initialValue: false,
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Identify Accessory",
|
||||
designedMaxLength: 1
|
||||
}]
|
||||
},{
|
||||
sType: types.LIGHTBULB_STYPE,
|
||||
characteristics: [{
|
||||
cType: types.NAME_CTYPE,
|
||||
onUpdate: null,
|
||||
perms: ["pr"],
|
||||
format: "string",
|
||||
initialValue: this.name,
|
||||
supportEvents: true,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Name of service",
|
||||
designedMaxLength: 255
|
||||
},{
|
||||
cType: types.POWER_STATE_CTYPE,
|
||||
onUpdate: function(value) { that.setPowerState(value); },
|
||||
perms: ["pw","pr","ev"],
|
||||
format: "bool",
|
||||
initialValue: 0,
|
||||
supportEvents: true,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Change the power state",
|
||||
designedMaxLength: 1
|
||||
},{
|
||||
cType: types.BRIGHTNESS_CTYPE,
|
||||
onUpdate: function(value) { that.setBrightness(value); },
|
||||
perms: ["pw","pr","ev"],
|
||||
format: "int",
|
||||
initialValue: 0,
|
||||
supportEvents: true,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Adjust Brightness",
|
||||
designedMinValue: 0,
|
||||
designedMaxValue: 100,
|
||||
designedMinStep: 1,
|
||||
unit: "%"
|
||||
}]
|
||||
}];
|
||||
|
||||
// you can OPTIONALLY create an information service if you wish to override
|
||||
// the default values for things like serial number, model, etc.
|
||||
var informationService = new Service.AccessoryInformation();
|
||||
|
||||
informationService
|
||||
.setCharacteristic(Characteristic.Manufacturer, "HTTP Manufacturer")
|
||||
.setCharacteristic(Characteristic.Model, "HTTP Model")
|
||||
.setCharacteristic(Characteristic.SerialNumber, "HTTP Serial Number");
|
||||
|
||||
var lightbulbService = new Service.Lightbulb();
|
||||
|
||||
lightbulbService
|
||||
.getCharacteristic(Characteristic.On)
|
||||
.on('set', this.setPowerState.bind(this));
|
||||
|
||||
lightbulbService
|
||||
.addCharacteristic(new Characteristic.Brightness())
|
||||
.on('set', this.setBrightness.bind(this));
|
||||
|
||||
return [informationService, lightbulbService];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.accessory = HttpAccessory;
|
||||
|
||||
153
app.js
153
app.js
@@ -5,6 +5,8 @@ var hap = require('HAP-NodeJS');
|
||||
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 accessoryLoader = require('HAP-NodeJS').AccessoryLoader;
|
||||
|
||||
console.log("Starting HomeBridge server...");
|
||||
@@ -72,28 +74,19 @@ function loadAccessories() {
|
||||
var accessoryConfig = config.accessories[i];
|
||||
|
||||
// Load up the class for this accessory
|
||||
var accessoryName = accessoryConfig["accessory"]; // like "WeMo"
|
||||
var accessoryModule = require('./accessories/' + accessoryName + ".js"); // like "./accessories/WeMo.js"
|
||||
var accessoryType = accessoryConfig["accessory"]; // like "WeMo"
|
||||
var accessoryModule = require('./accessories/' + accessoryType + ".js"); // like "./accessories/WeMo.js"
|
||||
var accessoryConstructor = accessoryModule.accessory; // like "WeMoAccessory", a JavaScript constructor
|
||||
|
||||
// Create a custom logging function that prepends the device display name for debugging
|
||||
var name = accessoryConfig["name"];
|
||||
var log = function(name) { return function(s) { console.log("[" + name + "] " + s); }; }(name);
|
||||
var accessoryName = accessoryConfig["name"];
|
||||
var log = createLog(accessoryName);
|
||||
|
||||
log("Initializing " + accessoryName + " accessory...");
|
||||
log("Initializing %s accessory...", accessoryType);
|
||||
|
||||
var accessoryInstance = new accessoryConstructor(log, accessoryConfig);
|
||||
|
||||
// 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();
|
||||
var accessory = createAccessory(accessoryInstance, accessoryName);
|
||||
|
||||
// Create the actual HAP-NodeJS "Accessory" instance
|
||||
var accessory = accessoryLoader.parseAccessoryJSON({
|
||||
displayName: name,
|
||||
services: services
|
||||
});
|
||||
|
||||
// add it to the bridge
|
||||
bridge.addBridgedAccessory(accessory);
|
||||
}
|
||||
@@ -108,54 +101,104 @@ function loadPlatforms() {
|
||||
var platformConfig = config.platforms[i];
|
||||
|
||||
// Load up the class for this accessory
|
||||
var platformName = platformConfig["platform"]; // like "Wink"
|
||||
var platformModule = require('./platforms/' + platformName + ".js"); // like "./platforms/Wink.js"
|
||||
var platformType = platformConfig["platform"]; // like "Wink"
|
||||
var platformName = platformConfig["name"];
|
||||
var platformModule = require('./platforms/' + platformType + ".js"); // like "./platforms/Wink.js"
|
||||
var platformConstructor = platformModule.platform; // like "WinkPlatform", a JavaScript constructor
|
||||
|
||||
// Create a custom logging function that prepends the platform display name for debugging
|
||||
var name = platformConfig["name"];
|
||||
var log = function(name) { return function(s) { console.log("[" + name + "] " + s); }; }(name);
|
||||
// Create a custom logging function that prepends the platform name for debugging
|
||||
var log = createLog(platformName);
|
||||
|
||||
log("Initializing " + platformName + " platform...");
|
||||
log("Initializing %s platform...", platformType);
|
||||
|
||||
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
|
||||
getAccessories(name, log);
|
||||
loadPlatformAccessories(platformInstance, log);
|
||||
}
|
||||
}
|
||||
|
||||
function loadPlatformAccessories(platformInstance, 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];
|
||||
var accessoryName = accessoryInstance.name; // assume this property was set
|
||||
|
||||
log("Initializing platform accessory '%s'...", accessoryName);
|
||||
|
||||
var accessory = createAccessory(accessoryInstance, accessoryName);
|
||||
|
||||
// add it to the bridge
|
||||
bridge.addBridgedAccessory(accessory);
|
||||
}
|
||||
|
||||
// were we the last callback?
|
||||
if (asyncCalls === 0 && !asyncWait)
|
||||
publish();
|
||||
});
|
||||
}
|
||||
|
||||
function createAccessory(accessoryInstance, displayName) {
|
||||
|
||||
var services = accessoryInstance.getServices();
|
||||
|
||||
if (!(services[0] instanceof Service)) {
|
||||
// The returned "services" for this accessory is assumed to be the old style: a big array
|
||||
// of JSON-style objects that will need to be parsed by HAP-NodeJS's AccessoryLoader.
|
||||
|
||||
// Create the actual HAP-NodeJS "Accessory" instance
|
||||
return accessoryLoader.parseAccessoryJSON({
|
||||
displayName: displayName,
|
||||
services: services
|
||||
});
|
||||
}
|
||||
else {
|
||||
// The returned "services" for this accessory are simply an array of new-API-style
|
||||
// Service instances which we can add to a created HAP-NodeJS Accessory directly.
|
||||
|
||||
var accessoryUUID = uuid.generate(accessoryInstance.constructor.name + ":" + displayName);
|
||||
|
||||
var accessory = new Accessory(displayName, accessoryUUID);
|
||||
|
||||
// listen for the identify event if the accessory instance has defined an identify() method
|
||||
if (accessoryInstance.identify)
|
||||
accessory.on('identify', function(paired, callback) { accessoryInstance.identify(callback); });
|
||||
|
||||
services.forEach(function(service) {
|
||||
|
||||
// if you returned an AccessoryInformation service, merge its values with ours
|
||||
if (service instanceof Service.AccessoryInformation) {
|
||||
var existingService = accessory.getService(Service.AccessoryInformation);
|
||||
|
||||
// pull out any values you may have defined
|
||||
var manufacturer = service.getCharacteristic(Characteristic.Manufacturer).value;
|
||||
var model = service.getCharacteristic(Characteristic.Model).value;
|
||||
var serialNumber = service.getCharacteristic(Characteristic.SerialNumber).value;
|
||||
|
||||
if (manufacturer) existingService.setCharacteristic(Characteristic.Manufacturer, manufacturer);
|
||||
if (model) existingService.setCharacteristic(Characteristic.Model, model);
|
||||
if (serialNumber) existingService.setCharacteristic(Characteristic.SerialNumber, serialNumber);
|
||||
}
|
||||
else {
|
||||
accessory.addService(service);
|
||||
}
|
||||
});
|
||||
|
||||
return accessory;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a logging function that prepends messages with the given name in [brackets].
|
||||
function createLog(name) {
|
||||
return function(message) {
|
||||
var rest = Array.prototype.slice.call(arguments, 1 ); // any arguments after message
|
||||
var args = ["[%s] " + message, name].concat(rest);
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
}
|
||||
|
||||
function publish() {
|
||||
bridge.publish({
|
||||
username: bridgeConfig.username || "CC:22:3D:E3:CE:30",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"carwingsjs": "0.0.x",
|
||||
"color": "0.10.x",
|
||||
"elkington": "kevinohara80/elkington",
|
||||
"hap-nodejs": "git+https://github.com/KhaosT/HAP-NodeJS#187174846dc4b8970efba74b9eb2968b35f15d87",
|
||||
"hap-nodejs": "git+https://github.com/KhaosT/HAP-NodeJS#46ba0597eb339983a14d98c53764a58a5516fcd2",
|
||||
"harmonyhubjs-client": "^1.1.4",
|
||||
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",
|
||||
"mdns": "^2.2.4",
|
||||
|
||||
@@ -66,11 +66,17 @@ DomoticzPlatform.prototype = {
|
||||
},
|
||||
|
||||
accessories: function(callback) {
|
||||
this.log("Fetching Domoticz lights and switches...");
|
||||
var that = this;
|
||||
var foundAccessories = [];
|
||||
if (this.roomid == 0) {
|
||||
this.log("Fetching Domoticz lights and switches...");
|
||||
var that = this;
|
||||
var foundAccessories = [];
|
||||
|
||||
// mechanism to ensure callback is only executed once all requests complete
|
||||
var asyncCalls = 0;
|
||||
function callbackLater() { if (--asyncCalls == 0) callback(foundAccessories); }
|
||||
|
||||
if (this.roomid == 0) {
|
||||
//Get Lights
|
||||
asyncCalls++;
|
||||
request.get({
|
||||
url: this.urlForQuery("type=devices&filter=light&used=true&order=Name"),
|
||||
json: true
|
||||
@@ -83,14 +89,15 @@ DomoticzPlatform.prototype = {
|
||||
foundAccessories.push(accessory);
|
||||
})
|
||||
}
|
||||
callback(foundAccessories);
|
||||
callbackLater();
|
||||
} else {
|
||||
that.log("There was a problem connecting to Domoticz. (" + err + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
//Get all devices specified in the room
|
||||
asyncCalls++;
|
||||
request.get({
|
||||
url: this.urlForQuery("type=devices&plan=" + this.roomid),
|
||||
json: true
|
||||
@@ -106,30 +113,30 @@ DomoticzPlatform.prototype = {
|
||||
}
|
||||
})
|
||||
}
|
||||
callback(foundAccessories);
|
||||
callbackLater();
|
||||
} else {
|
||||
that.log("There was a problem connecting to Domoticz.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
//Get Scenes
|
||||
foundAccessories = [];
|
||||
asyncCalls++;
|
||||
request.get({
|
||||
url: this.urlForQuery("type=scenes"),
|
||||
json: true
|
||||
}, function(err, response, json) {
|
||||
json: true
|
||||
}, function(err, response, json) {
|
||||
if (!err && response.statusCode == 200) {
|
||||
if (json['result'] != undefined) {
|
||||
var sArray=sortByKey(json['result'],"Name");
|
||||
sArray.map(function(s) {
|
||||
accessory = new DomoticzAccessory(that.log, that, true, s.idx, s.Name, false, 0, false);
|
||||
foundAccessories.push(accessory);
|
||||
})
|
||||
})
|
||||
}
|
||||
callback(foundAccessories);
|
||||
callbackLater();
|
||||
} else {
|
||||
that.log("There was a problem connecting to Domoticz.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user