Initial work. Still in progress

This commit is contained in:
Kraig McConaghy
2015-10-17 20:51:57 -05:00
parent 831480d035
commit c897913005

View File

@@ -1,5 +1,11 @@
var types = require("HAP-NodeJS/accessories/types.js");
var nest = require('unofficial-nest-api');
var Service = require("hap-nodejs").Service;
var Characteristic = require("hap-nodejs").Characteristic;
var Accessory = require("hap-nodejs").Accessory;
var uuid = require("hap-nodejs").uuid;
var inherits = require('util').inherits;
function NestPlatform(log, config){
@@ -29,8 +35,9 @@ NestPlatform.prototype = {
// it's a thermostat, adjust this to detect other accessories
if (data.shared[deviceId].hasOwnProperty('current_temperature'))
{
var name = data.shared[deviceId].name
var accessory = new NestThermostatAccessory(that.log, name, device, deviceId);
var initialData = data.shared[deviceId];
var name = initialData.name
var accessory = new NestThermostatAccessory(that.log, name, device, deviceId, initialData);
foundAccessories.push(accessory);
}
}
@@ -42,7 +49,7 @@ NestPlatform.prototype = {
}
}
function NestThermostatAccessory(log, name, device, deviceId) {
function NestThermostatAccessory(log, name, device, deviceId, initialData) {
// device info
if (name) {
this.name = name;
@@ -53,124 +60,226 @@ function NestThermostatAccessory(log, name, device, deviceId) {
this.serial = device.serial_number;
this.deviceId = deviceId;
this.log = log;
Accessory.call(this, name, uuid.generate(deviceId));
this.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Manufacturer, "Nest")
.setCharacteristic(Characteristic.Model, this.model)
.setCharacteristic(Characteristic.SerialNumber, this.serial);
this.addService(Service.Thermostat, name);
this.getService(Service.Thermostat)
.setCharacteristic(Characteristic.TemperatureDisplayUnits, this.extractTemperatureUnits(device))
.on('get', this.getTemperatureUnits);
this.getService(Service.Thermostat)
.setCharacteristic(Characteristic.CurrentTemperature, this.extractCurrentTemperature(device))
//.getCharacteristic(Characteristic.CurrentTemperature)
.on('get', this.getCurrentTemperature);
this.getService(Service.Thermostat)
.setCharacteristic(Characteristic.TargetTemperature, this.extractTargetTemperature(device))
.on('get', this.getTargetTemperature)
.on('set', this.setTargetTemperature);
this.getService(Service.Thermostat)
.setCharacteristic(Characteristic.CurrentHeatingCoolingState, this.extractCurrentHeatingCooling(device))
.on('get', this.getCurrentHeatingCooling);
this.getService(Service.Thermostat)
.setCharacteristic(Characteristic.TargetHeatingCoolingState, this.extractTargetHeatingCooling(device))
.on('get', this.getTargetHeatingCoooling)
.on('set', this.setTargetHeatingCooling);
//this.getService(Service.Thermostat)
// .getCharacteristic(Characteristic.CurrentRelativeHumidity)
// .on('get', function(callback) {
// that.getCurrentRelativeHumidity(function(currentRelativeHumidity){
// callback(currentRelativeHumidity);
// });
// });
}
NestThermostatAccessory.prototype = {
getCurrentHeatingCooling: function(callback){
var that = this;
this.log("Checking current heating cooling for: " + this.name);
nest.fetchStatus(function (data) {
var device = data.device[that.deviceId];
var currentHeatingCooling = 0;
switch(device.current_schedule_mode) {
case "OFF":
targetHeatingCooling = 0;
break;
case "HEAT":
currentHeatingCooling = 1;
break;
case "COOL":
currentHeatingCooling = 2;
break;
case "RANGE":
currentHeatingCooling = 3;
break;
default:
currentHeatingCooling = 0;
inherits(NestThermostatAccessory, Accessory);
//NestThermostatAccessory.prototype.parent = Accessory.prototype;
Service.prototype.getCharacteristic = function(name) {
// returns a characteristic object from the service
// If Service.prototype.getCharacteristic(Characteristic.Type) does not find the characteristic,
// but the type is in optionalCharacteristics, it adds the characteristic.type to the service and returns it.
var index, characteristic;
for (index in this.characteristics) {
characteristic = this.characteristics[index];
if (typeof name === 'string' && characteristic.displayName === name) {
return characteristic;
}
else if (typeof name === 'function' && characteristic instanceof name) {
return characteristic;
}
}
if (typeof name === 'function') {
for (index in this.optionalCharacteristics) {
characteristic = this.optionalCharacteristics[index];
if (characteristic instanceof name) {
return this.addCharacteristic(name);
}
that.log("Current heating for " + this.name + "is: " + currentHeatingCooling);
callback(currentHeatingCooling);
});
}
}
};
NestThermostatAccessory.prototype.getServices = function() {
return this.services;
};
},
getTargetHeatingCoooling: function(callback){
NestThermostatAccessory.prototype.extractCurrentHeatingCooling = function(device){
var currentHeatingCooling = 0;
switch(device.current_schedule_mode) {
case "OFF":
currentHeatingCooling = 0;
break;
case "HEAT":
currentHeatingCooling = 1;
break;
case "COOL":
currentHeatingCooling = 2;
break;
case "RANGE":
currentHeatingCooling = 3;
break;
default:
currentHeatingCooling = 0;
}
this.log("Current heating for " + this.name + "is: " + currentHeatingCooling);
return currentHeatingCooling;
};
NestThermostatAccessory.prototype.getCurrentHeatingCooling = function(callback){
var that = this;
this.log("Checking current heating cooling for: " + this.name);
nest.fetchStatus(function (data) {
var device = data.device[that.deviceId];
var currentHeatingCooling = that.extractCurrentHeatingCooling(device);
callback(currentHeatingCooling);
});
};
NestThermostatAccessory.prototype.extractTargetHeatingCooling = function(device){
var targetHeatingCooling = 0;
switch(device.target_temperature_type) {
case "off":
targetHeatingCooling = 0;
break;
case "heat":
targetHeatingCooling = 1;
break;
case "cool":
targetHeatingCooling = 2;
break;
case "range":
targetHeatingCooling = 3;
break;
default:
targetHeatingCooling = 0;
}
this.log("Current target heating for " + this.name + " is: " + targetHeatingCooling);
return targetHeatingCooling;
};
NestThermostatAccessory.prototype.getTargetHeatingCoooling = function(callback){
var that = this;
this.log("Checking target heating cooling for: " + this.name);
nest.fetchStatus(function (data) {
var device = data.device[that.deviceId];
var targetHeatingCooling = 0;
switch(device.target_temperature_type) {
case "off":
targetHeatingCooling = 0;
break;
case "heat":
targetHeatingCooling = 1;
break;
case "cool":
targetHeatingCooling = 2;
break;
case "range":
targetHeatingCooling = 3;
break;
default:
targetHeatingCooling = 0;
}
that.log("Current target heating for " + this.name + " is: " + targetHeatingCooling);
var targetHeatingCooling = that.extractTargetHeatingCooling(device);
callback(targetHeatingCooling);
});
},
};
getCurrentTemperature: function(callback){
NestThermostatAccessory.prototype.extractCurrentTemperature = function(device){
var curTemp = this.extractAsDisplayUnit(device.current_temperature, device);
this.log("Current temperature for " + this.name + " is: " + curTemp);
return curTemp;
};
NestThermostatAccessory.prototype.getCurrentTemperature = function(callback){
var that = this;
nest.fetchStatus(function (data) {
var device = data.shared[that.deviceId];
that.log("Current temperature for " + this.name + " is: " + device.current_temperature);
callback(device.current_temperature);
var curTemp = this.extractCurrentTemperature(device);
callback(curTemp);
});
};
NestThermostatAccessory.prototype.extractTargetTemperature = function(device){
var targetTemp;
if (device.target_temperature != undefined) {
targetTemp = device.target_temperature;
} else if (device.temperature_lock_high_temp != undefined) {
targetTemp = device.temperature_lock_high_temp;
} else {
return null;
}
},
getTargetTemperature: function(callback){
targetTemp = this.extractAsDisplayUnit(targetTemp, device);
this.log("Target temperature for " + this.name + " is: " + targetTemp);
return targetTemp;
};
NestThermostatAccessory.prototype.getTargetTemperature = function(callback){
var that = this;
nest.fetchStatus(function (data) {
var device = data.shared[that.deviceId];
that.log("Target temperature for " + this.name + " is: " + device.target_temperature);
callback(device.target_temperature);
var targetTemp = this.extractTargetTemperature(device);
callback(targetTemp);
});
};
NestThermostatAccessory.prototype.extractTemperatureUnits = function(device) {
var temperatureUnits = 0;
switch(device.temperature_scale) {
case "F":
this.log("Tempature unit for " + this.name + " is: " + "Fahrenheit");
temperatureUnits = 1;
break;
case "C":
this.log("Tempature unit for " + this.name + " is: " + "Celsius");
temperatureUnits = 0;
break;
default:
temperatureUnits = 0;
}
return temperatureUnits;
};
},
NestThermostatAccessory.prototype.isFahrenheitUnit = function(unit) {
return unit == 1;
};
getTemperatureUnits: function(callback){
NestThermostatAccessory.prototype.convertToDisplayUnit = function(value, displayUnit) {
return this.isFahrenheitUnit(displayUnit) ? nest.ctof(value) : value;
};
NestThermostatAccessory.prototype.convertToValueUnit = function(value, displayUnit) {
return this.isFahrenheitUnit(displayUnit) ? nest.ftoc(value) : value;
};
NestThermostatAccessory.prototype.extractAsDisplayUnit = function(value, device) {
var tempUnit = this.extractTemperatureUnits(device);
return this.convertToDisplayUnit(value, tempUnit);
};
NestThermostatAccessory.prototype.extractAsValueUnit = function(value, device) {
return this.convertToValueUnit(value, this.extractTemperatureUnits(device));
};
NestThermostatAccessory.prototype.getTemperatureUnits = function(callback){
var that = this;
nest.fetchStatus(function (data) {
var device = data.device[that.deviceId];
var temperatureUnits = 0;
switch(device.temperature_scale) {
case "F":
that.log("Tempature unit for " + this.name + " is: " + "Fahrenheit");
temperatureUnits = 1;
break;
case "C":
that.log("Tempature unit for " + this.name + " is: " + "Celsius");
temperatureUnits = 0;
break;
default:
temperatureUnits = 0;
}
var temperatureUnits = that.extractTemperatureUnits(device);
callback(temperatureUnits);
});
};
},
getCurrentRelativeHumidity: function(callback){
NestThermostatAccessory.prototype.getCurrentRelativeHumidity = function(callback){
var that = this;
@@ -181,12 +290,9 @@ NestThermostatAccessory.prototype = {
})
},
setTargetHeatingCooling: function(targetHeatingCooling){
var that = this;
};
NestThermostatAccessory.prototype.setTargetHeatingCooling = function(targetHeatingCooling, callback){
var targetTemperatureType = 'off';
switch(targetHeatingCooling) {
case 0:
@@ -208,190 +314,18 @@ NestThermostatAccessory.prototype = {
this.log("Setting target heating cooling for " + this.name + " to: " + targetTemperatureType);
nest.setTargetTemperatureType(this.deviceId, targetTemperatureType);
},
setTargetTemperature: function(targetTemperature){
var that = this;
this.log("Setting target temperature for " + this.name + " to: " + targetTemperature);
nest.setTemperature(this.deviceId, targetTemperature);
},
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: "Nest",
supportEvents: false,
supportBonjour: false,
manfDescription: "Manufacturer",
designedMaxLength: 255
},{
cType: types.MODEL_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.model,
supportEvents: false,
supportBonjour: false,
manfDescription: "Model",
designedMaxLength: 255
},{
cType: types.SERIAL_NUMBER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.serial,
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.THERMOSTAT_STYPE,
characteristics: [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.name,
supportEvents: false,
supportBonjour: false,
manfDescription: "Name of thermostat",
designedMaxLength: 255
},{
cType: types.CURRENTHEATINGCOOLING_CTYPE,
onUpdate: null,
onRead: function(callback) {
that.getCurrentHeatingCooling(function(currentHeatingCooling){
callback(currentHeatingCooling);
});
},
perms: ["pr","ev"],
format: "int",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Current Mode",
designedMaxLength: 1,
designedMinValue: 0,
designedMaxValue: 2,
designedMinStep: 1,
},{
cType: types.TARGETHEATINGCOOLING_CTYPE,
onUpdate: function(value) {
that.setTargetHeatingCooling(value);
},
onRead: function(callback) {
that.getTargetHeatingCoooling(function(targetHeatingCooling){
callback(targetHeatingCooling);
});
},
perms: ["pw","pr","ev"],
format: "int",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Target Mode",
designedMinValue: 0,
designedMaxValue: 3,
designedMinStep: 1,
},{
cType: types.CURRENT_TEMPERATURE_CTYPE,
onUpdate: null,
onRead: function(callback) {
that.getCurrentTemperature(function(currentTemperature){
callback(currentTemperature);
});
},
perms: ["pr","ev"],
format: "int",
initialValue: 20,
supportEvents: false,
supportBonjour: false,
manfDescription: "Current Temperature",
unit: "celsius"
},{
cType: types.TARGET_TEMPERATURE_CTYPE,
onUpdate: function(value) {
that.setTargetTemperature(value);
},
onRead: function(callback) {
that.getTargetTemperature(function(targetTemperature){
callback(targetTemperature);
});
},
perms: ["pw","pr","ev"],
format: "int",
initialValue: 20,
supportEvents: false,
supportBonjour: false,
manfDescription: "Target Temperature",
designedMinValue: 16,
designedMaxValue: 38,
designedMinStep: 1,
unit: "celsius"
},{
cType: types.TEMPERATURE_UNITS_CTYPE,
onUpdate: null,
onRead: function(callback) {
that.getTemperatureUnits(function(temperatureUnits){
callback(temperatureUnits);
});
},
perms: ["pr","ev"],
format: "int",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Unit",
},{
cType: types.CURRENT_RELATIVE_HUMIDITY_CTYPE,
onUpdate: null,
onRead: function(callback) {
that.getCurrentRelativeHumidity(function(currentRelativeHumidity){
callback(currentRelativeHumidity);
});
},
perms: ["pr","ev"],
format: "int",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Humidity",
}]
}];
if (callback) {
callback();
}
}
};
NestThermostatAccessory.prototype.setTargetTemperature = function(targetTemperature, callback){
this.log("Setting target temperature for " + this.name + " to: " + targetTemperature);
nest.setTemperature(this.deviceId, targetTemperature);
if (callback) {
callback();
}
};
module.exports.accessory = NestThermostatAccessory;
module.exports.platform = NestPlatform;