mirror of
https://github.com/mtan93/homebridge.git
synced 2026-05-29 14:21:46 +01:00
Merge branch 'master' into osx-launchd
This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
var Service = require("HAP-NodeJS").Service;
|
||||||
|
var Characteristic = require("HAP-NodeJS").Characteristic;
|
||||||
|
var chokidar = require("chokidar");
|
||||||
|
var debug = require("debug")("FileSensorAccessory");
|
||||||
|
var crypto = require("crypto");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
accessory: FileSensorAccessory
|
||||||
|
}
|
||||||
|
|
||||||
|
function FileSensorAccessory(log, config) {
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
// url info
|
||||||
|
this.name = config["name"];
|
||||||
|
this.path = config["path"];
|
||||||
|
this.window_seconds = config["window_seconds"] || 5;
|
||||||
|
this.sensor_type = config["sensor_type"] || "m";
|
||||||
|
this.inverse = config["inverse"] || false;
|
||||||
|
|
||||||
|
if(config["sn"]){
|
||||||
|
this.sn = config["sn"];
|
||||||
|
} else {
|
||||||
|
var shasum = crypto.createHash('sha1');
|
||||||
|
shasum.update(this.path);
|
||||||
|
this.sn = shasum.digest('base64');
|
||||||
|
debug('Computed SN ' + this.sn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSensorAccessory.prototype = {
|
||||||
|
|
||||||
|
getServices: function() {
|
||||||
|
|
||||||
|
// 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.Name, this.name)
|
||||||
|
.setCharacteristic(Characteristic.Manufacturer, "Homebridge")
|
||||||
|
.setCharacteristic(Characteristic.Model, "File Sensor")
|
||||||
|
.setCharacteristic(Characteristic.SerialNumber, this.sn);
|
||||||
|
|
||||||
|
var service, changeAction;
|
||||||
|
if(this.sensor_type === "c"){
|
||||||
|
service = new Service.ContactSensor();
|
||||||
|
changeAction = function(newState){
|
||||||
|
service.getCharacteristic(Characteristic.ContactSensorState)
|
||||||
|
.setValue(newState ? Characteristic.ContactSensorState.CONTACT_DETECTED : Characteristic.ContactSensorState.CONTACT_NOT_DETECTED);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
service = new Service.MotionSensor();
|
||||||
|
changeAction = function(newState){
|
||||||
|
service.getCharacteristic(Characteristic.MotionDetected)
|
||||||
|
.setValue(newState);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var changeHandler = function(path, stats){
|
||||||
|
var d = new Date();
|
||||||
|
if(d.getTime() - stats.mtime.getTime() <= (this.window_seconds * 1000)){
|
||||||
|
var newState = this.inverse ? false : true;
|
||||||
|
changeAction(newState);
|
||||||
|
if(this.timer !== undefined) clearTimeout(this.timer);
|
||||||
|
this.timer = setTimeout(function(){changeAction(!newState);}, this.window_seconds * 1000);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
var watcher = chokidar.watch(this.path, {alwaysStat: true});
|
||||||
|
watcher.on('add', changeHandler);
|
||||||
|
watcher.on('change', changeHandler);
|
||||||
|
|
||||||
|
return [informationService, service];
|
||||||
|
}
|
||||||
|
};
|
||||||
+11
-1
@@ -94,7 +94,8 @@
|
|||||||
"platform": "HomeAssistant",
|
"platform": "HomeAssistant",
|
||||||
"name": "HomeAssistant",
|
"name": "HomeAssistant",
|
||||||
"host": "http://192.168.1.10:8123",
|
"host": "http://192.168.1.10:8123",
|
||||||
"password": "XXXXX"
|
"password": "XXXXX",
|
||||||
|
"supported_types": ["light", "switch", "media_player", "scene"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -196,6 +197,15 @@
|
|||||||
"host" : "localhost",
|
"host" : "localhost",
|
||||||
"port" : 6600,
|
"port" : 6600,
|
||||||
"description": "Allows some control of an MPD server"
|
"description": "Allows some control of an MPD server"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accessory": "FileSensor",
|
||||||
|
"name": "File Time Motion Sensor",
|
||||||
|
"path": "/tmp/CameraDump/",
|
||||||
|
"window_seconds": 5,
|
||||||
|
"sensor_type": "m",
|
||||||
|
"inverse": false
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -13,10 +13,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ad2usb": "git+https://github.com/alistairg/node-ad2usb.git#local",
|
"ad2usb": "git+https://github.com/alistairg/node-ad2usb.git#local",
|
||||||
"carwingsjs": "0.0.x",
|
"carwingsjs": "0.0.x",
|
||||||
|
"chokidar": "^1.0.5",
|
||||||
"color": "0.10.x",
|
"color": "0.10.x",
|
||||||
"eibd": "^0.3.1",
|
"eibd": "^0.3.1",
|
||||||
"elkington": "kevinohara80/elkington",
|
"elkington": "kevinohara80/elkington",
|
||||||
"hap-nodejs": "git+https://github.com/KhaosT/HAP-NodeJS#6bf0f9eaaa2d87db8d1768114c61f4acbb095c41",
|
"hap-nodejs": "git+https://github.com/KhaosT/HAP-NodeJS#0030b35856e04ee2b42f0d05839feaa5c44cbd1f",
|
||||||
"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",
|
||||||
"lifx-api": "^1.0.1",
|
"lifx-api": "^1.0.1",
|
||||||
|
|||||||
+618
-781
File diff suppressed because it is too large
Load Diff
+80
-18
@@ -7,7 +7,27 @@
|
|||||||
// URL: http://home-assistant.io
|
// URL: http://home-assistant.io
|
||||||
// GitHub: https://github.com/balloob/home-assistant
|
// GitHub: https://github.com/balloob/home-assistant
|
||||||
//
|
//
|
||||||
// HA accessories supported: Lights, Switches, Media Players.
|
// HA accessories supported: Lights, Switches, Media Players, Scenes.
|
||||||
|
//
|
||||||
|
// Optional Devices - Edit the supported_types key in the config to pick which
|
||||||
|
// of the 4 types you would like to expose to HomeKit from
|
||||||
|
// Home Assistant. light, switch, media_player, scene.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Scene Support
|
||||||
|
//
|
||||||
|
// You can optionally import your Home Assistant scenes. These will appear to
|
||||||
|
// HomeKit as switches. You can simply say "turn on party time". In some cases
|
||||||
|
// scenes names are already rerved in HomeKit...like "Good Morning" and
|
||||||
|
// "Good Night". You will be able to just say "Good Morning" or "Good Night" to
|
||||||
|
// have these triggered.
|
||||||
|
//
|
||||||
|
// You might want to play with the wording to figure out what ends up working well
|
||||||
|
// for your scene names. It's also important to not populate any actual HomeKit
|
||||||
|
// scenes with the same names, as Siri will pick these instead of your Home
|
||||||
|
// Assistant scenes.
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// Media Player Support
|
// Media Player Support
|
||||||
//
|
//
|
||||||
@@ -25,6 +45,8 @@
|
|||||||
// will need to use the same language you use to set the brighness of a light.
|
// will need to use the same language you use to set the brighness of a light.
|
||||||
// You can play around with language to see what fits best.
|
// You can play around with language to see what fits best.
|
||||||
//
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
// Examples
|
// Examples
|
||||||
//
|
//
|
||||||
// Dim the Kitchen Speaker to 40% - sets volume to 40%
|
// Dim the Kitchen Speaker to 40% - sets volume to 40%
|
||||||
@@ -37,7 +59,8 @@
|
|||||||
// "platform": "HomeAssistant",
|
// "platform": "HomeAssistant",
|
||||||
// "name": "HomeAssistant",
|
// "name": "HomeAssistant",
|
||||||
// "host": "http://192.168.1.50:8123",
|
// "host": "http://192.168.1.50:8123",
|
||||||
// "password": "xxx"
|
// "password": "xxx",
|
||||||
|
// "supported_types": ["light", "switch", "media_player", "scene"]
|
||||||
// }
|
// }
|
||||||
// ]
|
// ]
|
||||||
//
|
//
|
||||||
@@ -56,6 +79,7 @@ function HomeAssistantPlatform(log, config){
|
|||||||
// auth info
|
// auth info
|
||||||
this.host = config["host"];
|
this.host = config["host"];
|
||||||
this.password = config["password"];
|
this.password = config["password"];
|
||||||
|
this.supportedTypes = config["supported_types"];
|
||||||
|
|
||||||
this.log = log;
|
this.log = log;
|
||||||
}
|
}
|
||||||
@@ -121,22 +145,26 @@ HomeAssistantPlatform.prototype = {
|
|||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
var foundAccessories = [];
|
var foundAccessories = [];
|
||||||
var lightsRE = /^light\./i
|
|
||||||
var switchRE = /^switch\./i
|
|
||||||
var mediaPlayerRE = /^media_player\./i
|
|
||||||
|
|
||||||
|
|
||||||
this._request('GET', '/states', {}, function(error, response, data){
|
this._request('GET', '/states', {}, function(error, response, data){
|
||||||
|
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
entity = data[i]
|
entity = data[i]
|
||||||
|
entity_type = entity.entity_id.split('.')[0]
|
||||||
|
|
||||||
|
if (that.supportedTypes.indexOf(entity_type) == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var accessory = null
|
var accessory = null
|
||||||
|
|
||||||
if (entity.entity_id.match(lightsRE)) {
|
if (entity_type == 'light') {
|
||||||
accessory = new HomeAssistantLight(that.log, entity, that)
|
accessory = new HomeAssistantLight(that.log, entity, that)
|
||||||
}else if (entity.entity_id.match(switchRE)){
|
}else if (entity_type == 'switch'){
|
||||||
accessory = new HomeAssistantSwitch(that.log, entity, that)
|
accessory = new HomeAssistantSwitch(that.log, entity, that)
|
||||||
}else if (entity.entity_id.match(mediaPlayerRE) && entity.attributes && entity.attributes.supported_media_commands){
|
}else if (entity_type == 'scene'){
|
||||||
|
accessory = new HomeAssistantSwitch(that.log, entity, that, 'scene')
|
||||||
|
}else if (entity_type == 'media_player' && entity.attributes && entity.attributes.supported_media_commands){
|
||||||
accessory = new HomeAssistantMediaPlayer(that.log, entity, that)
|
accessory = new HomeAssistantMediaPlayer(that.log, entity, that)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,6 +268,12 @@ HomeAssistantLight.prototype = {
|
|||||||
},
|
},
|
||||||
getServices: function() {
|
getServices: function() {
|
||||||
var lightbulbService = new Service.Lightbulb();
|
var lightbulbService = new Service.Lightbulb();
|
||||||
|
var informationService = new Service.AccessoryInformation();
|
||||||
|
|
||||||
|
informationService
|
||||||
|
.setCharacteristic(Characteristic.Manufacturer, "Home Assistant")
|
||||||
|
.setCharacteristic(Characteristic.Model, "Light")
|
||||||
|
.setCharacteristic(Characteristic.SerialNumber, "xxx");
|
||||||
|
|
||||||
lightbulbService
|
lightbulbService
|
||||||
.getCharacteristic(Characteristic.On)
|
.getCharacteristic(Characteristic.On)
|
||||||
@@ -251,7 +285,7 @@ HomeAssistantLight.prototype = {
|
|||||||
.on('get', this.getBrightness.bind(this))
|
.on('get', this.getBrightness.bind(this))
|
||||||
.on('set', this.setBrightness.bind(this));
|
.on('set', this.setBrightness.bind(this));
|
||||||
|
|
||||||
return [lightbulbService];
|
return [informationService, lightbulbService];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -375,6 +409,12 @@ HomeAssistantMediaPlayer.prototype = {
|
|||||||
},
|
},
|
||||||
getServices: function() {
|
getServices: function() {
|
||||||
var lightbulbService = new Service.Lightbulb();
|
var lightbulbService = new Service.Lightbulb();
|
||||||
|
var informationService = new Service.AccessoryInformation();
|
||||||
|
|
||||||
|
informationService
|
||||||
|
.setCharacteristic(Characteristic.Manufacturer, "Home Assistant")
|
||||||
|
.setCharacteristic(Characteristic.Model, "Media Player")
|
||||||
|
.setCharacteristic(Characteristic.SerialNumber, "xxx");
|
||||||
|
|
||||||
lightbulbService
|
lightbulbService
|
||||||
.getCharacteristic(Characteristic.On)
|
.getCharacteristic(Characteristic.On)
|
||||||
@@ -389,15 +429,15 @@ HomeAssistantMediaPlayer.prototype = {
|
|||||||
.on('set', this.setVolume.bind(this));
|
.on('set', this.setVolume.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
return [lightbulbService];
|
return [informationService, lightbulbService];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function HomeAssistantSwitch(log, data, client) {
|
function HomeAssistantSwitch(log, data, client, type) {
|
||||||
// device info
|
// device info
|
||||||
this.domain = "switch"
|
this.domain = type || "switch"
|
||||||
this.data = data
|
this.data = data
|
||||||
this.entity_id = data.entity_id
|
this.entity_id = data.entity_id
|
||||||
if (data.attributes && data.attributes.friendly_name) {
|
if (data.attributes && data.attributes.friendly_name) {
|
||||||
@@ -454,13 +494,35 @@ HomeAssistantSwitch.prototype = {
|
|||||||
},
|
},
|
||||||
getServices: function() {
|
getServices: function() {
|
||||||
var switchService = new Service.Switch();
|
var switchService = new Service.Switch();
|
||||||
|
var informationService = new Service.AccessoryInformation();
|
||||||
|
var model;
|
||||||
|
|
||||||
switchService
|
switch (this.domain) {
|
||||||
.getCharacteristic(Characteristic.On)
|
case "scene":
|
||||||
.on('get', this.getPowerState.bind(this))
|
model = "Scene"
|
||||||
.on('set', this.setPowerState.bind(this));
|
break;
|
||||||
|
default:
|
||||||
|
model = "Switch"
|
||||||
|
}
|
||||||
|
|
||||||
return [switchService];
|
informationService
|
||||||
|
.setCharacteristic(Characteristic.Manufacturer, "Home Assistant")
|
||||||
|
.setCharacteristic(Characteristic.Model, model)
|
||||||
|
.setCharacteristic(Characteristic.SerialNumber, "xxx");
|
||||||
|
|
||||||
|
if (this.domain == 'switch') {
|
||||||
|
switchService
|
||||||
|
.getCharacteristic(Characteristic.On)
|
||||||
|
.on('get', this.getPowerState.bind(this))
|
||||||
|
.on('set', this.setPowerState.bind(this));
|
||||||
|
|
||||||
|
}else{
|
||||||
|
switchService
|
||||||
|
.getCharacteristic(Characteristic.On)
|
||||||
|
.on('set', this.setPowerState.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [informationService, switchService];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user