@boozilla/homebridge-shome 1.0.6 → 1.0.7
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/dist/platform.js +43 -21
- package/dist/platform.js.map +1 -1
- package/package.json +1 -1
- package/src/platform.ts +53 -28
package/dist/platform.js
CHANGED
|
@@ -20,8 +20,17 @@ export class ShomePlatform {
|
|
|
20
20
|
this.api = api;
|
|
21
21
|
this.Service = this.api.hap.Service;
|
|
22
22
|
this.Characteristic = this.api.hap.Characteristic;
|
|
23
|
+
// 1. Validate configuration
|
|
24
|
+
if (!this.config.username || !this.config.password || !this.config.deviceId) {
|
|
25
|
+
this.log.error('Missing required configuration. Please check your config.json file.');
|
|
26
|
+
this.log.error('Required fields are: "username", "password", and "deviceId".');
|
|
27
|
+
// Prevent further initialization by not creating the client
|
|
28
|
+
this.shomeClient = null;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
23
31
|
this.shomeClient = new ShomeClient(this.log, this.config.username, this.config.password, this.config.deviceId);
|
|
24
32
|
this.api.on('didFinishLaunching', () => {
|
|
33
|
+
// Defer device discovery until Homebridge is fully launched.
|
|
25
34
|
this.discoverDevices();
|
|
26
35
|
});
|
|
27
36
|
}
|
|
@@ -29,32 +38,45 @@ export class ShomePlatform {
|
|
|
29
38
|
this.accessories.push(accessory);
|
|
30
39
|
}
|
|
31
40
|
async discoverDevices() {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
// Gracefully handle cases where the client was not initialized due to config errors
|
|
42
|
+
if (!this.shomeClient) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const devices = await this.shomeClient.getDeviceList();
|
|
47
|
+
const foundAccessories = [];
|
|
48
|
+
if (!devices || devices.length === 0) {
|
|
49
|
+
this.log.warn('No devices found on your sHome account. Please check your account or network connection.');
|
|
50
|
+
}
|
|
51
|
+
for (const device of devices) {
|
|
52
|
+
if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
|
|
53
|
+
const deviceInfoList = await this.shomeClient.getDeviceInfo(device.thngId, device.thngModelTypeName);
|
|
54
|
+
if (deviceInfoList) {
|
|
55
|
+
for (const subDevice of deviceInfoList) {
|
|
56
|
+
const uuid = this.api.hap.uuid.generate(`${device.thngId}-${subDevice.deviceId}`);
|
|
57
|
+
const accessory = this.setupAccessory(device, subDevice, uuid);
|
|
58
|
+
foundAccessories.push(accessory);
|
|
59
|
+
}
|
|
42
60
|
}
|
|
43
61
|
}
|
|
62
|
+
else if (SPECIAL_CONTROLLABLE_TYPES.includes(device.thngModelTypeName)) {
|
|
63
|
+
const uuid = this.api.hap.uuid.generate(device.thngId);
|
|
64
|
+
const accessory = this.setupAccessory(device, null, uuid);
|
|
65
|
+
foundAccessories.push(accessory);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
this.log.info(`Ignoring device: ${device.nickname} (Type: ${device.thngModelTypeName})`);
|
|
69
|
+
}
|
|
44
70
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
this.log.info(`Ignoring device: ${device.nickname} (Type: ${device.thngModelTypeName})`);
|
|
71
|
+
const accessoriesToRemove = this.accessories.filter(cachedAccessory => !foundAccessories.some(foundAccessory => foundAccessory.UUID === cachedAccessory.UUID));
|
|
72
|
+
if (accessoriesToRemove.length > 0) {
|
|
73
|
+
this.log.info('Removing stale accessories:', accessoriesToRemove.map(a => a.displayName));
|
|
74
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessoriesToRemove);
|
|
52
75
|
}
|
|
53
76
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
this.log.
|
|
57
|
-
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessoriesToRemove);
|
|
77
|
+
catch (error) {
|
|
78
|
+
this.log.error('Failed to discover devices due to a network or API error.');
|
|
79
|
+
this.log.error('Please check your network connection and sHome credentials. The plugin will not be able to control devices.');
|
|
58
80
|
}
|
|
59
81
|
}
|
|
60
82
|
setupAccessory(mainDevice, subDevice, uuid) {
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEvE,MAAM,+BAA+B,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAC1E,MAAM,0BAA0B,GAAG,CAAC,UAAU,CAAC,CAAC;AAEhD,MAAM,OAAO,aAAa;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/platform.ts
CHANGED
|
@@ -16,13 +16,22 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
16
16
|
public readonly shomeClient: ShomeClient;
|
|
17
17
|
|
|
18
18
|
constructor(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
public readonly log: Logger,
|
|
20
|
+
public readonly config: PlatformConfig,
|
|
21
|
+
public readonly api: API,
|
|
22
22
|
) {
|
|
23
23
|
this.Service = this.api.hap.Service;
|
|
24
24
|
this.Characteristic = this.api.hap.Characteristic;
|
|
25
25
|
|
|
26
|
+
// 1. Validate configuration
|
|
27
|
+
if (!this.config.username || !this.config.password || !this.config.deviceId) {
|
|
28
|
+
this.log.error('Missing required configuration. Please check your config.json file.');
|
|
29
|
+
this.log.error('Required fields are: "username", "password", and "deviceId".');
|
|
30
|
+
// Prevent further initialization by not creating the client
|
|
31
|
+
this.shomeClient = null!;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
this.shomeClient = new ShomeClient(
|
|
27
36
|
this.log,
|
|
28
37
|
this.config.username,
|
|
@@ -31,6 +40,7 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
31
40
|
);
|
|
32
41
|
|
|
33
42
|
this.api.on('didFinishLaunching', () => {
|
|
43
|
+
// Defer device discovery until Homebridge is fully launched.
|
|
34
44
|
this.discoverDevices();
|
|
35
45
|
});
|
|
36
46
|
}
|
|
@@ -40,35 +50,50 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
40
50
|
}
|
|
41
51
|
|
|
42
52
|
async discoverDevices() {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
// Gracefully handle cases where the client was not initialized due to config errors
|
|
54
|
+
if (!this.shomeClient) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
const devices = await this.shomeClient.getDeviceList();
|
|
60
|
+
const foundAccessories: PlatformAccessory[] = [];
|
|
61
|
+
|
|
62
|
+
if (!devices || devices.length === 0) {
|
|
63
|
+
this.log.warn('No devices found on your sHome account. Please check your account or network connection.');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const device of devices) {
|
|
67
|
+
if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
|
|
68
|
+
const deviceInfoList = await this.shomeClient.getDeviceInfo(device.thngId, device.thngModelTypeName);
|
|
69
|
+
|
|
70
|
+
if (deviceInfoList) {
|
|
71
|
+
for (const subDevice of deviceInfoList) {
|
|
72
|
+
const uuid = this.api.hap.uuid.generate(`${device.thngId}-${subDevice.deviceId}`);
|
|
73
|
+
const accessory = this.setupAccessory(device, subDevice, uuid);
|
|
74
|
+
foundAccessories.push(accessory);
|
|
75
|
+
}
|
|
55
76
|
}
|
|
77
|
+
} else if (SPECIAL_CONTROLLABLE_TYPES.includes(device.thngModelTypeName)) {
|
|
78
|
+
const uuid = this.api.hap.uuid.generate(device.thngId);
|
|
79
|
+
const accessory = this.setupAccessory(device, null, uuid);
|
|
80
|
+
foundAccessories.push(accessory);
|
|
81
|
+
} else {
|
|
82
|
+
this.log.info(`Ignoring device: ${device.nickname} (Type: ${device.thngModelTypeName})`);
|
|
56
83
|
}
|
|
57
|
-
} else if (SPECIAL_CONTROLLABLE_TYPES.includes(device.thngModelTypeName)) {
|
|
58
|
-
const uuid = this.api.hap.uuid.generate(device.thngId);
|
|
59
|
-
const accessory = this.setupAccessory(device, null, uuid);
|
|
60
|
-
foundAccessories.push(accessory);
|
|
61
|
-
} else {
|
|
62
|
-
this.log.info(`Ignoring device: ${device.nickname} (Type: ${device.thngModelTypeName})`);
|
|
63
84
|
}
|
|
64
|
-
}
|
|
65
85
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
86
|
+
const accessoriesToRemove = this.accessories.filter(cachedAccessory =>
|
|
87
|
+
!foundAccessories.some(foundAccessory => foundAccessory.UUID === cachedAccessory.UUID),
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
if (accessoriesToRemove.length > 0) {
|
|
91
|
+
this.log.info('Removing stale accessories:', accessoriesToRemove.map(a => a.displayName));
|
|
92
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessoriesToRemove);
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
this.log.error('Failed to discover devices due to a network or API error.');
|
|
96
|
+
this.log.error('Please check your network connection and sHome credentials. The plugin will not be able to control devices.');
|
|
72
97
|
}
|
|
73
98
|
}
|
|
74
99
|
|