reintegrated Homematic Platform fork from https://github.com/thkl/homebridge/tree/xmlrpc

This commit is contained in:
Thomas König
2015-10-29 19:06:47 +01:00
parent fe4c63fd75
commit 98c61bc72a
3 changed files with 1038 additions and 0 deletions

View File

@@ -22,6 +22,7 @@
"hap-nodejs": "^0.0.3",
"harmonyhubjs-client": "^1.1.6",
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",
"homematic-xmlrpc": "git+https://github.com/hobbyquaker/homematic-xmlrpc",
"isy-js": "",
"komponist": "0.1.0",
"lifx": "git+https://github.com/magicmonkey/lifxjs.git",

406
platforms/HomeMatic.js Normal file
View File

@@ -0,0 +1,406 @@
//
// Homematic Platform Shim for HomeBridge
//
// V0.1 - 2015/10/29
// - initial version
// - reintegrated Homematic Platform fork from https://github.com/thkl/homebridge/tree/xmlrpc
var types = require("hap-nodejs/accessories/types.js");
var xmlrpc = require('homematic-xmlrpc')
var request = require("request");
var http = require("http");
var path = require("path");
var HomeMaticGenericChannel = require(path.resolve(__dirname, 'HomematicChannel.js'));
function RegaRequest(log,ccuip) {
this.log = log;
this.ccuIP = ccuip;
}
RegaRequest.prototype = {
script: function (script, callback) {
var post_options = {
host: this.ccuIP,
port: '80',
path: '/tclrega.exe',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': script.length
}
};
var post_req = http.request(post_options, function(res) {
var data = "";
res.setEncoding('binary');
res.on('data', function (chunk) {
data += chunk.toString();
});
res.on('end', function () {
var pos = data.lastIndexOf("<xml><exec>");
var response = (data.substring(0, pos));
callback(response);
});
});
post_req.on('error', function(e) {
callback("{}");
});
post_req.write(script);
post_req.end();
},
getValue: function(channel,datapoint,callback) {
var that = this;
var script = "var d = dom.GetObject(\""+channel+"."+datapoint+"\");if (d){Write(d.State());}";
//that.log("Rega Request " + script);
var regarequest = this.script(script, function(data) {
that.log("Rega Response" + data);
if (data!=undefined) {
callback(parseFloat(data));
}
}
);
},
setValue: function(channel,datapoint,value) {
var that = this;
var script = "var d = dom.GetObject(\""+channel+"."+datapoint+"\");if (d){d.State(\""+value+"\");}";
//that.log("Rega Request " + script);
var regarequest = this.script(script, function(data) {
});
}
}
function HomematicRPC(log,ccuip,platform) {
this.log = log;
this.ccuip = ccuip;
this.platform = platform;
this.server;
this.client;
this.stopping = false;
this.localIP;
}
HomematicRPC.prototype= {
init:function() {
var that = this;
var ip = this.getIPAddress();
if (ip=="0.0.0.0") {
that.log("Can not fetch IP");
return;
}
this.localIP = ip;
this.log("Local IP: "+this.localIP)
this.server = xmlrpc.createServer({ host: this.localIP , port: 9090 })
this.server.on('NotFound', function(method, params) {
that.log('Method ' + method + ' does not exist');
});
this.server.on('system.listMethods', function (err, params, callback) {
that.log('Method call params for \'system.listMethods\': ' + params)
callback(null,['system.listMethods', 'system.multicall']);
});
this.server.on('system.multicall', function (err, params, callback) {
params.map(function(events) {
try {
events.map(function(event){
if ((event["methodName"]=="event") && (event['params'] != undefined)) {
var params = event['params'];
var channel = "BidCos-RF." + params[1];
var datapoint = params[2];
var value = params[3];
that.platform.foundAccessories.map(function(accessory){
if (accessory.adress == channel) {
accessory.event(datapoint,value);
}
});
}
});
} catch(err) {}
});
callback(null);
});
this.log('XML-RPC server listening on port 9090')
this.connect();
process.on('SIGINT', function () {
if (that.stopping) {
return;
}
that.stopping = true;
that.stop();
});
process.on('SIGTERM', function () {
if (that.stopping) {
return;
}
that.stopping = true;
that.stop();
});
},
getIPAddress: function() {
var interfaces = require('os').networkInterfaces();
for (var devName in interfaces) {
var iface = interfaces[devName];
for (var i = 0; i < iface.length; i++) {
var alias = iface[i];
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal)
return alias.address;
}
}
return '0.0.0.0';
},
getValue:function(channel,datapoint,callback) {
var that = this;
if (this.client == undefined) {
that.log("Returning cause client is invalid");
return;
}
if (channel.indexOf("BidCos-RF.")>-1) {
channel = channel.substr(10);
this.log("Calling rpc getValue");
this.client.methodCall('getValue', [channel,datapoint], function (error, value) {
callback(value);
});
return;
}
},
setValue:function(channel,datapoint,value) {
var that = this;
if (this.client == undefined) return;
if (channel.indexOf("BidCos-RF.")>-1) {
channel = channel.substr(10);
}
this.client.methodCall('setValue', [channel,datapoint,value], function (error, value) {
});
},
connect:function(){
var that = this;
this.log('Creating Local HTTP Client for CCU RPC Events');
this.client = xmlrpc.createClient({ host: this.ccuip, port: 2001, path: '/'});
this.log('CCU RPC Init Call on port 2001');
this.client.methodCall('init', ['http://'+this.localIP+':9090','homebridge'], function (error, value) {
that.log('CCU Response ....')
});
},
stop:function() {
this.log("Removing Event Server");
this.client.methodCall('init', ['http://'+this.localIP+':9090'], function (error, value) {
});
setTimeout(process.exit(0), 1000);
}
}
function HomeMaticPlatform(log, config) {
this.log = log;
this.ccuIP = config["ccu_ip"];
this.filter_device = config["filter_device"];
this.filter_channel = config["filter_channel"];
this.outlets = config["outlets"];
this.sendQueue = [];
this.timer = 0;
this.foundAccessories = [];
this.adressesToQuery = [];
this.xmlrpc = new HomematicRPC(this.log,this.ccuIP,this);
this.xmlrpc.init();
}
HomeMaticPlatform.prototype = {
accessories: function(callback) {
this.log("Fetching Homematic devices...");
var that = this;
that.foundAccessories = [];
var script = "string sDeviceId;string sChannelId;boolean df = true;Write(\'{\"devices\":[\');foreach(sDeviceId, root.Devices().EnumIDs()){object oDevice = dom.GetObject(sDeviceId);if(oDevice){var oInterface = dom.GetObject(oDevice.Interface());if(df) {df = false;} else { Write(\',\');}Write(\'{\');Write(\'\"id\": \"\' # sDeviceId # \'\",\');Write(\'\"name\": \"\' # oDevice.Name() # \'\",\');Write(\'\"address\": \"\' # oDevice.Address() # \'\",\');Write(\'\"channels\": [\');boolean bcf = true;foreach(sChannelId, oDevice.Channels().EnumIDs()){object oChannel = dom.GetObject(sChannelId);if(bcf) {bcf = false;} else {Write(\',\');}Write(\'{\');Write(\'\"cId\": \' # sChannelId # \',\');Write(\'\"name\": \"\' # oChannel.Name() # \'\",\');if(oInterface){Write(\'\"address\": \"\' # oInterface.Name() #\'.'\ # oChannel.Address() # \'\",\');}Write(\'\"type\": \"\' # oChannel.HssType() # \'\"\');Write(\'}\');}Write(\']}\');}}Write(\']}\');";
var regarequest = new RegaRequest(this.log,this.ccuIP).script(script, function(data) {
var json = JSON.parse(data);
if (json['devices'] != undefined) {
json['devices'].map(function(device) {
var isFiltered = false;
if ((that.filter_device != undefined) && (that.filter_device.indexOf(device.address) > -1)) {
isFiltered = true;
} else {
isFiltered = false;
}
// that.log('device address:', device.address);
if ((device['channels'] != undefined) && (!isFiltered)) {
device['channels'].map(function(ch) {
var isChannelFiltered = false;
if ((that.filter_channel != undefined) && (that.filter_channel.indexOf(ch.address) > -1)) {
isChannelFiltered = true;
} else {
isChannelFiltered = false;
}
// that.log('name', ch.name, ' -> address:', ch.address);
if ((ch.address != undefined) && (!isChannelFiltered)) {
if ((ch.type=="SWITCH") || (ch.type=="BLIND") || (ch.type=="SHUTTER_CONTACT")
|| (ch.type=="DIMMER") || (ch.type=="CLIMATECONTROL_RT_TRANSCEIVER")
|| (ch.type=="MOTION_DETECTOR") || (ch.type=="KEYMATIC")
) {
// Switch found
// Check if marked as Outlet
var special = (that.outlets.indexOf(ch.address) > -1) ? 'OUTLET' : undefined;
accessory = new HomeMaticGenericChannel(that.log, that, ch.id , ch.name , ch.type , ch.address, special);
that.foundAccessories.push(accessory);
}
} else {
that.log(device.name + " has no address");
}
});
} else {
that.log(device.name + " has no channels or is filtered");
}
});
/*
accessory = new HomeMaticGenericChannel(that.log, that, "1234" , "DummyKM" , "KEYMATIC" , "1234");
that.foundAccessories.push(accessory);
accessory = new HomeMaticGenericChannel(that.log, that, "5678" , "DummyBLIND" , "BLIND" , "5678");
that.foundAccessories.push(accessory);
*/
callback(that.foundAccessories);
} else {
callback(that.foundAccessories);
}
});
},
setValue:function(channel,datapoint,value) {
if (channel.indexOf("BidCos-RF.")>-1) {
this.xmlrpc.setValue(channel,datapoint,value);
return;
}
if (channel.indexOf("VirtualDevices.")>-1) {
var rega = new RegaRequest(this.log,this.ccuIP);
rega.setValue(channel,datapoint,value);
return;
}
},
getValue:function(channel,datapoint,callback) {
if (channel.indexOf("BidCos-RF.")>-1) {
this.xmlrpc.getValue(channel,datapoint,callback);
return;
}
if (channel.indexOf("VirtualDevices.")>-1) {
var rega = new RegaRequest(this.log,this.ccuIP);
rega.getValue(channel,datapoint,callback);
return;
}
},
prepareRequest: function(accessory,script) {
var that = this;
this.sendQueue.push(script);
that.delayed(100);
},
sendPreparedRequests: function() {
var that = this;
var script = "var d;";
this.sendQueue.map(function(command) {
script = script + command;
});
this.sendQueue = [];
//this.log("RegaSend: " + script);
var regarequest = new RegaRequest(this.log,this.ccuIP).script(script, function(data) {
});
},
sendRequest: function(accessory,script,callback) {
var that = this;
var regarequest = new RegaRequest(this.log,this.ccuIP).script(script, function(data) {
if (data != undefined) {
try {
var json = JSON.parse(data);
callback(json);
} catch (err) {
callback(undefined);
}
return;
}
});
},
delayed: function(delay) {
var timer = this.delayed[delay];
if( timer ) {
this.log("removing old command");
clearTimeout( timer );
}
var that = this;
this.delayed[delay] = setTimeout( function(){clearTimeout(that.delayed[delay]);that.sendPreparedRequests()}, delay?delay:100);
this.log("New Timer was set");
}
}
module.exports.platform = HomeMaticPlatform;

View File

@@ -0,0 +1,631 @@
var types = require("hap-nodejs/accessories/types.js");
function HomeMaticGenericChannel(log,platform, id ,name, type ,adress,special) {
this.name = name;
this.type = type;
this.adress = adress;
this.log = log;
this.platform = platform;
this.state = [];
this.eventupdate = false;
this.special = special;
this.currentStateCharacteristic = [];
this.reverseDP = [];
}
HomeMaticGenericChannel.prototype = {
// Return current States
query: function(dp,callback) {
var that = this;
if (this.state[dp] != undefined) {
callback(this.state[dp]);
} else {
// that.log("No cached Value found start fetching and send temp 0 back");
this.remoteGetValue(dp);
callback(0);
}
},
dpvalue:function(dp,fallback) {
if (this.state[dp] != undefined) {
return(this.state[dp]);
} else {
return fallback;
}
},
remoteGetValue:function(dp) {
var that = this;
that.platform.getValue(that.adress,dp,function(newValue) {
that.log("Remote Value Response for " + that.adress + "." + dp + "->" + newValue);
that.eventupdate = true;
that.cache(dp,newValue);
that.eventupdate = false;
});
},
event:function(dp,newValue) {
if (dp=="LEVEL") {
newValue = newValue*100;
}
this.eventupdate = true;
this.cache(dp,newValue);
this.eventupdate = false;
},
reverse:function(value) {
if (value=="true") return "false";
if (value=="false") return "true";
if (value==0) return 1;
if (value==1) return 0;
if (value=="0") return "1";
if (value=="1") return "0";
return value;
},
cache:function(dp,value) {
var that = this;
if ((that.reverseDP[dp]!=undefined) && (that.reverseDP[dp]==true)) {
value = that.reverse(value);
}
if (that.currentStateCharacteristic[dp]!=undefined) {
that.currentStateCharacteristic[dp].updateValue(value, null);
}
this.state[dp] = value;
},
delayed: function(mode, dp,value,delay) {
if (this.eventupdate==true) {
return;
}
var timer = this.delayed[delay];
if( timer ) {
clearTimeout( timer );
}
this.log(this.name + " delaying command "+mode + " " + dp +" with value " + value);
var that = this;
this.delayed[delay] = setTimeout( function(){clearTimeout(that.delayed[delay]);that.command(mode,dp,value)}, delay?delay:100 );
},
command: function(mode,dp,value,callback) {
if (this.eventupdate==true) {
return;
}
var that = this;
if (mode == "set") {
//this.log("Send " + value + " to Datapoint " + dp + " at " + that.adress);
that.platform.setValue(that.adress,dp,value);
}
},
informationCharacteristics: function() {
return [
{
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: "EQ-3",
supportEvents: false,
supportBonjour: false,
manfDescription: "Manufacturer",
designedMaxLength: 255
},{
cType: types.MODEL_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.type,
supportEvents: false,
supportBonjour: false,
manfDescription: "Model",
designedMaxLength: 255
},{
cType: types.SERIAL_NUMBER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.adress ,
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
}
]
},
controlCharacteristics: function(that) {
cTypes = [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: this.name,
supportEvents: true,
supportBonjour: false,
manfDescription: "Name of service",
designedMaxLength: 255
}]
if (this.type=="SWITCH") {
cTypes.push({
cType: types.POWER_STATE_CTYPE,
onUpdate: function(value) {
that.command("set","STATE" , (value==1)?true:false)
},
onRead: function(callback) {
that.query("STATE",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["STATE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("STATE");
},
perms: ["pw","pr","ev"],
format: "bool",
initialValue: that.dpvalue("STATE",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Change the power state",
designedMaxLength: 1
});
if (this.special=="OUTLET") {
cTypes.push({
cType: types.OUTLET_IN_USE_CTYPE,
onRead: function(callback) {
callback(true);
},
perms: ["pr","ev"],
format: "bool",
initialValue: true,
supportEvents: false,
supportBonjour: false,
manfDescription: "Is Outlet in Use",
designedMaxLength: 1
})
}
}
if (this.type=="KEYMATIC") {
cTypes.push(
{
cType: types.CURRENT_LOCK_MECHANISM_STATE_CTYPE,
onRead: function(callback) {
that.query("STATE",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["STATE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("STATE");
},
perms: ["pr","ev"],
format: "bool",
initialValue: that.dpvalue("STATE",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Current State of your Lock",
designedMaxLength: 1
},
{
cType: types.TARGET_LOCK_MECHANISM_STATE_CTYPE,
onUpdate: function(value) {
that.command("set","STATE",(value==1)?"true":"false")
},
onRead: function(callback) {
that.query("STATE",callback);
},
onRegister: function(characteristic) {
that.reverseDP["STATE"] = true;
that.currentStateCharacteristic["STATE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("STATE");
},
perms: ["pw","pr","ev"],
format: "bool",
initialValue: that.dpvalue("STATE",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Target State of your Lock",
designedMaxLength: 1
}
,
{
cType: types.TARGET_DOORSTATE_CTYPE,
onUpdate: function(value) {
that.command("set","OPEN" , "true")
},
onRead: function(callback) {
callback(1);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["OPEN"] = characteristic;
characteristic.eventEnabled = true;
},
perms: ["pw","pr","ev"],
format: "bool",
initialValue: 1,
supportEvents: false,
supportBonjour: false,
manfDescription: "Open the Lock",
designedMaxLength: 1
}
);
}
if (this.type=="DIMMER") {
cTypes.push({
cType: types.POWER_STATE_CTYPE,
onUpdate: function(value) {
that.command("set","LEVEL" , (value==true) ? "1" : "0")
},
onRead: function(callback) {
that.query("LEVEL",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["LEVEL"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("LEVEL");
},
perms: ["pw","pr","ev"],
format: "bool",
initialValue: (that.dpvalue("LEVEL")>0,0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Change the power state",
designedMaxLength: 1
},
{
cType: types.BRIGHTNESS_CTYPE,
onUpdate: function(value) {
that.delayed("set","LEVEL" , String(value/100),100);
},
onRead: function(callback) {
that.query("LEVEL",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["LEVEL"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("LEVEL");
},
perms: ["pw","pr","ev"],
format: "int",
initialValue: that.dpvalue("LEVEL",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Adjust Brightness of Light",
designedMinValue: 0,
designedMaxValue: 100,
designedMinStep: 1,
unit: "%"
});
}
if (this.type=="BLIND") {
cTypes.push(
{
cType: types.WINDOW_COVERING_CURRENT_POSITION_CTYPE,
onRead: function(callback) {
that.query("LEVEL",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["LEVEL"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("LEVEL");
},
perms: ["pr","ev"],
format: "int",
initialValue: that.dpvalue("LEVEL",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Current Blind Position",
designedMinValue: 0,
designedMaxValue: 100,
designedMinStep: 1,
unit: "%"
},
{
cType: types.WINDOW_COVERING_TARGET_POSITION_CTYPE,
onUpdate: function(value) {
that.delayed("set","LEVEL" , String(value/100),100);
},
onRead: function(callback) {
that.query("LEVEL",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["LEVEL"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("LEVEL");
},
perms: ["pw","pr","ev"],
format: "int",
initialValue: that.dpvalue("LEVEL",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Target Blind Position",
designedMinValue: 0,
designedMaxValue: 100,
designedMinStep: 1,
unit: "%"
},
{
cType: types.WINDOW_COVERING_OPERATION_STATE_CTYPE,
onRead: function(callback) {
that.query("DIRECTION",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["DIRECTION"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("DIRECTION");
},
perms: ["pr","ev"],
format: "int",
initialValue: that.dpvalue("DIRECTION",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Operating State ",
designedMinValue: 0,
designedMaxValue: 2,
designedMinStep: 1
}
);
}
if (this.type=="SHUTTER_CONTACT") {
cTypes.push(
{
cType: types.CONTACT_SENSOR_STATE_CTYPE,
onRead: function(callback) {
that.query("STATE",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["STATE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("STATE");
},
perms: ["pr","ev"],
format: "bool",
initialValue: that.dpvalue("STATE",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Current State"
});
}
if (this.type=="MOTION_DETECTOR") {
cTypes.push(
{
cType: types.MOTION_DETECTED_CTYPE,
onRead: function(callback) {
that.query("MOTION",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["MOTION"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("MOTION");
},
perms: ["pr","ev"],
format: "bool",
initialValue: that.dpvalue("MOTION",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Current Motion State"
});
}
if (this.type=="CLIMATECONTROL_RT_TRANSCEIVER") {
cTypes.push({
cType: types.NAME_CTYPE,onUpdate: null,perms: ["pr"],format: "string",
initialValue: this.name,supportEvents: true,supportBonjour: false,manfDescription: "Name of service",designedMaxLength: 255
},
{
cType: types.CURRENTHEATINGCOOLING_CTYPE,onUpdate: null,
perms: ["pr"],format: "int",initialValue: 1,supportEvents: false,
supportBonjour: false,manfDescription: "Current Mode",designedMaxLength: 1,designedMinValue: 1,designedMaxValue: 1,designedMinStep: 1
},
{
cType: types.TARGETHEATINGCOOLING_CTYPE,onUpdate: null,perms: ["pw","pr"],
format: "int",initialValue: 1,supportEvents: false,supportBonjour: false,manfDescription: "Target Mode",
designedMinValue: 1,designedMaxValue: 1,designedMinStep: 1
},
{
cType: types.CURRENT_TEMPERATURE_CTYPE,
onUpdate: null,
onRead: function(callback) {
that.query("ACTUAL_TEMPERATURE",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["ACTUAL_TEMPERATURE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("ACTUAL_TEMPERATURE");
},
perms: ["pw","pr","ev"], perms: ["pr"],format: "double",
initialValue: that.dpvalue("ACTUAL_TEMPERATURE",20),
supportEvents: false,supportBonjour: false,manfDescription: "Current Temperature",unit: "celsius"
},
{
cType: types.TARGET_TEMPERATURE_CTYPE,
onUpdate: function(value) {
that.delayed("set", "SET_TEMPERATURE", value,500);
},
onRead: function(callback) {
that.query("SET_TEMPERATURE",callback);
},
onRegister: function(characteristic) {
that.currentStateCharacteristic["SET_TEMPERATURE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("SET_TEMPERATURE");
},
perms: ["pw","pr","ev"],format: "double",
initialValue: that.dpvalue("SET_TEMPERATURE",16),
supportEvents: false,supportBonjour: false, manfDescription: "Target Temperature",
designedMinValue: 16,designedMaxValue: 38,designedMinStep: 1,unit: "celsius"
},
{
cType: types.TEMPERATURE_UNITS_CTYPE,onRead: null,
perms: ["pr"],format: "int",initialValue: 0,supportEvents: false,
supportBonjour: false,manfDescription: "Current Temperature Unit",unit: "celsius"
}
);
}
return cTypes
},
sType: function() {
if (this.type=="SWITCH") {
if (this.special=="OUTLET") {
return types.OUTLET_STYPE;
} else {
return types.LIGHTBULB_STYPE;
}
}
if (this.type=="DIMMER") {
return types.LIGHTBULB_STYPE;
}
if (this.type=="BLIND") {
return types.WINDOW_COVERING_STYPE;
}
if (this.type=="CLIMATECONTROL_RT_TRANSCEIVER") {
return types.THERMOSTAT_STYPE;
}
if (this.type=="SHUTTER_CONTACT") {
return types.CONTACT_SENSOR_STYPE;
}
if (this.type=="MOTION_DETECTOR") {
return types.MOTION_SENSOR_STYPE
}
if (this.type=="KEYMATIC") {
return types.LOCK_MECHANISM_STYPE
}
},
getServices: function() {
var that = this;
var services = [{
sType: types.ACCESSORY_INFORMATION_STYPE,
characteristics: this.informationCharacteristics(),
},
{
sType: this.sType(),
characteristics: this.controlCharacteristics(that)
}];
this.log("Loaded services for " + this.name)
return services;
}
};
module.exports = HomeMaticGenericChannel;