homebridge-creskit2
Version:
A crestron plugin for homebridge
1,132 lines (962 loc) • 73 kB
JavaScript
'use strict';
var async = require('async');
var net = require('net');
var events = require('events');
var Service, Characteristic;
module.exports = function (homebridge) {
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
homebridge.registerPlatform("homebridge-creskit", "CresKit", CresKit);
}
// TCP connection to Crestron Module
var cresKitSocket = new net.Socket();
var eventEmitter = new events.EventEmitter();
var openGetStatus = []; // Sometimes a getStatus does not come back. We need to re-try for the app to be responsive.
function closeGetStatus(what) {
var found = openGetStatus.indexOf(what);
openGetStatus.splice(found, 1);
console.log(openGetStatus);
}
// Resend unclosed GetStatus
function retryGetStatus() {
async.each(openGetStatus, function (writeString, callback) {
try {
cresKitSocket.write(writeString);
console.log("RETRY: " + writeString);
} catch (err) {
console.log(err);
}
callback();
}.bind(this), function (err) {
//console.log("retryGetStatus complete");
});
}
setInterval(function () { retryGetStatus(); }, 2000);
function CresKit(log, config) {
this.log = log;
this.config = config;
}
CresKit.prototype = {
accessories: function (callback) {
var foundAccessories = [];
// Build Device List
this.log("Starting CresKit Config");
cresKitSocket.connect(this.config["port"], this.config["host"], function () {
this.log('Connected to Crestron Machine');
// ERROR CONNECITON
}.bind(this));
cresKitSocket.on('close', function () {
this.log('Connection closed');
// Handle error properly
// Reconnect
try {
setTimeout(() => cresKitSocket.connect(this.config["port"], this.config["host"], function () {
this.log('Re-Connected to Crestron Machine');
}.bind(this)), 25000);
} catch (err) {
this.log(err);
}
}.bind(this));
// All Crestron replies goes via this connection
cresKitSocket.on('data', function (data) {
//this.log("Raw Crestron Data : " + data);
// Data from Creston Module. This listener parses the information and updates Homebridge
// get* - replies from get* requests
// event* - sent upon any changes on Crestron side (including in response to set* commands)
var dataArray = data.toString().split("*"); // Commands terminated with *
async.each(dataArray, function (response, callback) {
var responseArray = response.toString().split(":");
// responseArray[0] = (config.type ie lightbulbs) : responseArray[1] = (id) : responseArray[2] = (command ie getPowerState) : responseArray[3] = (value)
if (responseArray[0] != "") {
eventEmitter.emit(responseArray[0] + ":" + responseArray[1] + ":" + responseArray[2], parseInt(responseArray[3])); // convert string to value
//this.log("EMIT: " + responseArray[0] + ":" + responseArray[1] + ":" + responseArray[2] + " = " + responseArray[3]);
}
callback();
}.bind(this), function (err) {
//console.log("SockedRx Processed");
});
}.bind(this));
// Accessories Configuration
async.each(this.config.accessories, function (accessory, asynCallback) {
var accessory = new CresKitAccessory(this.log, this.config, accessory);
foundAccessories.push(accessory);
return asynCallback(); //let async know we are done
}.bind(this), function (err) {
if (err) {
this.log(err);
} else {
this.log("Success CresKit Config");
callback(foundAccessories);
}
}.bind(this));
}
}
function CresKitAccessory(log, platformConfig, accessoryConfig) {
this.log = log;
this.config = accessoryConfig;
this.id = accessoryConfig.id;
this.name = accessoryConfig.name;
this.model = "Komen v2.3.4";
this.minValue = platformConfig.minValue || 16;
this.maxValue = platformConfig.maxValue || 32;
this.Fahrenheit = platformConfig.Fahrenheit || 0;
this.minStep = platformConfig.minStep || 1;
}
CresKitAccessory.prototype = {
identify: function (callback) {
callback();
},
//---------------
// PowerState - Lightbulb, Switch, SingleSpeedFan (Scenes)
//---------------
getPowerState: function (callback) { // this.config.type = Lightbulb, Switch, etc
cresKitSocket.write(this.config.type + ":" + this.id + ":getPowerState:*"); // (:* required) on get
openGetStatus.push(this.config.type + ":" + this.id + ":getPowerState:*");
// Listen Once for value coming back, if it does trigger callback
eventEmitter.once(this.config.type + ":" + this.id + ":getPowerState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getPowerState:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventPowerState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setPowerState: function (value, callback) {
//Do NOT send cmd to Crestron when Homebridge was notified from an Event - Crestron already knows the state!
if (value) {
value = 1;
}
else {
value = 0;
}
cresKitSocket.write(this.config.type + ":" + this.id + ":setPowerState:" + value + "*"); // (* after value required on set)
callback();
},
//---------------
// Dimming Light
//---------------
getLightBrightness: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getLightBrightness:*"); // (:* required) on get
openGetStatus.push(this.config.type + ":" + this.id + ":getLightBrightness:*");
// Listen Once for value coming back, if it does trigger callback
eventEmitter.once(this.config.type + ":" + this.id + ":getLightBrightness", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getLightBrightness:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventLightBrightness", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setLightBrightness: function (value, callback) {
// fix the light not dim to the set brightness,when the light closed
setTimeout(() => cresKitSocket.write(this.config.type + ":" + this.id + ":setLightBrightness:" + value + "*"), 50);
callback(null);
},
setLightState: function (value, callback) {
this.log(this.config.type + ":" + this.id + ":setLightState:" + value + "*");
if (value) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setLightBrightness:999*");
} else {
cresKitSocket.write(this.config.type + ":" + this.id + ":setLightBrightness:0*");
}
callback(null);
},
//---------------
// Garage
//---------------
getCurrentDoorState: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getCurrentDoorState:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getCurrentDoorState:*");
// Listen Once for value coming back. 0 open, 1 closed
eventEmitter.once(this.config.type + ":" + this.id + ":getCurrentDoorState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getCurrentDoorState:*");
// Update TargetDoorState via event event
eventEmitter.emit(this.config.type + ":" + this.id + ":eventCurrentDoorState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setTargetDoorState: function (value, callback) {
//this.log("setTargetDoorState %s", value);
cresKitSocket.write(this.config.type + ":" + this.id + ":setTargetDoorState:" + value + "*");
callback();
},
getObstructionDetected: function (callback) {
// Not yet support
callback(null, 0);
},
//---------------
// Security System
//---------------
getSecuritySystemCurrentState: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getSecuritySystemCurrentState:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getSecuritySystemCurrentState:*");
//armedStay=0 , armedAway=1, armedNight=2, disarmed=3, alarmValues = 4
eventEmitter.once(this.config.type + ":" + this.id + ":getSecuritySystemCurrentState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getSecuritySystemCurrentState:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventSecuritySystemCurrentState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setSecuritySystemTargetState: function (value, callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setSecuritySystemTargetState:" + value + "*");
callback();
},
//---------------
// Lock (or any event that you needs push notifications)
//---------------
getLockCurrentState: function (callback) {
//UNSECURED = 0;, SECURED = 1; .JAMMED = 2; UNKNOWN = 3;
cresKitSocket.write(this.config.type + ":" + this.id + ":getLockCurrentState:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getLockCurrentState:*");
// Listen Once for value coming back. 0 open, 1 closed
eventEmitter.once(this.config.type + ":" + this.id + ":getLockCurrentState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getLockCurrentState:*");
// Update setLockTargetState via event event
eventEmitter.emit(this.config.type + ":" + this.id + ":eventLockCurrentState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setLockTargetState: function (value, callback) {
//UNSECURED = 0;, SECURED = 1;
cresKitSocket.write(this.config.type + ":" + this.id + ":setLockTargetState:" + value + "*");
callback();
},
//---------------
// SpeedFan
//---------------
getRotationSpeed: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getRotationSpeed:*"); // (:* required) on get
openGetStatus.push(this.config.type + ":" + this.id + ":getRotationSpeed:*");
// Listen Once for value coming back, if it does trigger callback
eventEmitter.once(this.config.type + ":" + this.id + ":getRotationSpeed", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getRotationSpeed:*");
// Update RotationSpeed via event event
eventEmitter.emit(this.config.type + ":" + this.id + ":eventRotationSpeed", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setRotationSpeed: function (value, callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setRotationSpeed:" + value + "*"); // (* after value required on set)
callback();
},
setRotationState: function (value, callback) {
if (value === 0) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setRotationSpeed:0*");
}
else {
cresKitSocket.write(this.config.type + ":" + this.id + ":setRotationSpeed:999*"); //999 = 100 if off, otherwise leave current
}
callback();
},
//---------------
// Window Covering, Door
//---------------
getCurrentPosition: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getCurrentPosition:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getCurrentPosition:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getCurrentPosition", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getCurrentPosition:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventCurrentPosition", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setTargetPosition: function (value, callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setTargetPosition:" + value + "*"); // (* after value required on set)
callback();
},
//---------------
// Thermostat
//---------------
getTargetHeatingCoolingState: function (callback) {
//INACTIVE = 0;, IDLE = 1; HEATING = 2; COOLING = 3;
cresKitSocket.write(this.config.type + ":" + this.id + ":getTargetHeatingCoolingState:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getTargetHeatingCoolingState:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getTargetHeatingCoolingState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getTargetHeatingCoolingState:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventTargetHeatingCoolingState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setTargetHeatingCoolingState: function (value, callback) {
//AUTO = 0;, HEAT = 1; COOL = 2;
cresKitSocket.write(this.config.type + ":" + this.id + ":setTargetHeatingCoolingState:" + value + "*");
callback();
},
getCurrentTemperature: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getCurrentTemperature:*"); // (:* required) on get
openGetStatus.push(this.config.type + ":" + this.id + ":getCurrentTemperature:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getCurrentTemperature", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getCurrentTemperature:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventCurrentTemperature", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
getTargetTemperature: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getTargetTemperature:*"); // (:* required) on get
openGetStatus.push(this.config.type + ":" + this.id + ":getTargetTemperature:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getTargetTemperature", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getTargetTemperature:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventTargetTemperature", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setTargetTemperature: function (value, callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setTargetTemperature:" + value + "*"); // (* after value required on set)
callback();
},
//---------------
// HeaterCooler
//---------------
getTargetHeaterCoolerState: function (callback) {
//INACTIVE = 0;, IDLE = 1; HEATING = 2; COOLING = 3;
cresKitSocket.write(this.config.type + ":" + this.id + ":getTargetHeaterCoolerState:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getTargetHeaterCoolerState:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getTargetHeaterCoolerState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getTargetHeaterCoolerState:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventTargetHeaterCoolerState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setTargetHeaterCoolerState: function (value, callback) {
//AUTO = 0;, HEAT = 1; COOL = 2;
cresKitSocket.write(this.config.type + ":" + this.id + ":setTargetHeaterCoolerState:" + value + "*");
callback();
},
setRotationSpeed: function (value, callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setRotationSpeed:" + value + "*"); // (* after value required on set)
callback();
},
getRotationSpeed: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getRotationSpeed:*"); // (:* required) on get
openGetStatus.push(this.config.type + ":" + this.id + ":getRotationSpeed:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getRotationSpeed", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getRotationSpeed:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventRotationSpeed", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
//---------------
// AirPurifier
//---------------
getTargetAirPurifierState: function (callback) {
//MANUAL = 0; AUTO = 1;
cresKitSocket.write(this.config.type + ":" + this.id + ":getTargetAirPurifierState:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getTargetAirPurifierState:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getTargetAirPurifierState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getTargetAirPurifierState:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventTargetAirPurifierState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setTargetAirPurifierState: function (value, callback) {
//MANUAL = 0; AUTO = 1;
cresKitSocket.write(this.config.type + ":" + this.id + ":setTargetAirPurifierState:" + value + "*");
callback();
},
getAirPurifierRotationSpeed: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getAirPurifierRotationSpeed:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getAirPurifierRotationSpeed:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getAirPurifierRotationSpeed", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getAirPurifierRotationSpeed:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventAirPurifierRotationSpeed", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setAirPurifierRotationSpeed: function (value, callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":setAirPurifierRotationSpeed:" + value + "*");
callback();
},
//---------------
// AirQualitySensor
//---------------
/*getAirQuality: function (callback) {
//UNKNOWN = 0; EXCELLENT = 1;GOOD = 2; FAIR = 3;INFERIOR = 4; POOR = 5;
cresKitSocket.write(this.config.type + ":" + this.id + ":getAirQuality:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getAirQuality:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getAirQuality", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getAirQuality:*");
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},*/
getPM2_5Value: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getPM2_5Value:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getPM2_5Value:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getPM2_5Value", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getPM2_5Value:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventPM2_5Value", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
getVOC_Value: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getVOC_Value:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getVOC_Value:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getVOC_Value", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getVOC_Value:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventVOC_Value", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
getCarbonDioxideLevel: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getCarbonDioxideLevel:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getCarbonDioxideLevel:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getCarbonDioxideLevel", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getCarbonDioxideLevel:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventCarbonDioxideLevel", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
//---------------
// HumiditySensor
//---------------
getCurrentRelativeHumidity: function (callback) {
//Humidity 0-100
cresKitSocket.write(this.config.type + ":" + this.id + ":getCurrentRelativeHumidity:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getCurrentRelativeHumidity:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getCurrentRelativeHumidity", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getCurrentRelativeHumidity:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventCurrentRelativeHumidity", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
//---------------
// TemperatureSensor
//---------------
//---------------
// Binary Sensor, SmokeSensor, OccupancySensor, MotionSensor, LeakSensor
//---------------
getSensorState: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getSensorState:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getSensorState:*");
// Listen Once for value coming back. 0 open, 1 closed
eventEmitter.once(this.config.type + ":" + this.id + ":getSensorState", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getSensorState:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventSensorState", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
//---------------
// LightSensor
//---------------
getCurrentAmbientLightLevel: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getCurrentAmbientLightLevel:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getCurrentAmbientLightLevel:*");
// Listen Once for value coming back. 0 open, 1 closed
eventEmitter.once(this.config.type + ":" + this.id + ":getCurrentAmbientLightLevel", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getCurrentAmbientLightLevel:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventCurrentAmbientLightLevel", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
//---------------
// Faucet
//---------------
getFaucetActive: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getFaucetActive:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getFaucetActive:*");
// Listen Once for value coming back. 0 open, 1 closed
eventEmitter.once(this.config.type + ":" + this.id + ":getFaucetActive", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getFaucetActive:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventFaucetActive", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setFaucetActive: function (value, callback) {
//INACTIVE = 0; ACTIVE = 1;
cresKitSocket.write(this.config.type + ":" + this.id + ":setFaucetActive:" + value + "*");
callback();
},
//---------------
// Outlet
//---------------
getOutletPower: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getOutletPower:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getOutletPower:*");
// Listen Once for value coming back. 0 open, 1 closed
eventEmitter.once(this.config.type + ":" + this.id + ":getOutletPower", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getOutletPower:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventOutletPower", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setOutletPower: function (value, callback) {
//ON = 1; OFF = 0
cresKitSocket.write(this.config.type + ":" + this.id + ":setOutletPower:" + value + "*");
callback();
},
//---------------
// Valve
//---------------
getValveActive: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getValveActive:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getValveActive:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getValveActive", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getValveActive:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventValveActive", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setValveActive: function (value, callback) {
//ON = 1; OFF = 0
cresKitSocket.write(this.config.type + ":" + this.id + ":setValveActive:" + value + "*");
callback();
},
//---------------
// FilterMaintenance
//---------------
getFilterLifeLevel: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getFilterLifeLevel:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getFilterLifeLevel:*");
// Listen Once for value coming back. 0 open, 1 closed
eventEmitter.once(this.config.type + ":" + this.id + ":getFilterLifeLevel", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getFilterLifeLevel:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventFilterLifeLevel", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
//---------------
// Speaker
//---------------
getVolume: function (callback) {
cresKitSocket.write(this.config.type + ":" + this.id + ":getVolume:*"); // (:* required)
openGetStatus.push(this.config.type + ":" + this.id + ":getVolume:*");
eventEmitter.once(this.config.type + ":" + this.id + ":getVolume", function (value) {
try {
closeGetStatus(this.config.type + ":" + this.id + ":getVolume:*");
eventEmitter.emit(this.config.type + ":" + this.id + ":eventVolume", value);
callback(null, value);
} catch (err) {
this.log(err);
}
}.bind(this));
},
setVolume: function (value, callback) {
//ON = 1; OFF = 0
cresKitSocket.write(this.config.type + ":" + this.id + ":setVolume:" + value + "*");
callback();
},
//---------------
// Characteristic Config
//---------------
getServices: function () {
var services = []
var informationService = new Service.AccessoryInformation();
informationService
.setCharacteristic(Characteristic.Manufacturer, "CresKit")
.setCharacteristic(Characteristic.Model, this.model)
.setCharacteristic(Characteristic.SerialNumber, "CK " + this.config.type + " ID " + this.id);
services.push(informationService);
switch (this.config.type) {
case "Lightbulb": {
var lightbulbService = new Service.Lightbulb();
var PowerState = lightbulbService
.getCharacteristic(Characteristic.On)
.on('set', this.setPowerState.bind(this))
.on('get', this.getPowerState.bind(this));
// Register a listener
eventEmitter.on(this.config.type + ":" + this.id + ":eventPowerState", function (value) {
PowerState.updateValue(value);
}.bind(this));
services.push(lightbulbService);
break;
}
case "DimLightbulb": {
var DimLightbulbService = new Service.Lightbulb();
var LightState = DimLightbulbService
.getCharacteristic(Characteristic.On)
.on('set', this.setLightState.bind(this));
var Brightness = DimLightbulbService
.getCharacteristic(Characteristic.Brightness)
.on('set', this.setLightBrightness.bind(this))
.on('get', this.getLightBrightness.bind(this));
// Register a listener for event changes (dim-light)
eventEmitter.on(this.config.type + ":" + this.id + ":eventLightBrightness", function (value) {
var light_power_value;
if (value) {
light_power_value = 1;
}
else {
light_power_value = 0;
}
Brightness.updateValue(value);
LightState.updateValue(light_power_value);
}.bind(this));
services.push(DimLightbulbService);
break;
}
case "Switch": {
var switchService = new Service.Switch();
var PowerState = switchService
.getCharacteristic(Characteristic.On)
.on('set', this.setPowerState.bind(this))
.on('get', this.getPowerState.bind(this));
// Register a listener for event changes
eventEmitter.on(this.config.type + ":" + this.id + ":eventPowerState", function (value) {
PowerState.updateValue(value);
}.bind(this));
services.push(switchService);
break;
}
case "TV": {
var tvService = new Service.Television();
var PowerState = tvService
.getCharacteristic(Characteristic.Active)
.on('get', this.getPowerState.bind(this))
.on('set', this.setPowerState.bind(this));
// Register a listener for event changes
eventEmitter.on(this.config.type + ":" + this.id + ":eventPowerState", function (value) {
PowerState.updateValue(value);
}.bind(this));
tvService
.setCharacteristic(
Characteristic.SleepDiscoveryMode,
Characteristic.SleepDiscoveryMode.ALWAYS_DISCOVERABLE
);
var speakerService = new Service.TelevisionSpeaker();
speakerService
.setCharacteristic(Characteristic.Active, Characteristic.Active.ACTIVE);
speakerService
.setCharacteristic(Characteristic.Name, this.soundoutput);
speakerService
.setCharacteristic(Characteristic.VolumeControlType, Characteristic.VolumeControlType.RELATIVE);
speakerService
.getCharacteristic(Characteristic.VolumeSelector) //increase/decrease volume
.on('set', this.setVolume.bind(this));
services.push(speakerService);
tvService
.getCharacteristic(Characteristic.RemoteKey)
.on('set', 1);
services.push(this.tvService);
var inputSource = new Service.InputSource("test", "1"); //displayname, subtype?
inputSource.setCharacteristic(Characteristic.Identifier, 1)
.setCharacteristic(Characteristic.ConfiguredName, "Apple TV")
.setCharacteristic(Characteristic.CurrentVisibilityState, Characteristic.CurrentVisibilityState.SHOWN)
.setCharacteristic(Characteristic.IsConfigured, Characteristic.IsConfigured.CONFIGURED)
.setCharacteristic(Characteristic.InputSourceType, Characteristic.InputSourceType.AIRPLAY);
inputSource.uri = 1;
inputSource.type = InputSourceType.AIRPLAY;
inputSource.id = 1;
services.push(inputSource);
tvService.addLinkedService(inputSource);
//this.inputSources[this.inputSourceCount] = inputSource;
//this.uriToInputSource[uri] = inputSource;
//this.inputSourceCount++;
services.push(tvService);
break;
}
case "Lock": {
var lockService = new Service.LockMechanism();
var LockCurrentState = lockService
.getCharacteristic(Characteristic.LockCurrentState)
.on('get', this.getLockCurrentState.bind(this));
var LockTargetState = lockService
.getCharacteristic(Characteristic.LockTargetState)
.on('set', this.setLockTargetState.bind(this));
// Register a listener for event changes
eventEmitter.on(this.config.type + ":" + this.id + ":eventLockCurrentState", function (value) {
LockCurrentState.updateValue(value);
LockTargetState.updateValue(value)
}.bind(this));
services.push(lockService);
break;
}
case "Fan": {
var fanService = new Service.Fan();
var PowerState = fanService
.getCharacteristic(Characteristic.On)
.on('set', this.setPowerState.bind(this))
.on('get', this.getPowerState.bind(this));
// Register a listener for event changes
eventEmitter.on(this.config.type + ":" + this.id + ":eventPowerState", function (value) {
PowerState.updateValue(value);
}.bind(this));
services.push(fanService);
break;
}
case "GarageDoorOpener": {
var garageDoorOpenerService = new Service.GarageDoorOpener();
var CurrentDoorState = garageDoorOpenerService
.getCharacteristic(Characteristic.CurrentDoorState)
.on('get', this.getCurrentDoorState.bind(this));
var TargetDoorState = garageDoorOpenerService
.getCharacteristic(Characteristic.TargetDoorState)
.on('set', this.setTargetDoorState.bind(this));
garageDoorOpenerService
.getCharacteristic(Characteristic.ObstructionDetected)
.on('get', this.getObstructionDetected.bind(this));
// Register a listener for event changes
eventEmitter.on(this.config.type + ":" + this.id + ":eventCurrentDoorState", function (value) {
CurrentDoorState.updateValue(value); // also set target so the system knows we initiated it open/closed
TargetDoorState.updateValue(value);
}.bind(this));
services.push(garageDoorOpenerService);
break;
}
case "SecuritySystem": {
var securitySystemService = new Service.SecuritySystem();
var SecuritySystemCurrentState = securitySystemService
.getCharacteristic(Characteristic.SecuritySystemCurrentState)
.on('get', this.getSecuritySystemCurrentState.bind(this));
var SecuritySystemTargetState = securitySystemService
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.on('set', this.setSecuritySystemTargetState.bind(this));
// Register a listener for event changes
eventEmitter.on(this.config.type + ":" + this.id + ":eventSecuritySystemCurrentState", function (value) {
SecuritySystemCurrentState.updateValue(value);
SecuritySystemTargetState.updateValue(value);
}.bind(this));
services.push(securitySystemService);
break;
}
case "WindowCovering": {
var windowCoveringService = new Service.WindowCovering();
var CurrentPosition = windowCoveringService
.getCharacteristic(Characteristic.CurrentPosition)
.on('get', this.getCurrentPosition.bind(this));
var TargetPosition = windowCoveringService
.getCharacteristic(Characteristic.TargetPosition)
.on('set', this.setTargetPosition.bind(this));
//.on('get', this.getTargetPosition.bind(this));
var PositionState = windowCoveringService
.getCharacteristic(Characteristic.PositionState)
// Register a listener for event changes
eventEmitter.on(this.config.type + ":" + this.id + ":eventCurrentPosition", function (value) {
TargetPosition.updateValue(value);
setTimeout(function () { CurrentPosition.updateValue(value); }, 2000);
}.bind(this));
services.push(windowCoveringService);
break;
}
case "Thermostat": {
var ThermostatService = new Service.Thermostat();
var CurrentHeatingCoolingState = ThermostatService
.getCharacteristic(Characteristic.CurrentHeatingCoolingState)
//.on('get', this.getCurrentHeatingCoolingState.bind(this));
var TargetHeatingCoolingState = ThermostatService
.getCharacteristic(Characteristic.TargetHeatingCoolingState)
.on('get', this.getTargetHeatingCoolingState.bind(this))
.on('set', this.setTargetHeatingCoolingState.bind(this));
var TargetTemperature = ThermostatService
.getCharacteristic(Characteristic.TargetTemperature)
.setProps({
minValue: this.minValue,
maxValue: this.maxValue,
minStep: this.minStep,
})
.on('set', this.setTargetTemperature.bind(this))
.on('get', this.getTargetTemperature.bind(this));
var CurrentTemperature = ThermostatService
.getCharacteristic(Characteristic.CurrentTemperature)
.on('get', this.getCurrentTemperature.bind(this));
var TemperatureDisplayUnits = ThermostatService
.getCharacteristic(Characteristic.TemperatureDisplayUnits)
TemperatureDisplayUnits.setValue(this.Fahrenheit);
//State
eventEmitter.on(this.config.type + ":" + this.id + ":eventTargetHeatingCoolingState", function (value) {
CurrentHeatingCoolingState.updateValue(value);
setTimeout(function () { TargetHeatingCoolingState.updateValue(value);; }, 500);
}.bind(this));
//TargetTemperature
eventEmitter.on(this.config.type + ":" + this.id + ":eventTargetTemperature", function (value) {
TargetTemperature.updateValue(value);
}.bind(this));
//CurrentTemperature
eventEmitter.on(this.config.type + ":" + this.id + ":eventCurrentTemperature", function (value) {
CurrentTemperature.updateValue(value);
}.bind(this));
services.push(ThermostatService);
break;
}
case "HeaterCooler": {
var HeaterCoolerService = new Service.HeaterCooler();
var HeaterCoolerPower = HeaterCoolerService
.getCharacteristic(Characteristic.Active)
.on('get', this.getPowerState.bind(this))
.on('set', this.setPowerState.bind(this));
var TargetHeaterCoolerState = HeaterCoolerService
.getCharacteristic(Characteristic.TargetHeaterCoolerState)
.setProps({
validValues: [1, 2]
})
.on('get', this.getTargetHeaterCoolerState.bind(this))
.on('set', this.setTargetHeaterCoolerState.bind(this));
var CurrentHeaterCoolerState = HeaterCoolerService
.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
var CoolingThresholdTemperature = HeaterCoolerService
.getCharacteristic(Characteristic.CoolingThresholdTemperature)
.setProps({
minValue: this.minValue,
maxValue: this.maxValue,
minStep: this.minStep
})
.on('set', this.setTargetTemperature.bind(this))
.on('get', this.getTargetTemperature.bind(this));
var HeatingThresholdTemperature = HeaterCoolerService
.getCharacteristic(Characteristic.HeatingThresholdTemperature)
.setProps({
minValue: this.minValue,
maxValue: this.maxValue,
minStep: this.minStep
})
.on('set', this.setTargetTemperature.bind(this))
.on('get', this.getTargetTemperature.bind(this));
var CurrentTemperature = HeaterCoolerService
.getCharacteristic(Characteristic.CurrentTemperature)
.on('get', this.getCurrentTemperature.bind(this));
var RotationSpeed = HeaterCoolerService
.getCharacteristic(Characteristic.RotationSpeed)
.on('set', this.setRotationSpeed.bind(this))
.on('get', this.getRotationSpeed.bind(this));
var TemperatureDisplayUnits = HeaterCoolerService
.getCharacteristic(Characteristic.TemperatureDisplayUnits)
TemperatureDisplayUnits.setValue(this.Fahrenheit);
eventEmitter.on(this.config.type + ":" + this.id + ":eventPowerState", function (value) {
HeaterCoolerPower.updateValue(value);
}.bind(this));
eventEmitter.on(this.config.type + ":" + this.id + ":eventTargetHeaterCoolerState", function (value) {
var currStateValue;
if (!value && typeof (exp) != "undefined") {
return;
}
else {
if (value === 1) {
currStateValue = 2;
}
else if (value === 2) {
currStateValue = 3;
}
}
// update TargetHeaterCoolerState
TargetHeaterCoolerState.updateValue(value);
// update CurrentHeaterCoolerState
setTimeout(function () { CurrentHeaterCoolerState.updateValue(currStateValue); }, 500);
}.bind(this));
//CurrentTemperature
eventEmitter.on(this.config.type + ":" + this.id + ":eventCurrentTemperature", function (value) {
CurrentTemperature.updateValue(value);
}.bind(this));
//TargetTemperature
eventEmitter.on(this.config.type + ":" + this.id + ":eventTargetTemperature", function (value) {
HeatingThresholdTemperature.updateValue(value);
CoolingThresholdTemperature.updateValue(value);
}.bind(this));
eventEmitter.on(this.config.type + ":" + this.id + ":eventRotationSpeed", function (value) {
RotationSpeed.updateValue(value);
}.bind(this));
services.push(HeaterCoolerService);
break;
}
case "Heater": {
var HeaterService = new Service.HeaterCooler();
var HeaterPower = HeaterService
.getCharacteristic(Characteristic.Active)
.on('get', this.getPowerState.bind(this))
.on('set', this.setPowerState.bind(this));
var TargetHeaterState = HeaterService
.getCharacteristic(Characteristic.TargetHeaterCoolerState)
.setProps({
validValues: [1]
})
var CurrentHeaterState = HeaterService
.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
.setProps({
validValues: [0, 2]
})
var HeatingThresholdTemperature = HeaterService
.getCharacteristic(Characteristic.HeatingThresholdTemperature)
.set