homebridge-nest-accfactory 0.0.4-a

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 (88) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +176 -0
  3. package/README.md +121 -0
  4. package/config.schema.json +107 -0
  5. package/dist/HomeKitDevice.js +441 -0
  6. package/dist/HomeKitHistory.js +2835 -0
  7. package/dist/camera.js +1276 -0
  8. package/dist/doorbell.js +122 -0
  9. package/dist/index.js +35 -0
  10. package/dist/nexustalk.js +741 -0
  11. package/dist/protect.js +240 -0
  12. package/dist/protobuf/google/rpc/status.proto +91 -0
  13. package/dist/protobuf/google/rpc/stream_body.proto +26 -0
  14. package/dist/protobuf/google/trait/product/camera.proto +53 -0
  15. package/dist/protobuf/googlehome/foyer.proto +208 -0
  16. package/dist/protobuf/nest/messages.proto +8 -0
  17. package/dist/protobuf/nest/services/apigateway.proto +107 -0
  18. package/dist/protobuf/nest/trait/audio.proto +7 -0
  19. package/dist/protobuf/nest/trait/cellular.proto +313 -0
  20. package/dist/protobuf/nest/trait/debug.proto +37 -0
  21. package/dist/protobuf/nest/trait/detector.proto +41 -0
  22. package/dist/protobuf/nest/trait/diagnostics.proto +87 -0
  23. package/dist/protobuf/nest/trait/firmware.proto +221 -0
  24. package/dist/protobuf/nest/trait/guest.proto +105 -0
  25. package/dist/protobuf/nest/trait/history.proto +345 -0
  26. package/dist/protobuf/nest/trait/humanlibrary.proto +19 -0
  27. package/dist/protobuf/nest/trait/hvac.proto +1353 -0
  28. package/dist/protobuf/nest/trait/input.proto +29 -0
  29. package/dist/protobuf/nest/trait/lighting.proto +61 -0
  30. package/dist/protobuf/nest/trait/located.proto +193 -0
  31. package/dist/protobuf/nest/trait/media.proto +68 -0
  32. package/dist/protobuf/nest/trait/network.proto +352 -0
  33. package/dist/protobuf/nest/trait/occupancy.proto +373 -0
  34. package/dist/protobuf/nest/trait/olive.proto +15 -0
  35. package/dist/protobuf/nest/trait/pairing.proto +85 -0
  36. package/dist/protobuf/nest/trait/product/camera.proto +283 -0
  37. package/dist/protobuf/nest/trait/product/detect.proto +67 -0
  38. package/dist/protobuf/nest/trait/product/doorbell.proto +18 -0
  39. package/dist/protobuf/nest/trait/product/guard.proto +59 -0
  40. package/dist/protobuf/nest/trait/product/protect.proto +344 -0
  41. package/dist/protobuf/nest/trait/promonitoring.proto +14 -0
  42. package/dist/protobuf/nest/trait/resourcedirectory.proto +32 -0
  43. package/dist/protobuf/nest/trait/safety.proto +119 -0
  44. package/dist/protobuf/nest/trait/security.proto +516 -0
  45. package/dist/protobuf/nest/trait/selftest.proto +78 -0
  46. package/dist/protobuf/nest/trait/sensor.proto +291 -0
  47. package/dist/protobuf/nest/trait/service.proto +46 -0
  48. package/dist/protobuf/nest/trait/structure.proto +85 -0
  49. package/dist/protobuf/nest/trait/system.proto +51 -0
  50. package/dist/protobuf/nest/trait/test.proto +15 -0
  51. package/dist/protobuf/nest/trait/ui.proto +65 -0
  52. package/dist/protobuf/nest/trait/user.proto +98 -0
  53. package/dist/protobuf/nest/trait/voiceassistant.proto +30 -0
  54. package/dist/protobuf/nestlabs/eventingapi/v1.proto +83 -0
  55. package/dist/protobuf/nestlabs/gateway/v1.proto +273 -0
  56. package/dist/protobuf/nestlabs/gateway/v2.proto +96 -0
  57. package/dist/protobuf/nestlabs/history/v1.proto +73 -0
  58. package/dist/protobuf/root.proto +64 -0
  59. package/dist/protobuf/wdl-event-importance.proto +11 -0
  60. package/dist/protobuf/wdl.proto +450 -0
  61. package/dist/protobuf/weave/common.proto +144 -0
  62. package/dist/protobuf/weave/trait/audio.proto +12 -0
  63. package/dist/protobuf/weave/trait/auth.proto +22 -0
  64. package/dist/protobuf/weave/trait/description.proto +32 -0
  65. package/dist/protobuf/weave/trait/heartbeat.proto +38 -0
  66. package/dist/protobuf/weave/trait/locale.proto +20 -0
  67. package/dist/protobuf/weave/trait/network.proto +24 -0
  68. package/dist/protobuf/weave/trait/pairing.proto +8 -0
  69. package/dist/protobuf/weave/trait/peerdevices.proto +18 -0
  70. package/dist/protobuf/weave/trait/power.proto +86 -0
  71. package/dist/protobuf/weave/trait/schedule.proto +76 -0
  72. package/dist/protobuf/weave/trait/security.proto +343 -0
  73. package/dist/protobuf/weave/trait/telemetry/tunnel.proto +37 -0
  74. package/dist/protobuf/weave/trait/time.proto +16 -0
  75. package/dist/res/Nest_camera_connecting.h264 +0 -0
  76. package/dist/res/Nest_camera_connecting.jpg +0 -0
  77. package/dist/res/Nest_camera_off.h264 +0 -0
  78. package/dist/res/Nest_camera_off.jpg +0 -0
  79. package/dist/res/Nest_camera_offline.h264 +0 -0
  80. package/dist/res/Nest_camera_offline.jpg +0 -0
  81. package/dist/res/Nest_camera_transfer.jpg +0 -0
  82. package/dist/streamer.js +344 -0
  83. package/dist/system.js +3112 -0
  84. package/dist/tempsensor.js +99 -0
  85. package/dist/thermostat.js +1026 -0
  86. package/dist/weather.js +205 -0
  87. package/dist/webrtc.js +55 -0
  88. package/package.json +66 -0
@@ -0,0 +1,441 @@
1
+ // HomeKitDevice class
2
+ //
3
+ // This is the base class for all HomeKit accessories we code for in Homebridge/HAP-NodeJS
4
+ //
5
+ // The deviceData structure should at a minimum contain the following elements:
6
+ //
7
+ // Homebridge Plugin:
8
+ //
9
+ // uuid
10
+ // serial_number
11
+ // software_version
12
+ // description
13
+ // manufacturer
14
+ // model
15
+ //
16
+ // HAP-NodeJS Library Accessory:
17
+ //
18
+ // uuid
19
+ // serial_number
20
+ // software_version
21
+ // description
22
+ // manufacturer
23
+ // model
24
+ // hkUsername
25
+ // hkPairingCode
26
+ //
27
+ // Following constants should be overridden in the module loading this class file
28
+ //
29
+ // HomeKitDevice.HOMEKITHISTORY
30
+ // HomeKitDevice.PLUGIN_NAME
31
+ // HomeKitDevice.PLATFORM_NAME
32
+ //
33
+ // The following functions should be overriden in your class which extends this
34
+ //
35
+ // HomeKitDevice.addServices()
36
+ // HomeKitDevice.removeServices()
37
+ // HomeKitDevice.updateServices(deviceData)
38
+ // HomeKitDevice.messageServices(type, message)
39
+ //
40
+ // Code version 6/9/2024
41
+ // Mark Hulskamp
42
+ 'use strict';
43
+
44
+ // Define nodejs module requirements
45
+ import EventEmitter from 'node:events';
46
+
47
+ // Define our HomeKit device class
48
+ export default class HomeKitDevice {
49
+ static ADD = 'HomeKitDevice.add'; // Device add message
50
+ static UPDATE = 'HomeKitDevice.update'; // Device update message
51
+ static REMOVE = 'HomeKitDevice.remove'; // Device remove message
52
+ static SET = 'HomeKitDevice.set'; // Device set property message
53
+ static GET = 'HomeKitDevice.get'; // Device get property message
54
+ static PLUGIN_NAME = undefined; // Homebridge plugin name (override)
55
+ static PLATFORM_NAME = undefined; // Homebridge platform name (override)
56
+ static HISTORY = undefined; // HomeKit History object (override)
57
+
58
+ deviceData = {}; // The devices data we store
59
+ historyService = undefined; // HomeKit history service
60
+ accessory = undefined; // Accessory service for this device
61
+ hap = undefined; // HomeKit Accessory Protocol API stub
62
+ log = undefined; // Logging function object
63
+
64
+ // Internal data only for this class
65
+ #platform = undefined; // Homebridge platform api
66
+ #eventEmitter = undefined; // Event emitter to use for comms
67
+
68
+ constructor(accessory, api, log, eventEmitter, deviceData) {
69
+ // Validate the passed in logging object. We are expecting certain functions to be present
70
+ if (
71
+ typeof log?.info === 'function' &&
72
+ typeof log?.success === 'function' &&
73
+ typeof log?.warn === 'function' &&
74
+ typeof log?.error === 'function' &&
75
+ typeof log?.debug === 'function'
76
+ ) {
77
+ this.log = log;
78
+ }
79
+
80
+ // Workout if we're running under HomeBridge or HAP-NodeJS library
81
+ if (typeof api?.version === 'number' && typeof api?.hap === 'object' && typeof api?.HAPLibraryVersion === 'undefined') {
82
+ // We have the HomeBridge version number and hap API object
83
+ this.hap = api.hap;
84
+ this.#platform = api;
85
+
86
+ this?.log?.debug && this.log.debug('HomeKitDevice module using Homebridge backend for "%s"', deviceData?.description);
87
+ }
88
+
89
+ if (typeof api?.HAPLibraryVersion === 'function' && typeof api?.version === 'undefined' && typeof api?.hap === 'undefined') {
90
+ // As we're missing the HomeBridge entry points but have the HAP library version
91
+ this.hap = api;
92
+
93
+ this?.log?.debug && this.log.debug('HomeKitDevice module using HAP-NodeJS library for "%s"', deviceData?.description);
94
+ }
95
+
96
+ // Validate if eventEmitter object passed to us is an instance of EventEmitter
97
+ if (eventEmitter instanceof EventEmitter === true) {
98
+ this.#eventEmitter = eventEmitter;
99
+ }
100
+
101
+ // If we have a valid EventEmitter and a device uuid
102
+ // Setup a listener for messages to this device
103
+ if (this.#eventEmitter !== undefined && typeof this.deviceData?.uuid === 'string' && this.deviceData.uuid !== '') {
104
+ this.#eventEmitter.addListener(this.deviceData.uuid, this.#message.bind(this));
105
+ }
106
+
107
+ // Make copy of current data and store in this object
108
+ // eslint-disable-next-line no-undef
109
+ this.deviceData = structuredClone(deviceData);
110
+
111
+ // See if we were passed in an existing accessory object or array of accessory objects
112
+ // Mainly used to restore a HomeBridge cached accessory
113
+ if (
114
+ typeof accessory === 'object' &&
115
+ typeof this?.hap?.uuid?.generate === 'function' &&
116
+ typeof deviceData.uuid === 'string' &&
117
+ this.#platform !== undefined
118
+ ) {
119
+ let uuid = this.hap.uuid.generate(HomeKitDevice.PLUGIN_NAME + '_' + deviceData.uuid);
120
+
121
+ if (Array.isArray(accessory) === true) {
122
+ this.accessory = accessory.find((accessory) => accessory.UUID === uuid);
123
+ }
124
+ if (Array.isArray(accessory) === false && typeof accessory?.UUID === 'string' && accessory.UUID === uuid) {
125
+ this.accessory = accessory;
126
+ }
127
+ }
128
+ }
129
+
130
+ // Class functions
131
+ async add(accessoryName, accessoryCategory, useHistoryService) {
132
+ if (
133
+ this.hap === undefined ||
134
+ HomeKitDevice.PLUGIN_NAME === undefined ||
135
+ HomeKitDevice.PLATFORM_NAME === undefined ||
136
+ typeof accessoryName !== 'string' ||
137
+ accessoryName === '' ||
138
+ typeof this.hap.Categories[accessoryCategory] === 'undefined' ||
139
+ typeof useHistoryService !== 'boolean' ||
140
+ typeof this.deviceData !== 'object' ||
141
+ typeof this.deviceData?.uuid !== 'string' ||
142
+ this.deviceData.uuid === '' ||
143
+ typeof this.deviceData?.serial_number !== 'string' ||
144
+ this.deviceData.serial_number === '' ||
145
+ typeof this.deviceData?.software_version !== 'string' ||
146
+ this.deviceData.software_version === '' ||
147
+ (typeof this.deviceData?.description !== 'string' && this.deviceData.description === '') ||
148
+ typeof this.deviceData?.model !== 'string' ||
149
+ this.deviceData.model === '' ||
150
+ typeof this.deviceData?.manufacturer !== 'string' ||
151
+ this.deviceData.manufacturer === '' ||
152
+ (this.#platform === undefined && typeof this.deviceData?.hkPairingCode !== 'string' && this.deviceData.hkPairingCode === '') ||
153
+ (this.#platform === undefined &&
154
+ typeof this.deviceData?.hkUsername !== 'string' &&
155
+ new RegExp(/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/).test(this.deviceData.hkUsername) === false)
156
+ ) {
157
+ return;
158
+ }
159
+
160
+ // If we do not have an existing accessory object, create a new one
161
+ if (this.accessory === undefined && this.#platform !== undefined) {
162
+ // Create HomeBridge platform accessory
163
+ this.accessory = new this.#platform.platformAccessory(
164
+ this.deviceData.description,
165
+ this.hap.uuid.generate(HomeKitDevice.PLUGIN_NAME + '_' + this.deviceData.uuid),
166
+ );
167
+ this.#platform.registerPlatformAccessories(HomeKitDevice.PLUGIN_NAME, HomeKitDevice.PLATFORM_NAME, [this.accessory]);
168
+ }
169
+
170
+ if (this.accessory === undefined && this.#platform === undefined) {
171
+ // Create HAP-NodeJS libray accessory
172
+ // We're using our previous parameters to generate the uuid, rather than the 'new' way we do for Homebridge
173
+ this.accessory = new this.hap.Accessory(
174
+ accessoryName,
175
+ this.hap.uuid.generate(
176
+ 'hap-nodejs:accessories:' + this.deviceData.manufacturer.toLowerCase() + '_' + this.deviceData.serial_number,
177
+ ),
178
+ );
179
+ this.accessory.username = this.deviceData.hkUsername;
180
+ this.accessory.pincode = this.deviceData.hkPairingCode;
181
+ this.accessory.category = accessoryCategory;
182
+ }
183
+
184
+ // Setup accessory information
185
+ let informationService = this.accessory.getService(this.hap.Service.AccessoryInformation);
186
+ if (informationService !== undefined) {
187
+ informationService.updateCharacteristic(this.hap.Characteristic.Manufacturer, this.deviceData.manufacturer);
188
+ informationService.updateCharacteristic(this.hap.Characteristic.Model, this.deviceData.model);
189
+ informationService.updateCharacteristic(this.hap.Characteristic.SerialNumber, this.deviceData.serial_number);
190
+ informationService.updateCharacteristic(this.hap.Characteristic.FirmwareRevision, this.deviceData.software_version);
191
+ }
192
+ informationService.updateCharacteristic(this.hap.Characteristic.Name, this.deviceData.description);
193
+
194
+ // Setup our history service if module has been defined and requested to be active for this device
195
+ if (typeof HomeKitDevice?.HISTORY === 'function' && this.historyService === undefined && useHistoryService === true) {
196
+ this.historyService = new HomeKitDevice.HISTORY(this.accessory, this.log, this.hap, {});
197
+ }
198
+
199
+ if (typeof this.addServices === 'function') {
200
+ try {
201
+ let postSetupDetails = await this.addServices();
202
+ if (this?.log?.info) {
203
+ this.log.info('Setup %s %s as "%s"', this.deviceData.manufacturer, this.deviceData.model, this.deviceData.description);
204
+ if (this.historyService?.EveHome !== undefined) {
205
+ this.log.info(' += EveHome support as "%s"', this.historyService.EveHome.evetype);
206
+ }
207
+ if (typeof postSetupDetails === 'object') {
208
+ postSetupDetails.forEach((output) => {
209
+ if (this?.log?.info) {
210
+ this.log.info(' += %s', output);
211
+ }
212
+ });
213
+ }
214
+ }
215
+ } catch (error) {
216
+ this?.log?.error && this.log.error('addServices call for device "%s" failed. Error was', this.deviceData.description, error);
217
+ }
218
+ }
219
+
220
+ // if we have a valid EventEmitter and we have not previously setup an message event handler, do so now
221
+ if (this.#eventEmitter !== undefined && this.#eventEmitter.listenerCount(this.deviceData.uuid) === 0) {
222
+ this.#eventEmitter.addListener(this.deviceData.uuid, this.#message.bind(this));
223
+ }
224
+
225
+ // Perform an initial update using current data
226
+ this.update(this.deviceData, true);
227
+
228
+ // If using HAP-NodeJS library, publish accessory on local network
229
+ if (this.#platform === undefined && this.accessory !== undefined) {
230
+ if (this?.log?.info) {
231
+ this.log.info(' += Advertising as "%s"', accessoryName);
232
+ this.log.info(' += Pairing code is "%s"', this.accessory.pincode);
233
+ }
234
+ this.accessory.publish({
235
+ username: this.accessory.username,
236
+ pincode: this.accessory.pincode,
237
+ category: this.accessory.category,
238
+ });
239
+ }
240
+ }
241
+
242
+ async remove() {
243
+ this?.log?.warn && this.log.warn('Device "%s" has been removed', this.deviceData.description);
244
+
245
+ if (this.#eventEmitter === undefined && typeof this.deviceData?.uuid === 'string' && this.deviceData.uuid !== '') {
246
+ // Remove listener for 'messages'
247
+ this.#eventEmitter.removeAllListeners(this.deviceData.uuid);
248
+ }
249
+
250
+ if (typeof this.removeServices === 'function') {
251
+ try {
252
+ await this.removeServices();
253
+ } catch (error) {
254
+ this?.log?.error && this.log.error('removeServices call for device "%s" failed. Error was', this.deviceData.description, error);
255
+ }
256
+ }
257
+
258
+ if (this.accessory !== undefined && this.#platform !== undefined) {
259
+ // Unregister the accessory from Homebridge
260
+ this.#platform.unregisterPlatformAccessories(HomeKitDevice.PLUGIN_NAME, HomeKitDevice.PLATFORM_NAME, [this.accessory]);
261
+ }
262
+
263
+ if (this.accessory !== undefined && this.#platform === undefined) {
264
+ // Unpublish the accessory from HAP
265
+ this.accessory.unpublish();
266
+ }
267
+
268
+ this.deviceData = {};
269
+ this.accessory = undefined;
270
+ this.historyService = undefined;
271
+ this.hap = undefined;
272
+ this.log = undefined;
273
+ this.#platform = undefined;
274
+ this.#eventEmitter = undefined;
275
+
276
+ // Do we destroy this object??
277
+ // this = null;
278
+ // delete this;
279
+ }
280
+
281
+ async update(deviceData, forceUpdate) {
282
+ if (typeof deviceData !== 'object' || typeof forceUpdate !== 'boolean') {
283
+ return;
284
+ }
285
+
286
+ // Updated data may only contain selected fields, so we'll handle that here by taking our internally stored data
287
+ // and merge with the updates to ensure we have a complete data object
288
+ Object.entries(this.deviceData).forEach(([key, value]) => {
289
+ if (typeof deviceData[key] === 'undefined') {
290
+ // Updated data doesn't have this key, so add it to our internally stored data
291
+ deviceData[key] = value;
292
+ }
293
+ });
294
+
295
+ // Check updated device data with our internally stored data. Flag if changes between the two
296
+ let changedData = false;
297
+ Object.keys(deviceData).forEach((key) => {
298
+ if (JSON.stringify(deviceData[key]) !== JSON.stringify(this.deviceData[key])) {
299
+ changedData = true;
300
+ }
301
+ });
302
+
303
+ // If we have any changed data OR we've been requested to force an update, do so here
304
+ if ((changedData === true || forceUpdate === true) && this.accessory !== undefined) {
305
+ let informationService = this.accessory.getService(this.hap.Service.AccessoryInformation);
306
+ if (informationService !== undefined) {
307
+ // Update details associated with the accessory
308
+ // ie: Name, Manufacturer, Model, Serial # and firmware version
309
+ if (typeof deviceData?.description === 'string' && deviceData.description !== this.deviceData.description) {
310
+ // Update serial number on the HomeKit accessory
311
+ informationService.updateCharacteristic(this.hap.Characteristic.Name, this.deviceData.description);
312
+ }
313
+
314
+ if (
315
+ typeof deviceData?.manufacturer === 'string' &&
316
+ deviceData.manufacturer !== '' &&
317
+ deviceData.manufacturer !== this.deviceData.manufacturer
318
+ ) {
319
+ // Update serial number on the HomeKit accessory
320
+ informationService.updateCharacteristic(this.hap.Characteristic.Manufacturer, this.deviceData.manufacturer);
321
+ }
322
+
323
+ if (typeof deviceData?.model === 'string' && deviceData.model !== '' && deviceData.model !== this.deviceData.model) {
324
+ // Update serial number on the HomeKit accessory
325
+ informationService.updateCharacteristic(this.hap.Characteristic.Model, this.deviceData.model);
326
+ }
327
+
328
+ if (
329
+ typeof deviceData?.serial_number === 'string' &&
330
+ deviceData.serial_number !== '' &&
331
+ deviceData.serial_number !== this.deviceData.serial_number
332
+ ) {
333
+ // Update serial number on the HomeKit accessory
334
+ informationService.updateCharacteristic(this.hap.Characteristic.SerialNumber, this.deviceData.serial_number);
335
+ }
336
+
337
+ if (
338
+ typeof deviceData?.software_version === 'string' &&
339
+ deviceData.software_version !== '' &&
340
+ deviceData.software_version !== this.deviceData.software_version
341
+ ) {
342
+ // Update software version on the HomeKit accessory
343
+ informationService.updateCharacteristic(this.hap.Characteristic.FirmwareRevision, this.deviceData.software_version);
344
+ }
345
+ }
346
+
347
+ if (typeof deviceData?.online === 'boolean' && deviceData.online !== this.deviceData.online) {
348
+ // Output device online/offline status
349
+ if (deviceData.online === false && this?.log?.warn) {
350
+ this.log.warn('Device "%s" is offline', this.deviceData.description);
351
+ }
352
+
353
+ if (deviceData.online === true && this?.log?.success) {
354
+ this.log.success('Device "%s" is online', this.deviceData.description);
355
+ }
356
+ }
357
+
358
+ if (typeof this.updateServices === 'function') {
359
+ try {
360
+ await this.updateServices(deviceData); // Pass updated data on for accessory to process as it needs
361
+ } catch (error) {
362
+ this?.log?.error && this.log.error('updateServices call for device "%s" failed. Error was', this.deviceData.description, error);
363
+ }
364
+ }
365
+
366
+ // Finally, update our internally stored data with the new data
367
+ // eslint-disable-next-line no-undef
368
+ this.deviceData = structuredClone(deviceData);
369
+ }
370
+ }
371
+
372
+ async set(values) {
373
+ if (
374
+ typeof values !== 'object' ||
375
+ this.#eventEmitter === undefined ||
376
+ typeof this.deviceData?.uuid !== 'string' ||
377
+ this.deviceData.uuid === ''
378
+ ) {
379
+ return;
380
+ }
381
+
382
+ // Send event with data to set
383
+ this.#eventEmitter.emit(HomeKitDevice.SET, this.deviceData.uuid, values);
384
+ }
385
+
386
+ async get(values) {
387
+ if (
388
+ typeof values !== 'object' ||
389
+ this.#eventEmitter === undefined ||
390
+ typeof this.deviceData?.uuid !== 'string' ||
391
+ this.deviceData.uuid === ''
392
+ ) {
393
+ return;
394
+ }
395
+
396
+ // Send event with data to get
397
+ // Once get has completed, we'll get an eevent back with the requested data
398
+ this.#eventEmitter.emit(HomeKitDevice.GET, this.deviceData.uuid, values);
399
+
400
+ // This should always return, but we probably should put in a timeout?
401
+ let results = await EventEmitter.once(this.#eventEmitter, HomeKitDevice.GET + '->' + this.deviceData.uuid);
402
+ return results?.[0];
403
+ }
404
+
405
+ async #message(type, message) {
406
+ switch (type) {
407
+ case HomeKitDevice.ADD: {
408
+ // Got message for device add
409
+ if (typeof message?.name === 'string' && typeof message?.category === 'number' && typeof message?.history === 'boolean') {
410
+ this.add(message.name, message.category, message.history);
411
+ }
412
+ break;
413
+ }
414
+
415
+ case HomeKitDevice.UPDATE: {
416
+ // Got some device data, so process any updates
417
+ this.update(message, false);
418
+ break;
419
+ }
420
+
421
+ case HomeKitDevice.REMOVE: {
422
+ // Got message for device removal
423
+ this.remove();
424
+ break;
425
+ }
426
+
427
+ default: {
428
+ // This is not a message we know about, so pass onto accessory for it to perform any processing
429
+ if (typeof this.messageServices === 'function') {
430
+ try {
431
+ await this.messageServices(type, message);
432
+ } catch (error) {
433
+ this?.log?.error &&
434
+ this.log.error('messageServices call for device "%s" failed. Error was', this.deviceData.description, error);
435
+ }
436
+ }
437
+ break;
438
+ }
439
+ }
440
+ }
441
+ }