homebridge 2.0.0-alpha.40 → 2.0.0-alpha.41
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.
- package/config-sample.json +1 -12
- package/dist/api.d.ts +4 -20
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -27
- package/dist/api.js.map +1 -1
- package/dist/bridgeService.d.ts +12 -15
- package/dist/bridgeService.d.ts.map +1 -1
- package/dist/bridgeService.js +7 -7
- package/dist/bridgeService.js.map +1 -1
- package/dist/childBridgeService.d.ts +1 -0
- package/dist/childBridgeService.d.ts.map +1 -1
- package/dist/childBridgeService.js +1 -0
- package/dist/childBridgeService.js.map +1 -1
- package/dist/childMatterBridgeFork.d.ts +108 -0
- package/dist/childMatterBridgeFork.d.ts.map +1 -0
- package/dist/childMatterBridgeFork.js +330 -0
- package/dist/childMatterBridgeFork.js.map +1 -0
- package/dist/childMatterBridgeService.d.ts +166 -0
- package/dist/childMatterBridgeService.d.ts.map +1 -0
- package/dist/childMatterBridgeService.js +623 -0
- package/dist/childMatterBridgeService.js.map +1 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/ipcService.d.ts +19 -3
- package/dist/ipcService.d.ts.map +1 -1
- package/dist/ipcService.js +13 -0
- package/dist/ipcService.js.map +1 -1
- package/dist/matter/index.d.ts +13 -0
- package/dist/matter/index.d.ts.map +1 -0
- package/dist/matter/index.js +12 -0
- package/dist/matter/index.js.map +1 -0
- package/dist/matter/matterBridge.d.ts +64 -0
- package/dist/matter/matterBridge.d.ts.map +1 -0
- package/dist/matter/matterBridge.js +154 -0
- package/dist/matter/matterBridge.js.map +1 -0
- package/dist/matter/matterConfigValidator.d.ts +27 -0
- package/dist/matter/matterConfigValidator.d.ts.map +1 -0
- package/dist/matter/matterConfigValidator.js +162 -0
- package/dist/matter/matterConfigValidator.js.map +1 -0
- package/dist/matter/matterDevice.d.ts +107 -0
- package/dist/matter/matterDevice.d.ts.map +1 -0
- package/dist/matter/matterDevice.js +913 -0
- package/dist/matter/matterDevice.js.map +1 -0
- package/dist/matter/matterDiagnostics.d.ts +121 -0
- package/dist/matter/matterDiagnostics.d.ts.map +1 -0
- package/dist/matter/matterDiagnostics.js +323 -0
- package/dist/matter/matterDiagnostics.js.map +1 -0
- package/dist/matter/matterErrorHandler.d.ts +113 -0
- package/dist/matter/matterErrorHandler.d.ts.map +1 -0
- package/dist/matter/matterErrorHandler.js +482 -0
- package/dist/matter/matterErrorHandler.js.map +1 -0
- package/dist/matter/matterNetworkMonitor.d.ts +65 -0
- package/dist/matter/matterNetworkMonitor.d.ts.map +1 -0
- package/dist/matter/matterNetworkMonitor.js +227 -0
- package/dist/matter/matterNetworkMonitor.js.map +1 -0
- package/dist/matter/matterServer.d.ts +110 -0
- package/dist/matter/matterServer.d.ts.map +1 -0
- package/dist/matter/matterServer.js +584 -0
- package/dist/matter/matterServer.js.map +1 -0
- package/dist/matter/matterSharedTypes.d.ts +167 -0
- package/dist/matter/matterSharedTypes.d.ts.map +1 -0
- package/dist/matter/matterSharedTypes.js +55 -0
- package/dist/matter/matterSharedTypes.js.map +1 -0
- package/dist/{matterTypes.d.ts → matter/matterTypes.d.ts} +15 -0
- package/dist/matter/matterTypes.d.ts.map +1 -0
- package/dist/{matterTypes.js → matter/matterTypes.js} +4 -4
- package/dist/matter/matterTypes.js.map +1 -0
- package/dist/matter/portAllocator.d.ts +85 -0
- package/dist/matter/portAllocator.d.ts.map +1 -0
- package/dist/matter/portAllocator.js +296 -0
- package/dist/matter/portAllocator.js.map +1 -0
- package/dist/server.d.ts +9 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +363 -31
- package/dist/server.js.map +1 -1
- package/package.json +10 -10
- package/dist/matterConfigValidator.d.ts +0 -34
- package/dist/matterConfigValidator.d.ts.map +0 -1
- package/dist/matterConfigValidator.js +0 -249
- package/dist/matterConfigValidator.js.map +0 -1
- package/dist/matterService.d.ts +0 -168
- package/dist/matterService.d.ts.map +0 -1
- package/dist/matterService.js +0 -677
- package/dist/matterService.js.map +0 -1
- package/dist/matterTypes.d.ts.map +0 -1
- package/dist/matterTypes.js.map +0 -1
- package/dist/util/matter-cli.d.ts +0 -3
- package/dist/util/matter-cli.d.ts.map +0 -1
- package/dist/util/matter-cli.js +0 -211
- package/dist/util/matter-cli.js.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Matter Types
|
|
3
|
+
*
|
|
4
|
+
* These types are used by both the homebridge core and the UI
|
|
5
|
+
* to ensure consistency across the Matter implementation.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Matter bridge status states
|
|
9
|
+
*/
|
|
10
|
+
export declare enum MatterBridgeStatus {
|
|
11
|
+
/**
|
|
12
|
+
* When the Matter bridge is loading or restarting
|
|
13
|
+
*/
|
|
14
|
+
PENDING = "pending",
|
|
15
|
+
/**
|
|
16
|
+
* The Matter bridge is online and ready for commissioning
|
|
17
|
+
*/
|
|
18
|
+
OK = "ok",
|
|
19
|
+
/**
|
|
20
|
+
* The bridge is shutting down or stopped
|
|
21
|
+
*/
|
|
22
|
+
DOWN = "down"
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Metadata for a Matter bridge instance
|
|
26
|
+
*/
|
|
27
|
+
export interface MatterBridgeMetadata {
|
|
28
|
+
/** Bridge type identifier */
|
|
29
|
+
type: 'matter';
|
|
30
|
+
/** Current operational status */
|
|
31
|
+
status: MatterBridgeStatus;
|
|
32
|
+
/** Matter server port */
|
|
33
|
+
port?: number;
|
|
34
|
+
/** QR code payload for commissioning */
|
|
35
|
+
qrCode?: string;
|
|
36
|
+
/** Manual pairing code for commissioning */
|
|
37
|
+
manualPairingCode?: string;
|
|
38
|
+
/** Device serial number */
|
|
39
|
+
serialNumber?: string;
|
|
40
|
+
/** Display name of the bridge */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Plugin identifier */
|
|
43
|
+
plugin: string;
|
|
44
|
+
/** Unique identifier for this bridge instance */
|
|
45
|
+
identifier: string;
|
|
46
|
+
/** Number of devices exposed by this bridge */
|
|
47
|
+
deviceCount: number;
|
|
48
|
+
/** Whether the bridge was manually stopped */
|
|
49
|
+
manuallyStopped?: boolean;
|
|
50
|
+
/** Process ID of the bridge if running as child process */
|
|
51
|
+
pid?: number;
|
|
52
|
+
/** Whether the bridge has been commissioned */
|
|
53
|
+
commissioned?: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Matter commissioning information
|
|
57
|
+
*/
|
|
58
|
+
export interface MatterCommissioningInfo {
|
|
59
|
+
/** QR code payload for commissioning */
|
|
60
|
+
qrCode?: string;
|
|
61
|
+
/** Manual pairing code for commissioning */
|
|
62
|
+
manualPairingCode?: string;
|
|
63
|
+
/** Device serial number */
|
|
64
|
+
serialNumber?: string;
|
|
65
|
+
/** Whether the device is commissioned */
|
|
66
|
+
commissioned: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Matter accessory information
|
|
70
|
+
*/
|
|
71
|
+
export interface MatterAccessoryInfo {
|
|
72
|
+
/** Unique identifier */
|
|
73
|
+
uuid: string;
|
|
74
|
+
/** Display name */
|
|
75
|
+
displayName: string;
|
|
76
|
+
/** HAP category */
|
|
77
|
+
category: number;
|
|
78
|
+
/** Matter device information */
|
|
79
|
+
matterInfo?: {
|
|
80
|
+
/** Whether this is a bridged device */
|
|
81
|
+
bridged: boolean;
|
|
82
|
+
/** Child bridge identifier if bridged */
|
|
83
|
+
childBridge?: string;
|
|
84
|
+
/** Matter device type */
|
|
85
|
+
deviceType?: string;
|
|
86
|
+
};
|
|
87
|
+
/** HAP services */
|
|
88
|
+
services?: Array<{
|
|
89
|
+
type: string;
|
|
90
|
+
subtype?: string;
|
|
91
|
+
displayName?: string;
|
|
92
|
+
characteristics: Array<{
|
|
93
|
+
type: string;
|
|
94
|
+
value: any;
|
|
95
|
+
props: any;
|
|
96
|
+
}>;
|
|
97
|
+
}>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Matter server configuration
|
|
101
|
+
*/
|
|
102
|
+
export interface MatterServerConfig {
|
|
103
|
+
/** Server port */
|
|
104
|
+
port?: number;
|
|
105
|
+
/** Bridge name */
|
|
106
|
+
name?: string;
|
|
107
|
+
/** Unique identifier */
|
|
108
|
+
uniqueId?: string;
|
|
109
|
+
/** Storage path */
|
|
110
|
+
storagePath?: string;
|
|
111
|
+
/** mDNS interface */
|
|
112
|
+
mdnsInterface?: string;
|
|
113
|
+
/** Enable IPv4 */
|
|
114
|
+
ipv4?: boolean;
|
|
115
|
+
/** Enable IPv6 */
|
|
116
|
+
ipv6?: boolean;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Child Matter configuration (extends server config)
|
|
120
|
+
*/
|
|
121
|
+
export interface ChildMatterConfiguration extends Partial<MatterServerConfig> {
|
|
122
|
+
/** Whether Matter is enabled */
|
|
123
|
+
enabled?: boolean;
|
|
124
|
+
/** Bridge name override */
|
|
125
|
+
name?: string;
|
|
126
|
+
/** Debug mode flag */
|
|
127
|
+
debug?: boolean;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Matter accessories collection
|
|
131
|
+
*/
|
|
132
|
+
export interface MatterAccessoriesResponse {
|
|
133
|
+
/** Child bridge accessories indexed by bridge ID */
|
|
134
|
+
children: {
|
|
135
|
+
[bridgeId: string]: MatterAccessoryInfo[];
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* IPC message types for Matter child bridges
|
|
140
|
+
*/
|
|
141
|
+
export declare enum ChildMatterMessageType {
|
|
142
|
+
/** Sent from child when ready to accept config */
|
|
143
|
+
READY = "ready",
|
|
144
|
+
/** Sent to child with configuration */
|
|
145
|
+
LOAD = "load",
|
|
146
|
+
/** Sent from child when loaded */
|
|
147
|
+
LOADED = "loaded",
|
|
148
|
+
/** Sent to child to start the Matter bridge */
|
|
149
|
+
START = "start",
|
|
150
|
+
/** Sent from child when Matter bridge is online */
|
|
151
|
+
ONLINE = "online",
|
|
152
|
+
/** Sent to/from child to add an accessory */
|
|
153
|
+
ADD_ACCESSORY = "addAccessory",
|
|
154
|
+
/** Sent to/from child to remove an accessory */
|
|
155
|
+
REMOVE_ACCESSORY = "removeAccessory",
|
|
156
|
+
/** Sent from child with status updates */
|
|
157
|
+
STATUS_UPDATE = "statusUpdate",
|
|
158
|
+
/** Sent from child when requesting a port */
|
|
159
|
+
PORT_REQUEST = "portRequest",
|
|
160
|
+
/** Sent from child when an error occurs */
|
|
161
|
+
ERROR = "error",
|
|
162
|
+
/** Sent to child with allocated port */
|
|
163
|
+
PORT_ALLOCATED = "portAllocated",
|
|
164
|
+
/** Sent to child to shut down */
|
|
165
|
+
SHUTDOWN = "shutdown"
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=matterSharedTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterSharedTypes.d.ts","sourceRoot":"","sources":["../../src/matter/matterSharedTypes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,oBAAY,kBAAkB;IAC5B;;OAEG;IACH,OAAO,YAAY;IAEnB;;OAEG;IACH,EAAE,OAAO;IAET;;OAEG;IACH,IAAI,SAAS;CACd;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,IAAI,EAAE,QAAQ,CAAA;IACd,iCAAiC;IACjC,MAAM,EAAE,kBAAkB,CAAA;IAC1B,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,+CAA+C;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,yCAAyC;IACzC,YAAY,EAAE,OAAO,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,mBAAmB;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,gCAAgC;IAChC,UAAU,CAAC,EAAE;QACX,uCAAuC;QACvC,OAAO,EAAE,OAAO,CAAA;QAChB,yCAAyC;QACzC,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,yBAAyB;QACzB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,mBAAmB;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,eAAe,EAAE,KAAK,CAAC;YACrB,IAAI,EAAE,MAAM,CAAA;YACZ,KAAK,EAAE,GAAG,CAAA;YACV,KAAK,EAAE,GAAG,CAAA;SACX,CAAC,CAAA;KACH,CAAC,CAAA;CACH;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qBAAqB;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,kBAAkB;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,OAAO,CAAC,kBAAkB,CAAC;IAC3E,gCAAgC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,oDAAoD;IACpD,QAAQ,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAAA;KAAE,CAAA;CACxD;AAED;;GAEG;AACH,oBAAY,sBAAsB;IAChC,kDAAkD;IAClD,KAAK,UAAU;IACf,uCAAuC;IACvC,IAAI,SAAS;IACb,kCAAkC;IAClC,MAAM,WAAW;IACjB,+CAA+C;IAC/C,KAAK,UAAU;IACf,mDAAmD;IACnD,MAAM,WAAW;IACjB,6CAA6C;IAC7C,aAAa,iBAAiB;IAC9B,gDAAgD;IAChD,gBAAgB,oBAAoB;IACpC,0CAA0C;IAC1C,aAAa,iBAAiB;IAC9B,6CAA6C;IAC7C,YAAY,gBAAgB;IAC5B,2CAA2C;IAC3C,KAAK,UAAU;IACf,wCAAwC;IACxC,cAAc,kBAAkB;IAChC,iCAAiC;IACjC,QAAQ,aAAa;CACtB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Matter Types
|
|
3
|
+
*
|
|
4
|
+
* These types are used by both the homebridge core and the UI
|
|
5
|
+
* to ensure consistency across the Matter implementation.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Matter bridge status states
|
|
9
|
+
*/
|
|
10
|
+
export var MatterBridgeStatus;
|
|
11
|
+
(function (MatterBridgeStatus) {
|
|
12
|
+
/**
|
|
13
|
+
* When the Matter bridge is loading or restarting
|
|
14
|
+
*/
|
|
15
|
+
MatterBridgeStatus["PENDING"] = "pending";
|
|
16
|
+
/**
|
|
17
|
+
* The Matter bridge is online and ready for commissioning
|
|
18
|
+
*/
|
|
19
|
+
MatterBridgeStatus["OK"] = "ok";
|
|
20
|
+
/**
|
|
21
|
+
* The bridge is shutting down or stopped
|
|
22
|
+
*/
|
|
23
|
+
MatterBridgeStatus["DOWN"] = "down";
|
|
24
|
+
})(MatterBridgeStatus || (MatterBridgeStatus = {}));
|
|
25
|
+
/**
|
|
26
|
+
* IPC message types for Matter child bridges
|
|
27
|
+
*/
|
|
28
|
+
export var ChildMatterMessageType;
|
|
29
|
+
(function (ChildMatterMessageType) {
|
|
30
|
+
/** Sent from child when ready to accept config */
|
|
31
|
+
ChildMatterMessageType["READY"] = "ready";
|
|
32
|
+
/** Sent to child with configuration */
|
|
33
|
+
ChildMatterMessageType["LOAD"] = "load";
|
|
34
|
+
/** Sent from child when loaded */
|
|
35
|
+
ChildMatterMessageType["LOADED"] = "loaded";
|
|
36
|
+
/** Sent to child to start the Matter bridge */
|
|
37
|
+
ChildMatterMessageType["START"] = "start";
|
|
38
|
+
/** Sent from child when Matter bridge is online */
|
|
39
|
+
ChildMatterMessageType["ONLINE"] = "online";
|
|
40
|
+
/** Sent to/from child to add an accessory */
|
|
41
|
+
ChildMatterMessageType["ADD_ACCESSORY"] = "addAccessory";
|
|
42
|
+
/** Sent to/from child to remove an accessory */
|
|
43
|
+
ChildMatterMessageType["REMOVE_ACCESSORY"] = "removeAccessory";
|
|
44
|
+
/** Sent from child with status updates */
|
|
45
|
+
ChildMatterMessageType["STATUS_UPDATE"] = "statusUpdate";
|
|
46
|
+
/** Sent from child when requesting a port */
|
|
47
|
+
ChildMatterMessageType["PORT_REQUEST"] = "portRequest";
|
|
48
|
+
/** Sent from child when an error occurs */
|
|
49
|
+
ChildMatterMessageType["ERROR"] = "error";
|
|
50
|
+
/** Sent to child with allocated port */
|
|
51
|
+
ChildMatterMessageType["PORT_ALLOCATED"] = "portAllocated";
|
|
52
|
+
/** Sent to child to shut down */
|
|
53
|
+
ChildMatterMessageType["SHUTDOWN"] = "shutdown";
|
|
54
|
+
})(ChildMatterMessageType || (ChildMatterMessageType = {}));
|
|
55
|
+
//# sourceMappingURL=matterSharedTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterSharedTypes.js","sourceRoot":"","sources":["../../src/matter/matterSharedTypes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,CAAN,IAAY,kBAeX;AAfD,WAAY,kBAAkB;IAC5B;;OAEG;IACH,yCAAmB,CAAA;IAEnB;;OAEG;IACH,+BAAS,CAAA;IAET;;OAEG;IACH,mCAAa,CAAA;AACf,CAAC,EAfW,kBAAkB,KAAlB,kBAAkB,QAe7B;AAwHD;;GAEG;AACH,MAAM,CAAN,IAAY,sBAyBX;AAzBD,WAAY,sBAAsB;IAChC,kDAAkD;IAClD,yCAAe,CAAA;IACf,uCAAuC;IACvC,uCAAa,CAAA;IACb,kCAAkC;IAClC,2CAAiB,CAAA;IACjB,+CAA+C;IAC/C,yCAAe,CAAA;IACf,mDAAmD;IACnD,2CAAiB,CAAA;IACjB,6CAA6C;IAC7C,wDAA8B,CAAA;IAC9B,gDAAgD;IAChD,8DAAoC,CAAA;IACpC,0CAA0C;IAC1C,wDAA8B,CAAA;IAC9B,6CAA6C;IAC7C,sDAA4B,CAAA;IAC5B,2CAA2C;IAC3C,yCAAe,CAAA;IACf,wCAAwC;IACxC,0DAAgC,CAAA;IAChC,iCAAiC;IACjC,+CAAqB,CAAA;AACvB,CAAC,EAzBW,sBAAsB,KAAtB,sBAAsB,QAyBjC"}
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
import { HomebridgeOptions } from '../server.js';
|
|
2
|
+
/**
|
|
3
|
+
* Matter bridge configuration interface
|
|
4
|
+
*/
|
|
5
|
+
export interface MatterConfiguration {
|
|
6
|
+
port?: number;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Matter bridge options extending Homebridge options
|
|
11
|
+
*/
|
|
12
|
+
export interface MatterBridgeOptions extends HomebridgeOptions {
|
|
13
|
+
matterBridgeServerPort?: number;
|
|
14
|
+
configPath?: string;
|
|
15
|
+
}
|
|
1
16
|
declare const MatterClusters: Record<string, unknown>;
|
|
2
17
|
declare const MatterDeviceTypes: Record<string, unknown>;
|
|
3
18
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterTypes.d.ts","sourceRoot":"","sources":["../../src/matter/matterTypes.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEhD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAGD,QAAA,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,CAAA;AAClD,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,CAAA;AAuHrD;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAoF9D,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmC3D,CAAA;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAwB/G;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA2BxG;AAED,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAA"}
|
|
@@ -7,8 +7,8 @@ import * as devices from '@matter/main/devices';
|
|
|
7
7
|
* This module provides access to standard Matter device types and clusters
|
|
8
8
|
* that plugin developers can use to create Matter-compatible devices.
|
|
9
9
|
*/
|
|
10
|
-
import { Logger } from '
|
|
11
|
-
const log = Logger.
|
|
10
|
+
import { Logger } from '../logger.js';
|
|
11
|
+
const log = Logger.withPrefix('Matter');
|
|
12
12
|
const MatterClusters = {};
|
|
13
13
|
const MatterDeviceTypes = {};
|
|
14
14
|
try {
|
|
@@ -219,8 +219,8 @@ export const HAPToMatterDeviceMapping = {
|
|
|
219
219
|
// Window covering services
|
|
220
220
|
WindowCovering: 'WindowCovering',
|
|
221
221
|
// Other services
|
|
222
|
-
StatelessProgrammableSwitch: '
|
|
223
|
-
Valve: '
|
|
222
|
+
StatelessProgrammableSwitch: 'OnOffLightSwitch', // Use light switch as closest match
|
|
223
|
+
Valve: 'OnOffPlugInUnit', // Use outlet as closest match for valve control
|
|
224
224
|
};
|
|
225
225
|
/**
|
|
226
226
|
* Helper function to get Matter device type for a HomeKit service
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterTypes.js","sourceRoot":"","sources":["../../src/matter/matterTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port Allocator for Matter Bridges
|
|
3
|
+
*
|
|
4
|
+
* Thread-safe port allocation with conflict prevention
|
|
5
|
+
* and automatic port discovery
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Port allocation result
|
|
9
|
+
*/
|
|
10
|
+
export interface PortAllocation {
|
|
11
|
+
port: number;
|
|
12
|
+
type: 'matter' | 'hap';
|
|
13
|
+
identifier: string;
|
|
14
|
+
allocated: Date;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Port allocator with thread-safe allocation and tracking
|
|
18
|
+
*/
|
|
19
|
+
export declare class PortAllocator {
|
|
20
|
+
private static instance;
|
|
21
|
+
private allocatedPorts;
|
|
22
|
+
private reservedRanges;
|
|
23
|
+
private mutex;
|
|
24
|
+
private defaultMatterStart;
|
|
25
|
+
private defaultMatterEnd;
|
|
26
|
+
private defaultHAPStart;
|
|
27
|
+
private defaultHAPEnd;
|
|
28
|
+
private constructor();
|
|
29
|
+
/**
|
|
30
|
+
* Get singleton instance
|
|
31
|
+
*/
|
|
32
|
+
static getInstance(): PortAllocator;
|
|
33
|
+
/**
|
|
34
|
+
* Allocate a port for Matter or HAP
|
|
35
|
+
*/
|
|
36
|
+
allocatePort(type: 'matter' | 'hap', identifier: string, preferredPort?: number): Promise<number>;
|
|
37
|
+
/**
|
|
38
|
+
* Release an allocated port
|
|
39
|
+
*/
|
|
40
|
+
releasePort(port: number): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Release all ports for an identifier
|
|
43
|
+
*/
|
|
44
|
+
releasePorts(identifier: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Check if a port is available
|
|
47
|
+
*/
|
|
48
|
+
private isPortAvailable;
|
|
49
|
+
/**
|
|
50
|
+
* Find any available port
|
|
51
|
+
*/
|
|
52
|
+
private findAvailablePort;
|
|
53
|
+
/**
|
|
54
|
+
* Get all allocated ports
|
|
55
|
+
*/
|
|
56
|
+
getAllocatedPorts(): Map<number, PortAllocation>;
|
|
57
|
+
/**
|
|
58
|
+
* Check for port conflicts
|
|
59
|
+
*/
|
|
60
|
+
checkForConflicts(): Promise<Array<{
|
|
61
|
+
port: number;
|
|
62
|
+
identifier: string;
|
|
63
|
+
available: boolean;
|
|
64
|
+
}>>;
|
|
65
|
+
/**
|
|
66
|
+
* Clear all allocations (use with caution)
|
|
67
|
+
*/
|
|
68
|
+
clearAllocations(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Set custom port range for a type
|
|
71
|
+
*/
|
|
72
|
+
setPortRange(type: 'matter' | 'hap', start: number, end: number): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get statistics about port allocation
|
|
75
|
+
*/
|
|
76
|
+
getStats(): {
|
|
77
|
+
totalAllocated: number;
|
|
78
|
+
matterPorts: number;
|
|
79
|
+
hapPorts: number;
|
|
80
|
+
oldestAllocation?: Date;
|
|
81
|
+
newestAllocation?: Date;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export declare const portAllocator: PortAllocator;
|
|
85
|
+
//# sourceMappingURL=portAllocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portAllocator.d.ts","sourceRoot":"","sources":["../../src/matter/portAllocator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4DH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,QAAQ,GAAG,KAAK,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,IAAI,CAAA;CAChB;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAe;IACtC,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,cAAc,CAAoD;IAC1E,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,kBAAkB,CAAO;IACjC,OAAO,CAAC,gBAAgB,CAAO;IAC/B,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,aAAa,CAAQ;IAE7B,OAAO;IAYP;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,aAAa;IAOnC;;OAEG;IACG,YAAY,CAChB,IAAI,EAAE,QAAQ,GAAG,KAAK,EACtB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC;IAkDlB;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBrD;;OAEG;YACW,eAAe;IA6B7B;;OAEG;YACW,iBAAiB;IA0B/B;;OAEG;IACH,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAIhD;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAiBnG;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAKxB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAStE;;OAEG;IACH,QAAQ,IAAI;QACV,cAAc,EAAE,MAAM,CAAA;QACtB,WAAW,EAAE,MAAM,CAAA;QACnB,QAAQ,EAAE,MAAM,CAAA;QAChB,gBAAgB,CAAC,EAAE,IAAI,CAAA;QACvB,gBAAgB,CAAC,EAAE,IAAI,CAAA;KACxB;CA6BF;AAGD,eAAO,MAAM,aAAa,eAA8B,CAAA"}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port Allocator for Matter Bridges
|
|
3
|
+
*
|
|
4
|
+
* Thread-safe port allocation with conflict prevention
|
|
5
|
+
* and automatic port discovery
|
|
6
|
+
*/
|
|
7
|
+
import * as net from 'node:net';
|
|
8
|
+
import { Logger } from '../logger.js';
|
|
9
|
+
const log = Logger.withPrefix('Matter');
|
|
10
|
+
/**
|
|
11
|
+
* Simple mutex implementation for synchronization
|
|
12
|
+
*/
|
|
13
|
+
class Mutex {
|
|
14
|
+
queue = [];
|
|
15
|
+
locked = false;
|
|
16
|
+
MAX_QUEUE_SIZE = 100; // Prevent unbounded growth
|
|
17
|
+
/**
|
|
18
|
+
* Acquire the lock
|
|
19
|
+
*/
|
|
20
|
+
async acquire() {
|
|
21
|
+
if (!this.locked) {
|
|
22
|
+
this.locked = true;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Prevent queue from growing unbounded
|
|
26
|
+
if (this.queue.length >= this.MAX_QUEUE_SIZE) {
|
|
27
|
+
throw new Error(`Port allocator queue exceeded maximum size (${this.MAX_QUEUE_SIZE})`);
|
|
28
|
+
}
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
this.queue.push(resolve);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Release the lock
|
|
35
|
+
*/
|
|
36
|
+
release() {
|
|
37
|
+
const next = this.queue.shift();
|
|
38
|
+
if (next) {
|
|
39
|
+
next();
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.locked = false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run a function exclusively with the lock
|
|
47
|
+
*/
|
|
48
|
+
async runExclusive(fn) {
|
|
49
|
+
await this.acquire();
|
|
50
|
+
try {
|
|
51
|
+
return await fn();
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
this.release();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Port allocator with thread-safe allocation and tracking
|
|
60
|
+
*/
|
|
61
|
+
export class PortAllocator {
|
|
62
|
+
static instance;
|
|
63
|
+
allocatedPorts = new Map();
|
|
64
|
+
reservedRanges = new Map();
|
|
65
|
+
mutex = new Mutex();
|
|
66
|
+
defaultMatterStart = 5540;
|
|
67
|
+
defaultMatterEnd = 5580;
|
|
68
|
+
defaultHAPStart = 51826;
|
|
69
|
+
defaultHAPEnd = 51926;
|
|
70
|
+
constructor() {
|
|
71
|
+
// Reserve default ranges
|
|
72
|
+
this.reservedRanges.set('matter', {
|
|
73
|
+
start: this.defaultMatterStart,
|
|
74
|
+
end: this.defaultMatterEnd,
|
|
75
|
+
});
|
|
76
|
+
this.reservedRanges.set('hap', {
|
|
77
|
+
start: this.defaultHAPStart,
|
|
78
|
+
end: this.defaultHAPEnd,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get singleton instance
|
|
83
|
+
*/
|
|
84
|
+
static getInstance() {
|
|
85
|
+
if (!PortAllocator.instance) {
|
|
86
|
+
PortAllocator.instance = new PortAllocator();
|
|
87
|
+
}
|
|
88
|
+
return PortAllocator.instance;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Allocate a port for Matter or HAP
|
|
92
|
+
*/
|
|
93
|
+
async allocatePort(type, identifier, preferredPort) {
|
|
94
|
+
return this.mutex.runExclusive(async () => {
|
|
95
|
+
// Try preferred port first
|
|
96
|
+
if (preferredPort) {
|
|
97
|
+
if (await this.isPortAvailable(preferredPort)) {
|
|
98
|
+
this.allocatedPorts.set(preferredPort, {
|
|
99
|
+
port: preferredPort,
|
|
100
|
+
type,
|
|
101
|
+
identifier,
|
|
102
|
+
allocated: new Date(),
|
|
103
|
+
});
|
|
104
|
+
log.info(`Allocated port ${preferredPort} for ${type} bridge: ${identifier}`);
|
|
105
|
+
return preferredPort;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
log.warn(`Preferred port ${preferredPort} is not available for ${identifier}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Find an available port in the appropriate range
|
|
112
|
+
const range = this.reservedRanges.get(type);
|
|
113
|
+
if (!range) {
|
|
114
|
+
throw new Error(`No port range defined for type: ${type}`);
|
|
115
|
+
}
|
|
116
|
+
for (let port = range.start; port <= range.end; port++) {
|
|
117
|
+
if (!this.allocatedPorts.has(port) && await this.isPortAvailable(port)) {
|
|
118
|
+
this.allocatedPorts.set(port, {
|
|
119
|
+
port,
|
|
120
|
+
type,
|
|
121
|
+
identifier,
|
|
122
|
+
allocated: new Date(),
|
|
123
|
+
});
|
|
124
|
+
log.info(`Allocated port ${port} for ${type} bridge: ${identifier}`);
|
|
125
|
+
return port;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// If no port in range is available, try to find any available port
|
|
129
|
+
const fallbackPort = await this.findAvailablePort();
|
|
130
|
+
this.allocatedPorts.set(fallbackPort, {
|
|
131
|
+
port: fallbackPort,
|
|
132
|
+
type,
|
|
133
|
+
identifier,
|
|
134
|
+
allocated: new Date(),
|
|
135
|
+
});
|
|
136
|
+
log.warn(`Allocated fallback port ${fallbackPort} for ${type} bridge: ${identifier}`);
|
|
137
|
+
return fallbackPort;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Release an allocated port
|
|
142
|
+
*/
|
|
143
|
+
async releasePort(port) {
|
|
144
|
+
return this.mutex.runExclusive(async () => {
|
|
145
|
+
const allocation = this.allocatedPorts.get(port);
|
|
146
|
+
if (allocation) {
|
|
147
|
+
this.allocatedPorts.delete(port);
|
|
148
|
+
log.debug(`Released port ${port} (was allocated to ${allocation.identifier})`);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Release all ports for an identifier
|
|
154
|
+
*/
|
|
155
|
+
async releasePorts(identifier) {
|
|
156
|
+
return this.mutex.runExclusive(async () => {
|
|
157
|
+
const portsToRelease = [];
|
|
158
|
+
for (const [port, allocation] of this.allocatedPorts) {
|
|
159
|
+
if (allocation.identifier === identifier) {
|
|
160
|
+
portsToRelease.push(port);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
for (const port of portsToRelease) {
|
|
164
|
+
this.allocatedPorts.delete(port);
|
|
165
|
+
log.debug(`Released port ${port} for identifier ${identifier}`);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if a port is available
|
|
171
|
+
*/
|
|
172
|
+
async isPortAvailable(port) {
|
|
173
|
+
// Check if already allocated by us
|
|
174
|
+
if (this.allocatedPorts.has(port)) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
// Check if port is actually available on the system
|
|
178
|
+
return new Promise((resolve) => {
|
|
179
|
+
const server = net.createServer();
|
|
180
|
+
server.once('error', (err) => {
|
|
181
|
+
if (err.code === 'EADDRINUSE') {
|
|
182
|
+
resolve(false);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// Other errors, assume port is not available
|
|
186
|
+
resolve(false);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
server.once('listening', () => {
|
|
190
|
+
server.close(() => {
|
|
191
|
+
resolve(true);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
server.listen(port, '0.0.0.0');
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Find any available port
|
|
199
|
+
*/
|
|
200
|
+
async findAvailablePort() {
|
|
201
|
+
return new Promise((resolve, reject) => {
|
|
202
|
+
const server = net.createServer();
|
|
203
|
+
server.once('error', (err) => {
|
|
204
|
+
reject(err);
|
|
205
|
+
});
|
|
206
|
+
server.once('listening', () => {
|
|
207
|
+
const address = server.address();
|
|
208
|
+
if (address && typeof address === 'object') {
|
|
209
|
+
const port = address.port;
|
|
210
|
+
server.close(() => {
|
|
211
|
+
resolve(port);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
server.close();
|
|
216
|
+
reject(new Error('Could not determine port'));
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
// Listen on port 0 to get a random available port
|
|
220
|
+
server.listen(0, '0.0.0.0');
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get all allocated ports
|
|
225
|
+
*/
|
|
226
|
+
getAllocatedPorts() {
|
|
227
|
+
return new Map(this.allocatedPorts);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Check for port conflicts
|
|
231
|
+
*/
|
|
232
|
+
async checkForConflicts() {
|
|
233
|
+
const conflicts = [];
|
|
234
|
+
for (const [port, allocation] of this.allocatedPorts) {
|
|
235
|
+
const available = await this.isPortAvailable(port);
|
|
236
|
+
if (!available) {
|
|
237
|
+
conflicts.push({
|
|
238
|
+
port,
|
|
239
|
+
identifier: allocation.identifier,
|
|
240
|
+
available,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return conflicts;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Clear all allocations (use with caution)
|
|
248
|
+
*/
|
|
249
|
+
clearAllocations() {
|
|
250
|
+
this.allocatedPorts.clear();
|
|
251
|
+
log.warn('Cleared all port allocations');
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Set custom port range for a type
|
|
255
|
+
*/
|
|
256
|
+
setPortRange(type, start, end) {
|
|
257
|
+
if (start < 1024 || end > 65535 || start > end) {
|
|
258
|
+
throw new Error('Invalid port range');
|
|
259
|
+
}
|
|
260
|
+
this.reservedRanges.set(type, { start, end });
|
|
261
|
+
log.info(`Set ${type} port range to ${start}-${end}`);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Get statistics about port allocation
|
|
265
|
+
*/
|
|
266
|
+
getStats() {
|
|
267
|
+
let matterPorts = 0;
|
|
268
|
+
let hapPorts = 0;
|
|
269
|
+
let oldest;
|
|
270
|
+
let newest;
|
|
271
|
+
for (const allocation of this.allocatedPorts.values()) {
|
|
272
|
+
if (allocation.type === 'matter') {
|
|
273
|
+
matterPorts++;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
hapPorts++;
|
|
277
|
+
}
|
|
278
|
+
if (!oldest || allocation.allocated < oldest) {
|
|
279
|
+
oldest = allocation.allocated;
|
|
280
|
+
}
|
|
281
|
+
if (!newest || allocation.allocated > newest) {
|
|
282
|
+
newest = allocation.allocated;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
totalAllocated: this.allocatedPorts.size,
|
|
287
|
+
matterPorts,
|
|
288
|
+
hapPorts,
|
|
289
|
+
oldestAllocation: oldest,
|
|
290
|
+
newestAllocation: newest,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// Export singleton instance
|
|
295
|
+
export const portAllocator = PortAllocator.getInstance();
|
|
296
|
+
//# sourceMappingURL=portAllocator.js.map
|