@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 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
- const devices = await this.shomeClient.getDeviceList();
33
- const foundAccessories = [];
34
- for (const device of devices) {
35
- if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
36
- const deviceInfoList = await this.shomeClient.getDeviceInfo(device.thngId, device.thngModelTypeName);
37
- if (deviceInfoList) {
38
- for (const subDevice of deviceInfoList) {
39
- const uuid = this.api.hap.uuid.generate(`${device.thngId}-${subDevice.deviceId}`);
40
- const accessory = this.setupAccessory(device, subDevice, uuid);
41
- foundAccessories.push(accessory);
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
- else if (SPECIAL_CONTROLLABLE_TYPES.includes(device.thngModelTypeName)) {
46
- const uuid = this.api.hap.uuid.generate(device.thngId);
47
- const accessory = this.setupAccessory(device, null, uuid);
48
- foundAccessories.push(accessory);
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
- const accessoriesToRemove = this.accessories.filter(cachedAccessory => !foundAccessories.some(foundAccessory => foundAccessory.UUID === cachedAccessory.UUID));
55
- if (accessoriesToRemove.length > 0) {
56
- this.log.info('Removing stale accessories:', accessoriesToRemove.map(a => a.displayName));
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) {
@@ -1 +1 @@
1
- {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@boozilla/homebridge-shome",
3
3
  "displayName": "sHome Plugin",
4
- "version": "1.0.6",
4
+ "version": "1.0.7",
5
5
  "private": false,
6
6
  "description": "A Homebridge plugin for Samsung Smart Home",
7
7
  "author": "boozilla",
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
- public readonly log: Logger,
20
- public readonly config: PlatformConfig,
21
- public readonly api: API,
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
- const devices = await this.shomeClient.getDeviceList();
44
- const foundAccessories: PlatformAccessory[] = [];
45
-
46
- for (const device of devices) {
47
- if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
48
- const deviceInfoList = await this.shomeClient.getDeviceInfo(device.thngId, device.thngModelTypeName);
49
-
50
- if (deviceInfoList) {
51
- for (const subDevice of deviceInfoList) {
52
- const uuid = this.api.hap.uuid.generate(`${device.thngId}-${subDevice.deviceId}`);
53
- const accessory = this.setupAccessory(device, subDevice, uuid);
54
- foundAccessories.push(accessory);
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
- const accessoriesToRemove = this.accessories.filter(cachedAccessory =>
67
- !foundAccessories.some(foundAccessory => foundAccessory.UUID === cachedAccessory.UUID),
68
- );
69
- if (accessoriesToRemove.length > 0) {
70
- this.log.info('Removing stale accessories:', accessoriesToRemove.map(a => a.displayName));
71
- this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessoriesToRemove);
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