From f1d599fd860d2bd6b26322375173c9d9fc761d4e Mon Sep 17 00:00:00 2001 From: Kraig McConaghy Date: Sat, 4 Jun 2016 11:53:40 -0500 Subject: [PATCH 1/5] Fixed min step issue (since Nest has a min step of 0.5 degrees celsius) --- lib/nest-thermostat-accessory.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/nest-thermostat-accessory.js b/lib/nest-thermostat-accessory.js index 02b7c2f..e8f413d 100644 --- a/lib/nest-thermostat-accessory.js +++ b/lib/nest-thermostat-accessory.js @@ -67,6 +67,10 @@ function NestThermostatAccessory(conn, log, device, structure) { return val + "%"; }); + thermostatService.getCharacteristic(Characteristic.TargetTemperature) + .setProps({ + minStep: 0.5 + }); bindCharacteristic(Characteristic.TargetTemperature, "Target temperature", this.getTargetTemperature, this.setTargetTemperature, formatAsDisplayTemperature); bindCharacteristic(Characteristic.TargetHeatingCoolingState, "Target heating", this.getTargetHeatingCooling, this.setTargetHeatingCooling, formatHeatingCoolingState); From df3cfe5141445d429761d46f61f8291b1c9e9fc4 Mon Sep 17 00:00:00 2001 From: Marshall Rose Date: Tue, 20 Sep 2016 12:13:59 -0400 Subject: [PATCH 2/5] use log.warn / log,info as appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1 use home bridge’s `log.warn` and `log.info` as appropriate 2. fix a few things that `jshint` doesn’t appreciate. --- index.js | 15 ++++++++------- lib/nest-connection.js | 8 ++++---- lib/nest-device-accessory.js | 8 ++++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index 88757a6..964b8cb 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ var nest = require('unofficial-nest-api'); var NestConnection = require('./lib/nest-connection.js'); var inherits = require('util').inherits; +var Promise = require('bluebird'); var Service, Characteristic, Accessory, uuid, Away; var DeviceAccessory, ThermostatAccessory, ProtectAccessory, CamAccessory; @@ -83,7 +84,7 @@ var setupConnection = function(config, log) { var conn = new NestConnection(token, log); if (token) { - resolve(conn) + resolve(conn); } else { conn.auth(clientId, clientSecret, code) .then(function(token) { @@ -200,7 +201,7 @@ NestPlatform.prototype = { function subscribeDone(id, data, type) { // data if set, is also stored here: nest.lastStatus.shared[thermostatID] - if (id && type != undefined && data && (that.accessoryLookup[id] || that.accessoryLookupByStructureId[id])) { + if (id && type !== undefined && data && (that.accessoryLookup[id] || that.accessoryLookupByStructureId[id])) { that.log('Update to Device: ' + id + " type: " + type); var accessory = that.accessoryLookup[id] || that.accessoryLookupByStructureId[id]; if (accessory) { @@ -224,12 +225,12 @@ NestPlatform.prototype = { } subscribe(); - callback(foundAccessories) + callback(foundAccessories); }); } }); } -} +}; function NestThermostatAccessory(log, name, device, deviceId, initialData, structure, structureId) { // device info @@ -322,7 +323,7 @@ NestThermostatAccessory.prototype.getServices = function () { }; NestThermostatAccessory.prototype.updateData = function (data) { - if (data != undefined) { + if (data !== undefined) { this.currentData = data; } var thermostat = this.getService(Service.Thermostat); @@ -344,7 +345,7 @@ NestThermostatAccessory.prototype.getCurrentHeatingCooling = function () { var low = isRange ? this.currentData.target_temperature_low : this.currentData.target_temperature; // Add threshold - var threshold = .2; + var threshold = 0.2; high += threshold; low -= threshold; @@ -462,4 +463,4 @@ NestThermostatAccessory.prototype.setAway = function (away, callback) { this.log("Setting Away for " + this.name + " to: " + away); nest.setAway(Boolean(away), this.structureId); if (callback) callback(null, away); -} +}; diff --git a/lib/nest-connection.js b/lib/nest-connection.js index c2ec3ac..a84db55 100644 --- a/lib/nest-connection.js +++ b/lib/nest-connection.js @@ -15,7 +15,7 @@ var logPrefix = "[NestFirebase] "; function Connection(token, log) { this.token = token; this.log = function(info) { - log(logPrefix + info); + log.info(logPrefix + info); }; this.debug = function(info) { log.debug(logPrefix + info); @@ -70,7 +70,7 @@ var reauthAsync = function() { return Promise.delay(5000) .then(function() { // Attempts to reauthorize Firebase connection - self.log("Reauthorizing connection"); + self.log.warn("Reauthorizing connection"); return authAsync.call(self); }) .catch(reauthLoopAsync); @@ -103,7 +103,7 @@ Connection.prototype.subscribe = function(handler) { var self = this; return new Promise(function (resolve, reject) { if (!handler){ - reject(new Error("You must specify a handler")) + reject(new Error("You must specify a handler")); } else { var notify = resolve || handler; this.conn.on('value', function (snapshot) { @@ -112,7 +112,7 @@ Connection.prototype.subscribe = function(handler) { notify(data); notify = handler; } else { - self.log("Disconnect Detected"); + self.log.warn("Disconnect Detected"); } }); } diff --git a/lib/nest-device-accessory.js b/lib/nest-device-accessory.js index a7905d4..7f74233 100644 --- a/lib/nest-device-accessory.js +++ b/lib/nest-device-accessory.js @@ -68,10 +68,10 @@ NestDeviceAccessory.prototype.bindCharacteristic = function (service, characteri }.bind(this)) .on('change', function (change) { var disp = change.newValue; - if (format && disp != null) { + if (format && disp !== null) { disp = format(disp); } - this.log(desc + " for " + this.name + " is: " + disp); + this.log.debug(desc + " for " + this.name + " is: " + disp); }.bind(this)); if (setFunc) { actual.on('set', setFunc.bind(this)); @@ -98,7 +98,7 @@ NestDeviceAccessory.prototype.getDevicePropertyPath = function(property) { NestDeviceAccessory.prototype.updateDevicePropertyAsync = function(property, value, propertyDescription, valueDescription) { propertyDescription = propertyDescription || property; valueDescription = valueDescription || value; - this.log("Setting " + propertyDescription + " for " + this.name + " to: " + valueDescription); + this.log.debug("Setting " + propertyDescription + " for " + this.name + " to: " + valueDescription); return this.conn.update(this.getDevicePropertyPath(property), value) .return(value); }; @@ -129,7 +129,7 @@ NestDeviceAccessory.prototype.cancelAutoAway = function () { NestDeviceAccessory.prototype.setAway = function (away, callback) { var val = away ? 'away' : 'home'; - this.log("Setting Away for " + this.name + " to: " + val); + this.log.info("Setting Away for " + this.name + " to: " + val); var promise = this.conn.update(this.getStructurePropertyPath("away"), val); return promise .return(away) From fa3bbbe6fa8282a49bd9ac999d342f4169f57445 Mon Sep 17 00:00:00 2001 From: Phil Freo Date: Sun, 1 Jan 2017 17:37:45 -0500 Subject: [PATCH 3/5] README clarifications --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5796dce..4106e97 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ It is **Strongly advised that you switch to the new API** but it is not required Until an alternative is determined (like Nest Weave which hasn't been released yet or setting up a website for generating tokens specifically for HomeBridge-Nest), you will have to setup an developer account for Nest. Its a simple process and if you specify that it is for Individual, then you are auto approved (at least in my experience). -_WARNING: Switching to the new API means it will show up as brand new device. This is do to the fact that the unofficial API used a different device id and we have no way to link it to the official cloud device id. This means any configurations, alarms, scenes, etc to which the Nest was associated will have need to be updated with the new Nest device._ +_WARNING: Switching to the new API means it will show up as brand new device. This is due to the fact that the unofficial API used a different device id and we have no way to link it to the official cloud device id. This means any configurations, alarms, scenes, etc to which the Nest was associated will have need to be updated with the new Nest device._ _Note: The name of the device will change as well. It matches the name displayed in the Nest app. In my case, I originally configured the Nest app so the the "Where" of my Nest was "Hallway" and I also added a label which was "Nest", so the display was "Hallway (Nest)". To fix the name to say "Nest", you can use the Nest app and blank out the "Label" and use the custom "Where" of "Nest". Anther option to fix the name is through HomeKit. HomeKit allows you to rename Accessories and Services, but it requires an app like [Insteon+](https://itunes.apple.com/us/app/insteon+/id919270334?uo=2&at=11la2C) that has the ability to change the name._ @@ -33,9 +33,10 @@ _Note: The name of the device will change as well. It matches the name displaye 6. Then just agree to the terms and submit 7. Go to **Products** and create a new product 8. Fill in: - * **Product Name**: _HomeBridge_ + * **Product Name**: _HomeBridge_ + your name (must be unique) * **Description**: _Open source project to provide HomeKit integration_ - * **Categories**: _HomeAutomation_ + * **Categories**: _Home Automation_ + * **Users**: _Individual_ * **Support URL**: _https://github.com/kraigm/homebridge-nest_ * **Redirect URL**: _[LEAVE BLANK]_ * **Permissions (minimum)**: @@ -43,7 +44,8 @@ _Note: The name of the device will change as well. It matches the name displaye * Enable **Away** with **read/write v2** * Enable **Smoke+CO alarm** with **read v4** (if you ever might want Nest Protect) * Enable **Camera** with **read v2** (if you ever might want Nest Cam, motion detection only) -9. Now you should have a product. Now locate the **Keys** section on the right of your product's page + * Permission description: fill in anything +9. Now you should have a product. Now locate the id/secret section on the right of your product's page 10. Copy the **Product ID** to your HomeBridge config as the **clientId** in the Nest config 11. Copy the **Product Secret** to your HomeBridge config as the **clientSecret** in the Nest config 12. Navigate to the **Authorization URL** @@ -65,11 +67,11 @@ Configuration sample: { "platform": "Nest", - "token" : "c.5ABsTpo88k5yfNIxZlh...", + "token" : "token will be generated upon first run of homebridge without a token", - "clientId": "developer client id", - "clientSecret": "developer client secret.", - "code": "Pin Code", + "clientId": "developer Product ID", + "clientSecret": "developer Product Secret.", + "code": "your Pincode from Nest", "username" : "username", "password" : "password" From 6d69db5a3c8488db63550be3ddec2d43bc158fb5 Mon Sep 17 00:00:00 2001 From: Ignacio Bona Piedrabuena Date: Wed, 25 Jan 2017 20:52:56 -0800 Subject: [PATCH 4/5] Added debounce to set temperature --- lib/nest-thermostat-accessory.js | 14 ++++++++++++-- package.json | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/nest-thermostat-accessory.js b/lib/nest-thermostat-accessory.js index 02b7c2f..5826127 100644 --- a/lib/nest-thermostat-accessory.js +++ b/lib/nest-thermostat-accessory.js @@ -2,6 +2,8 @@ * Created by kraigm on 12/15/15. */ +var Promise = require('bluebird'); +var debounce = require('lodash.debounce'); var inherits = require('util').inherits; var Accessory, Service, Characteristic, uuid; var NestDeviceAccessory = require('./nest-device-accessory')(); @@ -179,7 +181,15 @@ NestThermostatAccessory.prototype.setTargetHeatingCooling = function (targetHeat .asCallback(callback); }; -NestThermostatAccessory.prototype.setTargetTemperature = function (targetTemperature, callback) { +NestThermostatAccessory.prototype.setTargetTemperature = function(targetTemperature, callback) { + this.log('Trying to set temperature ' + targetTemperature); + this.setTargetTemperatureDebounced(targetTemperature, function() { + this.log('Temperature set to ' + targetTemperature); + }.bind(this)); + return Promise.resolve().asCallback(callback); +}; + +NestThermostatAccessory.prototype.setTargetTemperatureDebounced = debounce(function (targetTemperature, callback) { var usesFahrenheit = this.usesFahrenheit(); if (usesFahrenheit) { // Convert to Fahrenheit and round to nearest integer @@ -213,7 +223,7 @@ NestThermostatAccessory.prototype.setTargetTemperature = function (targetTempera return this.cancelAutoAway() .then(this.updateDevicePropertyAsync.bind(this, key, targetTemperature, prop + "target temperature")) .asCallback(callback); -}; +}, 5000); NestThermostatAccessory.prototype.usesFahrenheit = function () { return this.getTemperatureUnits() == Characteristic.TemperatureDisplayUnits.FAHRENHEIT; diff --git a/package.json b/package.json index f48626e..26b0fdc 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,9 @@ "homebridge": ">=0.2.5" }, "dependencies": { - "firebase": "^2.3.2", "bluebird": "^3.2.2", + "firebase": "^2.3.2", + "lodash.debounce": "^4.0.8", "request-promise": "^1.0.2", "unofficial-nest-api": "git+https://github.com/kraigm/unofficial_nodejs_nest.git#3cbd337adc32fab3b481659b38d86f9fcd6a9c02" } From 3af1704d8bb3ae5dabde5e395db4f24aea82daa6 Mon Sep 17 00:00:00 2001 From: Kraig McConaghy Date: Sat, 30 Sep 2017 07:27:28 -0500 Subject: [PATCH 5/5] Updated package version for release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 26b0fdc..da3507a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "homebridge-nest", "description": "Nest plugin for homebridge", - "version": "1.1.2", + "version": "1.1.3", "repository": { "type": "git", "url": "git://github.com/kraigm/homebridge-nest.git"