├── .gitignore
├── .npmignore
├── README.md
├── admin
├── homekit.png
└── index.html
├── img
└── admin_settings.png
├── io-package.json
├── lib
└── utils.js
├── main.js
├── package.json
└── postinstall.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | config
3 | www/_socket
4 | .idea
5 | npm-debug.log
6 | persist
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 | .gitignore
4 | npm-debug.log
5 | persist
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | ioBroker HomeKit Adapter
3 | ===============================
4 | [](https://www.npmjs.com/package/iobroker.homekit2)
5 | [](https://www.npmjs.com/package/iobroker.homekit2)
6 |
7 | [](https://nodei.co/npm/iobroker.homekit2/)
8 |
9 | HomeKit Adapter for ioBroker
10 |
11 | With this Adapter it is possible to use your iOS Device native for ioBroker Home Automation.
12 |
13 | Within Admin Settings you can set following Attributes
14 | - username
15 | - port
16 | - pincode
17 | - bridge name
18 |
19 | 
20 |
21 | ## Installation
22 | - Enums are no longer needed, Objects were included cause of ioBroker roles.
23 |
24 | Note: on some systems additional package is required ```sudo apt-get install libavahi-compat-libdnssd-dev```
25 |
26 | (For Usage you must define a enum named enum.homekit.
27 | There you must include all needed Objects.
28 | Set a common Name for all Objects e.g. hm-rpc.0.JEQ0225305.1.TEMPERATURE = Kinderzimmer)
29 |
30 | You can use every Homekit App on iOS. These Version is tested with Elgato Eve cause it's free.
31 |
32 | Currently implemented are:
33 | - Homematic Thermostat
34 | - Homematic Switch
35 | - zWave Temperature
36 | - zWave Switch
37 |
38 | Supported Roles from ioBroker:
39 | - value.temperature
40 | - indicator.battery (Not tested)
41 | - value.battery (Not tested)
42 | - alarm
43 | - level.temperature
44 | - switch
45 | - value.humidity
46 | - level.dimmer
47 |
48 | If iobroker.weatherground is used, forecast Objects are explicit removed from homekit.
49 |
50 | Within Homekit you can see the actual temperature and humidity from the Thermostat.
51 | The Switch can be used within Homekit.
52 |
53 | ## Changelog
54 | ### 0.1.6 (2016-10-29)
55 | - (PArns) Fix compatibility issues
56 |
57 | ### 0.1.4 (2016-03-05)
58 | - (husky-koglhof)
59 | Fixed Exception (error: TypeError: Cannot read property 'val' of null)
60 |
61 | ### 0.1.3 (2016-03-05)
62 | - (husky-koglhof)
63 | Fixed Exception (error exception: Cannot read property 'CurrentTemperature' of undefined)
64 | Added Debug log for Types
65 |
66 | ### 0.1.2 (2016-02-23)
67 | - (husky-koglhof)
68 | Added Dependency hap-nodejs 0.2.4 (No longer Reload / Timeout Failure available)
69 | Tested alarm role (With zwave Adapter)
70 |
71 | ### 0.1.1 (2016-01-31)
72 | - (husky-koglhof)
73 | fixed: Error when weatherground Adapter not found
74 | added: Role level.dimmer (Switch and Brightness)
75 |
76 | ### 0.1.0 (2016-01-29)
77 | - (husky-koglhof)
78 | fixed: timeout of homekit protocol
79 | fixed: zwave states change loop
80 | added: States are updated automatically in iOS
81 | added: zWave Objects
82 |
83 | ### 0.0.10 (2016-01-23)
84 | - (husky-koglhof) changed Store to correct path
85 |
86 | ### 0.0.8 (2016-01-22)
87 | - (husky-koglhof) Moved persistent Store to iobroker-data/homekit.0
88 | removed sensor.* Types
89 | added WeatherUnderGround Feature (forecast Objects are disabled)
90 |
91 | ### 0.0.7 (2015-12-13)
92 | - (husky-koglhof) Fixed saving admin Settings
93 |
94 | ### 0.0.6 (2015-12-12)
95 | - (husky-koglhof) Added new Devices
96 | Temperature can now be a negative Value (Needed for Outdoor Temperature)
97 | Package Name changed to lowercase
98 | Removed Dependency for installation of Packages
99 |
100 | ### 0.0.5 (2015-12-07)
101 | - (husky-koglhof) Added admin Table for Devices
102 |
103 | ### 0.0.4 (2015-12-05)
104 | - (husky-koglhof) Replaced hardcoded Values for Homematic
105 | Added Configuration for generic Objects.
106 | Currently tested:
107 | Homematic
108 | HM-CC-TC, HM-CC-RT-DN (CurrentTemperature, Setpoint, Humidity)
109 | HM-LC-Sw1-FM, HM-LC-Sw2-FM, HM-LC-Sw4-DR (Switch)
110 | MAX
111 | BC-RT-TRX-CyG-3 (CurrentTemperature, Setpoint)
112 | ZWave
113 | FGWPE (Switch), FGSS101 (Temperature), Danfoss Living Connect Radiator Thermostat (Temperature)
114 |
115 | ### 0.0.3 (2015-09-27)
116 | - (husky-koglhof) added Support for HM-CC-TC, HM-CC-RT-DN and BC-RT-TRX-CyG-3 Thermostat
117 | Supported now Actual Temperature, Set Temperature, Humidity
118 |
119 | ### 0.0.2 (2015-09-27)
120 | - (husky-koglhof) Refresh States if "Room" is refreshed.
121 |
122 | ### 0.0.1 (2015-09-26)
123 | - (husky-koglhof) Initial commit. Still non-functional.
124 |
125 | ## Todo
126 | Implement set Temperature for Homematic, etc.
127 |
128 | ## License
129 |
130 | ## Lizenz
131 |
132 | Copyright (c) 2015 husky-koglhof
133 |
134 | [CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
135 |
136 | Der obige Urheberrechtsvermerk ist in allen Kopien oder Teilkopien der Software beizulegen.
137 |
138 | DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE BEREITGESTELLT, EINSCHLIESSLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN ZWECK SOWIE JEGLICHER RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES, EINES DELIKTES ODER ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.
139 |
140 | HomeMatic und BidCoS sind eingetragene Warenzeichen der [eQ-3 AG](http://eq-3.de)
141 |
--------------------------------------------------------------------------------
/admin/homekit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioBroker/ioBroker.homekit2/6fc6d96e68a9fba908ba7380a2abfbe8a2a7da9e/admin/homekit.png
--------------------------------------------------------------------------------
/admin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
231 |
232 |
233 |
234 |
235 |  |
236 | HomeKit Adapter settings |
237 |
238 |
239 |
263 |
264 |
265 |
--------------------------------------------------------------------------------
/img/admin_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioBroker/ioBroker.homekit2/6fc6d96e68a9fba908ba7380a2abfbe8a2a7da9e/img/admin_settings.png
--------------------------------------------------------------------------------
/io-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "common": {
3 | "name": "homekit2",
4 | "title": "homekit",
5 | "desc": "Apple HomeKit based on HAP-NodeJS",
6 | "version": "0.1.6",
7 | "mode": "daemon",
8 | "platform": "javascript/Node.js",
9 | "os": ["darwin", "linux"],
10 | "loglevel": "debug",
11 | "keywords": ["ioBroker", "homekit", "Siri", "home automation"],
12 | "main": "main.js",
13 | "authors": [
14 | "Christian Baumgartner", "husky-koglhof "
15 | ],
16 | "license": "CC BY-NC-SA",
17 | "singletonHost": true,
18 | "readme": "https://github.com/husky-koglhof/ioBroker.homekit/blob/master/README.md",
19 | "icon": "homekit.png",
20 | "extIcon": "https://raw.githubusercontent.com/husky-koglhof/ioBroker.homekit/master/admin/homekit.png",
21 | "singleton": true,
22 | "type": "common adapters",
23 | "messagebox": true
24 | },
25 | "native": {
26 | "username": "CC:22:3D:E3:CE:F6",
27 | "port": 51826,
28 | "pincode": "031-45-154",
29 | "category": "Accessory.Categories.BRIDGE",
30 | "bridgename": "ioBroker Bridge",
31 | "Accessories": {
32 | "Switch": {
33 | "State": {
34 | "HM-LC-Sw1-FM": ".STATE",
35 | "HM-LC-Sw2-FM": ".STATE",
36 | "HM-LC-Sw4-DR": ".STATE",
37 | "FGWPE": "",
38 | "HM-LC-Sw1-Pl": ".STATE",
39 | "HM-LC-Sw4-PCB": ".STATE"
40 | }
41 | },
42 | "Dimmer": {
43 | "State": {
44 | "HM-LC-Dim1PWM-CV": ".STATE",
45 | "HM-LC-Sw2-FM": ".STATE",
46 | "HM-LC-Sw4-DR": ".STATE",
47 | "FGWPE": "",
48 | "HM-LC-Sw1-Pl": ".STATE",
49 | "HM-LC-Sw4-PCB": ".STATE"
50 | }
51 | },
52 | "Thermostat": {
53 | "CurrentTemperature": {
54 | "HM-CC-TC": "1.TEMPERATURE",
55 | "BC-RT-TRX-CyG-3": "1.ACTUAL_TEMPERATURE",
56 | "HM-CC-RT-DN": "4.ACTUAL_TEMPERATURE",
57 | "OpenWeatherMap": "1.TEMPERATURE",
58 | "HM-WDS10-TH-O": "1.TEMPERATURE"
59 | },
60 | "TargetTemperature": {
61 | "HM-CC-TC": "2.SETPOINT",
62 | "BC-RT-TRX-CyG-3": "1.SET_TEMPERATURE",
63 | "HM-CC-RT-DN": "4.SET_TEMPERATURE"
64 | },
65 | "State": {
66 | "HM-CC-TC": "2.STATE"
67 | },
68 | "CurrentRelativeHumidity": {
69 | "HM-CC-TC": "1.HUMIDITY",
70 | "OpenWeatherMap": "1.HUMIDITY",
71 | "HM-WDS10-TH-O": "1.HUMIDITY"
72 | }
73 | },
74 | "Temperature": {
75 | "CurrentTemperature": {
76 | "OpenWeatherMap": "1.TEMPERATURE",
77 | "HM-WDS10-TH-O": "1.TEMPERATURE"
78 | }
79 | },
80 | "Humidity": {
81 | "CurrentRelativeHumidity": {
82 | "OpenWeatherMap": "1.HUMIDITY",
83 | "HM-WDS10-TH-O": "1.HUMIDITY"
84 | }
85 | }
86 | }
87 | },
88 | "objects": [
89 | ],
90 | "instanceObjects": [
91 | ]
92 | }
93 |
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 | var controllerDir;
2 | var appName;
3 |
4 | function getAppName() {
5 | var parts = __dirname.replace(/\\/g, '/').split('/');
6 | return parts[parts.length - 2].split('.')[0];
7 | }
8 |
9 | // Get js-controller directory to load libs
10 | function getControllerDir(isInstall) {
11 | var fs = require('fs');
12 | // Find the js-controller location
13 | var controllerDir = __dirname.replace(/\\/g, '/');
14 | controllerDir = controllerDir.split('/');
15 | if (controllerDir[controllerDir.length - 3] == 'adapter') {
16 | controllerDir.splice(controllerDir.length - 3, 3);
17 | controllerDir = controllerDir.join('/');
18 | } else if (controllerDir[controllerDir.length - 3] == 'node_modules') {
19 | controllerDir.splice(controllerDir.length - 3, 3);
20 | controllerDir = controllerDir.join('/');
21 | if (fs.existsSync(controllerDir + '/node_modules/' + appName + '.js-controller')) {
22 | controllerDir += '/node_modules/' + appName + '.js-controller';
23 | } else if (fs.existsSync(controllerDir + '/node_modules/' + appName.toLowerCase() + '.js-controller')) {
24 | controllerDir += '/node_modules/' + appName.toLowerCase() + '.js-controller';
25 | } else if (!fs.existsSync(controllerDir + '/controller.js')) {
26 | if (!isInstall) {
27 | console.log('Cannot find js-controller');
28 | process.exit(10);
29 | } else {
30 | process.exit();
31 | }
32 | }
33 | } else {
34 | if (!isInstall) {
35 | console.log('Cannot find js-controller');
36 | process.exit(10);
37 | } else {
38 | process.exit();
39 | }
40 | }
41 | return controllerDir;
42 | }
43 |
44 | // Read controller configuration file
45 | function getConfig() {
46 | var fs = require('fs');
47 | if (fs.existsSync(controllerDir + '/conf/' + appName + '.json')) {
48 | return JSON.parse(fs.readFileSync(controllerDir + '/conf/' + appName + '.json'));
49 | } else if (fs.existsSync(controllerDir + '/conf/' + appName.toLowerCase() + '.json')) {
50 | return JSON.parse(fs.readFileSync(controllerDir + '/conf/' + appName.toLowerCase() + '.json'));
51 | } else {
52 | throw new Error('Cannot find ' + controllerDir + '/conf/' + appName + '.json');
53 | }
54 | }
55 | appName = getAppName();
56 | controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.indexOf('--install') !== -1);
57 |
58 | exports.controllerDir = controllerDir;
59 | exports.getConfig = getConfig;
60 | exports.adapter = require(controllerDir + '/lib/adapter.js');
61 | exports.appName = appName;
62 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * HomeKit Adapter
3 | *
4 | * License: GNU LGPL
5 | */
6 |
7 | var utils = require(__dirname + '/lib/utils'); // Get common adapter utils
8 | var objects = {};
9 | var states = {};
10 | var enums = [];
11 |
12 | var adapter = utils.adapter({
13 | name: 'homekit2',
14 |
15 | ready: function () {
16 | getData(function () {
17 | adapter.subscribeForeignStates("*");
18 | main();
19 | adapter.log.debug(JSON.stringify(allSensors));
20 | });
21 | },
22 | objectChange: function (id, obj) {
23 | // adapter.log.debug("objectChange for " + id + " found");
24 | },
25 | stateChange: function (id, state) {
26 | // adapter.log.debug("stateChange for " + id + ", state: " + JSON.stringify(state));
27 | states[id] = state;
28 |
29 | var address = createAddress(objects[id]);
30 | //adapter.log.debug("ADDRESS = " + address);
31 | var sensorObject = allSensors[address];
32 |
33 | if (sensorObject != undefined && state.val != undefined) {
34 | var value = state.val;
35 | adapter.log.debug(" VALUE: " + value + " id = " + id);
36 | var service = eval(sensorObject[0]);
37 | var characteristic = eval(sensorObject[1]);
38 | var sensor = sensorObject[2];
39 |
40 | var oldValue = sensor.getService(service).getCharacteristic(characteristic).value;
41 |
42 | // Bugfix: zwave Switch comes with State 0 / 1
43 | if (sensorObject[0] == 'Service.Switch') {
44 | adapter.log.debug("is Switch = true");
45 | var i = parseInt(value);
46 | if (i == 0) {
47 | value = false;
48 | } else if (i == 1) {
49 | value = true;
50 | }
51 |
52 | var o = parseInt(oldValue);
53 | if (o == 0) {
54 | oldValue = false;
55 | } else if (o == 1) {
56 | oldValue = true;
57 | }
58 | } else if (sensorObject[0] == 'Service.Lightbulb') {
59 | adapter.log.debug("is Lightbulb = true");
60 | var i = parseInt(value);
61 | if (sensorObject[1] == 'Characteristic.Brightness') {
62 | adapter.log.debug("brightness");
63 | } else {
64 | if (i == 0) {
65 | value = false;
66 | } else if (i > 0) {
67 | value = true;
68 | }
69 | }
70 | } else {
71 | // If value has decimal, convert to Float
72 | if (value !== true && value !== false && value !== "true" && value !== "false") {
73 | value = parseFloat(value);
74 | if (value % 1 == 0) value = parseInt(value);
75 | }
76 | }
77 |
78 | adapter.log.debug("OLDVALUE: " + oldValue);
79 | adapter.log.debug("NEWVALUE: " + value);
80 | if (oldValue != value) {
81 | adapter.log.debug("1. Change state for " + address + " to " + value + " ack = " + state.ack);
82 |
83 | adapter.log.debug("2. Change state for " + address + " to " + value + " ack = " + state.ack);
84 |
85 | if (value !== NaN && value !== null && value !== "NaN") {
86 | adapter.log.debug("3. Change state for " + address + " to " + value + " ack = " + state.ack);
87 | /*
88 | sensor
89 | .getService(service)
90 | .setCharacteristic(characteristic, value);
91 |
92 | if (sensorObject[1] == 'Characteristic.Brightness') {
93 | if (value == 0) {
94 | sensor
95 | .getService(service)
96 | .setCharacteristic(Characteristic.On, false);
97 | } else if (value > 0 ) {
98 | sensor
99 | .getService(service)
100 | .setCharacteristic(Characteristic.On, true);
101 | }
102 | }
103 | */
104 | }
105 | } else if (sensorObject[1] == 'Characteristic.Brightness') {
106 | if (value !== NaN && value !== null && value !== "NaN") {
107 | adapter.log.debug("4. Change state for " + address + " to " + value + " ack = " + state.ack);
108 |
109 | sensor
110 | .getService(service)
111 | .setCharacteristic(characteristic, value);
112 | if (value == 0) {
113 | sensor
114 | .getService(service)
115 | .setCharacteristic(Characteristic.On, false);
116 | } else if (value > 0 ) {
117 | sensor
118 | .getService(service)
119 | .setCharacteristic(Characteristic.On, true);
120 | }
121 | }
122 |
123 | }
124 | }
125 | },
126 | unload: function (callback) {
127 | callback();
128 | },
129 | });
130 |
131 | var thermostat = [];
132 | var humidity = [];
133 | var battery = [];
134 | var alarm = [];
135 | var setpoint = [];
136 | var switches = [];
137 | var temperature = [];
138 | var lightbulb = [];
139 |
140 | function getParent(address) {
141 | var a = address.split('.');
142 | var l = a.length;
143 | var b = "";
144 | for (var i = 0; i < a.length - 1; i++) {
145 | b += a[i] + ".";
146 | }
147 | return b.substr(0, b.length-1);
148 | }
149 |
150 | function getRoot(address) {
151 | var a = address.split('.');
152 | if (a.length >= 3) {
153 | return a[0]+"."+a[1]+"."+a[2];
154 | } else {
155 | return address;
156 | }
157 | }
158 |
159 | function getData(callback) {
160 | var statesReady;
161 | var objectsReady;
162 |
163 | adapter.log.debug('requesting all states');
164 | adapter.getForeignStates('*', function (err, res) {
165 | states = res;
166 | statesReady = true;
167 | adapter.log.debug('received all states');
168 | if (objectsReady && typeof callback === 'function') callback();
169 | });
170 |
171 | adapter.log.debug('requesting all objects');
172 | adapter.objects.getObjectList({include_docs: true}, function (err, res) {
173 | res = res.rows;
174 | objects = {};
175 | for (var i = 0; i < res.length; i++) {
176 | objects[res[i].doc._id] = res[i].doc;
177 | if (res[i].doc.type === 'enum') enums.push(res[i].doc._id);
178 | var obj = res[i].doc;
179 | // TODO: Remove hardcoded WeatherUnderGround
180 | if (obj._id != undefined && obj._id.search("forecast") < 0) {
181 | if (obj.common !== undefined && obj.common.role == "value.humidity") {
182 | var parent = getParent(obj._id);
183 | var pobj = objects[parent];
184 | if (pobj.native.PARENT_TYPE != undefined && pobj.native.PARENT_TYPE != "HM-CC-TC") {
185 | humidity.push(obj._id);
186 | }
187 | }
188 | if (obj.common !== undefined && obj.common.role == "value.temperature") thermostat.push(obj._id);
189 | if (obj.common !== undefined && obj.common.role == "indicator.battery") battery.push(obj._id);
190 | if (obj.common !== undefined && obj.common.role == "value.battery") battery.push(obj._id);
191 | if (obj.common !== undefined && obj.common.role == "alarm") alarm.push(obj._id);
192 | if (obj.common !== undefined && obj.common.role == "level.temperature") setpoint.push(obj._id);
193 | if (obj.common !== undefined && obj.common.role == "switch") switches.push(obj._id);
194 | if (obj.common !== undefined && obj.common.role == "level.dimmer") lightbulb.push(obj._id);
195 | }
196 | }
197 |
198 | objectsReady = true;
199 | adapter.log.debug('received all objects');
200 | if (statesReady && typeof callback === 'function') callback();
201 | });
202 | }
203 |
204 | var HAP = require('hap-nodejs');
205 | var uuid = HAP.uuid;
206 | var Bridge = HAP.Bridge;
207 | var Accessory = HAP.Accessory;
208 | var Service = HAP.Service;
209 | var Characteristic = HAP.Characteristic;
210 | var bridge;
211 |
212 | function main() {
213 | adapter.log.info("hap-nodejs starting...");
214 |
215 | var storage = require('hap-nodejs/node_modules/node-persist');
216 | var types = require('hap-nodejs/accessories/types');
217 | var bridgename = adapter.config.bridgename;
218 |
219 | // Initialize our storage system
220 |
221 | var store = adapter.adapterDir + "/../../iobroker-data/homekit.0";
222 | storage.initSync({ dir: store });
223 | //storage.initSync();
224 |
225 | // Start by creating our Bridge which will host all loaded Accessories
226 | bridge = new Bridge(bridgename, uuid.generate(bridgename));
227 |
228 | // Listen for bridge identification event
229 | bridge.on('identify', function (paired, callback) {
230 | adapter.log.info("Node Bridge identify:" + paired);
231 | callback(); // success
232 | });
233 |
234 | var accessories = adapter.config.Accessories;
235 | var types = {};
236 |
237 | var map = new Object();
238 |
239 | for (var acc_name in accessories) {
240 | var accessory = accessories[acc_name];
241 | for (var obj_name in accessory) {
242 | var object = accessory[obj_name];
243 | adapter.log.debug("Accessory: " + acc_name + " Object: " + obj_name);
244 | for (var addr_name in object) {
245 | var address = object[addr_name];
246 | // TODO: Check if this accessory is already defined
247 | if (types[addr_name] == undefined) {
248 | types[addr_name] = {};
249 | }
250 | types[addr_name][acc_name] = acc_name;
251 | }
252 | }
253 | }
254 |
255 | for (var i = 0; i < alarm.length; i++) {
256 | var temp = alarm[i];
257 | if (createAccessory['SecuritySystem']) {
258 | object = objects[temp];
259 | accessory = accessories['SecuritySystem'];
260 | map.object = object;
261 | map.accessory = accessory;
262 | map.types = types;
263 |
264 | bridge.addBridgedAccessory(createAccessory['SecuritySystem'](map));
265 | } else {
266 | adapter.log.error("UNKNOWN SERVICE");
267 | }
268 | map = new Object();
269 | }
270 |
271 | for (var i = 0; i < humidity.length; i++) {
272 | var temp = humidity[i];
273 | if (createAccessory['Humidity']) {
274 | object = objects[temp];
275 | accessory = accessories['Humidity'];
276 | map.object = object;
277 | map.accessory = accessory;
278 | map.types = types;
279 |
280 | bridge.addBridgedAccessory(createAccessory['Humidity'](map));
281 | } else {
282 | adapter.log.error("UNKNOWN SERVICE");
283 | }
284 | map = new Object();
285 | }
286 |
287 | for (var i = 0; i < temperature.length; i++) {
288 | var temp = temperature[i];
289 | if (createAccessory['Temperature']) {
290 | object = objects[temp];
291 | accessory = accessories['Temperature'];
292 | map.object = object;
293 | map.accessory = accessory;
294 | map.types = types;
295 |
296 | bridge.addBridgedAccessory(createAccessory['Temperature'](map));
297 | } else {
298 | adapter.log.error("UNKNOWN SERVICE");
299 | }
300 | map = new Object();
301 | }
302 |
303 | for (var i = 0; i < thermostat.length; i++) {
304 | var temp = thermostat[i];
305 | if (createAccessory['Thermostat']) {
306 | object = objects[temp];
307 | accessory = accessories['Thermostat'];
308 | map.object = object;
309 | map.accessory = accessory;
310 | map.types = types;
311 |
312 | bridge.addBridgedAccessory(createAccessory['Thermostat'](map));
313 | } else {
314 | adapter.log.error("UNKNOWN SERVICE");
315 | }
316 | map = new Object();
317 | }
318 |
319 | for (var i = 0; i < switches.length; i++) {
320 | var sw = switches[i];
321 |
322 | object = objects[sw];
323 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
324 | if (object && object.native && object.native.PARENT_TYPE != undefined) {
325 | if (createAccessory['Switch']) {
326 | accessory = accessories['Switch'];
327 | map.object = object;
328 | map.accessory = accessory;
329 |
330 | bridge.addBridgedAccessory(createAccessory['Switch'](map));
331 | } else {
332 | adapter.log.error("UNKNOWN SERVICE");
333 | }
334 | }
335 | if (object.common.type == "boolean") {
336 | if (createAccessory['Switch']) {
337 | accessory = accessories['Switch'];
338 | map.object = object;
339 | map.accessory = accessory;
340 |
341 | bridge.addBridgedAccessory(createAccessory['Switch'](map));
342 | } else {
343 | adapter.log.error("UNKNOWN SERVICE");
344 | }
345 | }
346 | map = new Object();
347 | }
348 |
349 | for (var i = 0; i < lightbulb.length; i++) {
350 | var di = lightbulb[i];
351 |
352 | object = objects[di];
353 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
354 | if (object.native.PARENT_TYPE != undefined) {
355 | if (createAccessory['Lightbulb']) {
356 | accessory = accessories['Lightbulb'];
357 | map.object = object;
358 | map.accessory = accessory;
359 |
360 | bridge.addBridgedAccessory(createAccessory['Lightbulb'](map));
361 | } else {
362 | adapter.log.error("UNKNOWN SERVICE");
363 | }
364 | }
365 | if (object.common.type == "number") {
366 | if (createAccessory['Lightbulb']) {
367 | accessory = accessories['Lightbulb'];
368 | map.object = object;
369 | map.accessory = accessory;
370 |
371 | bridge.addBridgedAccessory(createAccessory['Lightbulb'](map));
372 | } else {
373 | adapter.log.error("UNKNOWN SERVICE");
374 | }
375 | }
376 | map = new Object();
377 |
378 | }
379 | // Publish the Bridge on the local network.
380 | bridge.publish({
381 | username: adapter.config.username,
382 | port: parseInt(adapter.config.port),
383 | pincode: adapter.config.pincode,
384 | category: adapter.config.category
385 | });
386 |
387 | adapter.log.info("Bridge '" + bridgename + "' successfully published");
388 | adapter.log.debug("UserName: " + adapter.config.username);
389 | adapter.log.debug("PinCode: " + adapter.config.pincode);
390 | adapter.log.debug("Port: " + adapter.config.port);
391 | adapter.log.debug("Category: " + adapter.config.category);
392 | }
393 |
394 | function identify(settings, paired, callback) {
395 | adapter.log.debug('< hap ' + settings.name + ' identify ' + paired);
396 | if (settings.topic.identify) {
397 | adapter.log.debug('> iobroker ' + settings.topic.identify + " " + settings.payload.identify);
398 | // TODO: mqtt.publish(settings.topic.identify, settings.payload.identify);
399 | }
400 | callback();
401 | }
402 |
403 | function setInfos(acc, settings) {
404 | if (settings) {
405 | if (settings.ADDRESS || settings.TYPE) {
406 | acc.getService(Service.AccessoryInformation)
407 | .setCharacteristic(Characteristic.Manufacturer, "Homematic" || "-")
408 | .setCharacteristic(Characteristic.Model, settings.TYPE || "-")
409 | .setCharacteristic(Characteristic.SerialNumber, settings.ADDRESS || "-");
410 | }
411 | }
412 | }
413 |
414 | var allSensors = {};
415 |
416 | var createAccessory = {
417 | SecuritySystem: function createAccessory_SecuritySystem(settings) {
418 | var object = settings.object;
419 | var accessory = settings.accessory;
420 | var types = settings.types;
421 |
422 | var s = object._id.split(".");
423 | var a;
424 | for (var i = 0; i < s.length-2; i++) {
425 | if (a === undefined) {
426 | a = s[i];
427 | } else {
428 | a = a + "." + s[i];
429 | }
430 | }
431 | var p = objects[a];
432 | var t;
433 | if (p !== undefined && p.native.TYPE !== undefined) {
434 | t = p.native.TYPE;
435 | adapter.log.debug("< hap Type for SecuritySystem = " + t);
436 | }
437 | var objName = createName(object);
438 | var address = createAddress(object);
439 |
440 | var sensorUUID = uuid.generate('hap-nodejs:accessories:securitysystem:' + address + "_" + objName);
441 | var sensor = new Accessory(objName, sensorUUID);
442 | setInfos(sensor, object.native);
443 |
444 | adapter.log.debug('> iobroker subscribe SecuritySystem ' + address );
445 |
446 | if (t !== undefined && accessory['SecuritySystem'][t] !== undefined) {
447 | sensor.addService(Service.SecuritySystem)
448 | .getCharacteristic(Characteristic.SecuritySystemCurrentState)
449 | .on('get', function (callback) {
450 | var addr = p._id + "." + accessory['SecuritySystemCurrentState'][t];
451 | adapter.log.debug('< hap ' + objName + ' get SecuritySystemCurrentState for ' + addr);
452 |
453 | if (states[addr] != undefined && states[addr].val > 0) {
454 | value = Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED;
455 | } else {
456 | value = Characteristic.SecuritySystemCurrentState.STAY_ARM;
457 | }
458 | //value = states[addr].val;
459 | //adapter.subscribeForeignStates(addr);
460 | if (callback) callback(null, value);
461 | });
462 | var addr = p._id + "." + accessory['SecuritySystemCurrentState'][t];
463 | } else {
464 | sensor.addService(Service.SecuritySystem)
465 | .getCharacteristic(Characteristic.SecuritySystemCurrentState)
466 | .on('get', function(callback) {
467 | var addr = object._id;
468 | adapter.log.debug('< hap ' + objName + ' get SecuritySystemCurrentState for ' + addr);
469 |
470 | if (states[addr] != undefined && states[addr].val > 0) {
471 | value = Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED;
472 | } else {
473 | value = Characteristic.SecuritySystemCurrentState.STAY_ARM;
474 | }
475 | //value = parseFloat(states[addr].val);
476 | //adapter.subscribeForeignStates(addr);
477 | if (callback) callback(null, value);
478 | });
479 | var addr = object._id;
480 | }
481 | allSensors[addr] = ['Service.SecuritySystem', 'Characteristic.SecuritySystemCurrentState', sensor];
482 | return sensor;
483 | },
484 | Humidity: function createAccessory_Humidity(settings) {
485 | var object = settings.object;
486 | var accessory = settings.accessory;
487 | var types = settings.types;
488 |
489 | var s = object._id.split(".");
490 | var a;
491 | for (var i = 0; i < s.length-2; i++) {
492 | if (a === undefined) {
493 | a = s[i];
494 | } else {
495 | a = a + "." + s[i];
496 | }
497 | }
498 | var p = objects[a];
499 | var t;
500 | if (p !== undefined && p.native.TYPE !== undefined) {
501 | t = p.native.TYPE;
502 | adapter.log.debug("< hap Type for Humidity = " + t);
503 | }
504 | var objName = createName(object);
505 | var address = createAddress(object);
506 |
507 | var sensorUUID = uuid.generate('hap-nodejs:accessories:humidity:' + address + "_" + objName);
508 | var sensor = new Accessory(objName, sensorUUID);
509 | setInfos(sensor, object.native);
510 |
511 | adapter.log.debug('> iobroker subscribe Humidity ' + address );
512 |
513 | if (t !== undefined && accessory['CurrentRelativeHumidity'][t] !== undefined) {
514 | sensor.addService(Service.HumiditySensor)
515 | .getCharacteristic(Characteristic.CurrentRelativeHumidity)
516 | .on('get', function (callback) {
517 | var addr = p._id + "." + accessory['CurrentRelativeHumidity'][t];
518 | adapter.log.debug('< hap ' + objName + ' get CurrentRelativeHumidity for ' + addr);
519 |
520 | value = parseFloat(states[addr].val);
521 | //adapter.subscribeForeignStates(addr);
522 | if (callback) callback(null, value);
523 | });
524 | var addr = p._id + "." + accessory['CurrentRelativeHumidity'][t];
525 | } else {
526 | sensor.addService(Service.HumiditySensor)
527 | .getCharacteristic(Characteristic.CurrentRelativeHumidity)
528 | .on('get', function(callback) {
529 | var addr = object._id;
530 | adapter.log.debug('< hap ' + objName + ' get CurrentRelativeHumidity for ' + addr);
531 |
532 | value = parseFloat(states[addr].val);
533 | //adapter.subscribeForeignStates(addr);
534 | if (callback) callback(null, value);
535 | });
536 | var addr = object._id;
537 | }
538 | allSensors[addr] = ['Service.HumiditySensor', 'Characteristic.CurrentRelativeHumidity', sensor];
539 | return sensor;
540 | },
541 | Temperature: function createAccessory_Temperature(settings) {
542 | var object = settings.object;
543 | var accessory = settings.accessory;
544 | var types = settings.types;
545 |
546 | var s = object._id.split(".");
547 | var a;
548 | for (var i = 0; i < s.length-2; i++) {
549 | if (a === undefined) {
550 | a = s[i];
551 | } else {
552 | a = a + "." + s[i];
553 | }
554 | }
555 | var p = objects[a];
556 | var t;
557 | if (p !== undefined && p.native.TYPE !== undefined) {
558 | t = p.native.TYPE;
559 | adapter.log.debug("< hap Type for Temperature = " + t);
560 | }
561 | var objName = createName(object);
562 | var address = createAddress(object);
563 |
564 | var sensorUUID = uuid.generate('hap-nodejs:accessories:temperature:' + address + "_" + objName);
565 | var sensor = new Accessory(objName, sensorUUID);
566 | setInfos(sensor, object.native);
567 |
568 | adapter.log.debug('> iobroker subscribe Temperature ' + address );
569 |
570 | if (t !== undefined && accessory['CurrentTemperature'][t] !== undefined) {
571 | var service = sensor.addService(Service.TemperatureSensor);
572 | var char = service.getCharacteristic(Characteristic.CurrentTemperature);
573 | char.setProps({minValue: -100});
574 |
575 | var action = char.on('get', function (callback) {
576 | var addr = p._id + "." + accessory['CurrentTemperature'][t];
577 | adapter.log.debug('< hap ' + objName + ' get CurrentTemperature for ' + addr);
578 |
579 | value = parseFloat(states[addr].val);
580 | //adapter.subscribeForeignStates(addr);
581 | if (callback) callback(null, value);
582 | });
583 | var addr = p._id + "." + accessory['CurrentTemperature'][t];
584 | } else {
585 | var service = sensor.addService(Service.TemperatureSensor);
586 | var char = service.getCharacteristic(Characteristic.CurrentTemperature);
587 | char.setProps({minValue: -100});
588 |
589 | var action = char.on('get', function (callback) {
590 | var addr = object._id;
591 | adapter.log.debug('< hap ' + objName + ' get CurrentTemperature for ' + addr);
592 |
593 | value = parseFloat(states[addr].val);
594 | //adapter.subscribeForeignStates(addr);
595 | if (callback) callback(null, value);
596 | });
597 | var addr = object._id;
598 | }
599 | allSensors[addr] = ['Service.TemperatureSensor', 'Characteristic.CurrentTemperature', sensor];
600 | return sensor;
601 | },
602 | Thermostat: function createAccessory_Thermostat(settings) {
603 |
604 | var object = settings.object;
605 | var accessory = settings.accessory;
606 | var types = settings.types;
607 |
608 | // TODO: Try to get Parent Device so we can check which Type this Temperature is
609 | // Homematic Devices have alway PARENT_TYPE set e.g. HM-CC-TC
610 | var s = object._id.split(".");
611 | var a;
612 | for (var i = 0; i < s.length-2; i++) {
613 | if (a === undefined) {
614 | a = s[i];
615 | } else {
616 | a = a + "." + s[i];
617 | }
618 | }
619 | var p = objects[a];
620 | var t;
621 | // WORKAROUND: UVR61-3 Devices are generated with Type UVR61-3
622 | if (p !== undefined && p.native.TYPE !== undefined && p.native.TYPE !== "UVR61-3") {
623 | t = p.native.TYPE;
624 | adapter.log.debug("< hap Type for Thermostat = " + t);
625 | }
626 |
627 | var objName = createName(object);
628 | var address = createAddress(object);
629 |
630 | var sensorUUID = uuid.generate('hap-nodejs:accessories:thermostat:' + address + "_" + objName);
631 | var sensor = new Accessory(objName, sensorUUID);
632 | setInfos(sensor, object.native);
633 |
634 | adapter.log.debug('> iobroker subscribe Thermostat ' + address );
635 |
636 | if (p != undefined && p._id != undefined) {
637 | // var addr = p._id + "." + accessory['CurrentTemperature'][t];
638 | // adapter.log.debug('< hap ' + objName + ' get CurrentTemperature for ' + addr);
639 |
640 | if (t !== undefined) {
641 | if (accessory['CurrentTemperature'][t] !== undefined) {
642 | sensor.addService(Service.Thermostat)
643 | .getCharacteristic(Characteristic.CurrentTemperature)
644 | .on('get', function (callback) {
645 | // BUGFIX: If there are multiple Objects, use settings.object._id as correct address
646 | var addr;
647 | if (accessory['CurrentTemperature'][t] == "*") {
648 | addr = settings.object._id;
649 | } else {
650 | addr = p._id + "." + accessory['CurrentTemperature'][t];
651 | }
652 | adapter.log.debug('< hap ' + objName + ' get CurrentTemperature for ' + addr);
653 |
654 | value = parseFloat(states[addr].val);
655 | //adapter.subscribeForeignStates(addr);
656 | if (callback) callback(null, value);
657 | });
658 | var addr = p._id + "." + accessory['CurrentTemperature'][t];
659 | allSensors[addr] = ['Service.Thermostat', 'Characteristic.CurrentTemperature', sensor];
660 | }
661 | if (accessory['TargetTemperature'][t] !== undefined) {
662 | sensor.getService(Service.Thermostat)
663 | .getCharacteristic(Characteristic.TargetTemperature)
664 | .on('get', function (callback) {
665 | var addr = p._id + "." + accessory['TargetTemperature'][t];
666 | adapter.log.debug('< hap ' + objName + ' get TargetTemperature for ' + addr);
667 |
668 | value = parseFloat(states[addr].val);
669 | //adapter.subscribeForeignStates(addr);
670 | if (callback) callback(null, value);
671 | });
672 | var addr = p._id + "." + accessory['TargetTemperature'][t];
673 | allSensors[addr] = ['Service.Thermostat', 'Characteristic.TargetTemperature', sensor];
674 |
675 | sensor.getService(Service.Thermostat)
676 | .getCharacteristic(Characteristic.TargetTemperature)
677 | .on('set', function (value, callback) {
678 | var addr = p._id + "." + accessory['TargetTemperature'][t];
679 | adapter.log.debug('< hap ' + objName + ' get TargetTemperature for ' + addr);
680 |
681 | adapter.setForeignState(addr, {val: value, ack: false});
682 | callback();
683 | });
684 | }
685 |
686 | if (accessory['CurrentRelativeHumidity'][t] !== undefined) {
687 | sensor.getService(Service.Thermostat)
688 | .addCharacteristic(new Characteristic.CurrentRelativeHumidity())
689 | .on('get', function (callback) {
690 | var addr = p._id + "." + accessory['CurrentRelativeHumidity'][t];
691 | adapter.log.debug('< hap ' + objName + ' get CurrentRelativeHumidity for ' + addr);
692 |
693 | value = parseFloat(states[addr].val);
694 | //adapter.subscribeForeignStates(addr);
695 | if (callback) callback(null, value);
696 | });
697 | var addr = p._id + "." + accessory['CurrentRelativeHumidity'][t];
698 | allSensors[addr] = ['Service.Thermostat', 'Characteristic.CurrentRelativeHumidity', sensor];
699 |
700 | }
701 | } else {
702 | var service = sensor.addService(Service.TemperatureSensor);
703 | var char = service.getCharacteristic(Characteristic.CurrentTemperature);
704 | char.setProps({minValue: -100});
705 |
706 | var action = char.on('get', function (callback) {
707 | var addr = object._id;
708 | adapter.log.debug('< hap ' + objName + ' get CurrentTemperature for ' + addr);
709 |
710 | value = parseFloat(states[addr].val);
711 | //adapter.subscribeForeignStates(addr);
712 | if (callback) callback(null, value);
713 | });
714 | var addr = object._id;
715 | allSensors[addr] = ['Service.TemperatureSensor', 'Characteristic.CurrentTemperature', sensor];
716 | }
717 | } else {
718 | var service = sensor.addService(Service.TemperatureSensor);
719 | var char = service.getCharacteristic(Characteristic.CurrentTemperature);
720 | char.setProps({minValue: -100});
721 |
722 | var action = char.on('get', function (callback) {
723 | var addr = object._id;
724 | adapter.log.debug('< hap ' + objName + ' get CurrentTemperature for ' + addr);
725 |
726 | value = parseFloat(states[addr].val);
727 | //adapter.subscribeForeignStates(addr);
728 | if (callback) callback(null, value);
729 | });
730 | var addr = object._id;
731 | allSensors[addr] = ['Service.TemperatureSensor', 'Characteristic.CurrentTemperature', sensor];
732 | }
733 | return sensor;
734 | },
735 | Switch: function createAccessory_Switch(settings) {
736 |
737 | var object = settings.object;
738 | var accessory = settings.accessory;
739 |
740 | var objName = createName(object);
741 | var address = createAddress(object);
742 |
743 | var sensorUUID = uuid.generate('hap-nodejs:accessories:switch:' + address + "_" + objName);
744 | var sensor = new Accessory(objName, sensorUUID);
745 | setInfos(sensor, object.native);
746 |
747 | adapter.log.debug('> iobroker subscribe Switch ' + address );
748 |
749 | sensor.addService(Service.Switch)
750 | .getCharacteristic(Characteristic.On)
751 | .on('get', function (callback) {
752 | var addr;
753 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
754 | if (object && object.native && object.native.PARENT_TYPE != undefined) {
755 | addr = object._id + accessory['State'][object.native.PARENT_TYPE];
756 | } else {
757 | addr = object._id;
758 | }
759 | adapter.log.debug('< hap ' + objName + ' get Switch for ' + addr);
760 |
761 | if (!states[addr]) {
762 | adapter.log.warn('Request for nonexisting state "' + addr + '"!');
763 | if (callback) callback(null, null);
764 | } else {
765 | value = states[addr].val;
766 | if (value === true || value === 0 || value === "0") {
767 | value = true;
768 | } else if (value === false || value === 1 || value === "1") {
769 | value = false;
770 | } else {
771 | value = false;
772 | }
773 |
774 | //adapter.subscribeForeignStates(addr);
775 | if (callback) callback(null, value);
776 | }
777 | });
778 |
779 | sensor.getService(Service.Switch)
780 | .getCharacteristic(Characteristic.On)
781 | .on('change', function(values) {
782 | var addr;
783 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
784 | if (object.native.PARENT_TYPE != undefined) {
785 | addr = object._id + accessory['State'][object.native.PARENT_TYPE];
786 | } else {
787 | addr = object._id;
788 | }
789 | var value;
790 |
791 | // Bugfix: zwave Switch comes with State 0 / 1
792 | var i = parseInt(values.newValue);
793 | if (i === 0) {
794 | value = false;
795 | } else if (i === 1) {
796 | value = true;
797 | } else {
798 | value = values.newValue;
799 | }
800 |
801 | adapter.log.debug("CHANGED: " + addr + " = " + value);
802 | if (values.context !== undefined) {
803 | adapter.setForeignState(addr, {val: value, ack: false});
804 | }
805 | });
806 | var addr;
807 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
808 | if (object && object.native && object.native.PARENT_TYPE != undefined) {
809 | addr = object._id + accessory['State'][object.native.PARENT_TYPE];
810 | } else {
811 | addr = object._id;
812 | }
813 | adapter.log.debug("ADDRESS FOR SWITCH = " + addr);
814 | allSensors[addr] = ['Service.Switch', 'Characteristic.On', sensor];
815 | return sensor;
816 | },
817 | Lightbulb: function createAccessory_Lightbulb(settings) {
818 |
819 | var object = settings.object;
820 | var accessory = settings.accessory;
821 |
822 | var objName = createName(object);
823 | var address = createAddress(object);
824 |
825 | var sensorUUID = uuid.generate('hap-nodejs:accessories:lightbulb:' + address + "_" + objName);
826 | var sensor = new Accessory(objName, sensorUUID);
827 | setInfos(sensor, object.native);
828 |
829 | adapter.log.debug('> iobroker subscribe LightBulb ' + address );
830 |
831 | sensor.addService(Service.Lightbulb)
832 | .getCharacteristic(Characteristic.On)
833 | .on('get', function (callback) {
834 | var addr;
835 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
836 | if (object.native.PARENT_TYPE != undefined) {
837 | addr = object._id + accessory['State'][object.native.PARENT_TYPE];
838 | } else {
839 | addr = object._id;
840 | }
841 | adapter.log.debug('< hap ' + objName + ' get Lightbulb(on) for ' + addr);
842 |
843 | value = states[addr].val;
844 | if (callback) callback(null, value);
845 | });
846 |
847 | sensor.getService(Service.Lightbulb)
848 | .getCharacteristic(Characteristic.On)
849 | .on('change', function(values) {
850 | var addr;
851 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
852 | if (object.native.PARENT_TYPE != undefined) {
853 | addr = object._id + accessory['State'][object.native.PARENT_TYPE];
854 | } else {
855 | addr = object._id;
856 | }
857 | var value;
858 |
859 | // Bugfix: Homematic Dimmer comes with State true / false, convert to 100 / 0
860 | var i = eval(values.newValue);
861 | if (i === true) {
862 | value = 100;
863 | } else if (i === false) {
864 | value = 0;
865 | } else {
866 | value = values.newValue;
867 | }
868 |
869 | adapter.log.debug("CHANGED: " + addr + " = " + value);
870 | if (values.context !== undefined) {
871 | adapter.log.debug("CHANGED: " + addr + " = " + value);
872 | adapter.setForeignState(addr, {val: value, ack: false});
873 | }
874 | });
875 |
876 | sensor.getService(Service.Lightbulb)
877 | .getCharacteristic(Characteristic.Brightness)
878 | .on('get', function(callback) {
879 | var addr;
880 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
881 | if (object.native.PARENT_TYPE != undefined) {
882 | addr = object._id + accessory['State'][object.native.PARENT_TYPE];
883 | } else {
884 | addr = object._id;
885 | }
886 | adapter.log.debug('< hap ' + objName + ' get Lightbulb(brightness) for ' + addr);
887 |
888 | value = states[addr].val;
889 | if (callback) callback(null, value);
890 | });
891 |
892 | sensor.getService(Service.Lightbulb)
893 | .getCharacteristic(Characteristic.Brightness)
894 | .on('change', function(values) {
895 | adapter.log.debug(JSON.stringify(values));
896 |
897 | var value;
898 | value = values.newValue;
899 |
900 | if (values.context !== undefined) {
901 | adapter.setForeignState(addr, {val: value, ack: false});
902 | }
903 | });
904 |
905 | var addr;
906 | // Homematic Switches have PARENT_TYPE e.g. HM-LC-Sw2-FM
907 | if (object.native.PARENT_TYPE != undefined) {
908 | addr = object._id + accessory['State'][object.native.PARENT_TYPE];
909 | } else {
910 | addr = object._id;
911 | }
912 | adapter.log.debug("ADDRESS FOR LIGHTBULB = " + addr);
913 | allSensors[addr] = ['Service.Lightbulb', 'Characteristic.Brightness', sensor];
914 | return sensor;
915 | }
916 | };
917 |
918 | function createAddress(object) {
919 | if (object == undefined) {
920 | return "";
921 | }
922 | var address;
923 | if (object.native !== undefined && object.native.ADDRESS !== undefined) {
924 | address = object.native.ADDRESS;
925 | } else {
926 | address = object._id;
927 | }
928 |
929 | return address;
930 | }
931 |
932 | function createName(object) {
933 | var objName;
934 | if (object.common.name !== undefined && object.common.name !== "") {
935 | objName = object.common.name;
936 | } else {
937 | var root = getRoot(object._id);
938 | var robj = objects[root];
939 | if (robj.common.name !== undefined && robj.common.name !== "") {
940 | objName = robj.common.name;
941 | } else {
942 | objName = object._id;
943 | }
944 | }
945 | return objName;
946 | }
947 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "iobroker.homekit2",
3 | "description": "Apple HomeKit based on HAP-NodeJS",
4 | "version": "0.1.6",
5 | "author": {
6 | "name": "versteckt",
7 | "email": "husky.koglhof@icloud.com"
8 | },
9 | "homepage": "https://github.com/husky-koglhof/ioBroker.homekit",
10 | "license": "CC BY-NC-SA",
11 | "keywords": [
12 | "ioBroker",
13 | "homekit",
14 | "Siri",
15 | "home automation"
16 | ],
17 | "scripts": {
18 | "postinstall": "node postinstall.js"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "git+https://github.com/husky-koglhof/ioBroker.homekit.git"
23 | },
24 | "dependencies": {
25 | "hap-nodejs": "^0.3.2",
26 | "yalm": "^4.0.2",
27 | "yargs": "^4.8.1"
28 | },
29 | "devDependencies": {},
30 | "os": [
31 | "darwin",
32 | "linux"
33 | ],
34 | "bugs": {
35 | "url": "https://github.com/husky-koglhof/ioBroker.homekit/issues"
36 | },
37 | "main": "main.js",
38 | "maintainers": [
39 | {
40 | "name": "versteckt",
41 | "email": "husky.koglhof@icloud.com"
42 | }
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/postinstall.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var walk = function (dir, done) {
3 | var results = [];
4 | fs.readdir(dir, function (err, list) {
5 | if (err) return done(err);
6 | var i = 0;
7 | (function next() {
8 | var file = list[i++];
9 | if (!file) return done(null, results);
10 | file = dir + '/' + file;
11 | fs.stat(file, function (err, stat) {
12 | if (stat && stat.isDirectory()) {
13 | walk(file, function (err, res) {
14 | results = results.concat(res);
15 | next();
16 | });
17 | } else {
18 | results.push(file);
19 | next();
20 | }
21 | });
22 | })();
23 | });
24 | };
25 |
26 | // Check if already persisent store exists. If so, move it to the correct path
27 | var dir = '/persist';
28 | var store = __dirname + '/../../iobroker-data/homekit.0';
29 |
30 | var mkdirSync = function (path) {
31 | try {
32 | fs.mkdirSync(path);
33 | } catch(e) {
34 | if ( e.code !== 'EEXIST' ) console.log(e);
35 | }
36 | };
37 |
38 | walk(dir, function (err, results) {
39 | if (err) {
40 | //console.log(err);
41 | return;
42 | }
43 |
44 | mkdirSync( store );
45 |
46 | for (var f = 0; f < results.length; f++) {
47 | var source = fs.createReadStream(results[f]);
48 | var d = results[f].replace(dir, store);
49 | console.log('--------> ' + d);
50 | var dest = fs.createWriteStream(d);
51 |
52 | source.pipe(dest);
53 | source.on('end', function () { /* copied */
54 | });
55 | source.on('error', function (err) { /* error */
56 | console.log('MOVE ERROR: ' + err);
57 | });
58 | fs.unlinkSync(results[f]);
59 | }
60 | });
61 |
--------------------------------------------------------------------------------