-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
91 lines (75 loc) · 3.18 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
'use strict';
const path = require('path');
let Service, Characteristic;
module.exports = homebridge => {
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
homebridge.registerPlatform('homebridge-klikaanklikuit', 'KlikAanKlikUit', KaKuPlatform);
}
class KaKuPlatform {
constructor(log, config) {
this.log = log = log.bind(log, '[homebridge-klikaanklikuit]');
this.config = config;
// Load driver module.
let driver = config.driver || { type : process.env.H_KAKU_DRIVER || 'rpi' };
try {
let Driver = require( path.resolve(__dirname, 'drivers', driver.type) );
this.log(`using driver '${ driver.type }'`);
// Instantiate driver.
this.driver = new Driver(log, config);
} catch(e) {
throw Error(`Unable to load driver '${ driver.type }': ${ e.message }`);
}
}
accessories(callback) {
return callback( (this.config.accessories || []).map(acc => {
acc.type = acc.type || 'Outlet';
// Validate type.
if (! Service[ acc.type ]) {
throw Error(`Unknown device type '${ acc.type }'`);
}
this.log(`adding ${ acc.type.toLowerCase() } '${ acc.name }' (address = ${ acc.address }, device = ${ acc.device })`);
return new KaKuAccessory(acc, this.driver, this.log);
}) );
}
}
class KaKuAccessory {
constructor(config, driver, log) {
this.name = config.name; // needs to be set
this.service = new Service[config.type](config.name);
let currentValue = null;
this.service.getCharacteristic(Characteristic.On).on('set', (value, callback) => {
// If a device is dimmable, we have to prevent the `on` command to be
// sent successively. Otherwise, the device may end up in dimming mode
// (which we don't want).
if (config.dimmable && value === currentValue) return callback();
currentValue = value;
log(`switching ${ config.type.toLowerCase() } '${ config.name }' (address = ${ config.address }, device = ${ config.device }) ${ value ? 'on' : 'off' }`);
driver.switch(config.address, config.device, value);
return callback();
});
if (config.dimmable) {
if (typeof config.address === 'number') {
let previousLevel = -1;
this.service.getCharacteristic(Characteristic.Brightness).on('set', (level, callback) => {
// Convert 0-100 (Homekit) to 0-15 (Kaku).
level = Math.ceil((level / 100) * 15);
// If the previously set level is the same as the new level, don't perform the operation
// (setting the same value twice seems to turn off the device).
if (level === previousLevel) return callback();
previousLevel = level;
// Dim the device.
log(`dimming ${ config.type.toLowerCase() } '${ config.name }' (address = ${ config.address }, device = ${ config.device }) to level ${ level }`);
driver.dim(config.address, config.device, level);
// Done.
return callback();
});
} else {
log(`[WARNING] old-style devices cannot be dimmed, please adjust your configuration for device '${ this.name }'`);
}
}
}
getServices() {
return [ this.service ];
}
}