forked from michbeck100/pimatic-hap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhap.coffee
149 lines (122 loc) · 4.88 KB
/
hap.coffee
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# activate HAP-NodeJS logging
process.env['DEBUG'] = 'HAPServer,Accessory,EventedHttpServer'
module.exports = (env) =>
#import accessories
ButtonAccessory = require('./accessories/button')(env)
ContactAccessory = require('./accessories/contact')(env)
DimmerAccessory = require('./accessories/dimmer')(env)
GenericAccessory = require('./accessories/genericsensor')(env)
HueLightAccessory = require('./accessories/hue')(env)
LightbulbAccessory = require('./accessories/lightbulb')(env)
LedLightAccessory = require('./accessories/ledlight')(env)
MotionAccessory = require('./accessories/motion')(env)
PowerSwitchAccessory = require('./accessories/powerswitch')(env)
ShutterAccessory = require('./accessories/shutter')(env)
ThermostatAccessory = require('./accessories/thermostat')(env)
crypto = env.require 'crypto'
path = require 'path'
hap = require 'hap-nodejs'
Bridge = hap.Bridge
Accessory = hap.Accessory
Service = hap.Service
Characteristic = hap.Characteristic
uuid = require ('hap-nodejs/lib/util/uuid')
_ = require 'lodash'
# bind hap-nodejs' debug logging to pimatic logger
Debug = require ('hap-nodejs/node_modules/debug')
Debug.log = env.logger.debug.bind(env.logger)
Debug.formatArgs = () => arguments
class HapPlugin extends env.plugins.Plugin
knownTemplates: {
'buttons': ButtonAccessory
'dimmer': DimmerAccessory
'huezllonoff': LightbulbAccessory
'huezlldimmable': DimmerAccessory
'huezllcolortemp': DimmerAccessory
'huezllcolor': HueLightAccessory
'huezllextendedcolor': HueLightAccessory
'maxcul-heating-thermostat': ThermostatAccessory
'milight-cwww': LightbulbAccessory
'milight-rgb': DimmerAccessory
'milight-rgbw': DimmerAccessory
'switch': PowerSwitchAccessory
'shutter': ShutterAccessory
'temperature': GenericAccessory
'contact': ContactAccessory
'thermostat': ThermostatAccessory
'led-light': LedLightAccessory
'presence': MotionAccessory
}
init: (app, @framework, @config) =>
env.logger.info("Starting homekit bridge")
hap.init(path.resolve @framework.maindir, '../../hap-database')
bridge = new Bridge(@config.name, uuid.generate(@config.name))
bridge.on 'identify', (paired, callback) =>
env.logger.debug(@config.name + " identify")
callback()
@framework.on 'deviceAdded', (device) =>
accessory = @createAccessoryFromTemplate(device)
if accessory? && !accessory.exclude()
bridge.addBridgedAccessory(accessory)
env.logger.debug("successfully added device " + device.name)
@framework.once "after init", =>
# publish homekit bridge
env.logger.debug("publishing homekit bridge on port " + @config.port)
env.logger.debug("pincode is: " + @config.pincode)
bridge.publish({
username: @generateUniqueUsername(bridge.displayName),
port: @config.port,
pincode: @config.pincode,
category: Accessory.Categories.BRIDGE
})
@framework.deviceManager.deviceConfigExtensions.push(new HapConfigExtension())
generateUniqueUsername: (name) =>
shasum = crypto.createHash('sha1')
shasum.update(name)
hash = shasum.digest('hex')
return "" +
hash[0] + hash[1] + ':' +
hash[2] + hash[3] + ':' +
hash[4] + hash[5] + ':' +
hash[6] + hash[7] + ':' +
hash[8] + hash[9] + ':' +
hash[10] + hash[11]
createAccessoryFromTemplate: (device) =>
if @isKnownDevice(device)
# ButtonsDevice must not have more than one button
if device.template is "buttons" and device.config.buttons.length != 1 then return null
return new @knownTemplates[device.template](device)
else if @hasSupportedAttribute(device)
return new GenericAccessory(device)
else
env.logger.debug("unsupported device type: " + device.constructor.name)
return null
isKnownDevice: (device) =>
return device.template of @knownTemplates
hasSupportedAttribute: (device) =>
for attr in GenericAccessory.supportedAttributes
if device.hasAttribute(attr)
return true
return false
class HapConfigExtension
configSchema:
hap:
type: "object"
properties:
service:
description: "The homekit service to be used for this device"
type: "string"
enum: ["Lightbulb", "Switch"]
required: false
exclude:
description: "Whether to exclude this device from being bridged"
type: "boolean"
default: false
extendConfigShema: (schema) ->
for name, def of @configSchema
schema.properties[name] = _.cloneDeep(def)
applicable: (schema) ->
return yes
apply: (config, device) -> # do nothing here
plugin = new HapPlugin()
return plugin