@uboness/homebridge-tedee 0.1.2 → 0.2.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 (43) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +59 -7
  3. package/config.schema.json +252 -134
  4. package/dist/bin/tedee-cleanup.d.ts +3 -0
  5. package/dist/bin/tedee-cleanup.d.ts.map +1 -0
  6. package/dist/bin/tedee-cleanup.js +85 -0
  7. package/dist/bin/tedee-cleanup.js.map +1 -0
  8. package/dist/device/device.d.ts +5 -3
  9. package/dist/device/device.d.ts.map +1 -1
  10. package/dist/device/device.js +13 -14
  11. package/dist/device/device.js.map +1 -1
  12. package/dist/device/index.d.ts +1 -0
  13. package/dist/device/index.d.ts.map +1 -1
  14. package/dist/device/index.js +1 -0
  15. package/dist/device/index.js.map +1 -1
  16. package/dist/device/lock.d.ts +24 -3
  17. package/dist/device/lock.d.ts.map +1 -1
  18. package/dist/device/lock.js +36 -8
  19. package/dist/device/lock.js.map +1 -1
  20. package/dist/settings.d.ts +8 -2
  21. package/dist/settings.d.ts.map +1 -1
  22. package/dist/settings.js +9 -2
  23. package/dist/settings.js.map +1 -1
  24. package/dist/tedee-bridge.d.ts +53 -0
  25. package/dist/tedee-bridge.d.ts.map +1 -0
  26. package/dist/tedee-bridge.js +182 -0
  27. package/dist/tedee-bridge.js.map +1 -0
  28. package/dist/tedee-client.d.ts +1 -6
  29. package/dist/tedee-client.d.ts.map +1 -1
  30. package/dist/tedee-client.js +27 -58
  31. package/dist/tedee-client.js.map +1 -1
  32. package/dist/tedee-platform.d.ts +10 -34
  33. package/dist/tedee-platform.d.ts.map +1 -1
  34. package/dist/tedee-platform.js +70 -148
  35. package/dist/tedee-platform.js.map +1 -1
  36. package/dist/webhook-server.d.ts +28 -0
  37. package/dist/webhook-server.d.ts.map +1 -0
  38. package/dist/{tedee-event-server.js → webhook-server.js} +52 -15
  39. package/dist/webhook-server.js.map +1 -0
  40. package/package.json +5 -2
  41. package/dist/tedee-event-server.d.ts +0 -25
  42. package/dist/tedee-event-server.d.ts.map +0 -1
  43. package/dist/tedee-event-server.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.2.0](https://github.com/uboness/homebridge-tedee/compare/v0.1.2...v0.2.0) (2026-07-07)
6
+
7
+
8
+ ### ⚠ BREAKING CHANGES
9
+
10
+ * the config format has changed from a single bridge to a
11
+ `bridges[]` array with shared `webhook` and `defaults` sections. Each bridge
12
+ now requires a unique, stable `id`. Because accessory UUIDs now include that
13
+ id, existing accessories are re-created and lose their room and automation
14
+ assignments. Run `tedee-cleanup <homebridge-config.json>` after upgrading to
15
+ remove the old `/tedee/events` callbacks left by the previous version.
16
+
17
+ ### Features
18
+
19
+ * multi-bridge support via a shared local webhook server ([9e6ea87](https://github.com/uboness/homebridge-tedee/commit/9e6ea873b412be25886c3ca1b2c67c1fd474d736))
20
+
5
21
  ## [0.1.2](https://github.com/uboness/homebridge-tedee/compare/v0.1.1...v0.1.2) (2026-07-06)
6
22
 
7
23
  ## 0.1.1 (2026-06-02)
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Homebridge plugin for Tedee locks using the local Tedee Bridge API only.
4
4
 
5
+ A single platform manages multiple Tedee bridges through one shared webhook server.
6
+
5
7
  ## Local Development
6
8
 
7
9
  Install dependencies with pnpm:
@@ -10,7 +12,7 @@ Install dependencies with pnpm:
10
12
  pnpm install
11
13
  ```
12
14
 
13
- Edit `.homebridge/config.json` with your Tedee Bridge IP or hostname and local API token.
15
+ Edit `.homebridge/config.json` with your Tedee bridge(s) IP/host and local API token.
14
16
 
15
17
  Run Homebridge locally:
16
18
 
@@ -24,18 +26,68 @@ Run the Homebridge UI locally:
24
26
  pnpm run ui
25
27
  ```
26
28
 
29
+ ## Configuration
30
+
31
+ ```jsonc
32
+ {
33
+ "platform": "Tedee",
34
+ "name": "Tedee",
35
+ "webhook": { "port": 8088 },
36
+ "defaults": {
37
+ "bridge": { "port": 80, "tokenMode": "encrypted", "unlockMode": 3, "lowBatteryThreshold": 20, "refreshInterval": 600000 },
38
+ "lock": { "pullSpringSwitch": false, "unlockMode": 3 }
39
+ },
40
+ "bridges": [
41
+ {
42
+ "id": "main",
43
+ "host": "192.168.1.139",
44
+ "token": "…",
45
+ "locks": [ { "id": 77178, "pullSpringSwitch": true } ]
46
+ },
47
+ {
48
+ "id": "annex",
49
+ "host": "192.168.1.138",
50
+ "token": "…",
51
+ "locks": [ { "id": 77176 } ]
52
+ }
53
+ ]
54
+ }
55
+ ```
56
+
57
+ - Each entry under `bridges` is one Tedee bridge, keyed by a unique, stable `id`.
58
+ - `defaults.bridge` / `defaults.lock` set values inherited by every bridge / lock; per-entry
59
+ settings override them.
60
+ - `webhook.host` is optional — leave it unset to auto-detect the local address each bridge
61
+ can reach the plugin on; set it only for unusual multi-subnet setups.
62
+
63
+ The bridge `id` is part of each accessory's identity and of the webhook path, so changing it
64
+ re-creates that bridge's accessories in HomeKit.
65
+
27
66
  ## Tedee Features
28
67
 
29
- - Discovers all locks paired to the configured Tedee Bridge.
68
+ - Discovers all locks paired to each configured Tedee bridge.
30
69
  - Exposes each lock as a HomeKit Lock Mechanism.
31
70
  - Adds a Battery service per lock with battery level, low battery, and charging state.
32
- - Adds a linked momentary Switch service for pulling the spring.
33
- - Starts one platform-level local callback server and registers it with the Tedee Bridge.
71
+ - Adds a linked momentary Switch service for pulling the spring (per-lock, optional).
72
+ - Runs one shared local callback server registered with every Tedee bridge.
34
73
 
35
74
  ## Webhook Registration
36
75
 
37
- The callback server is mandatory and is managed by the plugin. It listens on `webhookPort` when configured, or `8088` by default, and uses a hard-coded internal path.
76
+ The callback server is mandatory and managed by the plugin. It listens on `webhook.port`
77
+ (default `8088`) and receives events for every bridge at `/tedee/events/<bridgeId>`.
78
+
79
+ On startup, each bridge resolves the local address the Tedee bridge can reach the plugin on
80
+ (or uses `webhook.host` when set), registers a single POST callback tagged with an internal
81
+ `X-Homebridge-Tedee-Instance` secret header, updates it if the URL changed, and removes any
82
+ duplicates. The callback is removed from the bridge on shutdown, so a bridge removed from the
83
+ configuration doesn't leave an orphaned callback behind.
84
+
85
+ ## Migrating from 0.1.x
38
86
 
39
- On startup, after the local server is listening, the plugin resolves the local Homebridge host address by checking which local network interface would be used to reach the Tedee Bridge. It then registers a single POST callback with the Tedee Bridge.
87
+ The multi-bridge configuration is a breaking change and accessories are re-created. A
88
+ one-shot cleanup CLI removes the old callbacks left by the single-bridge version from your
89
+ bridges:
40
90
 
41
- The callback record is tagged with an internal `X-Homebridge-Tedee-Instance` header. On restart, the plugin finds that existing callback and updates it if the URL changed. Any duplicate callbacks with the same internal instance header are removed. The callback is not removed on normal shutdown; this avoids callback create/delete churn, and the next startup will update the existing record.
91
+ ```sh
92
+ npx tedee-cleanup <path-to-homebridge-config.json> [--dry-run]
93
+ ```
@@ -11,168 +11,286 @@
11
11
  "required": false,
12
12
  "default": "Tedee"
13
13
  },
14
- "host": {
15
- "title": "Tedee Bridge IP/Host",
16
- "type": "string",
17
- "required": true,
18
- "description": "The local IP address or hostname of the Tedee Bridge API."
19
- },
20
- "port": {
21
- "title": "Bridge Port",
22
- "type": "number",
23
- "required": false,
24
- "default": 80,
25
- "description": "The local Tedee Bridge API port."
26
- },
27
- "token": {
28
- "title": "API Token",
29
- "type": "string",
30
- "required": true,
31
- "description": "The local Bridge API token from the Tedee app."
32
- },
33
- "tokenMode": {
34
- "title": "Token Mode",
35
- "type": "string",
36
- "required": false,
37
- "default": "plain",
38
- "oneOf": [
39
- {
40
- "title": "Plain",
41
- "enum": [
42
- "plain"
43
- ]
14
+ "webhook": {
15
+ "title": "Webhook Server",
16
+ "type": "object",
17
+ "description": "The local callback server the plugin runs to receive events from all Tedee bridges.",
18
+ "properties": {
19
+ "host": {
20
+ "title": "Webhook Host",
21
+ "type": "string",
22
+ "required": false,
23
+ "description": "Optional. The address the Tedee bridges should reach this server on. Leave empty to auto-detect the local interface on each bridge's subnet."
44
24
  },
45
- {
46
- "title": "Encrypted",
47
- "enum": [
48
- "encrypted"
49
- ]
25
+ "port": {
26
+ "title": "Webhook Port",
27
+ "type": "number",
28
+ "required": false,
29
+ "default": 8088,
30
+ "minimum": 0,
31
+ "maximum": 65535
50
32
  }
51
- ]
52
- },
53
- "apiVersion": {
54
- "title": "Bridge API Version",
55
- "type": "string",
56
- "required": false,
57
- "default": "v1.0"
33
+ }
58
34
  },
59
- "unlockMode": {
60
- "title": "Unlock Mode",
61
- "type": "number",
62
- "required": false,
63
- "default": 3,
64
- "oneOf": [
65
- {
66
- "title": "Normal",
67
- "enum": [
68
- 0
69
- ]
35
+ "defaults": {
36
+ "title": "Defaults",
37
+ "type": "object",
38
+ "description": "Default settings applied to every bridge and lock. Individual bridges and locks can override these.",
39
+ "properties": {
40
+ "port": {
41
+ "title": "Bridge Port",
42
+ "type": "number",
43
+ "required": false,
44
+ "default": 80
70
45
  },
71
- {
72
- "title": "Force",
73
- "enum": [
74
- 2
46
+ "tokenMode": {
47
+ "title": "Token Mode",
48
+ "type": "string",
49
+ "required": false,
50
+ "default": "encrypted",
51
+ "oneOf": [
52
+ { "title": "Plain", "enum": [ "plain" ] },
53
+ { "title": "Encrypted", "enum": [ "encrypted" ] }
75
54
  ]
76
55
  },
77
- {
78
- "title": "Without Pull",
79
- "enum": [
80
- 3
81
- ]
56
+ "apiVersion": {
57
+ "title": "Bridge API Version",
58
+ "type": "string",
59
+ "required": false,
60
+ "default": "v1.0"
82
61
  },
83
- {
84
- "title": "Unlock Or Pull",
85
- "enum": [
86
- 4
87
- ]
62
+ "lowBatteryThreshold": {
63
+ "title": "Low Battery Threshold",
64
+ "type": "number",
65
+ "required": false,
66
+ "default": 20,
67
+ "minimum": 1,
68
+ "maximum": 100
69
+ },
70
+ "refreshInterval": {
71
+ "title": "Refresh Interval",
72
+ "type": "number",
73
+ "required": false,
74
+ "default": 600000,
75
+ "description": "Periodic full refresh interval in milliseconds. Set to 0 to disable."
76
+ },
77
+ "lock": {
78
+ "title": "Lock Defaults",
79
+ "type": "object",
80
+ "properties": {
81
+ "pullSpringSwitch": {
82
+ "title": "Show Pull Spring Switch",
83
+ "type": "boolean",
84
+ "required": false,
85
+ "default": true
86
+ },
87
+ "unlockMode": {
88
+ "title": "Unlock Mode",
89
+ "type": "string",
90
+ "required": false,
91
+ "default": "without_pull",
92
+ "oneOf": [
93
+ { "title": "Normal", "enum": [ "normal" ] },
94
+ { "title": "Force", "enum": [ "force" ] },
95
+ { "title": "Without Pull", "enum": [ "without_pull" ] },
96
+ { "title": "Unlock Or Pull", "enum": [ "unlock_or_pull" ] }
97
+ ],
98
+ "description": "Default unlock mode for all locks. 'Without Pull' avoids pulling the spring because a separate switch is exposed for that."
99
+ }
100
+ }
88
101
  }
89
- ],
90
- "description": "Mode used when HomeKit unlocks the main lock service. The default avoids pulling the spring because a separate switch is exposed for that."
91
- },
92
- "lowBatteryThreshold": {
93
- "title": "Low Battery Threshold",
94
- "type": "number",
95
- "required": false,
96
- "default": 20,
97
- "minimum": 1,
98
- "maximum": 100
99
- },
100
- "refreshInterval": {
101
- "title": "Refresh Interval",
102
- "type": "number",
103
- "required": false,
104
- "default": 600000,
105
- "description": "Periodic full refresh interval in milliseconds. Set to 0 to disable."
106
- },
107
- "webhookPort": {
108
- "title": "Webhook Port",
109
- "type": "number",
110
- "required": false,
111
- "default": 8088,
112
- "minimum": 0,
113
- "maximum": 65535,
114
- "description": "Local port used by the plugin's mandatory Tedee callback server. The callback host and path are managed automatically."
102
+ }
115
103
  },
116
- "locks": {
117
- "title": "Locks",
104
+ "bridges": {
105
+ "title": "Bridges",
118
106
  "type": "array",
119
107
  "required": false,
120
108
  "items": {
121
- "title": "Lock",
109
+ "title": "Bridge",
110
+ "buttonText": "Add Bridge",
122
111
  "type": "object",
123
112
  "properties": {
124
113
  "id": {
125
114
  "title": "ID",
115
+ "type": "string",
116
+ "required": true,
117
+ "description": "A unique, stable identifier for this bridge (e.g. \"main\"). Changing it re-creates its accessories."
118
+ },
119
+ "host": {
120
+ "title": "Tedee Bridge IP/Host",
121
+ "type": "string",
122
+ "required": true,
123
+ "description": "The local IP address or hostname of the Tedee Bridge API."
124
+ },
125
+ "port": {
126
+ "title": "Bridge Port",
126
127
  "type": "number",
127
- "required": true
128
+ "required": false,
129
+ "description": "The local Tedee Bridge API port. Falls back to the bridge default (80)."
128
130
  },
129
- "ignore": {
130
- "title": "Ignore This Lock",
131
- "type": "boolean",
131
+ "token": {
132
+ "title": "API Token",
133
+ "type": "string",
134
+ "required": true,
135
+ "description": "The local Bridge API token from the Tedee app."
136
+ },
137
+ "tokenMode": {
138
+ "title": "Token Mode",
139
+ "type": "string",
132
140
  "required": false,
133
- "default": false
141
+ "oneOf": [
142
+ { "title": "Plain", "enum": [ "plain" ] },
143
+ { "title": "Encrypted", "enum": [ "encrypted" ] }
144
+ ]
145
+ },
146
+ "apiVersion": {
147
+ "title": "Bridge API Version",
148
+ "type": "string",
149
+ "required": false
134
150
  },
135
- "pullSpringSwitch": {
136
- "title": "Show Pull Spring Switch",
137
- "type": "boolean",
151
+ "lowBatteryThreshold": {
152
+ "title": "Low Battery Threshold",
153
+ "type": "number",
138
154
  "required": false,
139
- "default": true
155
+ "minimum": 1,
156
+ "maximum": 100
140
157
  },
141
- "unlockMode": {
142
- "title": "Unlock Mode",
158
+ "refreshInterval": {
159
+ "title": "Refresh Interval",
143
160
  "type": "number",
144
161
  "required": false,
145
- "oneOf": [
146
- {
147
- "title": "Normal",
148
- "enum": [
149
- 0
150
- ]
151
- },
152
- {
153
- "title": "Force",
154
- "enum": [
155
- 2
156
- ]
157
- },
158
- {
159
- "title": "Without Pull",
160
- "enum": [
161
- 3
162
- ]
163
- },
164
- {
165
- "title": "Unlock Or Pull",
166
- "enum": [
167
- 4
168
- ]
162
+ "description": "Periodic full refresh interval in milliseconds. Set to 0 to disable."
163
+ },
164
+ "locks": {
165
+ "title": "Locks",
166
+ "type": "array",
167
+ "required": false,
168
+ "items": {
169
+ "title": "Lock",
170
+ "type": "object",
171
+ "properties": {
172
+ "id": {
173
+ "title": "ID",
174
+ "type": "number",
175
+ "required": true
176
+ },
177
+ "ignore": {
178
+ "title": "Ignore This Lock",
179
+ "type": "boolean",
180
+ "required": false,
181
+ "default": false
182
+ },
183
+ "pullSpringSwitch": {
184
+ "title": "Show Pull Spring Switch",
185
+ "type": "boolean",
186
+ "required": false
187
+ },
188
+ "unlockMode": {
189
+ "title": "Unlock Mode",
190
+ "type": "string",
191
+ "required": false,
192
+ "oneOf": [
193
+ { "title": "Normal", "enum": [ "normal" ] },
194
+ { "title": "Force", "enum": [ "force" ] },
195
+ { "title": "Without Pull", "enum": [ "without_pull" ] },
196
+ { "title": "Unlock Or Pull", "enum": [ "unlock_or_pull" ] }
197
+ ],
198
+ "description": "Overrides the unlock mode for this specific lock. Falls back to the lock default."
199
+ }
169
200
  }
170
- ],
171
- "description": "Overrides the platform unlock mode for this specific lock. Falls back to the platform Unlock Mode setting when not set."
201
+ }
172
202
  }
173
203
  }
174
204
  }
175
205
  }
176
206
  }
177
- }
207
+ },
208
+ "layout": [
209
+ "name",
210
+ {
211
+ "type": "fieldset",
212
+ "title": "Advanced",
213
+ "labelHtmlClass": "fs-5",
214
+ "expandable": true,
215
+ "expanded": false,
216
+ "items": [
217
+ {
218
+ "type": "fieldset",
219
+ "title": "Webhook Server",
220
+ "labelHtmlClass": "fs-6",
221
+ "expandable": true,
222
+ "expanded": false,
223
+ "description": "The local callback server the plugin runs to receive events from all Tedee bridges.",
224
+ "items": [
225
+ "webhook.host",
226
+ "webhook.port"
227
+ ]
228
+ },
229
+ {
230
+ "type": "fieldset",
231
+ "title": "Bridge Defaults",
232
+ "labelHtmlClass": "fs-6",
233
+ "expandable": true,
234
+ "expanded": false,
235
+ "items": [
236
+ "defaults.port",
237
+ "defaults.tokenMode",
238
+ "defaults.apiVersion",
239
+ "defaults.lowBatteryThreshold",
240
+ "defaults.refreshInterval"
241
+ ]
242
+ },
243
+ {
244
+ "type": "fieldset",
245
+ "title": "Lock Defaults",
246
+ "labelHtmlClass": "fs-6",
247
+ "expandable": true,
248
+ "expanded": false,
249
+ "items": [
250
+ "defaults.lock.pullSpringSwitch",
251
+ "defaults.lock.unlockMode"
252
+ ]
253
+ }
254
+ ]
255
+ },
256
+ {
257
+ "key": "bridges",
258
+ "type": "array",
259
+ "title": "Bridges",
260
+ "buttonText": "Add Bridge",
261
+ "items": [
262
+ "bridges[].id",
263
+ "bridges[].host",
264
+ "bridges[].token",
265
+ {
266
+ "key": "bridges[]",
267
+ "type": "section",
268
+ "title": "Advanced",
269
+ "labelHtmlClass": "fs-6",
270
+ "expandable": true,
271
+ "expanded": false,
272
+ "items": [
273
+ "bridges[].port",
274
+ "bridges[].tokenMode",
275
+ "bridges[].apiVersion",
276
+ "bridges[].lowBatteryThreshold",
277
+ "bridges[].refreshInterval"
278
+ ]
279
+ },
280
+ {
281
+ "key": "bridges[].locks",
282
+ "type": "array",
283
+ "title": "Locks",
284
+ "labelHtmlClass": "fs-5",
285
+ "buttonText": "Add Lock",
286
+ "items": [
287
+ "bridges[].locks[].id",
288
+ "bridges[].locks[].ignore",
289
+ "bridges[].locks[].pullSpringSwitch",
290
+ "bridges[].locks[].unlockMode"
291
+ ]
292
+ }
293
+ ]
294
+ }
295
+ ]
178
296
  }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=tedee-cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tedee-cleanup.d.ts","sourceRoot":"","sources":["../../src/bin/tedee-cleanup.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import { WEBHOOK_PATH } from "../settings.js";
4
+ import { TedeeClient } from "../tedee-client.js";
5
+ const consoleLogger = () => {
6
+ const logger = {
7
+ debug: (message, ...params) => console.debug(message, ...params),
8
+ info: (message, ...params) => console.info(message, ...params),
9
+ warn: (message, ...params) => console.warn(message, ...params),
10
+ error: (message, ...params) => console.error(message, ...params),
11
+ getLogger: () => logger
12
+ };
13
+ return logger;
14
+ };
15
+ const isLegacyCallback = (url) => {
16
+ try {
17
+ return new URL(url).pathname === WEBHOOK_PATH;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ };
23
+ async function cleanupBridge(platform, dryRun, logger) {
24
+ if (!platform.host || !platform.token) {
25
+ logger.warn(`skipping Tedee platform with missing host/token`);
26
+ return 0;
27
+ }
28
+ const client = new TedeeClient({
29
+ host: platform.host,
30
+ port: platform.port,
31
+ token: platform.token,
32
+ tokenMode: platform.tokenMode,
33
+ apiVersion: platform.apiVersion
34
+ }, logger);
35
+ const callbacks = await client.listCallbacks();
36
+ const legacy = callbacks.filter(callback => isLegacyCallback(callback.url));
37
+ if (legacy.length === 0) {
38
+ logger.info(`[${platform.host}] no legacy callbacks found`);
39
+ return 0;
40
+ }
41
+ let removed = 0;
42
+ for (const callback of legacy) {
43
+ if (dryRun) {
44
+ logger.info(`[${platform.host}] would remove legacy callback [${callback.url}] id [${callback.id}]`);
45
+ removed++;
46
+ continue;
47
+ }
48
+ try {
49
+ await client.deleteCallback(callback.id);
50
+ logger.info(`[${platform.host}] removed legacy callback [${callback.url}] id [${callback.id}]`);
51
+ removed++;
52
+ }
53
+ catch (error) {
54
+ logger.error(`[${platform.host}] failed to remove callback id [${callback.id}]`, error);
55
+ }
56
+ }
57
+ return removed;
58
+ }
59
+ async function main() {
60
+ const args = process.argv.slice(2);
61
+ const dryRun = args.includes('--dry-run');
62
+ const configPath = args.find(arg => !arg.startsWith('--'));
63
+ if (!configPath) {
64
+ console.error('Usage: tedee-cleanup <path-to-homebridge-config.json> [--dry-run]');
65
+ process.exit(1);
66
+ }
67
+ const logger = consoleLogger();
68
+ const config = global.JSON.parse(readFileSync(configPath, 'utf8'));
69
+ const platforms = (config.platforms ?? []).filter(platform => platform.platform === 'Tedee');
70
+ if (platforms.length === 0) {
71
+ logger.warn(`no Tedee platforms found in [${configPath}]`);
72
+ return;
73
+ }
74
+ logger.info(`found ${platforms.length} Tedee platform(s)${dryRun ? ' (dry run)' : ''}`);
75
+ let total = 0;
76
+ for (const platform of platforms) {
77
+ total += await cleanupBridge(platform, dryRun, logger);
78
+ }
79
+ logger.info(`${dryRun ? 'would remove' : 'removed'} ${total} legacy callback(s)`);
80
+ }
81
+ main().catch(error => {
82
+ console.error(error);
83
+ process.exit(1);
84
+ });
85
+ //# sourceMappingURL=tedee-cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tedee-cleanup.js","sourceRoot":"","sources":["../../src/bin/tedee-cleanup.ts"],"names":[],"mappings":"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"}
@@ -2,18 +2,20 @@ import { Characteristic, PlatformAccessory, Service } from 'homebridge';
2
2
  import { Detachables } from '../common.ts';
3
3
  import { ILogger } from '../logger.ts';
4
4
  import { Tedee } from '../tedee.ts';
5
+ import { TedeeBridge } from '../tedee-bridge.ts';
5
6
  import { TedeeClient } from '../tedee-client.ts';
6
7
  import { TedeePlatform } from '../tedee-platform.ts';
7
8
  export declare abstract class Device<D extends Tedee.Lock = Tedee.Lock> {
8
- readonly platform: TedeePlatform;
9
- readonly client: TedeeClient;
9
+ readonly bridge: TedeeBridge;
10
10
  readonly accessory: PlatformAccessory;
11
11
  readonly primaryService: Service;
12
12
  readonly logger: ILogger;
13
13
  protected device: D;
14
14
  protected statusFault: Characteristic;
15
15
  protected readonly detachables: Detachables;
16
- protected constructor(platform: TedeePlatform, client: TedeeClient, accessory: PlatformAccessory, device: D, primaryService: Service);
16
+ protected constructor(bridge: TedeeBridge, accessory: PlatformAccessory, device: D, primaryService: Service);
17
+ get platform(): TedeePlatform;
18
+ get client(): TedeeClient;
17
19
  get id(): number;
18
20
  get type(): string;
19
21
  get name(): string;