homebridge 2.0.0-alpha.43 → 2.0.0-alpha.44

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 (76) hide show
  1. package/dist/api.d.ts +30 -0
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/api.js +26 -0
  4. package/dist/api.js.map +1 -1
  5. package/dist/bridgeService.d.ts +3 -13
  6. package/dist/bridgeService.d.ts.map +1 -1
  7. package/dist/bridgeService.js +8 -24
  8. package/dist/bridgeService.js.map +1 -1
  9. package/dist/childBridgeFork.d.ts +0 -8
  10. package/dist/childBridgeFork.d.ts.map +1 -1
  11. package/dist/childBridgeFork.js +26 -127
  12. package/dist/childBridgeFork.js.map +1 -1
  13. package/dist/childBridgeService.d.ts +0 -12
  14. package/dist/childBridgeService.d.ts.map +1 -1
  15. package/dist/childBridgeService.js +9 -25
  16. package/dist/childBridgeService.js.map +1 -1
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +1 -3
  19. package/dist/cli.js.map +1 -1
  20. package/dist/ipcService.d.ts +2 -12
  21. package/dist/ipcService.d.ts.map +1 -1
  22. package/dist/ipcService.js +0 -7
  23. package/dist/ipcService.js.map +1 -1
  24. package/dist/matter/index.d.ts +1 -1
  25. package/dist/matter/index.d.ts.map +1 -1
  26. package/dist/matter/index.js.map +1 -1
  27. package/dist/matter/matterAccessoryCache.d.ts +73 -0
  28. package/dist/matter/matterAccessoryCache.d.ts.map +1 -0
  29. package/dist/matter/matterAccessoryCache.js +168 -0
  30. package/dist/matter/matterAccessoryCache.js.map +1 -0
  31. package/dist/matter/matterBehaviors.d.ts +123 -0
  32. package/dist/matter/matterBehaviors.d.ts.map +1 -0
  33. package/dist/matter/matterBehaviors.js +582 -0
  34. package/dist/matter/matterBehaviors.js.map +1 -0
  35. package/dist/matter/matterConfigValidator.d.ts +0 -1
  36. package/dist/matter/matterConfigValidator.d.ts.map +1 -1
  37. package/dist/matter/matterConfigValidator.js +15 -45
  38. package/dist/matter/matterConfigValidator.js.map +1 -1
  39. package/dist/matter/matterErrorHandler.d.ts +1 -1
  40. package/dist/matter/matterErrorHandler.d.ts.map +1 -1
  41. package/dist/matter/matterErrorHandler.js +35 -22
  42. package/dist/matter/matterErrorHandler.js.map +1 -1
  43. package/dist/matter/matterNetworkMonitor.d.ts +3 -0
  44. package/dist/matter/matterNetworkMonitor.d.ts.map +1 -1
  45. package/dist/matter/matterNetworkMonitor.js +49 -26
  46. package/dist/matter/matterNetworkMonitor.js.map +1 -1
  47. package/dist/matter/matterServer.d.ts +79 -5
  48. package/dist/matter/matterServer.d.ts.map +1 -1
  49. package/dist/matter/matterServer.js +487 -97
  50. package/dist/matter/matterServer.js.map +1 -1
  51. package/dist/matter/matterSharedTypes.d.ts +12 -4
  52. package/dist/matter/matterSharedTypes.d.ts.map +1 -1
  53. package/dist/matter/matterSharedTypes.js.map +1 -1
  54. package/dist/matter/matterStorage.d.ts +11 -1
  55. package/dist/matter/matterStorage.d.ts.map +1 -1
  56. package/dist/matter/matterStorage.js +12 -2
  57. package/dist/matter/matterStorage.js.map +1 -1
  58. package/dist/matter/matterTypes.d.ts +68 -19
  59. package/dist/matter/matterTypes.d.ts.map +1 -1
  60. package/dist/matter/matterTypes.js.map +1 -1
  61. package/dist/matter/matterValidation.d.ts +57 -0
  62. package/dist/matter/matterValidation.d.ts.map +1 -0
  63. package/dist/matter/matterValidation.js +100 -0
  64. package/dist/matter/matterValidation.js.map +1 -0
  65. package/dist/plugin.d.ts.map +1 -1
  66. package/dist/plugin.js +2 -4
  67. package/dist/plugin.js.map +1 -1
  68. package/dist/server.d.ts +0 -7
  69. package/dist/server.d.ts.map +1 -1
  70. package/dist/server.js +80 -112
  71. package/dist/server.js.map +1 -1
  72. package/package.json +3 -3
  73. package/dist/matter/matterDiagnostics.d.ts +0 -121
  74. package/dist/matter/matterDiagnostics.d.ts.map +0 -1
  75. package/dist/matter/matterDiagnostics.js +0 -323
  76. package/dist/matter/matterDiagnostics.js.map +0 -1
@@ -11,11 +11,7 @@ export var IpcIncomingEvent;
11
11
  IpcIncomingEvent["STOP_MATTER_BRIDGE"] = "stopMatterBridge";
12
12
  IpcIncomingEvent["START_MATTER_BRIDGE"] = "startMatterBridge";
13
13
  IpcIncomingEvent["MATTER_BRIDGE_METADATA_REQUEST"] = "matterBridgeMetadataRequest";
14
- IpcIncomingEvent["MATTER_ACCESSORIES_REQUEST"] = "matterAccessoriesRequest";
15
- IpcIncomingEvent["TOGGLE_MATTER_DEVICE"] = "toggleMatterDevice";
16
14
  IpcIncomingEvent["MATTER_COMMISSIONING_INFO_REQUEST"] = "matterCommissioningInfoRequest";
17
- IpcIncomingEvent["MATTER_DEVICE_READY"] = "matterDeviceReady";
18
- IpcIncomingEvent["MATTER_DEVICE_REMOVED"] = "matterDeviceRemoved";
19
15
  })(IpcIncomingEvent || (IpcIncomingEvent = {}));
20
16
  // eslint-disable-next-line no-restricted-syntax
21
17
  export var IpcOutgoingEvent;
@@ -25,9 +21,6 @@ export var IpcOutgoingEvent;
25
21
  IpcOutgoingEvent["CHILD_BRIDGE_STATUS_UPDATE"] = "childBridgeStatusUpdate";
26
22
  IpcOutgoingEvent["MATTER_BRIDGE_METADATA_RESPONSE"] = "matterBridgeMetadataResponse";
27
23
  IpcOutgoingEvent["MATTER_BRIDGE_STATUS_UPDATE"] = "matterBridgeStatusUpdate";
28
- IpcOutgoingEvent["MATTER_ACCESSORIES_RESPONSE"] = "matterAccessoriesResponse";
29
- IpcOutgoingEvent["MATTER_DEVICE_STATUS_UPDATE"] = "matterDeviceStatusUpdate";
30
- IpcOutgoingEvent["MATTER_COMMISSIONING_STATUS"] = "matterCommissioningStatus";
31
24
  IpcOutgoingEvent["MATTER_COMMISSIONING_INFO_RESPONSE"] = "matterCommissioningInfoResponse";
32
25
  })(IpcOutgoingEvent || (IpcOutgoingEvent = {}));
33
26
  // eslint-disable-next-line ts/no-unsafe-declaration-merging
@@ -1 +1 @@
1
- {"version":3,"file":"ipcService.js","sourceRoot":"","sources":["../src/ipcService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,gDAAgD;AAChD,MAAM,CAAN,IAAkB,gBAcjB;AAdD,WAAkB,gBAAgB;IAChC,+DAA2C,CAAA;IAC3C,yDAAqC,CAAA;IACrC,2DAAuC,CAAA;IACvC,gFAA4D,CAAA;IAC5D,iEAA6C,CAAA;IAC7C,2DAAuC,CAAA;IACvC,6DAAyC,CAAA;IACzC,kFAA8D,CAAA;IAC9D,2EAAuD,CAAA;IACvD,+DAA2C,CAAA;IAC3C,wFAAoE,CAAA;IACpE,6DAAyC,CAAA;IACzC,iEAA6C,CAAA;AAC/C,CAAC,EAdiB,gBAAgB,KAAhB,gBAAgB,QAcjC;AAED,gDAAgD;AAChD,MAAM,CAAN,IAAkB,gBAUjB;AAVD,WAAkB,gBAAgB;IAChC,+DAA2C,CAAA;IAC3C,kFAA8D,CAAA;IAC9D,0EAAsD,CAAA;IACtD,oFAAgE,CAAA;IAChE,4EAAwD,CAAA;IACxD,6EAAyD,CAAA;IACzD,4EAAwD,CAAA;IACxD,6EAAyD,CAAA;IACzD,0FAAsE,CAAA;AACxE,CAAC,EAViB,gBAAgB,KAAhB,gBAAgB,QAUjC;AAOD,4DAA4D;AAC5D,MAAM,OAAO,UAAW,SAAQ,YAAY;IAC1C;QACE,KAAK,EAAE,CAAA;IACT,CAAC;IAED;;;OAGG;IACI,KAAK;QACV,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAoC,EAAE,EAAE;YAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBAC3D,OAAM;YACR,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;QACrC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,EAAoB,EAAE,IAAa;QACpD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE;gBACF,IAAI;aACL,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"ipcService.js","sourceRoot":"","sources":["../src/ipcService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,gDAAgD;AAChD,MAAM,CAAN,IAAkB,gBAUjB;AAVD,WAAkB,gBAAgB;IAChC,+DAA2C,CAAA;IAC3C,yDAAqC,CAAA;IACrC,2DAAuC,CAAA;IACvC,gFAA4D,CAAA;IAC5D,iEAA6C,CAAA;IAC7C,2DAAuC,CAAA;IACvC,6DAAyC,CAAA;IACzC,kFAA8D,CAAA;IAC9D,wFAAoE,CAAA;AACtE,CAAC,EAViB,gBAAgB,KAAhB,gBAAgB,QAUjC;AAED,gDAAgD;AAChD,MAAM,CAAN,IAAkB,gBAOjB;AAPD,WAAkB,gBAAgB;IAChC,+DAA2C,CAAA;IAC3C,kFAA8D,CAAA;IAC9D,0EAAsD,CAAA;IACtD,oFAAgE,CAAA;IAChE,4EAAwD,CAAA;IACxD,0FAAsE,CAAA;AACxE,CAAC,EAPiB,gBAAgB,KAAhB,gBAAgB,QAOjC;AAOD,4DAA4D;AAC5D,MAAM,OAAO,UAAW,SAAQ,YAAY;IAC1C;QACE,KAAK,EAAE,CAAA;IACT,CAAC;IAED;;;OAGG;IACI,KAAK;QACV,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAoC,EAAE,EAAE;YAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBAC3D,OAAM;YACR,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;QACrC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,EAAoB,EAAE,IAAa;QACpD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE;gBACF,IAAI;aACL,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -7,5 +7,5 @@
7
7
  export { type MatterConfigValidationResult, MatterConfigValidator } from './matterConfigValidator.js';
8
8
  export { MatterServer } from './matterServer.js';
9
9
  export { HomebridgeMatterStorage, MatterStorageManager } from './matterStorage.js';
10
- export { clusters, devices, deviceTypes, type InternalMatterAccessory, type MatterAccessory, MatterCommissioningError, type MatterConfig, MatterDeviceError, MatterError, MatterErrorType, MatterNetworkError, MatterStorageError, } from './matterTypes.js';
10
+ export { clusters, devices, deviceTypes, type InternalMatterAccessory, type MatterAccessory, type MatterClusterHandlers, type MatterCommandHandler, MatterCommissioningError, type MatterConfig, MatterDeviceError, MatterError, type MatterErrorDetails, MatterErrorType, MatterNetworkError, MatterStorageError, } from './matterTypes.js';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/matter/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAClF,OAAO,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,wBAAwB,EACxB,KAAK,YAAY,EACjB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/matter/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAClF,OAAO,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,wBAAwB,EACxB,KAAK,YAAY,EACjB,iBAAiB,EACjB,WAAW,EACX,KAAK,kBAAkB,EACvB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/matter/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAqC,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAClF,OAAO,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EAGX,wBAAwB,EAExB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/matter/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAqC,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAClF,OAAO,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EAKX,wBAAwB,EAExB,iBAAiB,EACjB,WAAW,EAEX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Matter Accessory Cache
3
+ *
4
+ * Handles persistence of Matter accessories across Homebridge restarts.
5
+ * Similar to HAP's cached accessories, but designed for Matter's simpler API.
6
+ */
7
+ import type { MatterAccessory } from './matterTypes.js';
8
+ /**
9
+ * Serializable Matter accessory (excludes functions and runtime state)
10
+ */
11
+ export interface SerializedMatterAccessory {
12
+ uuid: string;
13
+ displayName: string;
14
+ deviceType: {
15
+ name?: string;
16
+ code?: number;
17
+ };
18
+ serialNumber: string;
19
+ manufacturer: string;
20
+ model: string;
21
+ firmwareRevision?: string;
22
+ hardwareRevision?: string;
23
+ softwareVersion?: string;
24
+ context?: Record<string, any>;
25
+ clusters: {
26
+ [clusterName: string]: {
27
+ [attributeName: string]: any;
28
+ };
29
+ };
30
+ }
31
+ /**
32
+ * Matter Accessory Cache Manager
33
+ */
34
+ export declare class MatterAccessoryCache {
35
+ private readonly cacheFilePath;
36
+ private cachedAccessories;
37
+ private cacheLoaded;
38
+ private saveInProgress;
39
+ constructor(storagePath: string, bridgeId: string);
40
+ /**
41
+ * Load cached accessories from disk
42
+ */
43
+ load(): Promise<Map<string, SerializedMatterAccessory>>;
44
+ /**
45
+ * Save accessories to cache (serialized to prevent concurrent write conflicts)
46
+ */
47
+ save(accessories: Map<string, MatterAccessory>): Promise<void>;
48
+ /**
49
+ * Internal save implementation
50
+ */
51
+ private performSave;
52
+ /**
53
+ * Get cached accessory by UUID
54
+ */
55
+ getCached(uuid: string): SerializedMatterAccessory | undefined;
56
+ /**
57
+ * Check if an accessory is cached
58
+ */
59
+ hasCached(uuid: string): boolean;
60
+ /**
61
+ * Remove an accessory from cache
62
+ */
63
+ removeCached(uuid: string): void;
64
+ /**
65
+ * Get all cached accessories
66
+ */
67
+ getAllCached(): Map<string, SerializedMatterAccessory>;
68
+ /**
69
+ * Serialize a Matter accessory for storage
70
+ */
71
+ private serializeAccessory;
72
+ }
73
+ //# sourceMappingURL=matterAccessoryCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matterAccessoryCache.d.ts","sourceRoot":"","sources":["../../src/matter/matterAccessoryCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAUvD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC7B,QAAQ,EAAE;QACR,CAAC,WAAW,EAAE,MAAM,GAAG;YACrB,CAAC,aAAa,EAAE,MAAM,GAAG,GAAG,CAAA;SAC7B,CAAA;KACF,CAAA;CACF;AAED;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,iBAAiB,CAAoD;IAC7E,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,cAAc,CAA6B;gBAEvC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAIjD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IAgD7D;;OAEG;IACG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBpE;;OAEG;YACW,WAAW;IAqCzB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,yBAAyB,GAAG,SAAS;IAI9D;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAItD;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAsB3B"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Matter Accessory Cache
3
+ *
4
+ * Handles persistence of Matter accessories across Homebridge restarts.
5
+ * Similar to HAP's cached accessories, but designed for Matter's simpler API.
6
+ */
7
+ import * as path from 'node:path';
8
+ import fs from 'fs-extra';
9
+ import { Logger } from '../logger.js';
10
+ const log = Logger.withPrefix('Matter');
11
+ /**
12
+ * Matter Accessory Cache Manager
13
+ */
14
+ export class MatterAccessoryCache {
15
+ cacheFilePath;
16
+ cachedAccessories = new Map();
17
+ cacheLoaded = false;
18
+ saveInProgress = null;
19
+ constructor(storagePath, bridgeId) {
20
+ this.cacheFilePath = path.join(storagePath, bridgeId, 'accessories.json');
21
+ }
22
+ /**
23
+ * Load cached accessories from disk
24
+ */
25
+ async load() {
26
+ if (this.cacheLoaded) {
27
+ return this.cachedAccessories;
28
+ }
29
+ try {
30
+ // Ensure cache file exists
31
+ if (!await fs.pathExists(this.cacheFilePath)) {
32
+ log.info('No cached Matter accessories found (first run)');
33
+ this.cacheLoaded = true;
34
+ return this.cachedAccessories;
35
+ }
36
+ // Read and parse cache file
37
+ const cacheData = await fs.readJson(this.cacheFilePath);
38
+ if (!Array.isArray(cacheData)) {
39
+ log.warn('Invalid Matter accessory cache format, deleting corrupted file');
40
+ await fs.remove(this.cacheFilePath);
41
+ this.cacheLoaded = true;
42
+ return this.cachedAccessories;
43
+ }
44
+ // Load accessories into map
45
+ for (const serialized of cacheData) {
46
+ if (serialized.uuid) {
47
+ this.cachedAccessories.set(serialized.uuid, serialized);
48
+ }
49
+ }
50
+ log.info(`Loaded ${this.cachedAccessories.size} cached Matter accessories`);
51
+ this.cacheLoaded = true;
52
+ return this.cachedAccessories;
53
+ }
54
+ catch (error) {
55
+ // If JSON parsing failed (corrupted file), delete it and start fresh
56
+ log.error(`Failed to load Matter accessory cache: ${this.cacheFilePath}: ${error.message}`);
57
+ log.warn('Deleting corrupted cache file and starting fresh');
58
+ try {
59
+ await fs.remove(this.cacheFilePath);
60
+ }
61
+ catch (removeError) {
62
+ log.debug('Could not delete corrupted cache file:', removeError);
63
+ }
64
+ this.cacheLoaded = true;
65
+ return this.cachedAccessories;
66
+ }
67
+ }
68
+ /**
69
+ * Save accessories to cache (serialized to prevent concurrent write conflicts)
70
+ */
71
+ async save(accessories) {
72
+ // Wait for any in-progress save to complete
73
+ if (this.saveInProgress) {
74
+ await this.saveInProgress;
75
+ }
76
+ // Start new save operation
77
+ this.saveInProgress = this.performSave(accessories);
78
+ try {
79
+ await this.saveInProgress;
80
+ }
81
+ finally {
82
+ this.saveInProgress = null;
83
+ }
84
+ }
85
+ /**
86
+ * Internal save implementation
87
+ */
88
+ async performSave(accessories) {
89
+ const tempFilePath = `${this.cacheFilePath}.tmp`;
90
+ try {
91
+ // Serialize accessories (strip out functions)
92
+ const serialized = [];
93
+ for (const accessory of accessories.values()) {
94
+ serialized.push(this.serializeAccessory(accessory));
95
+ }
96
+ // Ensure directory exists
97
+ const directory = path.dirname(this.cacheFilePath);
98
+ await fs.ensureDir(directory);
99
+ // Write to temporary file first (atomic write pattern to prevent corruption)
100
+ await fs.writeJson(tempFilePath, serialized, { spaces: 2 });
101
+ // Atomically rename temp file to final location
102
+ // Use rename for true atomic operation on the same filesystem
103
+ await fs.rename(tempFilePath, this.cacheFilePath);
104
+ log.debug(`Saved ${serialized.length} Matter accessories to cache`);
105
+ }
106
+ catch (error) {
107
+ log.error(`Failed to save Matter accessory cache: ${error.message}`);
108
+ // Clean up temp file if it exists
109
+ try {
110
+ if (await fs.pathExists(tempFilePath)) {
111
+ await fs.remove(tempFilePath);
112
+ }
113
+ }
114
+ catch (cleanupError) {
115
+ log.debug('Could not clean up temporary cache file:', cleanupError);
116
+ }
117
+ }
118
+ }
119
+ /**
120
+ * Get cached accessory by UUID
121
+ */
122
+ getCached(uuid) {
123
+ return this.cachedAccessories.get(uuid);
124
+ }
125
+ /**
126
+ * Check if an accessory is cached
127
+ */
128
+ hasCached(uuid) {
129
+ return this.cachedAccessories.has(uuid);
130
+ }
131
+ /**
132
+ * Remove an accessory from cache
133
+ */
134
+ removeCached(uuid) {
135
+ this.cachedAccessories.delete(uuid);
136
+ }
137
+ /**
138
+ * Get all cached accessories
139
+ */
140
+ getAllCached() {
141
+ return new Map(this.cachedAccessories);
142
+ }
143
+ /**
144
+ * Serialize a Matter accessory for storage
145
+ */
146
+ serializeAccessory(accessory) {
147
+ // Extract device type information
148
+ const deviceType = accessory.deviceType;
149
+ const deviceTypeInfo = {
150
+ name: deviceType?.name,
151
+ code: deviceType?.code,
152
+ };
153
+ return {
154
+ uuid: accessory.uuid,
155
+ displayName: accessory.displayName,
156
+ deviceType: deviceTypeInfo,
157
+ serialNumber: accessory.serialNumber,
158
+ manufacturer: accessory.manufacturer,
159
+ model: accessory.model,
160
+ firmwareRevision: accessory.firmwareRevision,
161
+ hardwareRevision: accessory.hardwareRevision,
162
+ softwareVersion: accessory.softwareVersion,
163
+ context: accessory.context,
164
+ clusters: structuredClone(accessory.clusters),
165
+ };
166
+ }
167
+ }
168
+ //# sourceMappingURL=matterAccessoryCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matterAccessoryCache.js","sourceRoot":"","sources":["../../src/matter/matterAccessoryCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Custom Matter Behavior Classes for Homebridge
3
+ *
4
+ * These custom behaviors extend the base Matter.js behaviors and override
5
+ * command methods to allow plugins to inject custom handlers.
6
+ *
7
+ * Note: Only clusters with user-triggered commands need custom behaviors.
8
+ * Read-only clusters (like sensors) don't need custom behaviors since
9
+ * they only report state, they don't receive commands.
10
+ */
11
+ import type { MatterCommandHandler } from './matterTypes.js';
12
+ import { ColorControlServer, DoorLockServer, IdentifyServer, LevelControlServer, OnOffServer, ThermostatServer, WindowCoveringServer } from '@matter/main/behaviors';
13
+ /**
14
+ * Set the accessories map reference for cache syncing
15
+ */
16
+ export declare function setAccessoriesMap(map: Map<string, any>): void;
17
+ /**
18
+ * Register a handler for a specific endpoint/cluster/command
19
+ *
20
+ * @param endpointId - Unique endpoint identifier (typically the accessory UUID)
21
+ * @param clusterName - Name of the Matter cluster (e.g., 'onOff', 'levelControl')
22
+ * @param commandName - Name of the command method (e.g., 'on', 'off', 'moveToLevel')
23
+ * @param handler - Callback function to execute when the command is received
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * registerHandler('my-light-uuid', 'onOff', 'on', async () => {
28
+ * console.log('Light turned on!')
29
+ * })
30
+ * ```
31
+ */
32
+ export declare function registerHandler(endpointId: string, clusterName: string, commandName: string, handler: MatterCommandHandler): void;
33
+ /**
34
+ * Custom OnOff Server that calls plugin handlers
35
+ */
36
+ export declare class HomebridgeOnOffServer extends OnOffServer {
37
+ on(): any;
38
+ off(): any;
39
+ toggle(): any;
40
+ }
41
+ /**
42
+ * Custom LevelControl Server that calls plugin handlers
43
+ */
44
+ export declare class HomebridgeLevelControlServer extends LevelControlServer {
45
+ moveToLevel(request: any): any;
46
+ move(request: any): any;
47
+ step(request: any): any;
48
+ stop(request: any): any;
49
+ }
50
+ /**
51
+ * Custom WindowCovering Server that calls plugin handlers
52
+ */
53
+ export declare class HomebridgeWindowCoveringServer extends WindowCoveringServer {
54
+ upOrOpen(): any;
55
+ downOrClose(): any;
56
+ stopMotion(): any;
57
+ }
58
+ /**
59
+ * Custom DoorLock Server that calls plugin handlers
60
+ */
61
+ export declare class HomebridgeDoorLockServer extends DoorLockServer {
62
+ lockDoor(): any;
63
+ unlockDoor(): any;
64
+ }
65
+ /**
66
+ * Custom Thermostat Server that calls plugin handlers
67
+ */
68
+ export declare class HomebridgeThermostatServer extends ThermostatServer {
69
+ setpointRaiseLower(request: any): any;
70
+ }
71
+ /**
72
+ * Custom Identify Server that calls plugin handlers
73
+ */
74
+ export declare class HomebridgeIdentifyServer extends IdentifyServer {
75
+ identify(request: any): any;
76
+ }
77
+ /**
78
+ * Custom ColorControl Server that calls plugin handlers
79
+ *
80
+ * ColorControl handles color changes for lights (hue, saturation, XY color, color temperature).
81
+ * Plugin developers can override these *Logic methods to handle color changes in their hardware.
82
+ */
83
+ export declare class HomebridgeColorControlServer extends ColorControlServer {
84
+ /**
85
+ * Called when color temperature is changed
86
+ * @param targetMireds - Target color temperature in mireds (micro reciprocal degrees)
87
+ * @param transitionTime - Transition time in seconds (0 = as fast as possible)
88
+ */
89
+ moveToColorTemperatureLogic(targetMireds: number, transitionTime: number): any;
90
+ /**
91
+ * Called when hue and saturation are changed together
92
+ * @param targetHue - Target hue value (0-254 for normal hue, 0-65535 for enhanced hue)
93
+ * @param targetSaturation - Target saturation value (0-254)
94
+ * @param transitionTime - Transition time in seconds (0 = as fast as possible)
95
+ */
96
+ moveToHueAndSaturationLogic(targetHue: number, targetSaturation: number, transitionTime: number): any;
97
+ /**
98
+ * Called when XY color coordinates are changed
99
+ * @param targetX - Target X value (0-65535 representing 0.0-1.0 in CIE color space)
100
+ * @param targetY - Target Y value (0-65535 representing 0.0-1.0 in CIE color space)
101
+ * @param transitionTime - Transition time in seconds (0 = as fast as possible)
102
+ */
103
+ moveToColorLogic(targetX: number, targetY: number, transitionTime: number): any;
104
+ /**
105
+ * Called when hue is changed individually
106
+ * @param targetHue - Target hue value
107
+ * @param direction - Direction to move (shortest, longest, up, down)
108
+ * @param transitionTime - Transition time in seconds
109
+ * @param isEnhancedHue - Whether this is enhanced hue (16-bit) or normal hue (8-bit)
110
+ */
111
+ moveToHueLogic(targetHue: number, direction: any, transitionTime: number, isEnhancedHue?: boolean): any;
112
+ /**
113
+ * Called when saturation is changed individually
114
+ * @param targetSaturation - Target saturation value (0-254)
115
+ * @param transitionTime - Transition time in seconds
116
+ */
117
+ moveToSaturationLogic(targetSaturation: number, transitionTime: number): any;
118
+ /**
119
+ * Called when all color movement should be stopped
120
+ */
121
+ stopAllColorMovement(): any;
122
+ }
123
+ //# sourceMappingURL=matterBehaviors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matterBehaviors.d.ts","sourceRoot":"","sources":["../../src/matter/matterBehaviors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAE5D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,wBAAwB,CAAA;AAkB/B;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAEtD;AA4BD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,oBAAoB,QAc9B;AASD;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,WAAW;IAC3C,EAAE,IAAI,GAAG;IAyBT,GAAG,IAAI,GAAG;IAyBV,MAAM,IAAI,GAAG;CAuBvB;AAED;;GAEG;AACH,qBAAa,4BAA6B,SAAQ,kBAAkB;IACzD,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG;IAyB9B,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG;IAkBvB,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG;IAkBvB,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG;CAiBjC;AAED;;GAEG;AACH,qBAAa,8BAA+B,SAAQ,oBAAoB;IAC7D,QAAQ,IAAI,GAAG;IA+Bf,WAAW,IAAI,GAAG;IA+BlB,UAAU,IAAI,GAAG;CA8B3B;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc;IACjD,QAAQ,IAAI,GAAG;IA0Bf,UAAU,IAAI,GAAG;CAyB3B;AAED;;GAEG;AACH,qBAAa,0BAA2B,SAAQ,gBAAgB;IACrD,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG;CA8B/C;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc;IACjD,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG;CAiBrC;AAED;;;;;GAKG;AACH,qBAAa,4BAA6B,SAAQ,kBAAkB;IAClE;;;;OAIG;IACM,2BAA2B,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,GAAG;IA4BvF;;;;;OAKG;IACM,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,GAAG;IA+B9G;;;;;OAKG;IACM,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,GAAG;IA+BxF;;;;;;OAMG;IACM,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,GAAG;IA8B9G;;;;OAIG;IACM,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,GAAG;IA4BrF;;OAEG;IACM,oBAAoB,IAAI,GAAG;CAiBrC"}