homebridge-unifi-access 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE.md +3 -3
  2. package/README.md +88 -3
  3. package/config.schema.json +202 -0
  4. package/dist/access-controller.d.ts +45 -0
  5. package/dist/access-controller.js +387 -0
  6. package/dist/access-controller.js.map +1 -0
  7. package/dist/access-device.d.ts +53 -0
  8. package/dist/access-device.js +362 -0
  9. package/dist/access-device.js.map +1 -0
  10. package/dist/access-events.d.ts +24 -0
  11. package/dist/access-events.js +151 -0
  12. package/dist/access-events.js.map +1 -0
  13. package/dist/access-hub.d.ts +21 -0
  14. package/dist/access-hub.js +269 -0
  15. package/dist/access-hub.js.map +1 -0
  16. package/dist/access-mqtt.d.ts +20 -0
  17. package/dist/access-mqtt.js +163 -0
  18. package/dist/access-mqtt.js.map +1 -0
  19. package/dist/access-options.d.ts +38 -0
  20. package/dist/access-options.js +167 -0
  21. package/dist/access-options.js.map +1 -0
  22. package/dist/access-platform.d.ts +16 -0
  23. package/dist/access-platform.js +103 -0
  24. package/dist/access-platform.js.map +1 -0
  25. package/dist/access-types.d.ts +11 -0
  26. package/dist/access-types.js +13 -0
  27. package/dist/access-types.js.map +1 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.js +9 -5
  30. package/dist/index.js.map +1 -1
  31. package/dist/settings.d.ts +10 -0
  32. package/dist/settings.js +23 -10
  33. package/dist/settings.js.map +1 -1
  34. package/homebridge-ui/public/access-featureoptions.mjs +748 -0
  35. package/homebridge-ui/public/index.html +151 -0
  36. package/homebridge-ui/public/lib/featureoptions.mjs +201 -0
  37. package/homebridge-ui/public/ui.mjs +182 -0
  38. package/homebridge-ui/server.js +153 -0
  39. package/package.json +55 -23
  40. package/.eslintrc.json +0 -45
  41. package/dist/platform.js +0 -98
  42. package/dist/platform.js.map +0 -1
  43. package/dist/platformAccessory.js +0 -104
  44. package/dist/platformAccessory.js.map +0 -1
  45. package/src/index.ts +0 -11
  46. package/src/platform.ts +0 -116
  47. package/src/platformAccessory.ts +0 -130
  48. package/src/settings.ts +0 -9
  49. package/tsconfig.json +0 -20
@@ -0,0 +1,362 @@
1
+ /* Copyright(C) 2017-2024, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * access-device.ts: Base class for all UniFi Access devices.
4
+ */
5
+ import { ACCESS_MOTION_DURATION, ACCESS_OCCUPANCY_DURATION } from "./settings.js";
6
+ import { AccessReservedNames } from "./access-types.js";
7
+ import { getOptionFloat, getOptionNumber, getOptionValue, isOptionEnabled } from "./access-options.js";
8
+ import util from "node:util";
9
+ export class AccessBase {
10
+ api;
11
+ debug;
12
+ hap;
13
+ log;
14
+ controller;
15
+ udaApi;
16
+ platform;
17
+ // The constructor initializes key variables and calls configureDevice().
18
+ constructor(controller) {
19
+ this.api = controller.platform.api;
20
+ this.debug = controller.platform.debug.bind(this);
21
+ this.hap = this.api.hap;
22
+ this.controller = controller;
23
+ this.udaApi = controller.udaApi;
24
+ this.platform = controller.platform;
25
+ this.log = {
26
+ debug: (message, ...parameters) => controller.platform.debug(util.format(this.name + ": " + message, ...parameters)),
27
+ error: (message, ...parameters) => controller.platform.log.error(util.format(this.name + ": " + message, ...parameters)),
28
+ info: (message, ...parameters) => controller.platform.log.info(util.format(this.name + ": " + message, ...parameters)),
29
+ warn: (message, ...parameters) => controller.platform.log.warn(util.format(this.name + ": " + message, ...parameters))
30
+ };
31
+ }
32
+ // Configure the device information for HomeKit.
33
+ setInfo(accessory, device) {
34
+ // If we don't have a device, we're done.
35
+ if (!device) {
36
+ return false;
37
+ }
38
+ // Update the manufacturer information for this device.
39
+ accessory.getService(this.hap.Service.AccessoryInformation)?.updateCharacteristic(this.hap.Characteristic.Manufacturer, "Ubiquiti Inc.");
40
+ // Update the model information for this device.
41
+ let deviceModel = device.display_model;
42
+ if ("model" in device) {
43
+ deviceModel = device.model;
44
+ }
45
+ if (deviceModel.length) {
46
+ accessory.getService(this.hap.Service.AccessoryInformation)?.updateCharacteristic(this.hap.Characteristic.Model, deviceModel);
47
+ }
48
+ // Update the serial number for this device.
49
+ if (device.mac?.length) {
50
+ accessory.getService(this.hap.Service.AccessoryInformation)?.updateCharacteristic(this.hap.Characteristic.SerialNumber, device.mac.replace(/:/g, "").toUpperCase());
51
+ }
52
+ // Update the firmware revision for this device.
53
+ if (device.firmware?.length) {
54
+ accessory.getService(this.hap.Service.AccessoryInformation)?.updateCharacteristic(this.hap.Characteristic.FirmwareRevision, device.firmware);
55
+ }
56
+ return true;
57
+ }
58
+ // Utility function to return the fully enumerated name of this device.
59
+ get name() {
60
+ return this.controller.udaApi.name;
61
+ }
62
+ }
63
+ export class AccessDevice extends AccessBase {
64
+ accessory;
65
+ hints;
66
+ listeners;
67
+ // The constructor initializes key variables and calls configureDevice().
68
+ constructor(controller, accessory) {
69
+ // Call the constructor of our base class.
70
+ super(controller);
71
+ this.hints = {};
72
+ this.listeners = {};
73
+ // Set the accessory, if we have it. Otherwise, we expect configureDevice to assign it.
74
+ if (accessory) {
75
+ this.accessory = accessory;
76
+ }
77
+ }
78
+ // Configure device-specific settings.
79
+ configureHints() {
80
+ this.hints.logMotion = this.hasFeature("Log.Motion");
81
+ this.hints.motionDuration = this.getFeatureNumber("Motion.Duration") ?? ACCESS_MOTION_DURATION;
82
+ this.hints.occupancyDuration = this.getFeatureNumber("Motion.OccupancySensor.Duration") ?? ACCESS_OCCUPANCY_DURATION;
83
+ this.hints.syncName = this.hasFeature("Device.SyncName");
84
+ // Sanity check motion detection duration. Make sure it's never less than 2 seconds so we can actually alert the user.
85
+ if (this.hints.motionDuration < 2) {
86
+ this.hints.motionDuration = 2;
87
+ }
88
+ // Sanity check occupancy detection duration. Make sure it's never less than 60 seconds so we can actually alert the user.
89
+ if (this.hints.occupancyDuration < 60) {
90
+ this.hints.occupancyDuration = 60;
91
+ }
92
+ // Inform the user if we've opted for something other than the defaults.
93
+ if (this.hints.syncName) {
94
+ this.log.info("Syncing Access device name to HomeKit.");
95
+ }
96
+ if (this.hints.motionDuration !== ACCESS_MOTION_DURATION) {
97
+ this.log.info("Motion event duration set to %s seconds.", this.hints.motionDuration);
98
+ }
99
+ if (this.hints.occupancyDuration !== ACCESS_OCCUPANCY_DURATION) {
100
+ this.log.info("Occupancy event duration set to %s seconds.", this.hints.occupancyDuration);
101
+ }
102
+ return true;
103
+ }
104
+ // Configure the device information details for HomeKit.
105
+ configureInfo() {
106
+ // Sync the Access name with HomeKit, if configured.
107
+ if (this.hints.syncName) {
108
+ this.accessoryName = this.uda.name;
109
+ }
110
+ return this.setInfo(this.accessory, this.uda);
111
+ }
112
+ // Cleanup our event handlers and any other activities as needed.
113
+ cleanup() {
114
+ for (const eventName of Object.keys(this.listeners)) {
115
+ this.controller.events.removeListener(eventName, this.listeners[eventName]);
116
+ delete this.listeners[eventName];
117
+ }
118
+ }
119
+ // Configure the Access motion sensor for HomeKit.
120
+ configureMotionSensor(isEnabled = true, isInitialized = false) {
121
+ // Find the motion sensor service, if it exists.
122
+ let motionService = this.accessory.getService(this.hap.Service.MotionSensor);
123
+ // Have we disabled the motion sensor?
124
+ if (!isEnabled) {
125
+ if (motionService) {
126
+ this.accessory.removeService(motionService);
127
+ this.controller.mqtt?.unsubscribe(this.id, "motion/trigger");
128
+ this.log.info("Disabling motion sensor.");
129
+ }
130
+ this.configureMotionSwitch(isEnabled);
131
+ this.configureMotionTrigger(isEnabled);
132
+ return false;
133
+ }
134
+ // We don't have a motion sensor, let's add it to the device.
135
+ if (!motionService) {
136
+ // We don't have it, add the motion sensor to the device.
137
+ motionService = new this.hap.Service.MotionSensor(this.accessoryName);
138
+ if (!motionService) {
139
+ this.log.error("Unable to add motion sensor.");
140
+ return false;
141
+ }
142
+ this.accessory.addService(motionService);
143
+ isInitialized = false;
144
+ this.log.info("Enabling motion sensor.");
145
+ }
146
+ // Have we previously initialized this sensor? We assume not by default, but this allows for scenarios where you may be dynamically reconfiguring a sensor at
147
+ // runtime (e.g. UniFi sensors can be reconfigured for various sensor modes in realtime).
148
+ if (!isInitialized) {
149
+ // Initialize the state of the motion sensor.
150
+ motionService.displayName = this.accessoryName;
151
+ motionService.updateCharacteristic(this.hap.Characteristic.Name, this.accessoryName);
152
+ motionService.updateCharacteristic(this.hap.Characteristic.MotionDetected, false);
153
+ motionService.updateCharacteristic(this.hap.Characteristic.StatusActive, this.isOnline);
154
+ motionService.getCharacteristic(this.hap.Characteristic.StatusActive).onGet(() => {
155
+ return this.isOnline;
156
+ });
157
+ // Configure our MQTT support.
158
+ this.configureMqttMotionTrigger();
159
+ // Configure any motion switches or triggers the user may have enabled or disabled.
160
+ this.configureMotionSwitch(isEnabled);
161
+ this.configureMotionTrigger(isEnabled);
162
+ }
163
+ return true;
164
+ }
165
+ // Configure a switch to easily activate or deactivate motion sensor detection for HomeKit.
166
+ configureMotionSwitch(isEnabled = true) {
167
+ // Find the switch service, if it exists.
168
+ let switchService = this.accessory.getServiceById(this.hap.Service.Switch, AccessReservedNames.SWITCH_MOTION_SENSOR);
169
+ // Motion switches are disabled by default unless the user enables them.
170
+ if (!isEnabled || !this.hasFeature("Motion.Switch")) {
171
+ if (switchService) {
172
+ this.accessory.removeService(switchService);
173
+ }
174
+ // If we disable the switch, make sure we fully reset it's state. Otherwise, we can end up in a situation (e.g. liveview switches) where we have
175
+ // disabled motion detection with no meaningful way to enable it again.
176
+ this.accessory.context.detectMotion = true;
177
+ return false;
178
+ }
179
+ this.log.info("Enabling motion sensor switch.");
180
+ const switchName = this.accessoryName + " Motion Events";
181
+ // Add the switch to the device, if needed.
182
+ if (!switchService) {
183
+ switchService = new this.hap.Service.Switch(switchName, AccessReservedNames.SWITCH_MOTION_SENSOR);
184
+ if (!switchService) {
185
+ this.log.error("Unable to add motion sensor switch.");
186
+ return false;
187
+ }
188
+ switchService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName);
189
+ this.accessory.addService(switchService);
190
+ }
191
+ // Activate or deactivate motion detection.
192
+ switchService.getCharacteristic(this.hap.Characteristic.On)?.onGet(() => {
193
+ return this.accessory.context.detectMotion === true;
194
+ });
195
+ switchService.getCharacteristic(this.hap.Characteristic.On)?.onSet((value) => {
196
+ if (this.accessory.context.detectMotion !== value) {
197
+ this.log.info("Motion detection %s.", (value === true) ? "enabled" : "disabled");
198
+ }
199
+ this.accessory.context.detectMotion = value === true;
200
+ });
201
+ // Initialize the switch state.
202
+ if (!("detectMotion" in this.accessory.context)) {
203
+ this.accessory.context.detectMotion = true;
204
+ }
205
+ switchService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, switchName);
206
+ switchService.updateCharacteristic(this.hap.Characteristic.On, this.accessory.context.detectMotion);
207
+ return true;
208
+ }
209
+ // Configure a switch to manually trigger a motion sensor event for HomeKit.
210
+ configureMotionTrigger(isEnabled = true) {
211
+ // Find the switch service, if it exists.
212
+ let triggerService = this.accessory.getServiceById(this.hap.Service.Switch, AccessReservedNames.SWITCH_MOTION_TRIGGER);
213
+ // Motion triggers are disabled by default and primarily exist for automation purposes.
214
+ if (!isEnabled || !this.hasFeature("Motion.Trigger")) {
215
+ if (triggerService) {
216
+ this.accessory.removeService(triggerService);
217
+ }
218
+ return false;
219
+ }
220
+ const triggerName = this.accessoryName + " Motion Trigger";
221
+ // Add the switch to the device, if needed.
222
+ if (!triggerService) {
223
+ triggerService = new this.hap.Service.Switch(triggerName, AccessReservedNames.SWITCH_MOTION_TRIGGER);
224
+ if (!triggerService) {
225
+ this.log.error("Unable to add motion sensor trigger.");
226
+ return false;
227
+ }
228
+ triggerService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName);
229
+ this.accessory.addService(triggerService);
230
+ }
231
+ const motionService = this.accessory.getService(this.hap.Service.MotionSensor);
232
+ const switchService = this.accessory.getServiceById(this.hap.Service.Switch, AccessReservedNames.SWITCH_MOTION_SENSOR);
233
+ // Activate or deactivate motion detection.
234
+ triggerService.getCharacteristic(this.hap.Characteristic.On)?.onGet(() => {
235
+ return motionService?.getCharacteristic(this.hap.Characteristic.MotionDetected).value === true;
236
+ });
237
+ triggerService.getCharacteristic(this.hap.Characteristic.On)?.onSet((isOn) => {
238
+ if (isOn) {
239
+ // Check to see if motion events are disabled.
240
+ if (switchService && !switchService.getCharacteristic(this.hap.Characteristic.On).value) {
241
+ setTimeout(() => {
242
+ triggerService?.updateCharacteristic(this.hap.Characteristic.On, false);
243
+ }, 50);
244
+ }
245
+ else {
246
+ // Trigger the motion event.
247
+ this.controller.events.motionEventHandler(this);
248
+ // Inform the user.
249
+ this.log.info("Motion event triggered.");
250
+ }
251
+ return;
252
+ }
253
+ // If the motion sensor is still on, we should be as well.
254
+ if (motionService?.getCharacteristic(this.hap.Characteristic.MotionDetected).value) {
255
+ setTimeout(() => {
256
+ triggerService?.updateCharacteristic(this.hap.Characteristic.On, true);
257
+ }, 50);
258
+ }
259
+ });
260
+ // Initialize the switch.
261
+ triggerService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, triggerName);
262
+ triggerService.updateCharacteristic(this.hap.Characteristic.On, false);
263
+ this.log.info("Enabling motion sensor automation trigger.");
264
+ return true;
265
+ }
266
+ // Configure MQTT motion triggers.
267
+ configureMqttMotionTrigger() {
268
+ // Trigger a motion event in MQTT, if requested to do so.
269
+ this.controller.mqtt?.subscribe(this.id, "motion/trigger", (message) => {
270
+ const value = message.toString();
271
+ // When we get the right message, we trigger the motion event.
272
+ if (value?.toLowerCase() !== "true") {
273
+ return;
274
+ }
275
+ // Trigger the motion event.
276
+ this.controller.events.motionEventHandler(this);
277
+ this.log.info("Motion event triggered via MQTT.");
278
+ });
279
+ return true;
280
+ }
281
+ // Configure the Access occupancy sensor for HomeKit.
282
+ configureOccupancySensor(isEnabled = true, isInitialized = false) {
283
+ // Find the occupancy sensor service, if it exists.
284
+ let occupancyService = this.accessory.getService(this.hap.Service.OccupancySensor);
285
+ // Occupancy sensors are disabled by default and primarily exist for automation purposes.
286
+ if (!isEnabled || !this.hasFeature("Motion.OccupancySensor")) {
287
+ if (occupancyService) {
288
+ this.accessory.removeService(occupancyService);
289
+ this.log.info("Disabling occupancy sensor.");
290
+ }
291
+ return false;
292
+ }
293
+ // We don't have an occupancy sensor, let's add it to the device.
294
+ if (!occupancyService) {
295
+ // We don't have it, add the occupancy sensor to the device.
296
+ occupancyService = new this.hap.Service.OccupancySensor(this.accessoryName);
297
+ if (!occupancyService) {
298
+ this.log.error("Unable to add occupancy sensor.");
299
+ return false;
300
+ }
301
+ this.accessory.addService(occupancyService);
302
+ }
303
+ // Have we previously initialized this sensor? We assume not by default, but this allows for scenarios where you may be dynamically reconfiguring a sensor at
304
+ // runtime (e.g. UniFi sensors can be reconfigured for various sensor modes in realtime).
305
+ if (!isInitialized) {
306
+ // Initialize the state of the occupancy sensor.
307
+ occupancyService.updateCharacteristic(this.hap.Characteristic.OccupancyDetected, false);
308
+ occupancyService.updateCharacteristic(this.hap.Characteristic.StatusActive, this.isOnline);
309
+ occupancyService.getCharacteristic(this.hap.Characteristic.StatusActive).onGet(() => {
310
+ return this.isOnline;
311
+ });
312
+ this.log.info("Enabling occupancy sensor.");
313
+ }
314
+ return true;
315
+ }
316
+ // Utility function to return a floating point configuration parameter on a device.
317
+ getFeatureFloat(option) {
318
+ return getOptionFloat(this.getFeatureValue(option));
319
+ }
320
+ // Utility function to return an integer configuration parameter on a device.
321
+ getFeatureNumber(option) {
322
+ return getOptionNumber(this.getFeatureValue(option));
323
+ }
324
+ // Utility function to return a configuration parameter on a device.
325
+ getFeatureValue(option) {
326
+ return getOptionValue(this.platform.featureOptions, this.controller.uda, this.uda, option);
327
+ }
328
+ // Utility for checking feature options on a device.
329
+ hasFeature(option, defaultReturnValue) {
330
+ return isOptionEnabled(this.platform.featureOptions, this.controller.uda, this.uda, option, defaultReturnValue ?? this.platform.featureOptionDefault(option));
331
+ }
332
+ // Utility function for reserved identifiers for switches.
333
+ isReservedName(name) {
334
+ return name === undefined ? false : Object.values(AccessReservedNames).map(x => x.toUpperCase()).includes(name.toUpperCase());
335
+ }
336
+ // Utility function to determine whether or not a device is currently online.
337
+ get isOnline() {
338
+ return this.uda.is_online;
339
+ }
340
+ // Return a unique identifier for an Access device.
341
+ get id() {
342
+ return this.uda.mac.replace(/:/g, "");
343
+ }
344
+ // Utility function to return the fully enumerated name of this device.
345
+ get name() {
346
+ return this.controller.udaApi.getFullName(this.uda);
347
+ }
348
+ // Utility function to return the current accessory name of this device.
349
+ get accessoryName() {
350
+ return this.accessory.getService(this.hap.Service.AccessoryInformation)?.getCharacteristic(this.hap.Characteristic.Name).value ??
351
+ (this.uda?.name ?? "Unknown");
352
+ }
353
+ // Utility function to set the current accessory name of this device.
354
+ set accessoryName(name) {
355
+ // Set all the internally managed names within Homebridge to the new accessory name.
356
+ this.accessory.displayName = name;
357
+ this.accessory._associatedHAPAccessory.displayName = name;
358
+ // Set all the HomeKit-visible names.
359
+ this.accessory.getService(this.hap.Service.AccessoryInformation)?.updateCharacteristic(this.hap.Characteristic.Name, name);
360
+ }
361
+ }
362
+ //# sourceMappingURL=access-device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-device.js","sourceRoot":"","sources":["../src/access-device.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /// <reference types="node" />
2
+ import { AccessController } from "./access-controller.js";
3
+ import { AccessDevice } from "./access-device.js";
4
+ import { EventEmitter } from "node:events";
5
+ export declare class AccessEvents extends EventEmitter {
6
+ private api;
7
+ private controller;
8
+ private eventsHandler;
9
+ private readonly eventTimers;
10
+ private hap;
11
+ private log;
12
+ private mqttPublishTelemetry;
13
+ private platform;
14
+ private udaApi;
15
+ private udaDeviceState;
16
+ private udaUpdatesHandler;
17
+ private unsupportedDevices;
18
+ constructor(controller: AccessController);
19
+ private udaUpdates;
20
+ private manageDevices;
21
+ private configureEvents;
22
+ motionEventHandler(accessDevice: AccessDevice): void;
23
+ private motionEventDelivery;
24
+ }
@@ -0,0 +1,151 @@
1
+ import { AccessReservedNames } from "./access-types.js";
2
+ import { EventEmitter } from "node:events";
3
+ export class AccessEvents extends EventEmitter {
4
+ api;
5
+ controller;
6
+ eventsHandler;
7
+ eventTimers;
8
+ hap;
9
+ log;
10
+ mqttPublishTelemetry;
11
+ platform;
12
+ udaApi;
13
+ udaDeviceState;
14
+ udaUpdatesHandler;
15
+ unsupportedDevices;
16
+ // Initialize an instance of our Access events handler.
17
+ constructor(controller) {
18
+ super();
19
+ this.api = controller.platform.api;
20
+ this.eventTimers = {};
21
+ this.hap = controller.platform.api.hap;
22
+ this.log = controller.log;
23
+ this.mqttPublishTelemetry = controller.hasFeature("Controller.Publish.Telemetry");
24
+ this.controller = controller;
25
+ this.udaApi = controller.udaApi;
26
+ this.udaDeviceState = {};
27
+ this.platform = controller.platform;
28
+ this.unsupportedDevices = {};
29
+ this.eventsHandler = null;
30
+ this.udaUpdatesHandler = null;
31
+ // If we've enabled telemetry from the controller inform the user.
32
+ if (this.mqttPublishTelemetry) {
33
+ this.log.info("Access controller telemetry enabled.");
34
+ }
35
+ this.configureEvents();
36
+ }
37
+ // Process Access API update events.
38
+ udaUpdates(packet) {
39
+ let accessDevice;
40
+ switch (packet.data.device_type) {
41
+ case "UAH":
42
+ default:
43
+ // Lookup the device.
44
+ accessDevice = this.controller.deviceLookup(packet.event_object_id);
45
+ // No device found, we're done.
46
+ if (!accessDevice) {
47
+ break;
48
+ }
49
+ // Update our device configuration state.
50
+ accessDevice.uda = packet.data;
51
+ // If we have services on the accessory associated with the Access device that have a StatusActive characteristic set, update our availability state.
52
+ accessDevice.accessory.services.filter(x => x.testCharacteristic(this.hap.Characteristic.StatusActive))
53
+ ?.map(x => x.updateCharacteristic(this.hap.Characteristic.StatusActive, accessDevice?.uda.is_online === true));
54
+ // Sync names, if configured to do so.
55
+ if (accessDevice.hints.syncName && accessDevice.name !== accessDevice.uda.name) {
56
+ accessDevice.log.info("Name change detected. A restart of Homebridge may be needed in order to complete name synchronization with HomeKit.");
57
+ accessDevice.configureInfo();
58
+ }
59
+ break;
60
+ }
61
+ // Update the internal list we maintain.
62
+ this.udaDeviceState[packet.event_object_id] = packet.data;
63
+ }
64
+ // Process device additions and removals from the Access events API.
65
+ manageDevices(packet) {
66
+ // Lookup the device.
67
+ const accessDevice = this.controller.deviceLookup(packet.event_object_id);
68
+ // We're unadopting.
69
+ if (packet.event === "access.data.device.delete") {
70
+ // If it's already gone, we're done.
71
+ if (!accessDevice) {
72
+ return;
73
+ }
74
+ // Remove the device.
75
+ this.controller.removeHomeKitDevice(accessDevice);
76
+ return;
77
+ }
78
+ }
79
+ // Listen to the UniFi Access events API for updates we are interested in (e.g. unlock).
80
+ configureEvents() {
81
+ // Only configure the event listener if it exists and it's not already configured.
82
+ if (this.eventsHandler && this.udaUpdatesHandler) {
83
+ return true;
84
+ }
85
+ // Ensure we update our UDA state before we process any other events.
86
+ this.prependListener("access.data.device.update", this.udaUpdatesHandler = this.udaUpdates.bind(this));
87
+ // Process remove events.
88
+ this.prependListener("access.data.device.delete", this.manageDevices.bind(this));
89
+ // Listen for any messages coming in from our listener. We route events to the appropriate handlers based on the type of event that comes across.
90
+ this.udaApi.on("message", this.eventsHandler = (packet) => {
91
+ // Emit messages based on the event type.
92
+ this.emit(packet.event, packet);
93
+ // Emit messages based on the specific device.
94
+ this.emit(packet.event_object_id, packet);
95
+ // Finally, emit messages based on the specific event and device combination.
96
+ this.emit(packet.event + "." + packet.event_object_id, packet);
97
+ // If enabled, publish all the event traffic coming from the Access controller to MQTT.
98
+ if (this.mqttPublishTelemetry) {
99
+ this.controller.mqtt?.publish(this.controller.uda.host.mac, "telemetry", JSON.stringify(packet));
100
+ }
101
+ });
102
+ return true;
103
+ }
104
+ // Motion event processing from UniFi Access.
105
+ motionEventHandler(accessDevice) {
106
+ if (!accessDevice) {
107
+ return;
108
+ }
109
+ // Only notify the user if we have a motion sensor and it's active.
110
+ const motionService = accessDevice.accessory.getService(this.hap.Service.MotionSensor);
111
+ if (motionService) {
112
+ this.motionEventDelivery(accessDevice, motionService);
113
+ }
114
+ }
115
+ // Motion event delivery to HomeKit.
116
+ motionEventDelivery(accessDevice, motionService) {
117
+ if (!accessDevice) {
118
+ return;
119
+ }
120
+ // If we have disabled motion events, we're done here.
121
+ if (("detectMotion" in accessDevice.accessory.context) && !accessDevice.accessory.context.detectMotion) {
122
+ return;
123
+ }
124
+ // If we have an active motion event inflight, we're done.
125
+ if (this.eventTimers[accessDevice.id]) {
126
+ return;
127
+ }
128
+ // Trigger the motion event in HomeKit.
129
+ motionService.updateCharacteristic(this.hap.Characteristic.MotionDetected, true);
130
+ // If we have a motion trigger switch configured, update it.
131
+ accessDevice.accessory.getServiceById(this.hap.Service.Switch, AccessReservedNames.SWITCH_MOTION_TRIGGER)?.updateCharacteristic(this.hap.Characteristic.On, true);
132
+ // Publish the motion event to MQTT, if the user has configured it.
133
+ this.controller.mqtt?.publish(accessDevice.accessory, "motion", "true");
134
+ // Log the event, if configured to do so.
135
+ if (accessDevice.hints.logMotion) {
136
+ accessDevice.log.info("Motion detected.");
137
+ }
138
+ // Reset our motion event after motionDuration.
139
+ this.eventTimers[accessDevice.id] = setTimeout(() => {
140
+ motionService.updateCharacteristic(this.hap.Characteristic.MotionDetected, false);
141
+ // If we have a motion trigger switch configured, update it.
142
+ accessDevice.accessory.getServiceById(this.hap.Service.Switch, AccessReservedNames.SWITCH_MOTION_TRIGGER)?.updateCharacteristic(this.hap.Characteristic.On, false);
143
+ accessDevice.log.debug("Resetting motion event.");
144
+ // Publish to MQTT, if the user has configured it.
145
+ this.controller.mqtt?.publish(accessDevice.accessory, "motion", "false");
146
+ // Delete the timer from our motion event tracker.
147
+ delete this.eventTimers[accessDevice.id];
148
+ }, accessDevice.hints.motionDuration * 1000);
149
+ }
150
+ }
151
+ //# sourceMappingURL=access-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-events.js","sourceRoot":"","sources":["../src/access-events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { AccessDeviceConfig } from "unifi-access";
2
+ import { PlatformAccessory } from "homebridge";
3
+ import { AccessController } from "./access-controller.js";
4
+ import { AccessDevice } from "./access-device.js";
5
+ export declare class AccessHub extends AccessDevice {
6
+ private _hkLockState;
7
+ private doorbellRingRequestId;
8
+ private lockDelayInterval;
9
+ uda: AccessDeviceConfig;
10
+ constructor(controller: AccessController, device: AccessDeviceConfig, accessory: PlatformAccessory);
11
+ protected configureHints(): boolean;
12
+ private configureDevice;
13
+ private configureLock;
14
+ private configureDoorbell;
15
+ private configureDoorbellTrigger;
16
+ private configureMqtt;
17
+ private get hkLockState();
18
+ private set hkLockState(value);
19
+ private get hubLockState();
20
+ private eventHandler;
21
+ }