mirror of
https://github.com/mtan93/homebridge.git
synced 2026-03-08 21:02:38 +00:00
29
README.md
29
README.md
@@ -1,7 +1,7 @@
|
||||
|
||||
# HomeBridge
|
||||
|
||||
HomeBridge is a lightweight NodeJS server you can run on your home network that emulates the iOS HomeKit API. It includes a set of "shims" (found in the [accessories](accessories/) folder) that provide a basic bridge from HomeKit to various 3rd-party APIs provided by manufacturers of "smart home" devices.
|
||||
HomeBridge is a lightweight NodeJS server you can run on your home network that emulates the iOS HomeKit API. It includes a set of "shims" (found in the [accessories](accessories/) and [platforms](platforms/) folders) that provide a basic bridge from HomeKit to various 3rd-party APIs provided by manufacturers of "smart home" devices.
|
||||
|
||||
Since Siri supports devices added through HomeKit, this means that with HomeBridge you can ask Siri to control devices that don't have any support for HomeKit at all. For instance, using the included shims, you can say things like:
|
||||
|
||||
@@ -15,6 +15,24 @@ Since Siri supports devices added through HomeKit, this means that with HomeBrid
|
||||
|
||||
If you would like to support any other devices, please write a shim and create a pull request and I'd be happy to add it to this official list.
|
||||
|
||||
# Shim types
|
||||
There are 2 types of shims supported in HomeBridge.
|
||||
|
||||
* Accessory - Individual device
|
||||
* Platform - A full bridge to another system
|
||||
|
||||
## Accessories
|
||||
|
||||
Accessories are individual devices you would like to bridge to HomeKit. You set them up by declaring them individually in your `config.json` file. Generally, you specify them by `name` or `id` and which system they use.
|
||||
|
||||
## Platforms
|
||||
|
||||
Platforms bridge entire systems to HomeKit. Platforms can be things like Wink or SmartThings or Vera. By adding a platform to your `config.json`, HomeBridge will automatically detect all of your devices for you.
|
||||
|
||||
Wink is currently the only supported platform at the moment.
|
||||
|
||||
All you have to do is add the right config options so HomeBridge can authenticate and communicate with your other system, and voila, your devices will be available to HomeKit via HomeBridge.
|
||||
|
||||
# Why?
|
||||
|
||||
Technically, the device manufacturers should be the ones implementing the HomeKit API. And I'm sure they will - eventually. When they do, these shims will be obsolete, and I hope that happens soon. In the meantime, this server is a fun way to get a taste of the future, for those who just can't bear to wait until "real" HomeKit devices are on the market.
|
||||
@@ -58,15 +76,20 @@ Now you should be able to run the homebridge server:
|
||||
Starting HomeBridge server...
|
||||
Couldn't find a config.json file [snip]
|
||||
|
||||
The server won't do anything until you've created a `config.json` file containing your home devices (or _accessories_ in HomeKit parlance) you wish to make available to iOS.
|
||||
The server won't do anything until you've created a `config.json` file containing your home devices (or _accessories_ in HomeKit parlance) or platforms you wish to make available to iOS.
|
||||
|
||||
One you've added your devices, you should be able to run the server again and see them initialize:
|
||||
Once you've added your devices or platforms, you should be able to run the server again and see them initialize:
|
||||
|
||||
$ npm run start
|
||||
Starting HomeBridge server...
|
||||
Loading 6 accessories...
|
||||
[Speakers] Initializing 'Sonos' accessory...
|
||||
[Coffee Maker] Initializing 'WeMo' accessory...
|
||||
[Speakers] Initializing 'Sonos' accessory...
|
||||
[Coffee Maker] Initializing 'WeMo' accessory...
|
||||
[Wink] Initializing Wink platform...
|
||||
[Wink] Fetching Wink devices.
|
||||
[Wink] Initializing device with name Living Room Lamp...
|
||||
|
||||
Your server is now ready to receive commands from iOS.
|
||||
|
||||
|
||||
39
app.js
39
app.js
@@ -21,11 +21,46 @@ storage.initSync();
|
||||
var config = JSON.parse(fs.readFileSync(configPath));
|
||||
|
||||
function loadAccessories() {
|
||||
console.log("Loading " + config.accessories.length + " accessories...");
|
||||
|
||||
var accessories = [];
|
||||
|
||||
console.log("Loading " + config.platforms.length + " platforms...");
|
||||
for (var i=0; i<config.platforms.length; i++) {
|
||||
|
||||
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 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);
|
||||
|
||||
log("Initializing " + platformName + " platform...");
|
||||
|
||||
var platform = new platformConstructor(log, platformConfig);
|
||||
|
||||
// query for devices
|
||||
platform.accessories(function(foundAccessories){
|
||||
// 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);
|
||||
}
|
||||
accessories.push.apply(accessories, foundAccessories);
|
||||
})
|
||||
}
|
||||
|
||||
// Instantiate all accessories in the config
|
||||
console.log("Loading " + config.accessories.length + " accessories...");
|
||||
for (var i=0; i<config.accessories.length; i++) {
|
||||
|
||||
var accessoryConfig = config.accessories[i];
|
||||
@@ -140,4 +175,4 @@ function createUsername(str) {
|
||||
hash[10] + hash[11];
|
||||
}
|
||||
|
||||
loadAccessories();
|
||||
loadAccessories();
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
{
|
||||
"description": "This is an example configuration file with all supported devices. You can use this as a template for creating your own configuration file containing devices you actually own.",
|
||||
|
||||
"platforms": [
|
||||
{
|
||||
"platform": "Wink",
|
||||
"name": "Wink",
|
||||
"client_id": "YOUR_WINK_API_CLIENT_ID",
|
||||
"client_secret": "YOUR_WINK_API_CLIENT_SECRET",
|
||||
"username": "your@email.com",
|
||||
"password": "WINK_PASSWORD"
|
||||
}
|
||||
],
|
||||
|
||||
"accessories": [
|
||||
{
|
||||
"accessory": "WeMo",
|
||||
@@ -58,15 +69,6 @@
|
||||
"device_id": "E1",
|
||||
"protocol": "pl",
|
||||
"can_dim": true
|
||||
},
|
||||
{
|
||||
"accessory": "Wink",
|
||||
"client_id": "YOUR_WINK_API_CLIENT_ID",
|
||||
"client_secret": "YOUR_WINK_API_CLIENT_SECRET",
|
||||
"username": "your@email.com",
|
||||
"password": "WINK_PASSWORD",
|
||||
"name": "Family Room Lamp",
|
||||
"description": "Lamp on the left side of the room"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
var types = require("../lib/HAP-NodeJS/accessories/types.js");
|
||||
var wink = require('wink-js');
|
||||
|
||||
function WinkAccessory(log, config) {
|
||||
this.log = log;
|
||||
var model = {
|
||||
light_bulbs: require('wink-js/lib/model/light')
|
||||
};
|
||||
|
||||
|
||||
function WinkPlatform(log, config){
|
||||
|
||||
// auth info
|
||||
this.client_id = config["client_id"];
|
||||
@@ -10,18 +14,15 @@ function WinkAccessory(log, config) {
|
||||
this.username = config["username"];
|
||||
this.password = config["password"];
|
||||
|
||||
// device info
|
||||
this.name = config["name"];
|
||||
this.device = null;
|
||||
|
||||
this.log("Searching for Wink device with exact name '" + this.name + "'...");
|
||||
this.search();
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
WinkAccessory.prototype = {
|
||||
WinkPlatform.prototype = {
|
||||
accessories: function(callback) {
|
||||
this.log("Fetching Wink devices.");
|
||||
|
||||
search: function() {
|
||||
var that = this;
|
||||
var foundAccessories = [];
|
||||
|
||||
wink.init({
|
||||
"client_id": this.client_id,
|
||||
@@ -33,13 +34,28 @@ WinkAccessory.prototype = {
|
||||
that.log("There was a problem authenticating with Wink.");
|
||||
} else {
|
||||
// success
|
||||
wink.user().device(that.name, function(device) {
|
||||
that.device = device
|
||||
wink.user().devices('light_bulbs', function(devices) {
|
||||
for (var i=0; i<devices.data.length; i++){
|
||||
device = model.light_bulbs(devices.data[i], wink)
|
||||
accessory = new WinkAccessory(that.log, device);
|
||||
foundAccessories.push(accessory);
|
||||
}
|
||||
callback(foundAccessories);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function WinkAccessory(log, device) {
|
||||
// device info
|
||||
this.name = device.name;
|
||||
this.device = device;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
WinkAccessory.prototype = {
|
||||
|
||||
setPowerState: function(powerOn) {
|
||||
if (!this.device) {
|
||||
@@ -79,7 +95,7 @@ WinkAccessory.prototype = {
|
||||
|
||||
var that = this;
|
||||
|
||||
this.log("Setting brightness on the '"+this.name+"' to on");
|
||||
this.log("Setting brightness on the '"+this.name+"' to " + level);
|
||||
this.device.brightness(level, function(response) {
|
||||
if (response === undefined) {
|
||||
that.log("Error setting brightness on the '"+that.name+"'")
|
||||
@@ -185,3 +201,4 @@ WinkAccessory.prototype = {
|
||||
};
|
||||
|
||||
module.exports.accessory = WinkAccessory;
|
||||
module.exports.platform = WinkPlatform;
|
||||
Reference in New Issue
Block a user