From f3e08b0a151760830982141e41b88703d15c4ad5 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Wed, 16 Sep 2015 03:12:56 -0400 Subject: [PATCH 1/7] add device types from Home Assistant based on the supported types declared in the config Instead of matching with a regex, we use a config of supported device types to attempt to load in. This allows the user to whitelist just the ones they want to add. --- platforms/HomeAssistant.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/platforms/HomeAssistant.js b/platforms/HomeAssistant.js index 6088b94..4c12a40 100644 --- a/platforms/HomeAssistant.js +++ b/platforms/HomeAssistant.js @@ -37,7 +37,8 @@ // "platform": "HomeAssistant", // "name": "HomeAssistant", // "host": "http://192.168.1.50:8123", -// "password": "xxx" +// "password": "xxx", +// "supported_types": ["light", "switch", "media_player", "scene"] // } // ] // @@ -56,6 +57,7 @@ function HomeAssistantPlatform(log, config){ // auth info this.host = config["host"]; this.password = config["password"]; + this.supportedTypes = config["supported_types"]; this.log = log; } @@ -121,22 +123,24 @@ HomeAssistantPlatform.prototype = { var that = this; var foundAccessories = []; - var lightsRE = /^light\./i - var switchRE = /^switch\./i - var mediaPlayerRE = /^media_player\./i - this._request('GET', '/states', {}, function(error, response, data){ for (var i = 0; i < data.length; i++) { entity = data[i] + entity_type = entity.entity_id.split('.')[0] + + if (that.supportedTypes.indexOf(entity_type) == -1) { + continue; + } + var accessory = null - if (entity.entity_id.match(lightsRE)) { + if (entity_type == 'light') { 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) - }else if (entity.entity_id.match(mediaPlayerRE) && entity.attributes && entity.attributes.supported_media_commands){ + }else if (entity_type == 'media_player' && entity.attributes && entity.attributes.supported_media_commands){ accessory = new HomeAssistantMediaPlayer(that.log, entity, that) } From 7f753f79f69f38fa84a9b1f1c4a43bfe3b022792 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Wed, 16 Sep 2015 03:14:09 -0400 Subject: [PATCH 2/7] HA switch takes a type argument This lets you pass the domain to the switch to let it be other types of objects, like say, a scene. --- platforms/HomeAssistant.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/HomeAssistant.js b/platforms/HomeAssistant.js index 4c12a40..3929b3e 100644 --- a/platforms/HomeAssistant.js +++ b/platforms/HomeAssistant.js @@ -399,9 +399,9 @@ HomeAssistantMediaPlayer.prototype = { } -function HomeAssistantSwitch(log, data, client) { +function HomeAssistantSwitch(log, data, client, type) { // device info - this.domain = "switch" + this.domain = type || "switch" this.data = data this.entity_id = data.entity_id if (data.attributes && data.attributes.friendly_name) { From eb6c881d2893c46c42581cda311d0b296ab5950e Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Wed, 16 Sep 2015 03:14:22 -0400 Subject: [PATCH 3/7] support loading scenes from HA --- platforms/HomeAssistant.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platforms/HomeAssistant.js b/platforms/HomeAssistant.js index 3929b3e..a4fd992 100644 --- a/platforms/HomeAssistant.js +++ b/platforms/HomeAssistant.js @@ -140,6 +140,8 @@ HomeAssistantPlatform.prototype = { accessory = new HomeAssistantLight(that.log, entity, that) }else if (entity_type == 'switch'){ accessory = new HomeAssistantSwitch(that.log, entity, that) + }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) } From ec8b5566183296cbe1de06be7b23f821101d3b3a Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Wed, 16 Sep 2015 03:15:37 -0400 Subject: [PATCH 4/7] return informationServices for HA devices --- platforms/HomeAssistant.js | 49 ++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/platforms/HomeAssistant.js b/platforms/HomeAssistant.js index a4fd992..5c50b26 100644 --- a/platforms/HomeAssistant.js +++ b/platforms/HomeAssistant.js @@ -246,6 +246,12 @@ HomeAssistantLight.prototype = { }, getServices: function() { 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 .getCharacteristic(Characteristic.On) @@ -257,7 +263,7 @@ HomeAssistantLight.prototype = { .on('get', this.getBrightness.bind(this)) .on('set', this.setBrightness.bind(this)); - return [lightbulbService]; + return [informationService, lightbulbService]; } } @@ -381,6 +387,12 @@ HomeAssistantMediaPlayer.prototype = { }, getServices: function() { 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 .getCharacteristic(Characteristic.On) @@ -395,7 +407,7 @@ HomeAssistantMediaPlayer.prototype = { .on('set', this.setVolume.bind(this)); } - return [lightbulbService]; + return [informationService, lightbulbService]; } } @@ -460,13 +472,36 @@ HomeAssistantSwitch.prototype = { }, getServices: function() { var switchService = new Service.Switch(); + var informationService = new Service.AccessoryInformation(); + var model; - switchService - .getCharacteristic(Characteristic.On) - .on('get', this.getPowerState.bind(this)) - .on('set', this.setPowerState.bind(this)); + switch (this.domain) { + case "scene": + model = "Scene" + 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]; } } From 0f89a6ae366c0c3808ce2f49adf1230ac2e220b0 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Wed, 16 Sep 2015 03:15:58 -0400 Subject: [PATCH 5/7] add new supported_types key for HA to sample config --- config-sample.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config-sample.json b/config-sample.json index 86782e6..49fc923 100644 --- a/config-sample.json +++ b/config-sample.json @@ -94,7 +94,8 @@ "platform": "HomeAssistant", "name": "HomeAssistant", "host": "http://192.168.1.10:8123", - "password": "XXXXX" + "password": "XXXXX", + "supported_types": ["light", "switch", "media_player", "scene"] } ], From 651cdfa786c011cb9ecbd3e213b536bdf36f6548 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Wed, 16 Sep 2015 03:16:49 -0400 Subject: [PATCH 6/7] close it --- platforms/HomeAssistant.js | 1 - 1 file changed, 1 deletion(-) diff --git a/platforms/HomeAssistant.js b/platforms/HomeAssistant.js index 5c50b26..23a4799 100644 --- a/platforms/HomeAssistant.js +++ b/platforms/HomeAssistant.js @@ -481,7 +481,6 @@ HomeAssistantSwitch.prototype = { break; default: model = "Switch" - } informationService From 773eb8fd0e878d2f1907883d98628564fb89f5af Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Wed, 16 Sep 2015 03:21:24 -0400 Subject: [PATCH 7/7] some docs --- platforms/HomeAssistant.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/platforms/HomeAssistant.js b/platforms/HomeAssistant.js index 23a4799..5a23ab5 100644 --- a/platforms/HomeAssistant.js +++ b/platforms/HomeAssistant.js @@ -7,7 +7,27 @@ // URL: http://home-assistant.io // 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 // @@ -25,6 +45,8 @@ // 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. // +// +// // Examples // // Dim the Kitchen Speaker to 40% - sets volume to 40%