homebridge-deco 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,288 @@
1
+ import { randomUUID } from 'crypto';
2
+ export class DecoAPI {
3
+ log;
4
+ username;
5
+ password;
6
+ token = null;
7
+ baseUrl = 'https://use1-wap.tplinkdeco.com';
8
+ termid;
9
+ lastAuthTime = 0;
10
+ authValidityMs = 3600000; // 1 hour
11
+ constructor(config) {
12
+ this.log = config.log;
13
+ this.username = config.username;
14
+ this.password = config.password;
15
+ this.termid = randomUUID();
16
+ }
17
+ /**
18
+ * Authenticate with TP-Link cloud service
19
+ */
20
+ async authenticate() {
21
+ try {
22
+ // Check if we have a valid token already
23
+ if (this.token && (Date.now() - this.lastAuthTime) < this.authValidityMs) {
24
+ return true;
25
+ }
26
+ this.log.debug('Authenticating with TP-Link cloud...');
27
+ const params = {
28
+ method: 'login',
29
+ params: {
30
+ appType: 'Deco',
31
+ cloudUserName: this.username,
32
+ cloudPassword: this.password,
33
+ terminalUUID: this.termid,
34
+ },
35
+ };
36
+ const response = await this.makeRequest('/', params, false);
37
+ if (response.error_code !== 0) {
38
+ this.log.error('Authentication failed:', response.msg || 'Unknown error');
39
+ return false;
40
+ }
41
+ if (response.result && typeof response.result === 'object' && 'token' in response.result) {
42
+ this.token = response.result.token;
43
+ this.lastAuthTime = Date.now();
44
+ this.log.info('Successfully authenticated with TP-Link cloud');
45
+ return true;
46
+ }
47
+ this.log.error('Invalid authentication response');
48
+ return false;
49
+ }
50
+ catch (error) {
51
+ this.log.error('Authentication error:', error);
52
+ return false;
53
+ }
54
+ }
55
+ /**
56
+ * Get list of Deco devices in the network
57
+ */
58
+ async getDeviceList() {
59
+ try {
60
+ if (!await this.ensureAuthenticated()) {
61
+ return [];
62
+ }
63
+ const params = {
64
+ method: 'getDeviceList',
65
+ params: {},
66
+ };
67
+ const response = await this.makeRequest('/', params);
68
+ if (response.error_code !== 0) {
69
+ this.log.error('Failed to get device list:', response.msg);
70
+ return [];
71
+ }
72
+ if (response.result && typeof response.result === 'object' && 'deviceList' in response.result) {
73
+ const devices = response.result.deviceList || [];
74
+ this.log.debug(`Found ${devices.length} Deco devices`);
75
+ return devices;
76
+ }
77
+ return [];
78
+ }
79
+ catch (error) {
80
+ this.log.error('Error getting device list:', error);
81
+ return [];
82
+ }
83
+ }
84
+ /**
85
+ * Get network status including internet connectivity and guest network
86
+ */
87
+ async getNetworkStatus() {
88
+ try {
89
+ if (!await this.ensureAuthenticated()) {
90
+ return {
91
+ internetOnline: false,
92
+ guestNetworkEnabled: false,
93
+ devices: [],
94
+ clients: [],
95
+ };
96
+ }
97
+ const [devices, clients, guestNetwork] = await Promise.all([
98
+ this.getDeviceList(),
99
+ this.getClientList(),
100
+ this.getGuestNetworkStatus(),
101
+ ]);
102
+ // Check if any device is online to determine internet status
103
+ const internetOnline = devices.some(d => d.status === 1);
104
+ return {
105
+ internetOnline,
106
+ guestNetworkEnabled: guestNetwork,
107
+ devices,
108
+ clients,
109
+ };
110
+ }
111
+ catch (error) {
112
+ this.log.error('Error getting network status:', error);
113
+ return {
114
+ internetOnline: false,
115
+ guestNetworkEnabled: false,
116
+ devices: [],
117
+ clients: [],
118
+ };
119
+ }
120
+ }
121
+ /**
122
+ * Get list of connected clients
123
+ */
124
+ async getClientList() {
125
+ try {
126
+ if (!await this.ensureAuthenticated()) {
127
+ return [];
128
+ }
129
+ const params = {
130
+ method: 'getClientList',
131
+ params: {},
132
+ };
133
+ const response = await this.makeRequest('/', params);
134
+ if (response.error_code !== 0) {
135
+ this.log.debug('Failed to get client list:', response.msg);
136
+ return [];
137
+ }
138
+ if (response.result && typeof response.result === 'object' && 'clientList' in response.result) {
139
+ const clients = response.result.clientList || [];
140
+ this.log.debug(`Found ${clients.length} connected clients`);
141
+ return clients;
142
+ }
143
+ return [];
144
+ }
145
+ catch (error) {
146
+ this.log.error('Error getting client list:', error);
147
+ return [];
148
+ }
149
+ }
150
+ /**
151
+ * Get guest network status
152
+ */
153
+ async getGuestNetworkStatus() {
154
+ try {
155
+ if (!await this.ensureAuthenticated()) {
156
+ return false;
157
+ }
158
+ const params = {
159
+ method: 'getGuestNetwork',
160
+ params: {},
161
+ };
162
+ const response = await this.makeRequest('/', params);
163
+ if (response.error_code !== 0) {
164
+ this.log.debug('Failed to get guest network status:', response.msg);
165
+ return false;
166
+ }
167
+ if (response.result && typeof response.result === 'object' && 'enabled' in response.result) {
168
+ return response.result.enabled === true;
169
+ }
170
+ return false;
171
+ }
172
+ catch (error) {
173
+ this.log.debug('Error getting guest network status:', error);
174
+ return false;
175
+ }
176
+ }
177
+ /**
178
+ * Toggle guest network on/off
179
+ */
180
+ async setGuestNetwork(enabled) {
181
+ try {
182
+ if (!await this.ensureAuthenticated()) {
183
+ return false;
184
+ }
185
+ const params = {
186
+ method: 'setGuestNetwork',
187
+ params: {
188
+ enabled,
189
+ },
190
+ };
191
+ const response = await this.makeRequest('/', params);
192
+ if (response.error_code !== 0) {
193
+ this.log.error('Failed to set guest network:', response.msg);
194
+ return false;
195
+ }
196
+ this.log.info(`Guest network ${enabled ? 'enabled' : 'disabled'}`);
197
+ return true;
198
+ }
199
+ catch (error) {
200
+ this.log.error('Error setting guest network:', error);
201
+ return false;
202
+ }
203
+ }
204
+ /**
205
+ * Check if a specific device (by MAC) is connected
206
+ */
207
+ async isDeviceConnected(mac) {
208
+ try {
209
+ const clients = await this.getClientList();
210
+ const normalizedMac = mac.toLowerCase().replace(/[:-]/g, '');
211
+ return clients.some(client => {
212
+ const clientMac = client.mac.toLowerCase().replace(/[:-]/g, '');
213
+ return clientMac === normalizedMac && client.online;
214
+ });
215
+ }
216
+ catch (error) {
217
+ this.log.error('Error checking device connection:', error);
218
+ return false;
219
+ }
220
+ }
221
+ /**
222
+ * Reboot a specific Deco device
223
+ */
224
+ async rebootDevice(deviceId) {
225
+ try {
226
+ if (!await this.ensureAuthenticated()) {
227
+ return false;
228
+ }
229
+ const params = {
230
+ method: 'reboot',
231
+ params: {
232
+ deviceId,
233
+ },
234
+ };
235
+ const response = await this.makeRequest('/', params);
236
+ if (response.error_code !== 0) {
237
+ this.log.error('Failed to reboot device:', response.msg);
238
+ return false;
239
+ }
240
+ this.log.info(`Rebooted device ${deviceId}`);
241
+ return true;
242
+ }
243
+ catch (error) {
244
+ this.log.error('Error rebooting device:', error);
245
+ return false;
246
+ }
247
+ }
248
+ /**
249
+ * Make HTTP request to TP-Link API
250
+ */
251
+ async makeRequest(endpoint, params, requireAuth = true) {
252
+ const url = `${this.baseUrl}${endpoint}`;
253
+ const headers = {
254
+ 'Content-Type': 'application/json',
255
+ 'User-Agent': 'Deco/3.0 (iPhone; iOS 15.0; Scale/3.00)',
256
+ };
257
+ if (requireAuth && this.token) {
258
+ headers.Authorization = `Bearer ${this.token}`;
259
+ }
260
+ const body = JSON.stringify(params);
261
+ try {
262
+ const response = await fetch(url, {
263
+ method: 'POST',
264
+ headers,
265
+ body,
266
+ });
267
+ if (!response.ok) {
268
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
269
+ }
270
+ const data = await response.json();
271
+ return data;
272
+ }
273
+ catch (error) {
274
+ this.log.error('API request failed:', error);
275
+ throw error;
276
+ }
277
+ }
278
+ /**
279
+ * Ensure we have a valid authentication token
280
+ */
281
+ async ensureAuthenticated() {
282
+ if (!this.token || (Date.now() - this.lastAuthTime) >= this.authValidityMs) {
283
+ return await this.authenticate();
284
+ }
285
+ return true;
286
+ }
287
+ }
288
+ //# sourceMappingURL=decoAPI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoAPI.js","sourceRoot":"","sources":["../src/decoAPI.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { DecoHomebridgePlatform } from './platform.js';
3
+ /**
4
+ * Deco Device Accessory
5
+ * Represents an individual Deco mesh unit with status indicator
6
+ */
7
+ export declare class DecoDeviceAccessory {
8
+ private readonly platform;
9
+ private readonly accessory;
10
+ private service;
11
+ private device;
12
+ constructor(platform: DecoHomebridgePlatform, accessory: PlatformAccessory);
13
+ /**
14
+ * Get device online status
15
+ */
16
+ getContactSensorState(): Promise<CharacteristicValue>;
17
+ /**
18
+ * Update device status
19
+ */
20
+ private updateStatus;
21
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Deco Device Accessory
3
+ * Represents an individual Deco mesh unit with status indicator
4
+ */
5
+ export class DecoDeviceAccessory {
6
+ platform;
7
+ accessory;
8
+ service;
9
+ device;
10
+ constructor(platform, accessory) {
11
+ this.platform = platform;
12
+ this.accessory = accessory;
13
+ this.device = accessory.context.device;
14
+ // Set accessory information
15
+ this.accessory.getService(this.platform.Service.AccessoryInformation)
16
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'TP-Link')
17
+ .setCharacteristic(this.platform.Characteristic.Model, this.device.deviceModel || 'Deco')
18
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, this.device.mac || 'Unknown');
19
+ // Use Contact Sensor to indicate if Deco unit is online
20
+ this.service = this.accessory.getService(this.platform.Service.ContactSensor) ||
21
+ this.accessory.addService(this.platform.Service.ContactSensor);
22
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.device.deviceName);
23
+ // Register handlers
24
+ this.service.getCharacteristic(this.platform.Characteristic.ContactSensorState)
25
+ .onGet(this.getContactSensorState.bind(this));
26
+ // Update status
27
+ this.updateStatus();
28
+ }
29
+ /**
30
+ * Get device online status
31
+ */
32
+ async getContactSensorState() {
33
+ try {
34
+ const status = await this.platform.api_client.getNetworkStatus();
35
+ const device = status.devices.find(d => d.deviceId === this.device.deviceId);
36
+ if (device) {
37
+ this.device = device;
38
+ this.accessory.context.device = device;
39
+ // CONTACT_DETECTED (0) = online, CONTACT_NOT_DETECTED (1) = offline
40
+ return device.status === 1 ?
41
+ this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED :
42
+ this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
43
+ }
44
+ return this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
45
+ }
46
+ catch (error) {
47
+ this.platform.log.error('Error getting device status:', error);
48
+ return this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
49
+ }
50
+ }
51
+ /**
52
+ * Update device status
53
+ */
54
+ async updateStatus() {
55
+ try {
56
+ const status = await this.platform.api_client.getNetworkStatus();
57
+ const device = status.devices.find(d => d.deviceId === this.device.deviceId);
58
+ if (device) {
59
+ this.device = device;
60
+ this.accessory.context.device = device;
61
+ const state = device.status === 1 ?
62
+ this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED :
63
+ this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
64
+ this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, state);
65
+ this.platform.log.debug(`Device ${device.deviceName}:`, device.status === 1 ? 'Online' : 'Offline');
66
+ }
67
+ }
68
+ catch (error) {
69
+ this.platform.log.error('Error updating device status:', error);
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=decoDeviceAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoDeviceAccessory.js","sourceRoot":"","sources":["../src/decoDeviceAccessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { DecoHomebridgePlatform } from './platform.js';
3
+ /**
4
+ * Device Tracker Accessory
5
+ * Tracks specific devices by MAC address and reports as Occupancy Sensor
6
+ */
7
+ export declare class DecoDeviceTrackerAccessory {
8
+ private readonly platform;
9
+ private readonly accessory;
10
+ private service;
11
+ private device;
12
+ private isConnected;
13
+ constructor(platform: DecoHomebridgePlatform, accessory: PlatformAccessory);
14
+ /**
15
+ * Check if device is connected
16
+ */
17
+ getOccupancyDetected(): Promise<CharacteristicValue>;
18
+ /**
19
+ * Update device connection status
20
+ */
21
+ private updateStatus;
22
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Device Tracker Accessory
3
+ * Tracks specific devices by MAC address and reports as Occupancy Sensor
4
+ */
5
+ export class DecoDeviceTrackerAccessory {
6
+ platform;
7
+ accessory;
8
+ service;
9
+ device;
10
+ isConnected = false;
11
+ constructor(platform, accessory) {
12
+ this.platform = platform;
13
+ this.accessory = accessory;
14
+ this.device = accessory.context.device;
15
+ // Set accessory information
16
+ this.accessory.getService(this.platform.Service.AccessoryInformation)
17
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Device Tracker')
18
+ .setCharacteristic(this.platform.Characteristic.Model, 'Network Device')
19
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, this.device.mac);
20
+ // Use Occupancy Sensor to indicate if device is connected
21
+ this.service = this.accessory.getService(this.platform.Service.OccupancySensor) ||
22
+ this.accessory.addService(this.platform.Service.OccupancySensor);
23
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.device.name);
24
+ // Register handlers
25
+ this.service.getCharacteristic(this.platform.Characteristic.OccupancyDetected)
26
+ .onGet(this.getOccupancyDetected.bind(this));
27
+ // Update status
28
+ this.updateStatus();
29
+ }
30
+ /**
31
+ * Check if device is connected
32
+ */
33
+ async getOccupancyDetected() {
34
+ try {
35
+ const isConnected = await this.platform.api_client.isDeviceConnected(this.device.mac);
36
+ this.isConnected = isConnected;
37
+ // OCCUPANCY_DETECTED (1) = connected, OCCUPANCY_NOT_DETECTED (0) = not connected
38
+ return isConnected ?
39
+ this.platform.Characteristic.OccupancyDetected.OCCUPANCY_DETECTED :
40
+ this.platform.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED;
41
+ }
42
+ catch (error) {
43
+ this.platform.log.error('Error checking device connection:', error);
44
+ return this.platform.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED;
45
+ }
46
+ }
47
+ /**
48
+ * Update device connection status
49
+ */
50
+ async updateStatus() {
51
+ try {
52
+ const isConnected = await this.platform.api_client.isDeviceConnected(this.device.mac);
53
+ this.isConnected = isConnected;
54
+ const state = isConnected ?
55
+ this.platform.Characteristic.OccupancyDetected.OCCUPANCY_DETECTED :
56
+ this.platform.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED;
57
+ this.service.updateCharacteristic(this.platform.Characteristic.OccupancyDetected, state);
58
+ this.platform.log.debug(`Device ${this.device.name} (${this.device.mac}):`, isConnected ? 'Connected' : 'Not connected');
59
+ }
60
+ catch (error) {
61
+ this.platform.log.error('Error updating device connection status:', error);
62
+ }
63
+ }
64
+ }
65
+ //# sourceMappingURL=decoDeviceTrackerAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoDeviceTrackerAccessory.js","sourceRoot":"","sources":["../src/decoDeviceTrackerAccessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { DecoHomebridgePlatform } from './platform.js';
3
+ /**
4
+ * Guest Network Accessory
5
+ * Exposes guest network control as a Switch
6
+ */
7
+ export declare class DecoGuestNetworkAccessory {
8
+ private readonly platform;
9
+ private readonly accessory;
10
+ private service;
11
+ private guestNetworkEnabled;
12
+ constructor(platform: DecoHomebridgePlatform, accessory: PlatformAccessory);
13
+ /**
14
+ * Get guest network on/off state
15
+ */
16
+ getOn(): Promise<CharacteristicValue>;
17
+ /**
18
+ * Set guest network on/off
19
+ */
20
+ setOn(value: CharacteristicValue): Promise<void>;
21
+ /**
22
+ * Update status periodically
23
+ */
24
+ private updateStatus;
25
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Guest Network Accessory
3
+ * Exposes guest network control as a Switch
4
+ */
5
+ export class DecoGuestNetworkAccessory {
6
+ platform;
7
+ accessory;
8
+ service;
9
+ guestNetworkEnabled = false;
10
+ constructor(platform, accessory) {
11
+ this.platform = platform;
12
+ this.accessory = accessory;
13
+ // Set accessory information
14
+ this.accessory.getService(this.platform.Service.AccessoryInformation)
15
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'TP-Link')
16
+ .setCharacteristic(this.platform.Characteristic.Model, 'Deco Guest Network')
17
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, 'GUEST-001');
18
+ // Get or create Switch service
19
+ this.service = this.accessory.getService(this.platform.Service.Switch) ||
20
+ this.accessory.addService(this.platform.Service.Switch);
21
+ this.service.setCharacteristic(this.platform.Characteristic.Name, 'Guest Network');
22
+ // Register handlers
23
+ this.service.getCharacteristic(this.platform.Characteristic.On)
24
+ .onGet(this.getOn.bind(this))
25
+ .onSet(this.setOn.bind(this));
26
+ // Initialize status
27
+ this.updateStatus();
28
+ }
29
+ /**
30
+ * Get guest network on/off state
31
+ */
32
+ async getOn() {
33
+ try {
34
+ const enabled = await this.platform.api_client.getGuestNetworkStatus();
35
+ this.guestNetworkEnabled = enabled;
36
+ return enabled;
37
+ }
38
+ catch (error) {
39
+ this.platform.log.error('Error getting guest network status:', error);
40
+ return false;
41
+ }
42
+ }
43
+ /**
44
+ * Set guest network on/off
45
+ */
46
+ async setOn(value) {
47
+ try {
48
+ const enabled = value;
49
+ const success = await this.platform.api_client.setGuestNetwork(enabled);
50
+ if (success) {
51
+ this.guestNetworkEnabled = enabled;
52
+ this.platform.log.info('Guest network', enabled ? 'enabled' : 'disabled');
53
+ }
54
+ else {
55
+ this.platform.log.error('Failed to set guest network state');
56
+ throw new Error('Failed to set guest network');
57
+ }
58
+ }
59
+ catch (error) {
60
+ this.platform.log.error('Error setting guest network:', error);
61
+ throw error;
62
+ }
63
+ }
64
+ /**
65
+ * Update status periodically
66
+ */
67
+ async updateStatus() {
68
+ try {
69
+ const enabled = await this.platform.api_client.getGuestNetworkStatus();
70
+ this.guestNetworkEnabled = enabled;
71
+ this.service.updateCharacteristic(this.platform.Characteristic.On, enabled);
72
+ this.platform.log.debug('Guest network:', enabled ? 'Enabled' : 'Disabled');
73
+ }
74
+ catch (error) {
75
+ this.platform.log.error('Error updating guest network status:', error);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=decoGuestNetworkAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoGuestNetworkAccessory.js","sourceRoot":"","sources":["../src/decoGuestNetworkAccessory.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAO,yBAAyB;IAKjB;IACA;IALX,OAAO,CAAU;IACjB,mBAAmB,GAAG,KAAK,CAAC;IAEpC,YACmB,QAAgC,EAChC,SAA4B;QAD5B,aAAQ,GAAR,QAAQ,CAAwB;QAChC,cAAS,GAAT,SAAS,CAAmB;QAE7C,4BAA4B;QAC5B,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAE;aACnE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,SAAS,CAAC;aACvE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,oBAAoB,CAAC;aAC3E,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAE7E,+BAA+B;QAC/B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;YACpE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE1D,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAEnF,oBAAoB;QACpB,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;aAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC5B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEhC,oBAAoB;QACpB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC;YACvE,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC;YACnC,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;YACtE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,KAA0B;QACpC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,KAAgB,CAAC;YACjC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAExE,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC;gBACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;YAC5E,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBAC7D,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YAC/D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC;YACvE,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAC5E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { DecoHomebridgePlatform } from './platform.js';
3
+ /**
4
+ * Network Status Accessory
5
+ * Exposes internet connectivity as a Contact Sensor (open = online, closed = offline)
6
+ */
7
+ export declare class DecoNetworkAccessory {
8
+ private readonly platform;
9
+ private readonly accessory;
10
+ private service;
11
+ private internetOnline;
12
+ constructor(platform: DecoHomebridgePlatform, accessory: PlatformAccessory);
13
+ /**
14
+ * Get contact sensor state (CONTACT_DETECTED = online, CONTACT_NOT_DETECTED = offline)
15
+ */
16
+ getContactSensorState(): Promise<CharacteristicValue>;
17
+ /**
18
+ * Periodically update status
19
+ */
20
+ private updateStatus;
21
+ }