homebridge-smarthq-client 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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/Readme.md +138 -0
  3. package/config.schema.json +146 -0
  4. package/dist/index.d.ts +6 -0
  5. package/dist/index.js +9 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/platform.d.ts +40 -0
  8. package/dist/platform.js +243 -0
  9. package/dist/platform.js.map +1 -0
  10. package/dist/refrigerator/controlLock.d.ts +19 -0
  11. package/dist/refrigerator/controlLock.js +85 -0
  12. package/dist/refrigerator/controlLock.js.map +1 -0
  13. package/dist/refrigerator/convertibleDrawer.d.ts +27 -0
  14. package/dist/refrigerator/convertibleDrawer.js +317 -0
  15. package/dist/refrigerator/convertibleDrawer.js.map +1 -0
  16. package/dist/refrigerator/dispenserLight.d.ts +19 -0
  17. package/dist/refrigerator/dispenserLight.js +85 -0
  18. package/dist/refrigerator/dispenserLight.js.map +1 -0
  19. package/dist/refrigerator/energy.d.ts +19 -0
  20. package/dist/refrigerator/energy.js +93 -0
  21. package/dist/refrigerator/energy.js.map +1 -0
  22. package/dist/refrigerator/freezer.d.ts +41 -0
  23. package/dist/refrigerator/freezer.js +188 -0
  24. package/dist/refrigerator/freezer.js.map +1 -0
  25. package/dist/refrigerator/iceMaker.d.ts +19 -0
  26. package/dist/refrigerator/iceMaker.js +81 -0
  27. package/dist/refrigerator/iceMaker.js.map +1 -0
  28. package/dist/refrigerator/interiorLight.d.ts +21 -0
  29. package/dist/refrigerator/interiorLight.js +100 -0
  30. package/dist/refrigerator/interiorLight.js.map +1 -0
  31. package/dist/refrigerator/refrigerator.d.ts +41 -0
  32. package/dist/refrigerator/refrigerator.js +204 -0
  33. package/dist/refrigerator/refrigerator.js.map +1 -0
  34. package/dist/refrigerator/refrigeratorAlerts.d.ts +36 -0
  35. package/dist/refrigerator/refrigeratorAlerts.js +204 -0
  36. package/dist/refrigerator/refrigeratorAlerts.js.map +1 -0
  37. package/dist/refrigerator/sabbathMode.d.ts +20 -0
  38. package/dist/refrigerator/sabbathMode.js +91 -0
  39. package/dist/refrigerator/sabbathMode.js.map +1 -0
  40. package/dist/refrigerator/temperatureUnits.d.ts +21 -0
  41. package/dist/refrigerator/temperatureUnits.js +147 -0
  42. package/dist/refrigerator/temperatureUnits.js.map +1 -0
  43. package/dist/refrigerator/turboCoolMode.d.ts +23 -0
  44. package/dist/refrigerator/turboCoolMode.js +134 -0
  45. package/dist/refrigerator/turboCoolMode.js.map +1 -0
  46. package/dist/refrigerator/waterFilter.d.ts +19 -0
  47. package/dist/refrigerator/waterFilter.js +89 -0
  48. package/dist/refrigerator/waterFilter.js.map +1 -0
  49. package/dist/refrigeratorServices.d.ts +5 -0
  50. package/dist/refrigeratorServices.js +54 -0
  51. package/dist/refrigeratorServices.js.map +1 -0
  52. package/dist/settings.d.ts +12 -0
  53. package/dist/settings.js +13 -0
  54. package/dist/settings.js.map +1 -0
  55. package/dist/smartHqApi.d.ts +29 -0
  56. package/dist/smartHqApi.js +267 -0
  57. package/dist/smartHqApi.js.map +1 -0
  58. package/dist/smarthq-types.d.ts +29 -0
  59. package/dist/smarthq-types.js +2 -0
  60. package/dist/smarthq-types.js.map +1 -0
  61. package/eslint.config.js +12 -0
  62. package/images/homebridge.svg +1 -0
  63. package/package.json +61 -0
  64. package/src/@types/homebridge-lib.d.ts +14 -0
  65. package/src/index.ts +11 -0
  66. package/src/platform.ts +300 -0
  67. package/src/refrigerator/controlLock.ts +103 -0
  68. package/src/refrigerator/convertibleDrawer.ts +381 -0
  69. package/src/refrigerator/dispenserLight.ts +103 -0
  70. package/src/refrigerator/energy.ts +106 -0
  71. package/src/refrigerator/freezer.ts +227 -0
  72. package/src/refrigerator/iceMaker.ts +100 -0
  73. package/src/refrigerator/interiorLight.ts +118 -0
  74. package/src/refrigerator/refrigerator.ts +241 -0
  75. package/src/refrigerator/refrigeratorAlerts.ts +228 -0
  76. package/src/refrigerator/sabbathMode.ts +111 -0
  77. package/src/refrigerator/temperatureUnits.ts +178 -0
  78. package/src/refrigerator/turboCoolMode.ts +164 -0
  79. package/src/refrigerator/waterFilter.ts +107 -0
  80. package/src/refrigeratorServices.ts +60 -0
  81. package/src/settings.ts +14 -0
  82. package/src/smartHqApi.ts +305 -0
  83. package/src/smarthq-types.ts +31 -0
  84. package/tsconfig.json +24 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ceb400
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/Readme.md ADDED
@@ -0,0 +1,138 @@
1
+ <img src="images/homebridge.svg" width="100" height="100">
2
+
3
+ # Homebridge-SmartHQ Client
4
+
5
+ A homebridge plugin for GE appliances using the SmartHQ API s (Identity and Access Management API, Digital Twin API). Currently only services for a refrigerator are implemented.
6
+
7
+ The refrigerator services include controls for:
8
+ * refrigerator temperature
9
+ * freezer temperature
10
+ * controls lock
11
+ * convertible drawer modes
12
+ * dispenser light
13
+ * icemaker
14
+ * interior light
15
+ * sabbath mode
16
+ * temperature units
17
+ * turbo cool modes refrigerator & freezer
18
+ * water filter maintenance (see notes)
19
+ * additional switches are used to implement notifications
20
+
21
+
22
+
23
+ ## Installation
24
+
25
+ Option 1: Homebridge UI
26
+
27
+ Go to the 'Plugins' page, search for homebridge-smarthq-client, and click 'Install'.
28
+
29
+ Option 2: Manually
30
+
31
+ Run the following command to install the plugin globally:
32
+ ```
33
+ $ sudo npm install homebridge-smarthq-client -g
34
+ ```
35
+
36
+
37
+
38
+ ## Requirements
39
+ The SmartHQ API uses an OAuth 2.0 authentication process. The steps required to setup an account in order to use the API are
40
+
41
+ * Follow the steps at [Get Started - SmartHQ Docs](https://docs.smarthq.com/get-started/)
42
+ (The Callback URL specified in step 2.4 must match the corresponding field in the plugin config setup (recommended http://localhost:8888/callback)
43
+
44
+ * When step 2 from Get Started is complete and you have created an app, click on the app to display your apps page. Find the Credentials tab and copy the **Client Id**, **Client Secret** and **Callback URL** to the plugin config.
45
+ ## Configuration
46
+
47
+ Use the Homebridge UI to configure this plugin. See **Requirements** for steps to obtain a Client Id and Client Secret.
48
+
49
+ * Select the services you want to add for the appliance in the plugin config.
50
+
51
+ * Select Logging options.
52
+ *Plugin Debug Logging* will log additional messages to the Homebridge log.
53
+ *Display Service Details* will log sorted information about all services for each discovered device.
54
+ (This info is used to add support for other appliances.)
55
+
56
+ * Save plugin config and restart child bridge.
57
+
58
+ Or manually edit the config file with
59
+ ```
60
+ {
61
+ "name": "SmartHQ Client",
62
+ "clientId": "your client id",
63
+ "clientSecret": "your client secret",
64
+ "redirectUri": "http://localhost:8888/callback",
65
+ "addControlLock": false,
66
+ "addConvertibleDrawer": false,
67
+ "addDispenserLight": false,
68
+ "addIceMaker": false,
69
+ "addInteriorLight": false,
70
+ "addSabbathMode": false,
71
+ "addTemperatureUnits": false,
72
+ "addEnergyMonitor": false,
73
+ "addTurboCool": false,
74
+ "addWaterFilter": false,
75
+ "addAlerts": false,
76
+ "debugLogging": false,
77
+ "debugServices": false,
78
+ "_bridge": {
79
+ "name": "SmartHQ Bridge",
80
+ "username": "0E:23:87:36:1A:C8",
81
+ "port": 34603
82
+ },
83
+ "platform": "SmartHqPlatform"
84
+ }
85
+ ```
86
+
87
+
88
+ ## Initial Authentication
89
+ (*If access token does not exist*). Check the Homebridge log for a highlighted localhost URL.
90
+ ```
91
+ =======================================================================
92
+ Click to login for SmartHQ Auth setup ===>: http://localhost:8888/login
93
+ =======================================================================
94
+ ```
95
+ Click on the URL to be redirected to a SmartHQ authorization screen.
96
+ Login to your SmartHQ account to complete the process.
97
+ Once an access (and refresh) token have been saved this step will only be needed if the file
98
+ used to store your tokens is deleted.
99
+ When an access token expires the plugin will use the refresh token to obtain a new access token.
100
+
101
+ ## Notifications
102
+
103
+ API device alerts are monitored for the following conditions:
104
+ * Door left open
105
+ * Temperature alert (either fridge or freezer)
106
+ * Water pitcher leak
107
+ * Filter maintenance
108
+ * Firmware
109
+
110
+ If selected during configuration, switches are added that will be turned on temporarily
111
+ when a corresponding alert is triggered.
112
+ Using these switches in conjunction with a 3rd party service (e.g PushOver, PushCutter etc)
113
+ an Apple Home automation can be set up to issue notifications for your iOS devices.
114
+
115
+ These switches will appear in Accessories as *Alert Door*, *Alert Temp*, *Alert Leak*, *Alert Filter*, *Alert Firm*
116
+ ## Documentation
117
+
118
+ [SmartHQ Documentation](https://developer.smarthq.com/)
119
+
120
+ ## Notes
121
+ The *water filter maintenance* option uses the Filter Maintenance Service in the Homebridge API.
122
+ The service exists in HomeKit but has not been implemented in the Apple Home app.
123
+ If selected in the plugin config you will notice a tile on the Homebridge Accessories page but there
124
+ will not be any tile/device shown in the Home app.
125
+
126
+
127
+ ## Feedback
128
+
129
+ If you have any feedback, please reach out at: ceb40win@outlook.com
130
+
131
+ If you have GE smart appliances other than refrigerator you can capture
132
+ the following information (after adding the appliance to your SmartHQ account)
133
+ * Update the plugin config to select *Display Service Details*
134
+ * Restart the child bridge.
135
+ * Copy log output including 'SmartHQ Discovered device: newDevice Model: PVD28BYNIFS'
136
+ plus all logged services and forward the file to me.
137
+ As my time permits I will attempt to add support for new devices.
138
+
@@ -0,0 +1,146 @@
1
+ {
2
+ "pluginAlias": "SmartHqPlatform",
3
+ "pluginType": "platform",
4
+ "singular": true,
5
+ "schema": {
6
+ "type": "object",
7
+ "required": ["clientId", "clientSecret"],
8
+ "properties": {
9
+ "clientId": {
10
+ "type": "string",
11
+ "title": "SmartHQ Client ID",
12
+ "x-schema-form": {
13
+ "type": "password"
14
+ }
15
+ },
16
+ "clientSecret": {
17
+ "type": "string",
18
+ "title": "SmartHQ Client Secret",
19
+ "x-schema-form": {
20
+ "type": "password"
21
+ }
22
+ },
23
+ "redirectUri": {
24
+ "type": "string",
25
+ "format": "uri",
26
+ "title": "OAuth Redirect URI (must match the one defined for SmartHQ app @ https://developer.smarthq.com/user/???/apps",
27
+ "default": "http://localhost:8888/callback"
28
+ },
29
+ "addControlLock": {
30
+ "type": "boolean",
31
+ "title": "Add Controls Lock",
32
+ "default": false
33
+ },
34
+ "addConvertibleDrawer": {
35
+ "type": "boolean",
36
+ "title": "Add Convertible Drawer Controls",
37
+ "default": false
38
+ },
39
+ "addDispenserLight": {
40
+ "type": "boolean",
41
+ "title": "Add Dispenser Light Control",
42
+ "default": false
43
+ },
44
+ "addIceMaker": {
45
+ "type": "boolean",
46
+ "title": "Add Ice Maker Control",
47
+ "default": false
48
+ },
49
+ "addInteriorLight": {
50
+ "type": "boolean",
51
+ "title": "Add Interior Light Control",
52
+ "default": false
53
+ },
54
+ "addSabbathMode": {
55
+ "type": "boolean",
56
+ "title": "Add Sabbath Mode Control",
57
+ "default": false
58
+ },
59
+ "addTemperatureUnits": {
60
+ "type": "boolean",
61
+ "title": "Add Temperature Units Control",
62
+ "default": false
63
+ },
64
+ "addEnergyMonitor": {
65
+ "type": "boolean",
66
+ "title": "Add Energy Monitor",
67
+ "default": false
68
+ },
69
+ "addTurboCool": {
70
+ "type": "boolean",
71
+ "title": "Add Turbo Cool Controls",
72
+ "default": false
73
+ },
74
+ "addWaterFilter": {
75
+ "type": "boolean",
76
+ "title": "Add Water Filter Status",
77
+ "default": false
78
+ },
79
+ "addAlerts": {
80
+ "type": "boolean",
81
+ "title": "Add Alert Notifications",
82
+ "default": false
83
+ },
84
+ "debugLogging": {
85
+ "type": "boolean",
86
+ "title": "Plugin Debug Logging w/Chalk Colors",
87
+ "default": false
88
+ },
89
+ "debugServices": {
90
+ "type": "boolean",
91
+ "title": "Display Service Details for all discovered services",
92
+ "default": false
93
+ }
94
+ }
95
+ },
96
+ "layout": [
97
+ {
98
+ "type": "section",
99
+ "title": "Authentication Settings",
100
+ "items": [
101
+ {
102
+ "description": "Required SmartHQ API authentication settings.",
103
+ "items": [
104
+ "clientId",
105
+ "clientSecret",
106
+ "redirectUri"
107
+ ]
108
+ }
109
+ ]
110
+ },
111
+ {
112
+ "type": "section",
113
+ "title": "Refrigerator Services",
114
+ "expandable": true,
115
+ "expanded": false,
116
+ "items": [
117
+ {
118
+ "description": "Include the selected refrigerator services.",
119
+ "items": [
120
+ "addConvertibleDrawer",
121
+ "addControlLock",
122
+ "addDispenserLight",
123
+ "addEnergyMonitor",
124
+ "addIceMaker",
125
+ "addInteriorLight",
126
+ "addSabbathMode",
127
+ "addTemperatureUnits",
128
+ "addTurboCool",
129
+ "addWaterFilter",
130
+ "addAlerts"
131
+ ]
132
+ }
133
+ ]
134
+ },
135
+ {
136
+ "type": "section",
137
+ "title": "Logging Options",
138
+ "expandable": true,
139
+ "expanded": false,
140
+ "items": [
141
+ "debugLogging",
142
+ "debugServices"
143
+ ]
144
+ }
145
+ ]
146
+ }
@@ -0,0 +1,6 @@
1
+ import type { API } from 'homebridge';
2
+ /**
3
+ * This method registers the platform with Homebridge
4
+ */
5
+ declare const _default: (api: API) => void;
6
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import { SmartHqPlatform } 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, SmartHqPlatform);
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,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,eAAe,CAAC,GAAQ,EAAE,EAAE;IAC1B,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;AACvD,CAAC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { API, Logging, PlatformConfig, PlatformAccessory, Service, Characteristic } from 'homebridge';
2
+ import { SmartHqApi } from './smartHqApi.js';
3
+ import { EventEmitter } from 'node:events';
4
+ import { DevService } from './smarthq-types.js';
5
+ export declare class SmartHqPlatform {
6
+ readonly log: Logging;
7
+ readonly config: PlatformConfig;
8
+ private readonly api;
9
+ readonly Service: typeof Service;
10
+ readonly Characteristic: typeof Characteristic;
11
+ readonly accessories: Map<string, PlatformAccessory>;
12
+ readonly discoveredCacheUUIDs: string[];
13
+ readonly tokenPath: string;
14
+ private oauthServer?;
15
+ expires: number;
16
+ readonly smartHqApi: SmartHqApi;
17
+ authEmitter: EventEmitter;
18
+ serviceDeviceType: string;
19
+ serviceType: string;
20
+ constructor(log: Logging, config: PlatformConfig, api: API);
21
+ /**================================================================
22
+ * If no token file exists, start the OAuth process.
23
+ * In this process, we start a local express server to handle the redirect
24
+ * from the SmartHQ authorization endpoint.
25
+ * When the user clicks the link in Homebridge UI, they will be directed to the /login route
26
+ * which will redirect to SmartHQ authorization endpoint to obtain authorization code.
27
+ * After user login, SmartHQ authorization endpoint will redirect to whatever url:port/path was configured
28
+ * with authorization code in the query parameter.
29
+ * We will use this code to obtain access token and refresh token
30
+ *================================================================*/
31
+ startOAuth(): Promise<void>;
32
+ extractPortFromRedirectUri(redirectUri: string): {
33
+ port: number;
34
+ pathname: string;
35
+ };
36
+ configureAccessory(accessory: PlatformAccessory): void;
37
+ private discoverDevices;
38
+ debug(color: string, message: string): void;
39
+ deviceSupportsThisService(deviceServices: DevService[], serviceDeviceType: string, serviceType: string, domainType: string): boolean;
40
+ }
@@ -0,0 +1,243 @@
1
+ import chalk from 'chalk';
2
+ import express from 'express';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { stringify, parse } from 'querystring';
6
+ import { SmartHqApi } from './smartHqApi.js';
7
+ import { EventEmitter } from 'node:events';
8
+ import { PLATFORM_NAME, PLUGIN_NAME, AUTH_URL, TOKEN_STORE } from './settings.js';
9
+ import { setupRefrigeratorServices } from './refrigeratorServices.js';
10
+ export class SmartHqPlatform {
11
+ log;
12
+ config;
13
+ api;
14
+ Service;
15
+ Characteristic;
16
+ // this is used to track restored cached accessories
17
+ accessories = new Map();
18
+ discoveredCacheUUIDs = [];
19
+ tokenPath;
20
+ oauthServer;
21
+ expires;
22
+ smartHqApi;
23
+ authEmitter;
24
+ serviceDeviceType = '';
25
+ serviceType = '';
26
+ constructor(log, config, api) {
27
+ this.log = log;
28
+ this.config = config;
29
+ this.api = api;
30
+ this.api = api;
31
+ this.Service = api.hap.Service;
32
+ this.Characteristic = api.hap.Characteristic;
33
+ this.expires = 0;
34
+ this.tokenPath = path.join(this.api.user.persistPath(), TOKEN_STORE);
35
+ this.authEmitter = new EventEmitter();
36
+ chalk.level = 1; // Enable chalk colors
37
+ this.smartHqApi = new SmartHqApi(this);
38
+ // Validate required configuration parameters
39
+ if (!config.clientId || !config.clientSecret || !config.redirectUri) {
40
+ this.log.error('Missing required config parameter.');
41
+ return;
42
+ }
43
+ this.api.on('didFinishLaunching', async () => {
44
+ try {
45
+ this.debug('red', '(SmartHQ OAuth2 authentication starting)');
46
+ await this.startOAuth();
47
+ this.debug('blue', '(SmartHQ OAuth2 authentication completed)');
48
+ }
49
+ catch (error) {
50
+ this.log.error(chalk.red('SmartHQ OAuth2 authentication failed:'), error);
51
+ }
52
+ });
53
+ // Listen for authComplete event to start device discovery
54
+ this.authEmitter.on('authComplete', async () => {
55
+ this.debug('green', 'Auth complete event received, starting device discovery');
56
+ await this.discoverDevices();
57
+ });
58
+ }
59
+ /**================================================================
60
+ * If no token file exists, start the OAuth process.
61
+ * In this process, we start a local express server to handle the redirect
62
+ * from the SmartHQ authorization endpoint.
63
+ * When the user clicks the link in Homebridge UI, they will be directed to the /login route
64
+ * which will redirect to SmartHQ authorization endpoint to obtain authorization code.
65
+ * After user login, SmartHQ authorization endpoint will redirect to whatever url:port/path was configured
66
+ * with authorization code in the query parameter.
67
+ * We will use this code to obtain access token and refresh token
68
+ *================================================================*/
69
+ async startOAuth() {
70
+ const path = this.tokenPath;
71
+ if (!fs.existsSync(path)) {
72
+ this.debug('blue', '=== file does not exist starting OAuth process ===');
73
+ this.debug('red', ' Starting localhost server to handle OAuth redirects');
74
+ }
75
+ else {
76
+ this.debug('red', ' Returning because token path exists, emitting authComplete');
77
+ this.authEmitter.emit('authComplete');
78
+ return;
79
+ }
80
+ const url = new URL(this.config.redirectUri);
81
+ const pathname = url.pathname;
82
+ const port = parseInt(url.port, 10);
83
+ this.debug('blue', ' Redirect URI port: ' + port + ' , ' + pathname);
84
+ const app = express();
85
+ // By clicking on the link in Homebridge UI (Logs), user will be directed to the /login route
86
+ // which will redirect to SmartHQ authorization endpoint to obtain authorization code
87
+ this.log.info(chalk.blue("======================================================================="));
88
+ this.log.info("Click to login for SmartHQ Auth setup ===>: " + chalk.red("http://localhost:" + port + "/login"));
89
+ this.log.info(chalk.blue("======================================================================="));
90
+ // Clicking above link in Homebridge UI will redirect to SmartHQ authorization endpoint
91
+ app.get('/login', async (_req, res) => {
92
+ try {
93
+ const url = AUTH_URL + '?' + stringify({
94
+ response_type: 'code',
95
+ client_id: this.config.clientId,
96
+ redirect_uri: this.config.redirectUri
97
+ });
98
+ this.debug('blue', "Redirecting to: " + url);
99
+ res.redirect(url); ///====> Redirect to SmartHQ authorization endpoint
100
+ }
101
+ catch (error) {
102
+ this.log.error('SmartHQ /login error:', error);
103
+ res.status(500).send('Authentication /login failed: ' + error);
104
+ }
105
+ ;
106
+ });
107
+ // After user login, SmartHQ authorization endpoint will redirect to whatever url:port/path was configured
108
+ // with authorization code in the query parameter.
109
+ // We will use this code to obtain access token and refresh token
110
+ app.get(pathname, async (req, res) => {
111
+ try {
112
+ // Parse the request URL
113
+ const query = parse(req.url.split('?')[1]);
114
+ const code = query.code?.toString() || '';
115
+ this.debug('blue', 'An authorization code was returned: ' + code);
116
+ this.debug('blue', 'Now exchanging code for access token...');
117
+ if (!code) {
118
+ this.log.error('No code found in callback URL for SmartHQ OAuth');
119
+ }
120
+ await this.smartHqApi.exchangeCodeForToken(code);
121
+ res.send(`
122
+ <h2>SmartHQ Connected</h2>
123
+ <p>Authorization token saved to file.</p>
124
+ <p>You may close this window.</p>
125
+ `);
126
+ // Emit event to indicate authentication is complete
127
+ this.authEmitter.emit('authComplete');
128
+ this.log.success('SmartHQ authentication completed');
129
+ setTimeout(() => this.oauthServer?.close(), 1000);
130
+ this.debug('blue', 'OAuth server has been closed.');
131
+ return;
132
+ }
133
+ catch (error) {
134
+ this.log.error('SmartHQ OAuth failed', error);
135
+ res.status(500).send('Authentication failed: ' + error);
136
+ }
137
+ });
138
+ this.oauthServer = app.listen(port, () => {
139
+ this.log.info(`SmartHQ OAuth listening on ${port}`);
140
+ });
141
+ }
142
+ // Extract port and pathname from redirect URI
143
+ extractPortFromRedirectUri(redirectUri) {
144
+ const url = new URL(redirectUri);
145
+ const pathname = url.pathname;
146
+ const port = parseInt(url.port, 10);
147
+ return { port, pathname };
148
+ }
149
+ configureAccessory(accessory) {
150
+ this.log.info('Loading accessory from cache:', accessory.displayName);
151
+ // add the restored accessory to the accessories cache, so we can track if it has already been registered
152
+ this.accessories.set(accessory.UUID, accessory);
153
+ }
154
+ async discoverDevices() {
155
+ this.debug('yellow', '(discoverDevices) Starting device discovery...');
156
+ let devices = [];
157
+ devices = await this.smartHqApi.getAppliances();
158
+ // loop over the discovered devices and register each one if it has not already been registered
159
+ if (!devices || devices.length === 0) {
160
+ this.log.warn(chalk.yellow('No SmartHQ devices found for this account.'));
161
+ return;
162
+ }
163
+ for (const device of devices) {
164
+ this.log.info(chalk.yellow(`SmartHQ Discovered device: ${device.nickname} Model: ${device.model}`));
165
+ // Used to acquire service IDs and service deviceTypes for deviceServiceState queries
166
+ const deviceServices = await this.smartHqApi.getDeviceServices(device.deviceId);
167
+ let accessoryType;
168
+ const uuid = this.api.hap.uuid.generate(device.deviceId);
169
+ const existingAccessory = this.accessories.get(uuid);
170
+ // for existing accessories restore from cache
171
+ if (existingAccessory) {
172
+ this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
173
+ accessoryType = existingAccessory;
174
+ existingAccessory.context.device = device;
175
+ this.api.updatePlatformAccessories([existingAccessory]);
176
+ }
177
+ else {
178
+ // create new accessory
179
+ this.log.info('Adding new accessory:', device.nickname);
180
+ const accessory = new this.api.platformAccessory(device.nickname, uuid);
181
+ accessoryType = accessory;
182
+ accessory.context.device = device;
183
+ this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
184
+ }
185
+ this.discoveredCacheUUIDs.push(uuid);
186
+ // Setup services based on device type when there are multiple device types in account
187
+ // add more case statements e.g. Washer, Dryer, Oven, etc.
188
+ switch (device.nickname) {
189
+ case 'Refrigerator':
190
+ this.debug('green', `Setting up Refrigerator services for ${device.nickname}`);
191
+ setupRefrigeratorServices.call(this, accessoryType, device, deviceServices);
192
+ break;
193
+ case 'someNewAppliance':
194
+ this.debug('green', `Logic not implemented for ${device.nickname}`);
195
+ break;
196
+ default:
197
+ this.debug('red', `not implemented device : for device ${device.nickname}`);
198
+ }
199
+ }
200
+ // remove accessories from the cache which are no longer present
201
+ for (const [uuid, accessory] of this.accessories) {
202
+ if (!this.discoveredCacheUUIDs.includes(uuid)) {
203
+ this.log.info('Removing existing accessory from cache:', accessory.displayName);
204
+ this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
205
+ }
206
+ }
207
+ }
208
+ debug(color, message) {
209
+ if (this.config.debugLogging) {
210
+ switch (color) {
211
+ case 'red':
212
+ this.log.info(chalk.red('[Smarthq] ' + message));
213
+ break;
214
+ case 'blue':
215
+ this.log.info(chalk.blue('[Smarthq] ' + message));
216
+ break;
217
+ case 'green':
218
+ this.log.info(chalk.green('[Smarthq] ' + message));
219
+ break;
220
+ case 'yellow':
221
+ this.log.info(chalk.yellow('[Smarthq] ' + message));
222
+ break;
223
+ default:
224
+ this.log.info('[Smarthq] ' + message);
225
+ }
226
+ }
227
+ else {
228
+ return;
229
+ }
230
+ }
231
+ // Some models may not have all services available so don't add service if not supported
232
+ deviceSupportsThisService(deviceServices, serviceDeviceType, serviceType, domainType) {
233
+ for (const service of deviceServices) {
234
+ if (service.serviceDeviceType === serviceDeviceType
235
+ && service.serviceType === serviceType
236
+ && service.domainType === domainType) {
237
+ return true;
238
+ }
239
+ }
240
+ return false;
241
+ }
242
+ }
243
+ //# 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,19 @@
1
+ import { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import { SmartHqPlatform } from '../platform.js';
3
+ import { DevService } from '../smarthq-types.js';
4
+ /**
5
+ * Platform Accessory
6
+ * An instance of this class is created for each accessory your platform registers
7
+ * Each accessory may expose multiple services of different service types.
8
+ */
9
+ export declare class ControlLock {
10
+ private readonly platform;
11
+ private readonly accessory;
12
+ readonly deviceServices: DevService[];
13
+ readonly deviceId: string;
14
+ private readonly smartHqApi;
15
+ private log;
16
+ constructor(platform: SmartHqPlatform, accessory: PlatformAccessory, deviceServices: DevService[], deviceId: string);
17
+ getcontrolsLock(): Promise<CharacteristicValue>;
18
+ setcontrolsLock(value: CharacteristicValue): Promise<void>;
19
+ }