From ead491fb4c4bf8f18822e0341837264e689146d5 Mon Sep 17 00:00:00 2001
From: Thomas Kluge
Date: Fri, 30 Oct 2015 16:50:31 +0100
Subject: [PATCH 1/6] switch back from xmlrpc branch to master
---
platforms/HomeMatic.js | 16 +
platforms/HomematicChannel.js | 949 +++++++++++++++++-----------------
2 files changed, 498 insertions(+), 467 deletions(-)
diff --git a/platforms/HomeMatic.js b/platforms/HomeMatic.js
index a451451..219ebdf 100644
--- a/platforms/HomeMatic.js
+++ b/platforms/HomeMatic.js
@@ -2,9 +2,25 @@
//
// Homematic Platform Shim for HomeBridge
//
+// to add the homematic platform add this to config.json. Example:
+// "platforms": [
+// {
+// "platform": "HomeMatic",
+// "name": "HomeMatic",
+// "filter_device":[],
+// "filter_channel":["BidCos-RF.KEQXXXXXXX:4", "BidCos-RF.LEQXXXXXXX:2"],
+// "outlets":[ "BidCos-RF.KEQXXXXXXX:4","BidCos-RF.IEQXXXXXXX:1"]
+//
+// }
+//
// V0.1 - 2015/10/29
// - initial version
// - reintegrated Homematic Platform fork from https://github.com/thkl/homebridge/tree/xmlrpc
+// 2015/10/30 thkl
+// - added Rotary Sensors ; fixed thermostat
+
+// ],
+
var types = require("hap-nodejs/accessories/types.js");
diff --git a/platforms/HomematicChannel.js b/platforms/HomematicChannel.js
index 5b6cff2..e2818a5 100644
--- a/platforms/HomematicChannel.js
+++ b/platforms/HomematicChannel.js
@@ -1,180 +1,185 @@
-"use strict";
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;
+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.state = [];
this.eventupdate = false;
- this.special = special;
+ this.special = special;
this.currentStateCharacteristic = [];
- this.reverseDP = [];
+ this.datapointMappings = [];
}
+
HomeMaticGenericChannel.prototype = {
- // Return current States
- query: function(dp, callback) {
- if (this.state[dp] !== undefined) {
+ addValueMapping: function(dp,value,mappedvalue) {
+ if (this.datapointMappings[dp]==undefined) {
+ this.datapointMappings[dp] = [];
+ }
+ this.datapointMappings[dp][value] = mappedvalue;
+ } ,
+
+ // 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");
+// 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]);
+ 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;
- });
+ 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;
+
+ event:function(dp,newValue) {
+
+ if (dp=="LEVEL") {
+ newValue = newValue*100;
}
this.eventupdate = true;
- this.cache(dp, newValue);
+ 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) {
+ 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);
+ // Check custom Mapping from HM to HomeKit
+ var map = this.datapointMappings[dp];
+ if (map != undefined) {
+ this.log("Mapping found for " + dp);
+ if (map[value]!=undefined) {
+ this.log("Mapping found for " + dp + " " + value);
+ value = map[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;
- }
-
+ delayed: function(mode, dp,value,delay) {
+
+ if (this.eventupdate==true) {
+ return;
+ }
+
var timer = this.delayed[delay];
- if (timer) {
- clearTimeout(timer);
+ if( timer ) {
+ clearTimeout( timer );
}
- this.log(this.name + " delaying command " + mode + " " + dp + " with value " + value);
+ 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);
+ this.delayed[delay] = setTimeout( function(){clearTimeout(that.delayed[delay]);that.command(mode,dp,value)}, delay?delay:100 );
},
- command: function(mode, dp, value, callback) {
+ command: function(mode,dp,value,callback) {
+
+ if (this.eventupdate==true) {
+ return;
+ }
+ var that = this;
- 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);
- }
+ 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
- }];
+ 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) {
-
- var cTypes = [{
+
+ cTypes = [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
@@ -184,174 +189,183 @@ HomeMaticGenericChannel.prototype = {
supportBonjour: false,
manfDescription: "Name of service",
designedMaxLength: 255
- }];
-
-
- if (this.type == "SWITCH") {
- cTypes.push({
+ }]
+
+
+ if (this.type=="SWITCH") {
+ cTypes.push({
cType: types.POWER_STATE_CTYPE,
onUpdate: function(value) {
- that.command("set", "STATE", (value == 1) ? true : false);
+ that.command("set","STATE" , (value==1)?true:false)
},
onRead: function(callback) {
- that.query("STATE", callback);
+ that.query("STATE",callback);
},
-
- onRegister: function(characteristic) {
- that.currentStateCharacteristic["STATE"] = characteristic;
- characteristic.eventEnabled = true;
- that.remoteGetValue("STATE");
+
+ onRegister: function(characteristic) {
+ that.currentStateCharacteristic["STATE"] = characteristic;
+ characteristic.eventEnabled = true;
+ that.remoteGetValue("STATE");
},
-
- perms: ["pw", "pr", "ev"],
+
+ perms: ["pw","pr","ev"],
format: "bool",
- initialValue: that.dpvalue("STATE", 0),
+ initialValue: that.dpvalue("STATE",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Change the power state",
designedMaxLength: 1
});
-
- if (this.special == "OUTLET") {
+
+ if (this.special=="OUTLET") {
cTypes.push({
cType: types.OUTLET_IN_USE_CTYPE,
-
+
onRead: function(callback) {
- callback(true);
+ callback(true);
},
- perms: ["pr", "ev"],
- format: "bool",
- initialValue: true,
- supportEvents: false,
- supportBonjour: false,
- manfDescription: "Is Outlet in Use",
- designedMaxLength: 1
- });
- }
+ perms: ["pr","ev"],
+ format: "bool",
+ initialValue: true,
+ supportEvents: false,
+ supportBonjour: false,
+ manfDescription: "Is Outlet in Use",
+ designedMaxLength: 1
+ })
+ }
}
-
-
- if (this.type == "KEYMATIC") {
- cTypes.push({
+
+
+ if (this.type=="KEYMATIC") {
+ cTypes.push(
+ {
cType: types.CURRENT_LOCK_MECHANISM_STATE_CTYPE,
-
+
onRead: function(callback) {
- that.query("STATE", callback);
- },
-
- onRegister: function(characteristic) {
+ that.query("STATE",callback);
+ },
+
+ onRegister: function(characteristic) {
that.currentStateCharacteristic["STATE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("STATE");
- },
+ },
- perms: ["pr", "ev"],
+ perms: ["pr","ev"],
format: "bool",
- initialValue: that.dpvalue("STATE", 0),
+ 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;
+ 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.addValueMapping("STATE","1",0);
+ that.addValueMapping("STATE","0",1);
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");
+
+ 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) {
- that.query("LEVEL", callback);
+ callback(1);
},
-
- onRegister: function(characteristic) {
- that.currentStateCharacteristic["LEVEL"] = characteristic;
- characteristic.eventEnabled = true;
- that.remoteGetValue("LEVEL");
+
+ onRegister: function(characteristic) {
+ that.currentStateCharacteristic["OPEN"] = characteristic;
+ characteristic.eventEnabled = true;
},
-
- perms: ["pw", "pr", "ev"],
+
+ perms: ["pw","pr","ev"],
format: "bool",
- initialValue: (that.dpvalue("LEVEL") > 0, 0),
+ 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);
+ that.delayed("set","LEVEL" , String(value/100),100);
},
-
+
onRead: function(callback) {
- that.query("LEVEL", callback);
+ that.query("LEVEL",callback);
+ },
+
+ onRegister: function(characteristic) {
+ that.currentStateCharacteristic["LEVEL"] = characteristic;
+ characteristic.eventEnabled = true;
+ that.remoteGetValue("LEVEL");
},
- onRegister: function(characteristic) {
- that.currentStateCharacteristic["LEVEL"] = characteristic;
- characteristic.eventEnabled = true;
- that.remoteGetValue("LEVEL");
- },
-
-
- perms: ["pw", "pr", "ev"],
+
+ perms: ["pw","pr","ev"],
format: "int",
- initialValue: that.dpvalue("LEVEL", 0),
+ initialValue: that.dpvalue("LEVEL",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Adjust Brightness of Light",
@@ -362,23 +376,26 @@ HomeMaticGenericChannel.prototype = {
});
}
- if (this.type == "BLIND") {
- cTypes.push({
+
+
+ if (this.type=="BLIND") {
+ cTypes.push(
+ {
cType: types.WINDOW_COVERING_CURRENT_POSITION_CTYPE,
-
+
onRead: function(callback) {
- that.query("LEVEL", callback);
- },
-
- onRegister: function(characteristic) {
+ that.query("LEVEL",callback);
+ },
+
+ onRegister: function(characteristic) {
that.currentStateCharacteristic["LEVEL"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("LEVEL");
- },
+ },
- perms: ["pr", "ev"],
+ perms: ["pr","ev"],
format: "int",
- initialValue: that.dpvalue("LEVEL", 0),
+ initialValue: that.dpvalue("LEVEL",0),
supportEvents: false,
supportBonjour: false,
manfDescription: "Current Blind Position",
@@ -387,271 +404,269 @@ HomeMaticGenericChannel.prototype = {
designedMinStep: 1,
unit: "%"
},
+
+ {
+ cType: types.WINDOW_COVERING_TARGET_POSITION_CTYPE,
+
+ onUpdate: function(value) {
+ that.delayed("set","LEVEL" , String(value/100),100);
+ },
+
- {
- 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) {
+ 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) {
+ 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
- }
+ },
+ 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,
-
+
+ // Simple Contact (Magnet)
+
+ if (this.type=="SHUTTER_CONTACT") {
+ cTypes.push(
+ {
+ cType: types.CONTACT_SENSOR_STATE_CTYPE,
+
onRead: function(callback) {
- that.query("STATE", callback);
+ that.query("STATE",callback);
},
-
- onRegister: function(characteristic) {
- that.currentStateCharacteristic["STATE"] = characteristic;
- characteristic.eventEnabled = true;
- that.remoteGetValue("STATE");
+
+ 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,
-
+
+ perms: ["pr","ev"],
+ format: "bool",
+ initialValue: that.dpvalue("STATE",0),
+ supportEvents: false,
+ supportBonjour: false,
+ manfDescription: "Current State"
+ });
+ }
+
+ // Rotary Handle
+ if (this.type=="ROTARY_HANDLE_SENSOR") {
+ cTypes.push(
+ {
+ cType: types.CONTACT_SENSOR_STATE_CTYPE,
+
onRead: function(callback) {
- that.query("MOTION", callback);
+ that.query("STATE",callback);
},
-
- onRegister: function(characteristic) {
- that.currentStateCharacteristic["MOTION"] = characteristic;
- characteristic.eventEnabled = true;
- that.remoteGetValue("MOTION");
+
+ onRegister: function(characteristic) {
+ that.addValueMapping("STATE","2",1);
+ that.currentStateCharacteristic["STATE"] = characteristic;
+ characteristic.eventEnabled = true;
+ that.remoteGetValue("STATE");
},
-
- 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
+
+ perms: ["pr","ev"],
+ format: "bool",
+ initialValue: that.dpvalue("STATE",0),
+ supportEvents: false,
+ supportBonjour: false,
+ manfDescription: "Current State"
+ });
+ }
+
+
+ // Motion Detector
+
+ 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"
+ });
+ }
+
+ // Heating Device
+
+ if ((this.type=="CLIMATECONTROL_RT_TRANSCEIVER") || (this.type=="THERMALCONTROL_TRANSMIT")) {
+
+ 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);
},
-
- {
- 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) {
+
+ onRegister: function(characteristic) {
that.currentStateCharacteristic["ACTUAL_TEMPERATURE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("ACTUAL_TEMPERATURE");
- },
- perms: ["pr", "ev"],
- 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) {
+ },
+ 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);
+ that.delayed("set", "MANU_MODE", 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"
- }
-
- );
+ },
+ 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;
+ );
+ }
+
+
+ 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") {
+
+ 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") {
+ if (this.type=="BLIND") {
return types.WINDOW_COVERING_STYPE;
- }
+ }
- if (this.type == "CLIMATECONTROL_RT_TRANSCEIVER") {
+ if ((this.type=="CLIMATECONTROL_RT_TRANSCEIVER") || (this.type=="THERMALCONTROL_TRANSMIT")) {
return types.THERMOSTAT_STYPE;
- }
-
- if (this.type == "SHUTTER_CONTACT") {
+ }
+
+ if ((this.type=="SHUTTER_CONTACT") ||(this.type=="ROTARY_HANDLE_SENSOR")) {
return types.CONTACT_SENSOR_STYPE;
- }
-
- if (this.type == "MOTION_DETECTOR") {
- return types.MOTION_SENSOR_STYPE;
- }
-
-
- if (this.type == "KEYMATIC") {
- return types.LOCK_MECHANISM_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()
- }, {
+ characteristics: this.informationCharacteristics(),
+ },
+ {
sType: this.sType(),
characteristics: this.controlCharacteristics(that)
}];
- this.log("Loaded services for " + this.name);
+ this.log("Loaded services for " + this.name)
return services;
}
};
-module.exports = HomeMaticGenericChannel;
\ No newline at end of file
+module.exports = HomeMaticGenericChannel;
From ea1f75abb0da4c17e0a7ca27180cde5754a8a319 Mon Sep 17 00:00:00 2001
From: Thomas Kluge
Date: Fri, 30 Oct 2015 18:13:31 +0100
Subject: [PATCH 2/6] setup.sh complete installation on a pi2
---
setup.sh | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
create mode 100644 setup.sh
diff --git a/setup.sh b/setup.sh
new file mode 100644
index 0000000..8bb9164
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,104 @@
+#!/usr/bin/env
+
+# Check if we can use colours in our output
+use_colour=0
+[ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null && use_colour=1
+
+# Some useful functions
+progress() {
+ [ $use_colour -eq 1 ] && echo -ne "\033[01;32m"
+ echo "$@" >&2
+ [ $use_colour -eq 1 ] && echo -ne "\033[00m"
+}
+
+info() {
+ [ $use_colour -eq 1 ] && echo -ne "\033[01;34m"
+ echo "$@" >&2
+ [ $use_colour -eq 1 ] && echo -ne "\033[00m"
+}
+
+die () {
+ [ $use_colour -eq 1 ] && echo -ne "\033[01;31m"
+ echo "$@" >&2
+ [ $use_colour -eq 1 ] && echo -ne "\033[00m"
+ exit 1
+}
+
+install_package() {
+ package=$1
+ info "install ${package}"
+ sudo apt-get -y --force-yes install $package 2>&1 > /dev/null
+ return $?
+}
+
+# check architecture
+sudo test "`dpkg --print-architecture`" == "armhf" || die "This Repos is only for armhf."
+
+# set timezone and update system
+info "Setting up locale and keyboard"
+sudo dpkg-reconfigure locales
+
+TIMEZONE="Europe/Berlin"
+echo $TIMEZONE | sudo tee /etc/timezone
+sudo cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime
+sudo dpkg-reconfigure -f noninteractive tzdata
+
+info "Setting up Hostname"
+echo 'Homebridge' | sudo tee /etc/hostname
+
+info "Cleaning up"
+sudo dpkg --configure -a
+
+info "Update Package Lists this may take some time (10-20 min) depending on your internet connection"
+sudo apt-get update -y
+sudo apt-get dist-upgrade -y
+info "Done"
+
+info "Installing Zeroconf"
+
+install_package "libavahi-compat-libdnssd-dev"
+install_package "gcc-4.8 g++-4.8"
+install_package "libkrb5-dev"
+
+info "Installing node"
+wget https://s3-eu-west-1.amazonaws.com/conoroneill.net/wp-content/uploads/2015/03/node-v0.12.1-linux-arm-pi.tar.gz
+tar -zxvf node-v0.12.1-linux-arm-pi.tar.gz
+cd node-v0.12.1-linux-arm-pi
+sudo cp -R * /usr/local/
+
+
+info "Cloning Repository"
+cd /home/pi
+git clone -b master --single-branch https://github.com/thkl/homebridge.git
+cd homebridge
+
+info "Installing Node Modules"
+npm install
+
+info "Setup"
+
+hazconfig="$(cat /home/pi/homebridge/config.json| grep 'bridge' | wc -l)"
+if [ "$hazconfig" = "0" ]; then
+
+ CCUIP=$(whiptail --inputbox "Please enter your CCU IP" 20 60 "000.000.000.000" 3>&1 1>&2 2>&3)
+ if [ $? -eq 0 ]; then
+ echo "{\"bridge\": {\"name\": \"Homebridge\", \"username\": \"CC:22:3D:E3:CE:30\",\"port\": 51826,\"pin\": \"031-45-154\"}," >> /home/pi/homebridge/config.json;
+ echo "\"description\": \"This is an autogenerated config. only the homematic platform is enabled. see the sample for more\"," >> /home/pi/homebridge/config.json;
+ echo "\"platforms\": [" >> /home/pi/homebridge/config.json;
+ echo "{\"platform\": \"HomeMaticPlatform\",\"name\": \"HomeMatic CCU\",\"ccu_ip\": \"$CCUIP\"," >> /home/pi/homebridge/config.json;
+ echo "\"filter_device\":[],\"filter_channel\":[],\"outlets\":[]}" >> /home/pi/homebridge/config.json;
+ echo "],\"accessories\": []}" >> /home/pi/homebridge/config.json;
+ fi
+fi
+
+whiptail --yesno "Would you like to start homebridge at boot by default?" $DEFAULT 20 60 2
+RET=$?
+if [ $RET -eq 0 ]; then
+ sudo cp /home/pi/homebridge/homebridge.txt /etc/init.d/homebridge
+ sudo chmod 755 /etc/init.d/homebridge
+ sudo update-rc.d homebridge defaults
+fi
+
+info "Done. If there are no error messages you are done."
+info "Your config is ready to use"
+info "to start the homebridge goto /home/pi/homebridge and call npm run start."
From 727809e9b4ff188cf8325a0ae18990fe2234f676 Mon Sep 17 00:00:00 2001
From: Thomas Kluge
Date: Fri, 30 Oct 2015 18:30:07 +0100
Subject: [PATCH 3/6] removed some logs changed to autodetection if hm channel
is supported yet
---
platforms/HomeMatic.js | 9 +++++----
platforms/HomematicChannel.js | 4 +---
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/platforms/HomeMatic.js b/platforms/HomeMatic.js
index 219ebdf..30244e5 100644
--- a/platforms/HomeMatic.js
+++ b/platforms/HomeMatic.js
@@ -308,14 +308,15 @@ HomeMaticPlatform.prototype = {
// 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;
var accessory = new HomeMaticGenericChannel(that.log, that, ch.id, ch.name, ch.type, ch.address, special);
- that.foundAccessories.push(accessory);
- }
-
+ if (accessory.sType()!=undefined) {
+ // support exists for this channel
+ that.foundAccessories.push(accessory);
+ }
} else {
that.log(device.name + " has no address");
diff --git a/platforms/HomematicChannel.js b/platforms/HomematicChannel.js
index e2818a5..2322fed 100644
--- a/platforms/HomematicChannel.js
+++ b/platforms/HomematicChannel.js
@@ -78,9 +78,7 @@ HomeMaticGenericChannel.prototype = {
// Check custom Mapping from HM to HomeKit
var map = this.datapointMappings[dp];
if (map != undefined) {
- this.log("Mapping found for " + dp);
if (map[value]!=undefined) {
- this.log("Mapping found for " + dp + " " + value);
value = map[value];
}
}
@@ -636,7 +634,7 @@ HomeMaticGenericChannel.prototype = {
return types.THERMOSTAT_STYPE;
}
- if ((this.type=="SHUTTER_CONTACT") ||(this.type=="ROTARY_HANDLE_SENSOR")) {
+ if ((this.type=="SHUTTER_CONTACT") || (this.type=="ROTARY_HANDLE_SENSOR")) {
return types.CONTACT_SENSOR_STYPE;
}
From 04f48ecbaba6d40f0c76ae899f5bf45dc683bd26 Mon Sep 17 00:00:00 2001
From: Thomas Kluge
Date: Sat, 31 Oct 2015 12:02:06 +0100
Subject: [PATCH 4/6] fixed thermostats
---
platforms/HomeMatic.js | 6 ++++++
platforms/HomematicChannel.js | 22 ++++++++++++++++------
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/platforms/HomeMatic.js b/platforms/HomeMatic.js
index 30244e5..f140f3d 100644
--- a/platforms/HomeMatic.js
+++ b/platforms/HomeMatic.js
@@ -360,6 +360,12 @@ HomeMaticPlatform.prototype = {
},
+ setRegaValue: function(channel, datapoint, value) {
+ 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) {
diff --git a/platforms/HomematicChannel.js b/platforms/HomematicChannel.js
index 2322fed..786b556 100644
--- a/platforms/HomematicChannel.js
+++ b/platforms/HomematicChannel.js
@@ -32,11 +32,11 @@ HomeMaticGenericChannel.prototype = {
var that = this;
if (this.state[dp] != undefined) {
- callback(this.state[dp]);
+ if (callback!=undefined){callback(this.state[dp]);}
} else {
// that.log("No cached Value found start fetching and send temp 0 back");
this.remoteGetValue(dp);
- callback(0);
+ if (callback!=undefined){callback(0);}
}
},
@@ -107,16 +107,22 @@ HomeMaticGenericChannel.prototype = {
},
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);
+ this.log("Send " + value + " to Datapoint " + dp + " at " + that.adress);
that.platform.setValue(that.adress,dp,value);
}
+
+ if (mode == "setrega") {
+ this.log("Send " + value + " to Datapoint " + dp + " at " + that.adress);
+ that.platform.setRegaValue(that.adress,dp,value);
+ }
+
},
informationCharacteristics: function() {
@@ -580,11 +586,15 @@ HomeMaticGenericChannel.prototype = {
{
cType: types.TARGET_TEMPERATURE_CTYPE,
onUpdate: function(value) {
- //that.delayed("set", "SET_TEMPERATURE", value,500);
- that.delayed("set", "MANU_MODE", value,500);
+ if (that.state["CONTROL_MODE"]!=1) {
+ that.delayed("setrega", "MANU_MODE",value,500);
+ } else {
+ that.delayed("set", "SET_TEMPERATURE", value,500);
+ }
},
onRead: function(callback) {
that.query("SET_TEMPERATURE",callback);
+ that.query("CONTROL_MODE",undefined);
},
onRegister: function(characteristic) {
From 5c921570097d44f251126b4683fa945c1312e133 Mon Sep 17 00:00:00 2001
From: Thomas Kluge
Date: Sat, 31 Oct 2015 16:28:51 +0100
Subject: [PATCH 5/6] removed setup
---
setup.sh | 104 -------------------------------------------------------
1 file changed, 104 deletions(-)
delete mode 100644 setup.sh
diff --git a/setup.sh b/setup.sh
deleted file mode 100644
index 8bb9164..0000000
--- a/setup.sh
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env
-
-# Check if we can use colours in our output
-use_colour=0
-[ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null && use_colour=1
-
-# Some useful functions
-progress() {
- [ $use_colour -eq 1 ] && echo -ne "\033[01;32m"
- echo "$@" >&2
- [ $use_colour -eq 1 ] && echo -ne "\033[00m"
-}
-
-info() {
- [ $use_colour -eq 1 ] && echo -ne "\033[01;34m"
- echo "$@" >&2
- [ $use_colour -eq 1 ] && echo -ne "\033[00m"
-}
-
-die () {
- [ $use_colour -eq 1 ] && echo -ne "\033[01;31m"
- echo "$@" >&2
- [ $use_colour -eq 1 ] && echo -ne "\033[00m"
- exit 1
-}
-
-install_package() {
- package=$1
- info "install ${package}"
- sudo apt-get -y --force-yes install $package 2>&1 > /dev/null
- return $?
-}
-
-# check architecture
-sudo test "`dpkg --print-architecture`" == "armhf" || die "This Repos is only for armhf."
-
-# set timezone and update system
-info "Setting up locale and keyboard"
-sudo dpkg-reconfigure locales
-
-TIMEZONE="Europe/Berlin"
-echo $TIMEZONE | sudo tee /etc/timezone
-sudo cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime
-sudo dpkg-reconfigure -f noninteractive tzdata
-
-info "Setting up Hostname"
-echo 'Homebridge' | sudo tee /etc/hostname
-
-info "Cleaning up"
-sudo dpkg --configure -a
-
-info "Update Package Lists this may take some time (10-20 min) depending on your internet connection"
-sudo apt-get update -y
-sudo apt-get dist-upgrade -y
-info "Done"
-
-info "Installing Zeroconf"
-
-install_package "libavahi-compat-libdnssd-dev"
-install_package "gcc-4.8 g++-4.8"
-install_package "libkrb5-dev"
-
-info "Installing node"
-wget https://s3-eu-west-1.amazonaws.com/conoroneill.net/wp-content/uploads/2015/03/node-v0.12.1-linux-arm-pi.tar.gz
-tar -zxvf node-v0.12.1-linux-arm-pi.tar.gz
-cd node-v0.12.1-linux-arm-pi
-sudo cp -R * /usr/local/
-
-
-info "Cloning Repository"
-cd /home/pi
-git clone -b master --single-branch https://github.com/thkl/homebridge.git
-cd homebridge
-
-info "Installing Node Modules"
-npm install
-
-info "Setup"
-
-hazconfig="$(cat /home/pi/homebridge/config.json| grep 'bridge' | wc -l)"
-if [ "$hazconfig" = "0" ]; then
-
- CCUIP=$(whiptail --inputbox "Please enter your CCU IP" 20 60 "000.000.000.000" 3>&1 1>&2 2>&3)
- if [ $? -eq 0 ]; then
- echo "{\"bridge\": {\"name\": \"Homebridge\", \"username\": \"CC:22:3D:E3:CE:30\",\"port\": 51826,\"pin\": \"031-45-154\"}," >> /home/pi/homebridge/config.json;
- echo "\"description\": \"This is an autogenerated config. only the homematic platform is enabled. see the sample for more\"," >> /home/pi/homebridge/config.json;
- echo "\"platforms\": [" >> /home/pi/homebridge/config.json;
- echo "{\"platform\": \"HomeMaticPlatform\",\"name\": \"HomeMatic CCU\",\"ccu_ip\": \"$CCUIP\"," >> /home/pi/homebridge/config.json;
- echo "\"filter_device\":[],\"filter_channel\":[],\"outlets\":[]}" >> /home/pi/homebridge/config.json;
- echo "],\"accessories\": []}" >> /home/pi/homebridge/config.json;
- fi
-fi
-
-whiptail --yesno "Would you like to start homebridge at boot by default?" $DEFAULT 20 60 2
-RET=$?
-if [ $RET -eq 0 ]; then
- sudo cp /home/pi/homebridge/homebridge.txt /etc/init.d/homebridge
- sudo chmod 755 /etc/init.d/homebridge
- sudo update-rc.d homebridge defaults
-fi
-
-info "Done. If there are no error messages you are done."
-info "Your config is ready to use"
-info "to start the homebridge goto /home/pi/homebridge and call npm run start."
From c1cc8be8fabc13baa398c515f31f35b3d0001b9d Mon Sep 17 00:00:00 2001
From: Thomas Kluge
Date: Sun, 1 Nov 2015 12:57:29 +0100
Subject: [PATCH 6/6] new Devices : Smokedetector
---
platforms/HomeMatic.js | 2 +-
platforms/HomematicChannel.js | 32 +++++++++++++++++++++++++++++++-
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/platforms/HomeMatic.js b/platforms/HomeMatic.js
index f140f3d..6f3a6aa 100644
--- a/platforms/HomeMatic.js
+++ b/platforms/HomeMatic.js
@@ -330,7 +330,7 @@ HomeMaticPlatform.prototype = {
});
/*
- accessory = new HomeMaticGenericChannel(that.log, that, "1234" , "DummyKM" , "KEYMATIC" , "1234");
+ var accessory = new HomeMaticGenericChannel(that.log, that, "1234" , "DummyKM" , "SMOKE_DETECTOR" , "1234");
that.foundAccessories.push(accessory);
accessory = new HomeMaticGenericChannel(that.log, that, "5678" , "DummyBLIND" , "BLIND" , "5678");
diff --git a/platforms/HomematicChannel.js b/platforms/HomematicChannel.js
index 786b556..f15eb58 100644
--- a/platforms/HomematicChannel.js
+++ b/platforms/HomematicChannel.js
@@ -544,6 +544,31 @@ HomeMaticGenericChannel.prototype = {
});
}
+ // Smoke Detector
+ if (this.type=="SMOKE_DETECTOR") {
+ cTypes.push(
+ {
+ cType: "00000076-0000-1000-8000-0026BB765291",
+
+ 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: "Smoke detected"
+ });
+ }
+
// Heating Device
if ((this.type=="CLIMATECONTROL_RT_TRANSCEIVER") || (this.type=="THERMALCONTROL_TRANSMIT")) {
@@ -588,8 +613,9 @@ HomeMaticGenericChannel.prototype = {
onUpdate: function(value) {
if (that.state["CONTROL_MODE"]!=1) {
that.delayed("setrega", "MANU_MODE",value,500);
+ that.state["CONTROL_MODE"]=1; // set to Manual Mode
} else {
- that.delayed("set", "SET_TEMPERATURE", value,500);
+ that.delayed("setrega", "SET_TEMPERATURE", value,500);
}
},
onRead: function(callback) {
@@ -601,6 +627,7 @@ HomeMaticGenericChannel.prototype = {
that.currentStateCharacteristic["SET_TEMPERATURE"] = characteristic;
characteristic.eventEnabled = true;
that.remoteGetValue("SET_TEMPERATURE");
+ that.remoteGetValue("CONTROL_MODE");
},
perms: ["pw","pr","ev"],format: "double",
initialValue: that.dpvalue("SET_TEMPERATURE",16),
@@ -657,6 +684,9 @@ HomeMaticGenericChannel.prototype = {
return types.LOCK_MECHANISM_STYPE
}
+ if (this.type=="SMOKE_DETECTOR") {
+ return "00000087-0000-1000-8000-0026BB765291";
+ }
},