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.
- package/LICENSE +176 -0
- package/README.md +290 -0
- package/config.schema.json +89 -0
- package/dist/decoAPI.d.ts +85 -0
- package/dist/decoAPI.js +288 -0
- package/dist/decoAPI.js.map +1 -0
- package/dist/decoDeviceAccessory.d.ts +21 -0
- package/dist/decoDeviceAccessory.js +73 -0
- package/dist/decoDeviceAccessory.js.map +1 -0
- package/dist/decoDeviceTrackerAccessory.d.ts +22 -0
- package/dist/decoDeviceTrackerAccessory.js +65 -0
- package/dist/decoDeviceTrackerAccessory.js.map +1 -0
- package/dist/decoGuestNetworkAccessory.d.ts +25 -0
- package/dist/decoGuestNetworkAccessory.js +79 -0
- package/dist/decoGuestNetworkAccessory.js.map +1 -0
- package/dist/decoNetworkAccessory.d.ts +21 -0
- package/dist/decoNetworkAccessory.js +63 -0
- package/dist/decoNetworkAccessory.js.map +1 -0
- package/dist/decoRouterAccessory.d.ts +25 -0
- package/dist/decoRouterAccessory.js +65 -0
- package/dist/decoRouterAccessory.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +55 -0
- package/dist/platform.js +264 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +8 -0
- package/dist/settings.js +9 -0
- package/dist/settings.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Status Accessory
|
|
3
|
+
* Exposes internet connectivity as a Contact Sensor (open = online, closed = offline)
|
|
4
|
+
*/
|
|
5
|
+
export class DecoNetworkAccessory {
|
|
6
|
+
platform;
|
|
7
|
+
accessory;
|
|
8
|
+
service;
|
|
9
|
+
internetOnline = 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 Network')
|
|
17
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'NETWORK-001');
|
|
18
|
+
// Get or create Contact Sensor service
|
|
19
|
+
this.service = this.accessory.getService(this.platform.Service.ContactSensor) ||
|
|
20
|
+
this.accessory.addService(this.platform.Service.ContactSensor);
|
|
21
|
+
this.service.setCharacteristic(this.platform.Characteristic.Name, 'Internet Connection');
|
|
22
|
+
// Register handlers
|
|
23
|
+
this.service.getCharacteristic(this.platform.Characteristic.ContactSensorState)
|
|
24
|
+
.onGet(this.getContactSensorState.bind(this));
|
|
25
|
+
// Start status updates
|
|
26
|
+
this.updateStatus();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get contact sensor state (CONTACT_DETECTED = online, CONTACT_NOT_DETECTED = offline)
|
|
30
|
+
*/
|
|
31
|
+
async getContactSensorState() {
|
|
32
|
+
try {
|
|
33
|
+
const status = await this.platform.api_client.getNetworkStatus();
|
|
34
|
+
this.internetOnline = status.internetOnline;
|
|
35
|
+
// CONTACT_DETECTED (0) = online, CONTACT_NOT_DETECTED (1) = offline
|
|
36
|
+
return this.internetOnline ?
|
|
37
|
+
this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED :
|
|
38
|
+
this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
this.platform.log.error('Error getting network status:', error);
|
|
42
|
+
return this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Periodically update status
|
|
47
|
+
*/
|
|
48
|
+
async updateStatus() {
|
|
49
|
+
try {
|
|
50
|
+
const status = await this.platform.api_client.getNetworkStatus();
|
|
51
|
+
this.internetOnline = status.internetOnline;
|
|
52
|
+
const state = this.internetOnline ?
|
|
53
|
+
this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED :
|
|
54
|
+
this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
55
|
+
this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, state);
|
|
56
|
+
this.platform.log.debug('Network status:', this.internetOnline ? 'Online' : 'Offline');
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
this.platform.log.error('Error updating network status:', error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=decoNetworkAccessory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decoNetworkAccessory.js","sourceRoot":"","sources":["../src/decoNetworkAccessory.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
|
+
* Deco Router Accessory
|
|
5
|
+
* Exposes the main Deco as a Router with network status
|
|
6
|
+
*/
|
|
7
|
+
export declare class DecoRouterAccessory {
|
|
8
|
+
private readonly platform;
|
|
9
|
+
private readonly accessory;
|
|
10
|
+
private service;
|
|
11
|
+
private informationService;
|
|
12
|
+
constructor(platform: DecoHomebridgePlatform, accessory: PlatformAccessory);
|
|
13
|
+
/**
|
|
14
|
+
* Handle configured name changes
|
|
15
|
+
*/
|
|
16
|
+
setConfiguredName(value: CharacteristicValue): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Get configured name
|
|
19
|
+
*/
|
|
20
|
+
getConfiguredName(): Promise<CharacteristicValue>;
|
|
21
|
+
/**
|
|
22
|
+
* Update router status
|
|
23
|
+
*/
|
|
24
|
+
updateStatus(): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deco Router Accessory
|
|
3
|
+
* Exposes the main Deco as a Router with network status
|
|
4
|
+
*/
|
|
5
|
+
export class DecoRouterAccessory {
|
|
6
|
+
platform;
|
|
7
|
+
accessory;
|
|
8
|
+
service;
|
|
9
|
+
informationService;
|
|
10
|
+
constructor(platform, accessory) {
|
|
11
|
+
this.platform = platform;
|
|
12
|
+
this.accessory = accessory;
|
|
13
|
+
// Set accessory information
|
|
14
|
+
this.informationService = this.accessory.getService(this.platform.Service.AccessoryInformation);
|
|
15
|
+
this.informationService
|
|
16
|
+
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'TP-Link')
|
|
17
|
+
.setCharacteristic(this.platform.Characteristic.Model, 'Deco Mesh System')
|
|
18
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'DECO-MAIN');
|
|
19
|
+
// Get or create Router service
|
|
20
|
+
this.service = this.accessory.getService(this.platform.Service.WiFiRouter) ||
|
|
21
|
+
this.accessory.addService(this.platform.Service.WiFiRouter);
|
|
22
|
+
this.service.setCharacteristic(this.platform.Characteristic.Name, 'Deco Network');
|
|
23
|
+
// ConfiguredName - the user can rename this
|
|
24
|
+
this.service.getCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
25
|
+
.onSet(this.setConfiguredName.bind(this))
|
|
26
|
+
.onGet(this.getConfiguredName.bind(this));
|
|
27
|
+
// Initial update
|
|
28
|
+
this.updateStatus();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Handle configured name changes
|
|
32
|
+
*/
|
|
33
|
+
async setConfiguredName(value) {
|
|
34
|
+
const name = value;
|
|
35
|
+
this.accessory.context.configuredName = name;
|
|
36
|
+
this.platform.log.debug('Router name set to:', name);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get configured name
|
|
40
|
+
*/
|
|
41
|
+
async getConfiguredName() {
|
|
42
|
+
return this.accessory.context.configuredName || 'Deco Network';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Update router status
|
|
46
|
+
*/
|
|
47
|
+
async updateStatus() {
|
|
48
|
+
try {
|
|
49
|
+
const status = await this.platform.api_client.getNetworkStatus();
|
|
50
|
+
// Update accessory information with current network stats
|
|
51
|
+
const onlineDevices = status.devices.filter(d => d.status === 1).length;
|
|
52
|
+
const totalClients = status.clients.filter(c => c.online).length;
|
|
53
|
+
this.platform.log.debug(`Router status: ${status.internetOnline ? 'Online' : 'Offline'}, ` +
|
|
54
|
+
`${onlineDevices}/${status.devices.length} Deco units online, ` +
|
|
55
|
+
`${totalClients} clients connected`);
|
|
56
|
+
// Store status in context for other accessories to use
|
|
57
|
+
this.accessory.context.networkStatus = status;
|
|
58
|
+
this.accessory.context.lastUpdate = Date.now();
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this.platform.log.error('Error updating router status:', error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=decoRouterAccessory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decoRouterAccessory.js","sourceRoot":"","sources":["../src/decoRouterAccessory.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DecoHomebridgePlatform } from './platform.js';
|
|
2
|
+
import { PLATFORM_NAME } from './settings.js';
|
|
3
|
+
/**
|
|
4
|
+
* This method registers the platform with Homebridge
|
|
5
|
+
*/
|
|
6
|
+
export default (api) => {
|
|
7
|
+
api.registerPlatform(PLATFORM_NAME, DecoHomebridgePlatform);
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,eAAe,CAAC,GAAQ,EAAE,EAAE;IAC1B,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;AAC9D,CAAC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { API, Characteristic, DynamicPlatformPlugin, Logging, PlatformAccessory, PlatformConfig, Service } from 'homebridge';
|
|
2
|
+
import { DecoAPI } from './decoAPI.js';
|
|
3
|
+
/**
|
|
4
|
+
* TP-Link Deco Platform
|
|
5
|
+
* Discovers and registers Deco mesh network devices and features as HomeKit accessories
|
|
6
|
+
*/
|
|
7
|
+
export declare class DecoHomebridgePlatform implements DynamicPlatformPlugin {
|
|
8
|
+
readonly log: Logging;
|
|
9
|
+
readonly config: PlatformConfig;
|
|
10
|
+
readonly api: API;
|
|
11
|
+
readonly Service: typeof Service;
|
|
12
|
+
readonly Characteristic: typeof Characteristic;
|
|
13
|
+
readonly accessories: Map<string, PlatformAccessory>;
|
|
14
|
+
readonly discoveredCacheUUIDs: string[];
|
|
15
|
+
readonly api_client: DecoAPI;
|
|
16
|
+
private pollingInterval;
|
|
17
|
+
private pollingTimer?;
|
|
18
|
+
constructor(log: Logging, config: PlatformConfig, api: API);
|
|
19
|
+
/**
|
|
20
|
+
* Restore cached accessories from disk at startup
|
|
21
|
+
*/
|
|
22
|
+
configureAccessory(accessory: PlatformAccessory): void;
|
|
23
|
+
/**
|
|
24
|
+
* Discover and register Deco devices and network features
|
|
25
|
+
*/
|
|
26
|
+
discoverDevices(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Register main router accessory (native HomeKit router type)
|
|
29
|
+
*/
|
|
30
|
+
private registerRouterAccessory;
|
|
31
|
+
/**
|
|
32
|
+
* Register main network status accessory
|
|
33
|
+
*/
|
|
34
|
+
private registerNetworkAccessory;
|
|
35
|
+
/**
|
|
36
|
+
* Register guest network control accessory
|
|
37
|
+
*/
|
|
38
|
+
private registerGuestNetworkAccessory;
|
|
39
|
+
/**
|
|
40
|
+
* Register individual Deco mesh device
|
|
41
|
+
*/
|
|
42
|
+
private registerDecoDevice;
|
|
43
|
+
/**
|
|
44
|
+
* Register device tracker (occupancy sensor for specific MAC)
|
|
45
|
+
*/
|
|
46
|
+
private registerDeviceTracker;
|
|
47
|
+
/**
|
|
48
|
+
* Remove accessories that are no longer present
|
|
49
|
+
*/
|
|
50
|
+
private cleanupAccessories;
|
|
51
|
+
/**
|
|
52
|
+
* Start polling for status updates
|
|
53
|
+
*/
|
|
54
|
+
private startPolling;
|
|
55
|
+
}
|
package/dist/platform.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { DecoRouterAccessory } from './decoRouterAccessory.js';
|
|
2
|
+
import { DecoNetworkAccessory } from './decoNetworkAccessory.js';
|
|
3
|
+
import { DecoDeviceAccessory } from './decoDeviceAccessory.js';
|
|
4
|
+
import { DecoGuestNetworkAccessory } from './decoGuestNetworkAccessory.js';
|
|
5
|
+
import { DecoDeviceTrackerAccessory } from './decoDeviceTrackerAccessory.js';
|
|
6
|
+
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
|
|
7
|
+
import { DecoAPI } from './decoAPI.js';
|
|
8
|
+
/**
|
|
9
|
+
* TP-Link Deco Platform
|
|
10
|
+
* Discovers and registers Deco mesh network devices and features as HomeKit accessories
|
|
11
|
+
*/
|
|
12
|
+
export class DecoHomebridgePlatform {
|
|
13
|
+
log;
|
|
14
|
+
config;
|
|
15
|
+
api;
|
|
16
|
+
Service;
|
|
17
|
+
Characteristic;
|
|
18
|
+
// Track restored cached accessories
|
|
19
|
+
accessories = new Map();
|
|
20
|
+
discoveredCacheUUIDs = [];
|
|
21
|
+
// Deco API client
|
|
22
|
+
api_client;
|
|
23
|
+
// Polling interval
|
|
24
|
+
pollingInterval;
|
|
25
|
+
pollingTimer;
|
|
26
|
+
constructor(log, config, api) {
|
|
27
|
+
this.log = log;
|
|
28
|
+
this.config = config;
|
|
29
|
+
this.api = api;
|
|
30
|
+
this.Service = api.hap.Service;
|
|
31
|
+
this.Characteristic = api.hap.Characteristic;
|
|
32
|
+
const decoConfig = config;
|
|
33
|
+
// Validate required config
|
|
34
|
+
if (!decoConfig.username || !decoConfig.password) {
|
|
35
|
+
this.log.error('TP-Link account credentials are required in config.json');
|
|
36
|
+
this.log.error('Please add "username" and "password" to your platform configuration');
|
|
37
|
+
throw new Error('Missing required configuration');
|
|
38
|
+
}
|
|
39
|
+
// Initialize API client
|
|
40
|
+
this.api_client = new DecoAPI({
|
|
41
|
+
username: decoConfig.username,
|
|
42
|
+
password: decoConfig.password,
|
|
43
|
+
log: this.log,
|
|
44
|
+
});
|
|
45
|
+
// Set polling interval (default 30 seconds)
|
|
46
|
+
this.pollingInterval = (decoConfig.pollingInterval || 30) * 1000;
|
|
47
|
+
this.log.debug('Finished initializing platform:', this.config.name);
|
|
48
|
+
// Wait for Homebridge to finish loading cached accessories
|
|
49
|
+
this.api.on('didFinishLaunching', () => {
|
|
50
|
+
log.debug('Executed didFinishLaunching callback');
|
|
51
|
+
this.discoverDevices();
|
|
52
|
+
});
|
|
53
|
+
// Cleanup on shutdown
|
|
54
|
+
this.api.on('shutdown', () => {
|
|
55
|
+
if (this.pollingTimer) {
|
|
56
|
+
clearInterval(this.pollingTimer);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Restore cached accessories from disk at startup
|
|
62
|
+
*/
|
|
63
|
+
configureAccessory(accessory) {
|
|
64
|
+
this.log.info('Loading accessory from cache:', accessory.displayName);
|
|
65
|
+
this.accessories.set(accessory.UUID, accessory);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Discover and register Deco devices and network features
|
|
69
|
+
*/
|
|
70
|
+
async discoverDevices() {
|
|
71
|
+
try {
|
|
72
|
+
this.log.info('Discovering TP-Link Deco devices...');
|
|
73
|
+
// Authenticate with TP-Link cloud
|
|
74
|
+
const authenticated = await this.api_client.authenticate();
|
|
75
|
+
if (!authenticated) {
|
|
76
|
+
this.log.error('Failed to authenticate with TP-Link cloud. Please check your credentials.');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Get network status
|
|
80
|
+
const status = await this.api_client.getNetworkStatus();
|
|
81
|
+
const decoConfig = this.config;
|
|
82
|
+
// 1. Expose as Router accessory (default, native HomeKit router type)
|
|
83
|
+
if (decoConfig.exposeAsRouter !== false) {
|
|
84
|
+
this.registerRouterAccessory();
|
|
85
|
+
}
|
|
86
|
+
// 2. Create network status sensor (optional, off by default)
|
|
87
|
+
if (decoConfig.exposeNetworkSensor === true) {
|
|
88
|
+
this.registerNetworkAccessory();
|
|
89
|
+
}
|
|
90
|
+
// 3. Create guest network control (optional, off by default)
|
|
91
|
+
if (decoConfig.exposeGuestNetwork === true) {
|
|
92
|
+
this.registerGuestNetworkAccessory();
|
|
93
|
+
}
|
|
94
|
+
// 4. Register each Deco mesh unit as a separate accessory (optional, off by default)
|
|
95
|
+
if (decoConfig.exposeDecoUnits === true) {
|
|
96
|
+
for (const device of status.devices) {
|
|
97
|
+
this.registerDecoDevice(device);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// 5. Register device trackers for specific MAC addresses (optional, off by default)
|
|
101
|
+
if (decoConfig.exposeDeviceTrackers === true && decoConfig.trackedDevices) {
|
|
102
|
+
for (const trackedDevice of decoConfig.trackedDevices) {
|
|
103
|
+
if (trackedDevice.name && trackedDevice.mac) {
|
|
104
|
+
this.registerDeviceTracker(trackedDevice);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Remove accessories that are no longer present
|
|
109
|
+
this.cleanupAccessories();
|
|
110
|
+
// Start polling for status updates
|
|
111
|
+
this.startPolling();
|
|
112
|
+
this.log.info(`Successfully discovered ${status.devices.length} Deco devices`);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
this.log.error('Error discovering devices:', error);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Register main router accessory (native HomeKit router type)
|
|
120
|
+
*/
|
|
121
|
+
registerRouterAccessory() {
|
|
122
|
+
const uuid = this.api.hap.uuid.generate('deco-router-main');
|
|
123
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
124
|
+
if (existingAccessory) {
|
|
125
|
+
this.log.info('Restoring Router accessory from cache');
|
|
126
|
+
new DecoRouterAccessory(this, existingAccessory);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.log.info('Adding Router accessory');
|
|
130
|
+
const accessory = new this.api.platformAccessory('Deco Router', uuid);
|
|
131
|
+
accessory.context.device = { type: 'router', id: 'router-main' };
|
|
132
|
+
new DecoRouterAccessory(this, accessory);
|
|
133
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
134
|
+
}
|
|
135
|
+
this.discoveredCacheUUIDs.push(uuid);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Register main network status accessory
|
|
139
|
+
*/
|
|
140
|
+
registerNetworkAccessory() {
|
|
141
|
+
const uuid = this.api.hap.uuid.generate('deco-network-status');
|
|
142
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
143
|
+
if (existingAccessory) {
|
|
144
|
+
this.log.info('Restoring Network Status accessory from cache');
|
|
145
|
+
new DecoNetworkAccessory(this, existingAccessory);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
this.log.info('Adding Network Status accessory');
|
|
149
|
+
const accessory = new this.api.platformAccessory('Network Status', uuid);
|
|
150
|
+
accessory.context.device = { type: 'network', id: 'network-status' };
|
|
151
|
+
new DecoNetworkAccessory(this, accessory);
|
|
152
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
153
|
+
}
|
|
154
|
+
this.discoveredCacheUUIDs.push(uuid);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Register guest network control accessory
|
|
158
|
+
*/
|
|
159
|
+
registerGuestNetworkAccessory() {
|
|
160
|
+
const uuid = this.api.hap.uuid.generate('deco-guest-network');
|
|
161
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
162
|
+
if (existingAccessory) {
|
|
163
|
+
this.log.info('Restoring Guest Network accessory from cache');
|
|
164
|
+
new DecoGuestNetworkAccessory(this, existingAccessory);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this.log.info('Adding Guest Network accessory');
|
|
168
|
+
const accessory = new this.api.platformAccessory('Guest Network', uuid);
|
|
169
|
+
accessory.context.device = { type: 'guest-network', id: 'guest-network' };
|
|
170
|
+
new DecoGuestNetworkAccessory(this, accessory);
|
|
171
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
172
|
+
}
|
|
173
|
+
this.discoveredCacheUUIDs.push(uuid);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Register individual Deco mesh device
|
|
177
|
+
*/
|
|
178
|
+
registerDecoDevice(device) {
|
|
179
|
+
const uuid = this.api.hap.uuid.generate(`deco-device-${device.deviceId}`);
|
|
180
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
181
|
+
if (existingAccessory) {
|
|
182
|
+
this.log.info('Restoring Deco device from cache:', device.deviceName);
|
|
183
|
+
existingAccessory.context.device = device;
|
|
184
|
+
this.api.updatePlatformAccessories([existingAccessory]);
|
|
185
|
+
new DecoDeviceAccessory(this, existingAccessory);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
this.log.info('Adding new Deco device:', device.deviceName);
|
|
189
|
+
const accessory = new this.api.platformAccessory(device.deviceName, uuid);
|
|
190
|
+
accessory.context.device = device;
|
|
191
|
+
new DecoDeviceAccessory(this, accessory);
|
|
192
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
193
|
+
}
|
|
194
|
+
this.discoveredCacheUUIDs.push(uuid);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Register device tracker (occupancy sensor for specific MAC)
|
|
198
|
+
*/
|
|
199
|
+
registerDeviceTracker(trackedDevice) {
|
|
200
|
+
const uuid = this.api.hap.uuid.generate(`deco-tracker-${trackedDevice.mac}`);
|
|
201
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
202
|
+
if (existingAccessory) {
|
|
203
|
+
this.log.info('Restoring device tracker from cache:', trackedDevice.name);
|
|
204
|
+
existingAccessory.context.device = trackedDevice;
|
|
205
|
+
this.api.updatePlatformAccessories([existingAccessory]);
|
|
206
|
+
new DecoDeviceTrackerAccessory(this, existingAccessory);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
this.log.info('Adding device tracker:', trackedDevice.name);
|
|
210
|
+
const accessory = new this.api.platformAccessory(trackedDevice.name, uuid);
|
|
211
|
+
accessory.context.device = trackedDevice;
|
|
212
|
+
new DecoDeviceTrackerAccessory(this, accessory);
|
|
213
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
214
|
+
}
|
|
215
|
+
this.discoveredCacheUUIDs.push(uuid);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Remove accessories that are no longer present
|
|
219
|
+
*/
|
|
220
|
+
cleanupAccessories() {
|
|
221
|
+
for (const [uuid, accessory] of this.accessories) {
|
|
222
|
+
if (!this.discoveredCacheUUIDs.includes(uuid)) {
|
|
223
|
+
this.log.info('Removing accessory from cache:', accessory.displayName);
|
|
224
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Start polling for status updates
|
|
230
|
+
*/
|
|
231
|
+
startPolling() {
|
|
232
|
+
if (this.pollingTimer) {
|
|
233
|
+
clearInterval(this.pollingTimer);
|
|
234
|
+
}
|
|
235
|
+
this.log.info(`Starting status polling every ${this.pollingInterval / 1000} seconds`);
|
|
236
|
+
this.pollingTimer = setInterval(async () => {
|
|
237
|
+
try {
|
|
238
|
+
this.log.debug('Polling for status updates...');
|
|
239
|
+
const status = await this.api_client.getNetworkStatus();
|
|
240
|
+
// Update all accessories
|
|
241
|
+
for (const accessory of this.accessories.values()) {
|
|
242
|
+
const context = accessory.context.device;
|
|
243
|
+
if (context.type === 'network') {
|
|
244
|
+
// Network status will be updated by its own handler
|
|
245
|
+
}
|
|
246
|
+
else if (context.type === 'guest-network') {
|
|
247
|
+
// Guest network will be updated by its own handler
|
|
248
|
+
}
|
|
249
|
+
else if (context.deviceId) {
|
|
250
|
+
// Update Deco device status
|
|
251
|
+
const updatedDevice = status.devices.find(d => d.deviceId === context.deviceId);
|
|
252
|
+
if (updatedDevice) {
|
|
253
|
+
accessory.context.device = updatedDevice;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
this.log.error('Error during status polling:', error);
|
|
260
|
+
}
|
|
261
|
+
}, this.pollingInterval);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is the name of the platform that users will use to register the plugin in the Homebridge config.json
|
|
3
|
+
*/
|
|
4
|
+
export declare const PLATFORM_NAME = "TPLinkDeco";
|
|
5
|
+
/**
|
|
6
|
+
* This must match the name of your plugin as defined the package.json `name` property
|
|
7
|
+
*/
|
|
8
|
+
export declare const PLUGIN_NAME = "homebridge-deco";
|
package/dist/settings.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is the name of the platform that users will use to register the plugin in the Homebridge config.json
|
|
3
|
+
*/
|
|
4
|
+
export const PLATFORM_NAME = 'TPLinkDeco';
|
|
5
|
+
/**
|
|
6
|
+
* This must match the name of your plugin as defined the package.json `name` property
|
|
7
|
+
*/
|
|
8
|
+
export const PLUGIN_NAME = 'homebridge-deco';
|
|
9
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "homebridge-deco",
|
|
3
|
+
"displayName": "TP-Link Deco",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "Homebridge plugin for TP-Link Deco mesh network system with support for network monitoring, device tracking, and network controls.",
|
|
7
|
+
"author": "Fabian Oley",
|
|
8
|
+
"license": "Apache-2.0",
|
|
9
|
+
"homepage": "https://github.com/fabianoley/homebridge-deco#readme",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/fabianoley/homebridge-deco.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/fabianoley/homebridge-deco/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"homebridge-plugin",
|
|
19
|
+
"tp-link",
|
|
20
|
+
"deco",
|
|
21
|
+
"mesh",
|
|
22
|
+
"network",
|
|
23
|
+
"router"
|
|
24
|
+
],
|
|
25
|
+
"main": "dist/index.js",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": "^20.18.0 || ^22.10.0 || ^24.0.0",
|
|
28
|
+
"homebridge": "^1.8.0 || ^2.0.0-beta.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "rimraf ./dist && tsc",
|
|
32
|
+
"lint": "eslint . --max-warnings=0",
|
|
33
|
+
"prepublishOnly": "npm run lint && npm run build",
|
|
34
|
+
"watch": "npm run build && npm link && nodemon"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"homebridge-lib": "^7.1.12"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@eslint/js": "^9.39.1",
|
|
41
|
+
"@types/node": "^24.10.1",
|
|
42
|
+
"eslint": "^9.39.1",
|
|
43
|
+
"homebridge": "^2.0.0-beta.55",
|
|
44
|
+
"nodemon": "^3.1.11",
|
|
45
|
+
"rimraf": "^6.1.0",
|
|
46
|
+
"ts-node": "^10.9.2",
|
|
47
|
+
"typescript": "^5.9.3",
|
|
48
|
+
"typescript-eslint": "^8.46.4"
|
|
49
|
+
}
|
|
50
|
+
}
|