@homebridge-plugins/homebridge-smarthq 0.1.0 → 0.2.0-beta.1

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,120 @@
1
+ import axios from 'axios';
2
+ import { interval, skipWhile } from 'rxjs';
3
+ import { ERD_TYPES } from '../settings.js';
4
+ import { deviceBase } from './device.js';
5
+ export class SmartHQRefrigerator extends deviceBase {
6
+ platform;
7
+ device;
8
+ // Service
9
+ Refrigerator;
10
+ // Updates
11
+ SensorUpdateInProgress;
12
+ deviceStatus;
13
+ constructor(platform, accessory, device) {
14
+ super(platform, accessory, device);
15
+ this.platform = platform;
16
+ this.device = device;
17
+ this.debugLog(`Dishwasher Features: ${JSON.stringify(accessory.context.device.features)}`);
18
+ accessory.context.device.features.forEach((feature) => {
19
+ /* [
20
+ "DOOR_STATUS"
21
+ ] */
22
+ switch (feature) {
23
+ case 'DOOR_STATUS': {
24
+ const refrigerator = this.accessory.getService(accessory.displayName)
25
+ || this.accessory.addService(this.platform.Service.ContactSensor, accessory.displayName, 'Refrigerator');
26
+ refrigerator
27
+ .getCharacteristic(this.platform.Characteristic.ContactSensorState)
28
+ .onGet(() => this.readErd(ERD_TYPES.DOOR_STATUS).then(r => Number.parseInt(r) !== 0))
29
+ .onSet(value => this.writeErd(ERD_TYPES.DOOR_STATUS, value));
30
+ break;
31
+ }
32
+ }
33
+ });
34
+ // this is subject we use to track when we need to POST changes to the SmartHQ API
35
+ this.SensorUpdateInProgress = false;
36
+ // Retrieve initial values and updateHomekit
37
+ this.refreshStatus();
38
+ // Start an update interval
39
+ interval(this.deviceRefreshRate * 10000)
40
+ .pipe(skipWhile(() => this.SensorUpdateInProgress))
41
+ .subscribe(async () => {
42
+ await this.refreshStatus();
43
+ });
44
+ }
45
+ async readErd(erd) {
46
+ const d = await axios
47
+ .get(`/appliance/${this.accessory.context.device.applianceId}/erd/${erd}`);
48
+ return String(d.data.value);
49
+ }
50
+ async writeErd(erd, value) {
51
+ await axios
52
+ .post(`/appliance/${this.accessory.context.device.applianceId}/erd/${erd}`, {
53
+ kind: 'appliance#erdListEntry',
54
+ userId: this.accessory.context.userId,
55
+ applianceId: this.accessory.context.device.applianceId,
56
+ erd,
57
+ value: typeof value === 'boolean' ? (value ? '01' : '00') : value,
58
+ });
59
+ return undefined;
60
+ }
61
+ /**
62
+ * Parse the device status from the SmartHQ api
63
+ */
64
+ async parseStatus() {
65
+ try {
66
+ // On
67
+ // this.Refrigerator.On = this.deviceStatus.is_on
68
+ }
69
+ catch (e) {
70
+ await this.errorLog(`failed to parseStatus, Error Message: ${JSON.stringify(e.message ?? e)}`);
71
+ await this.apiError(e);
72
+ }
73
+ }
74
+ /**
75
+ * Asks the SmartHQ API for the latest device information
76
+ */
77
+ async refreshStatus() {
78
+ try {
79
+ // const status = await this.platform.client.getDeviceStatus(this.device.device_id)
80
+ // this.deviceStatus = status
81
+ await this.parseStatus();
82
+ await this.updateHomeKitCharacteristics();
83
+ }
84
+ catch (e) {
85
+ await this.errorLog(`failed to update status, Error Message: ${JSON.stringify(e.message ?? e)}`);
86
+ await this.apiError(e);
87
+ }
88
+ }
89
+ async setContactSensorState(ContactSensorState) {
90
+ try {
91
+ // await this.platform.client.setDeviceOn(this.device.device_id, On as boolean)
92
+ this.Refrigerator.ContactSensorState = ContactSensorState;
93
+ }
94
+ catch (e) {
95
+ await this.errorLog(`failed to setOn, Error Message: ${JSON.stringify(e.message ?? e)}`);
96
+ }
97
+ }
98
+ async getContactSensorState() {
99
+ try {
100
+ // const status = await this.platform.client.getDeviceStatus(this.device.device_id)
101
+ // this.Refrigerator.On = status.is_on
102
+ return this.Refrigerator.ContactSensorState;
103
+ }
104
+ catch (e) {
105
+ await this.errorLog(`failed to getOn, Error Message: ${JSON.stringify(e.message ?? e)}`);
106
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
107
+ }
108
+ }
109
+ /**
110
+ * Updates the status for each of the HomeKit Characteristics
111
+ */
112
+ async updateHomeKitCharacteristics() {
113
+ // AirQuality
114
+ await this.updateCharacteristic(this.Refrigerator.Service, this.hap.Characteristic.ContactSensorState, this.Refrigerator.ContactSensorState, 'ContactSensorState');
115
+ }
116
+ async apiError(e) {
117
+ this.Refrigerator.Service.updateCharacteristic(this.hap.Characteristic.On, e);
118
+ }
119
+ }
120
+ //# sourceMappingURL=refrigerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refrigerator.js","sourceRoot":"","sources":["../../src/devices/refrigerator.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IAatC;IAEA;IAdX,UAAU;IACF,YAAY,CAInB;IAED,UAAU;IACV,sBAAsB,CAAU;IAChC,YAAY,CAAK;IAEjB,YACW,QAAyB,EAClC,SAA4C,EACnC,MAAgD;QAEzD,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;QAJzB,aAAQ,GAAR,QAAQ,CAAiB;QAEzB,WAAM,GAAN,MAAM,CAA0C;QAIzD,IAAI,CAAC,QAAQ,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;QAC1F,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACpD;;gBAEI;YACJ,QAAQ,OAAO,EAAE,CAAC;gBAChB,KAAK,aAAa,CAAC,CAAC,CAAC;oBACnB,MAAM,YAAY,GACd,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC;2BAC/C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;oBAE1G,YAAY;yBACT,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC;yBAClE,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;yBACpF,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,KAAgB,CAAC,CAAC,CAAA;oBACzE,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,kFAAkF;QAClF,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAA;QAEnC,4CAA4C;QAC5C,IAAI,CAAC,aAAa,EAAE,CAAA;QAEpB,2BAA2B;QAC3B,QAAQ,CAAC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;aACrC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;aAClD,SAAS,CAAC,KAAK,IAAI,EAAE;YACpB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAA;QAC5B,CAAC,CAAC,CAAA;IACN,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,MAAM,CAAC,GAAG,MAAM,KAAK;aAClB,GAAG,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,QAAQ,GAAG,EAAE,CAAC,CAAA;QAC5E,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,KAAuB;QACjD,MAAM,KAAK;aACR,IAAI,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,QAAQ,GAAG,EAAE,EAAE;YAC1E,IAAI,EAAE,wBAAwB;YAC9B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM;YACrC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW;YACtD,GAAG;YACH,KAAK,EAAE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK;SAClE,CAAC,CAAA;QACJ,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,KAAK;YACL,iDAAiD;QACnD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,QAAQ,CAAC,yCAAyC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;YAC9F,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC;YACH,mFAAmF;YACnF,6BAA6B;YAC7B,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;YACxB,MAAM,IAAI,CAAC,4BAA4B,EAAE,CAAA;QAC3C,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,QAAQ,CAAC,2CAA2C,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;YAChG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,kBAAuC;QACjE,IAAI,CAAC;YACH,+EAA+E;YAC/E,IAAI,CAAC,YAAY,CAAC,kBAAkB,GAAG,kBAA6B,CAAA;QACtE,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,QAAQ,CAAC,mCAAmC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;IAED,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC;YACH,mFAAmF;YACnF,sCAAsC;YACtC,OAAO,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAA;QAC7C,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,QAAQ,CAAC,mCAAmC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;YACxF,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,4EAA+D,CAAA;QAC/G,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,4BAA4B;QAChC,aAAa;QACb,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,kBAAkB,EAAE,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAA;IACpK,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,CAAM;QAC1B,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IAC/E,CAAC;CACF"}
@@ -1,22 +1,21 @@
1
1
  <p class="text-center">
2
- <img src="https://raw.githubusercontent.com/homebridge-plugins/homebridge-smarthq/latest/branding/Homebridge_x_Air.svg"
3
- alt="@homebridge-plugins/homebridge-smarthq logo" style="width: 40%" />
2
+ <img
3
+ src="https://raw.githubusercontent.com/homebridge-plugins/homebridge-smarthq/latest/branding/Homebridge_x_SmartHQ.svg"
4
+ alt="homebridge-smarthq logo"
5
+ style="width: 40%" />
4
6
  </p>
5
7
  <div id="pageIntro" style="display: none">
6
- <p class="lead text-center">Thank you for installing <strong>@homebridge-plugins/homebridge-smarthq</strong></p>
7
- <p class="lead text-center">Before continuing:</p>
8
+ <p class="lead text-center">Thank you for installing <strong>homebridge-smarthq</strong></p>
9
+ <p class="lead text-center">Needed to Config:</p>
8
10
  <ol>
9
- <li class="mb-3">Login / create an account at <a href="https://docs.airnowapi.org/faq" target="_blank"
10
- rel="noreferrer noopener">https://docs.airnowapi.org/faq</a>.</li>
11
- <li class="mb-3">Click <strong>Web Services</strong>.</li>
12
- <li>Copy Your API Key in the top right.</li>
11
+ <li class="mb-3"><strong>Username</strong>.</li>
12
+ <li class="mb-3"><strong>Password</strong>.</li>
13
13
  </ol>
14
14
  <div class="text-center">
15
15
  <button type="button" class="btn btn-primary" id="introLink">Continue &rarr;</button>
16
16
  </div>
17
17
  </div>
18
18
  <div id="menuWrapper" class="btn-group w-100 mb-0" role="group" aria-label="UI Menu" style="display: none">
19
- <button type="button" class="btn btn-primary" id="menuLocation">Location</button>
20
19
  <button type="button" class="btn btn-primary" id="menuSettings">Settings</button>
21
20
  <button type="button" class="btn btn-primary" id="menuDevices">Devices</button>
22
21
  <button type="button" class="btn btn-primary mr-0" id="menuHome">Support</button>
@@ -25,19 +24,6 @@
25
24
  Plugin is currently disabled
26
25
  <button id="disabledEnable" type="button" class="btn btn-link p-0 m-0 float-right">Enable</button>
27
26
  </div>
28
- <div id="pageLocation" style="display: none;">
29
- <button type="button" class="btn btn-primary mb-3" id="getLocation">Use Current Location</button>
30
- <div class="mb-2">
31
- <label for="latitudeField">Latitude:</label>
32
- <input type="text" id="latitudeField" name="latitude">
33
- <button type="button" class="btn btn-outline-secondary btn-sm" id="copyLatitude">Copy</button>
34
- </div>
35
- <div>
36
- <label for="longitudeField">Longitude:</label>
37
- <input type="text" id="longitudeField" name="longitude">
38
- <button type="button" class="btn btn-outline-secondary btn-sm" id="copyLongitude">Copy</button>
39
- </div>
40
- </div>
41
27
  <div id="pageDevices" class="mt-4" style="display: none">
42
28
  <div id="deviceInfo">
43
29
  <form>
@@ -54,23 +40,20 @@
54
40
  </thead>
55
41
  <tbody>
56
42
  <tr>
57
- <th scope="row">Serial Number</th>
58
- <td id="serialNumber"></td>
59
- </tr>
60
- <tr>
61
- <th scope="row">Model</th>
62
- <td id="model"></td>
43
+ <th scope="row">Device ID</th>
44
+ <td id="ID"></td>
63
45
  </tr>
64
46
  <tr>
65
47
  <th scope="row">Firmware Version</th>
66
- <td id="firmwareRevision"></td>
48
+ <td id="FirmwareRevision"></td>
67
49
  </tr>
68
50
  </tbody>
69
51
  </table>
52
+ <p class="text-center">External Accessories Will Not Display Here.</p>
70
53
  </div>
71
54
  </div>
72
55
  <div id="pageSupport" class="mt-4" style="display: none">
73
- <p class="text-center lead">Thank you for using <strong>@homebridge-plugins/homebridge-smarthq</strong></p>
56
+ <p class="text-center lead">Thank you for using <strong>homebridge-smarthq</strong></p>
74
57
  <p class="text-center">The links below will take you to our GitHub wiki</p>
75
58
  <h5>Setup</h5>
76
59
  <ul>
@@ -93,11 +76,7 @@
93
76
  <h5>Features</h5>
94
77
  <ul>
95
78
  <li>
96
- <a href="https://github.com/homebridge-plugins/homebridge-smarthq/wiki/Supported-Devices" target="_blank">Supported
97
- Devices</a>
98
- </li>
99
- <li>
100
- <a href="https://github.com/homebridge-plugins/homebridge-smarthq/wiki/Fan-Modes" target="_blank">Fan Modes</a>
79
+ <a href="https://github.com/homebridge-plugins/homebridge-smarthq/wiki/Supported-Devices" target="_blank">Supported Devices</a>
101
80
  </li>
102
81
  </ul>
103
82
  <h5>Help/About</h5>
@@ -108,47 +87,32 @@
108
87
  <li>
109
88
  <a href="https://github.com/homebridge-plugins/homebridge-smarthq/blob/latest/CHANGELOG.md" target="_blank">Changelog</a>
110
89
  </li>
111
- <li>
112
- <a href="https://github.com/sponsors/donavanbecker" target="_blank">About Me</a>
113
- </li>
114
- </ul>
115
- <h5>Disclaimer</h5>
116
- <ul>
117
- <li>I am in no way affiliated with Airnow and this plugin is a personal project that I maintain in my free time.
118
- </li>
119
- <li>Use this plugin entirely at your own risk - please see licence for more information.</li>
120
90
  </ul>
121
91
  </div>
122
92
  <script>
123
93
  (async () => {
124
94
  try {
125
95
  const currentConfig = await homebridge.getPluginConfig();
126
-
127
- const showIntro = () => {
96
+ showIntro = () => {
128
97
  const introLink = document.getElementById('introLink');
129
98
  introLink.addEventListener('click', () => {
130
99
  homebridge.showSpinner();
131
100
  document.getElementById('pageIntro').style.display = 'none';
132
101
  document.getElementById('menuWrapper').style.display = 'inline-flex';
133
- showLocation();
102
+ showSettings();
134
103
  homebridge.hideSpinner();
135
104
  });
136
- document.getElementById('menuWrapper').style.display = 'none';
137
105
  document.getElementById('pageIntro').style.display = 'block';
138
106
  };
139
-
140
- const showDevices = async () => {
107
+ showDevices = async () => {
141
108
  homebridge.showSpinner();
142
109
  homebridge.hideSchemaForm();
143
110
  document.getElementById('menuHome').classList.remove('btn-elegant');
144
111
  document.getElementById('menuHome').classList.add('btn-primary');
145
112
  document.getElementById('menuDevices').classList.add('btn-elegant');
146
113
  document.getElementById('menuDevices').classList.remove('btn-primary');
147
- document.getElementById('menuLocation').classList.remove('btn-elegant');
148
- document.getElementById('menuLocation').classList.add('btn-primary');
149
114
  document.getElementById('menuSettings').classList.remove('btn-elegant');
150
115
  document.getElementById('menuSettings').classList.add('btn-primary');
151
- document.getElementById('pageLocation').style.display = 'none';
152
116
  document.getElementById('pageSupport').style.display = 'none';
153
117
  document.getElementById('pageDevices').style.display = 'block';
154
118
  const cachedAccessories =
@@ -168,14 +132,13 @@
168
132
  option.value = a.UUID;
169
133
  deviceSelect.add(option);
170
134
  });
171
- const showDeviceInfo = async (UUID) => {
135
+ showDeviceInfo = async (UUID) => {
172
136
  homebridge.showSpinner();
173
137
  const thisAcc = cachedAccessories.find((x) => x.UUID === UUID);
174
138
  const context = thisAcc.context;
175
139
  document.getElementById('displayName').innerHTML = thisAcc.displayName;
176
- document.getElementById('serialNumber').innerHTML = context.serialNumber;
177
- document.getElementById('model').innerHTML = context.model;
178
- document.getElementById('firmwareRevision').innerHTML = context.firmwareRevision || 'N/A';
140
+ document.getElementById('ID').innerHTML = context.device.id;
141
+ document.getElementById('FirmwareRevision').innerHTML = context.FirmwareRevision || 'N/A';
179
142
  document.getElementById('deviceTable').style.display = 'inline-table';
180
143
  homebridge.hideSpinner();
181
144
  };
@@ -190,120 +153,36 @@
190
153
  }
191
154
  homebridge.hideSpinner();
192
155
  };
193
-
194
- const showSupport = () => {
156
+ showSupport = () => {
195
157
  homebridge.showSpinner();
196
158
  homebridge.hideSchemaForm();
197
159
  document.getElementById('menuHome').classList.add('btn-elegant');
198
160
  document.getElementById('menuHome').classList.remove('btn-primary');
199
161
  document.getElementById('menuDevices').classList.remove('btn-elegant');
200
162
  document.getElementById('menuDevices').classList.add('btn-primary');
201
- document.getElementById('menuLocation').classList.remove('btn-elegant');
202
- document.getElementById('menuLocation').classList.add('btn-primary');
203
163
  document.getElementById('menuSettings').classList.remove('btn-elegant');
204
164
  document.getElementById('menuSettings').classList.add('btn-primary');
205
- document.getElementById('pageLocation').style.display = 'none';
206
165
  document.getElementById('pageSupport').style.display = 'block';
207
166
  document.getElementById('pageDevices').style.display = 'none';
208
167
  homebridge.hideSpinner();
209
168
  };
210
-
211
- const showLocation = () => {
212
- document.getElementById('getLocation').addEventListener('click', () => {
213
- if (navigator.geolocation) {
214
- navigator.geolocation.getCurrentPosition((position) => {
215
- const latitude = position.coords.latitude;
216
- const longitude = position.coords.longitude;
217
-
218
- // Assign the latitude and longitude to the input fields
219
- document.getElementById('latitudeField').value = latitude;
220
- document.getElementById('longitudeField').value = longitude;
221
-
222
- homebridge.toast.success('Location fetched successfully.', 'Success');
223
- }, (error) => {
224
- let errorMessage = 'Error getting location: ';
225
- switch (error.code) {
226
- case error.PERMISSION_DENIED:
227
- errorMessage += 'User denied the request for Geolocation.';
228
- break;
229
- case error.POSITION_UNAVAILABLE:
230
- errorMessage += 'Location information is unavailable.';
231
- break;
232
- case error.TIMEOUT:
233
- errorMessage += 'The request to get user location timed out.';
234
- break;
235
- case error.UNKNOWN_ERROR:
236
- errorMessage += 'An unknown error occurred.';
237
- break;
238
- }
239
- console.error(errorMessage, error);
240
- homebridge.toast.error(errorMessage, 'Error');
241
- });
242
- } else {
243
- homebridge.toast.error('Geolocation is not supported by this browser.', 'Error');
244
- }
245
- });
246
-
247
- document.getElementById('copyLatitude').addEventListener('click', () => {
248
- const latitude = document.getElementById('latitudeField').value;
249
- navigator.clipboard.writeText(latitude).then(() => {
250
- homebridge.toast.success('Latitude copied to clipboard.', 'Success');
251
- }).catch((error) => {
252
- console.error('Error copying latitude:', error);
253
- homebridge.toast.error('Error copying latitude: ' + error.message, 'Error');
254
- });
255
- });
256
-
257
- document.getElementById('copyLongitude').addEventListener('click', () => {
258
- const longitude = document.getElementById('longitudeField').value;
259
- navigator.clipboard.writeText(longitude).then(() => {
260
- homebridge.toast.success('Longitude copied to clipboard.', 'Success');
261
- }).catch((error) => {
262
- console.error('Error copying longitude:', error);
263
- homebridge.toast.error('Error copying longitude: ' + error.message, 'Error');
264
- });
265
- });
266
-
267
- homebridge.showSpinner();
268
- homebridge.hideSchemaForm();
269
- document.getElementById('menuHome').classList.remove('btn-elegant');
270
- document.getElementById('menuHome').classList.add('btn-primary');
271
- document.getElementById('menuDevices').classList.remove('btn-elegant');
272
- document.getElementById('menuDevices').classList.add('btn-primary');
273
- document.getElementById('menuLocation').classList.add('btn-elegant');
274
- document.getElementById('menuLocation').classList.remove('btn-primary');
275
- document.getElementById('menuSettings').classList.remove('btn-elegant');
276
- document.getElementById('menuSettings').classList.add('btn-primary');
277
- document.getElementById('pageLocation').style.display = 'block';
278
- document.getElementById('pageSupport').style.display = 'none';
279
- document.getElementById('pageDevices').style.display = 'none';
280
- homebridge.hideSpinner();
281
- };
282
-
283
- document.getElementById('menuLocation').addEventListener('click', showLocation);
284
-
285
- const showSettings = () => {
169
+ showSettings = () => {
286
170
  homebridge.showSpinner();
287
171
  document.getElementById('menuHome').classList.remove('btn-elegant');
288
172
  document.getElementById('menuHome').classList.add('btn-primary');
289
173
  document.getElementById('menuDevices').classList.remove('btn-elegant');
290
174
  document.getElementById('menuDevices').classList.add('btn-primary');
291
- document.getElementById('menuLocation').classList.remove('btn-elegant');
292
- document.getElementById('menuLocation').classList.add('btn-primary');
293
175
  document.getElementById('menuSettings').classList.add('btn-elegant');
294
176
  document.getElementById('menuSettings').classList.remove('btn-primary');
295
- document.getElementById('pageLocation').style.display = 'none';
296
177
  document.getElementById('pageSupport').style.display = 'none';
297
178
  document.getElementById('pageDevices').style.display = 'none';
298
179
  homebridge.showSchemaForm();
299
180
  homebridge.hideSpinner();
300
181
  };
301
-
302
- const showDisabledBanner = () => {
182
+ showDisabledBanner = () => {
303
183
  document.getElementById('disabledBanner').style.display = 'block';
304
184
  };
305
-
306
- const enablePlugin = async () => {
185
+ enablePlugin = async () => {
307
186
  homebridge.showSpinner();
308
187
  document.getElementById('disabledBanner').style.display = 'none';
309
188
  currentConfig[0].disablePlugin = false;
@@ -311,16 +190,13 @@
311
190
  await homebridge.savePluginConfig();
312
191
  homebridge.hideSpinner();
313
192
  };
314
-
315
- document.getElementById('menuHome').addEventListener('click', () => showSupport());
316
- document.getElementById('menuDevices').addEventListener('click', () => showDevices());
317
- document.getElementById('menuLocation').addEventListener('click', () => showLocation());
318
- document.getElementById('menuSettings').addEventListener('click', () => showSettings());
319
- document.getElementById('disabledEnable').addEventListener('click', () => enablePlugin());
320
-
193
+ menuHome.addEventListener('click', () => showSupport());
194
+ menuDevices.addEventListener('click', () => showDevices());
195
+ menuSettings.addEventListener('click', () => showSettings());
196
+ disabledEnable.addEventListener('click', () => enablePlugin());
321
197
  if (currentConfig.length) {
322
198
  document.getElementById('menuWrapper').style.display = 'inline-flex';
323
- showLocation(); // Set Location as the default tab
199
+ showSettings();
324
200
  if (currentConfig[0].disablePlugin) {
325
201
  showDisabledBanner();
326
202
  }
@@ -335,4 +211,4 @@
335
211
  homebridge.hideSpinner();
336
212
  }
337
213
  })();
338
- </script>
214
+ </script>
@@ -39,6 +39,7 @@ export declare class SmartHQPlatform implements DynamicPlatformPlugin {
39
39
  discoverDevices(): Promise<void>;
40
40
  private createSmartHQDishWasher;
41
41
  private createSmartHQOven;
42
+ private createSmartHQRefrigerator;
42
43
  unregisterPlatformAccessories(existingAccessory: PlatformAccessory): Promise<void>;
43
44
  getPlatformLogSettings(): Promise<void>;
44
45
  getPlatformRateSettings(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,qBAAqB,EAAE,GAAG,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG7F,OAAO,KAAK,EAA8B,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAkB/G;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,qBAAqB;IACpD,WAAW,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAAE,CAAA;IACvD,SAAgB,GAAG,EAAE,GAAG,CAAA;IACxB,SAAgB,GAAG,EAAE,OAAO,CAAA;IAC5B,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACpB,MAAM,EAAG,qBAAqB,CAAA;IAE9B,OAAO,EAAG,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAA;IACrC,cAAc,EAAG,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAA;IAC1D,OAAO,CAAC,QAAQ,CAAW;IAE3B,cAAc,EAAG,qBAAqB,CAAA;IACtC,eAAe,EAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IACpC,mBAAmB,EAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IAC5C,gBAAgB,EAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACtC,kBAAkB,EAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC1C,SAAS,EAAG,OAAO,CAAA;IACnB,OAAO,EAAG,MAAM,CAAA;gBAGd,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,GAAG;IAyDV;;;OAGG;IACG,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,CAAC,cAAc,CAAC;IAOrE;;OAEG;IACG,YAAY;IAcZ,sBAAsB;IAiB5B;;;OAGG;IACG,eAAe;YA0FP,uBAAuB;YAkDvB,iBAAiB;IAkDlB,6BAA6B,CAAC,iBAAiB,EAAE,iBAAiB;IAMzE,sBAAsB;IAUtB,uBAAuB;IAevB,yBAAyB;IAgB/B;;;;;;;;OAQG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;;;;;OAMG;IACG,2BAA2B,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCpG;;;OAGG;IACG,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrC,UAAU,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxC,eAAe,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrC,YAAY,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1C,QAAQ,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtC,aAAa,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,QAAQ,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAIlC,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC;CAGlD"}
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,qBAAqB,EAAE,GAAG,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG7F,OAAO,KAAK,EAA8B,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAmB/G;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,qBAAqB;IACpD,WAAW,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAAE,CAAA;IACvD,SAAgB,GAAG,EAAE,GAAG,CAAA;IACxB,SAAgB,GAAG,EAAE,OAAO,CAAA;IAC5B,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACpB,MAAM,EAAG,qBAAqB,CAAA;IAE9B,OAAO,EAAG,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAA;IACrC,cAAc,EAAG,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAA;IAC1D,OAAO,CAAC,QAAQ,CAAW;IAE3B,cAAc,EAAG,qBAAqB,CAAA;IACtC,eAAe,EAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IACpC,mBAAmB,EAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IAC5C,gBAAgB,EAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACtC,kBAAkB,EAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC1C,SAAS,EAAG,OAAO,CAAA;IACnB,OAAO,EAAG,MAAM,CAAA;gBAGd,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,GAAG;IAyDV;;;OAGG;IACG,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,CAAC,cAAc,CAAC;IAOrE;;OAEG;IACG,YAAY;IAcZ,sBAAsB;IAiB5B;;;OAGG;IACG,eAAe;YA8FP,uBAAuB;YAiDvB,iBAAiB;YAiDjB,yBAAyB;IAiD1B,6BAA6B,CAAC,iBAAiB,EAAE,iBAAiB;IAMzE,sBAAsB;IAUtB,uBAAuB;IAevB,yBAAyB;IAgB/B;;;;;;;;OAQG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;;;;;OAMG;IACG,2BAA2B,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCpG;;;OAGG;IACG,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrC,UAAU,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxC,eAAe,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrC,YAAY,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1C,QAAQ,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtC,aAAa,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,QAAQ,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAIlC,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC;CAGlD"}
package/dist/platform.js CHANGED
@@ -3,8 +3,9 @@ import { argv } from 'node:process';
3
3
  import axios from 'axios';
4
4
  import pkg from 'lodash';
5
5
  import ws from 'ws';
6
- import { SmartHQDishWasher } from './devices/dishwashers.js';
6
+ import { SmartHQDishWasher } from './devices/dishwasher.js';
7
7
  import { SmartHQOven } from './devices/oven.js';
8
+ import { SmartHQRefrigerator } from './devices/refrigerator.js';
8
9
  import getAccessToken, { refreshAccessToken } from './getAccessToken.js';
9
10
  import { API_URL, ERD_CODES, ERD_TYPES, KEEPALIVE_TIMEOUT, PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
10
11
  const { find } = pkg;
@@ -139,16 +140,16 @@ export class SmartHQPlatform {
139
140
  const connection = new ws(wssData.data.endpoint);
140
141
  connection.on('message', (data) => {
141
142
  const obj = JSON.parse(data.toString());
142
- this.log.debug(obj);
143
+ this.debugLog(obj);
143
144
  if (obj.kind === 'publish#erd') {
144
145
  const accessory = find(this.accessories, a => a.context.device.applianceId === obj.item.applianceId);
145
146
  if (!accessory) {
146
- this.log.info('Device not found in my list. Maybe we should rerun this plugin?');
147
+ this.infoLog('Device not found in my list. Maybe we should rerun this plugin?');
147
148
  return;
148
149
  }
149
150
  if (ERD_CODES[obj.item.erd]) {
150
- this.log.debug(ERD_CODES[obj.item.erd]);
151
- this.log.debug(obj.item.value);
151
+ this.debugLog(ERD_CODES[obj.item.erd]);
152
+ this.debugLog(obj.item.value);
152
153
  if (obj.item.erd === ERD_TYPES.UPPER_OVEN_LIGHT) {
153
154
  const service = accessory.getService('Upper Oven Light');
154
155
  if (service) {
@@ -159,8 +160,8 @@ export class SmartHQPlatform {
159
160
  }
160
161
  });
161
162
  connection.on('close', (_, reason) => {
162
- this.log.debug('Connection closed');
163
- this.log.debug(reason.toString());
163
+ this.debugLog('Connection closed');
164
+ this.debugLog(reason.toString());
164
165
  });
165
166
  connection.on('open', () => {
166
167
  connection.send(JSON.stringify({
@@ -181,13 +182,17 @@ export class SmartHQPlatform {
181
182
  axios.get(`/appliance/${device.applianceId}`),
182
183
  axios.get(`/appliance/${device.applianceId}/feature`),
183
184
  ]);
185
+ this.debugLog(`Device: ${JSON.stringify(device)}`);
184
186
  switch (device.type) {
185
187
  case 'Dishwasher':
186
188
  await this.createSmartHQDishWasher(userId, device, details, features);
187
189
  break;
188
- case 'oven':
190
+ case 'Oven':
189
191
  await this.createSmartHQOven(userId, device, details, features);
190
192
  break;
193
+ case 'Refrigerator':
194
+ await this.createSmartHQRefrigerator(userId, device, details, features);
195
+ break;
191
196
  default:
192
197
  await this.warnLog(`Device Type Not Supported: ${device.type}`);
193
198
  break;
@@ -213,18 +218,18 @@ export class SmartHQPlatform {
213
218
  // existingAccessory.context.FirmwareRevision = device.firmware ?? await this.getVersion();
214
219
  this.api.updatePlatformAccessories([existingAccessory]);
215
220
  // Restore accessory
216
- await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName}`);
221
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName}`);
217
222
  // create the accessory handler for the restored accessory
218
223
  // this is imported from `platformAccessory.ts`
219
224
  new SmartHQDishWasher(this, existingAccessory, device);
220
- await this.debugLog(`${device.nickname} uuid: ${device.device_id}`);
225
+ this.debugLog(`${device.nickname} uuid: ${device.jid}`);
221
226
  }
222
227
  else {
223
228
  this.unregisterPlatformAccessories(existingAccessory);
224
229
  }
225
230
  }
226
231
  else if (!device.hide_device && !existingAccessory) {
227
- this.log.info('Adding new accessory:', device.nickname);
232
+ this.infoLog(`Adding new accessory: ${device.nickname}`);
228
233
  const accessory = new this.api.platformAccessory(device.nickname, uuid);
229
234
  // store a copy of the device object in the `accessory.context`
230
235
  // the `context` property can be used to store any data about the accessory you may need
@@ -233,11 +238,10 @@ export class SmartHQPlatform {
233
238
  accessory.displayName = await this.validateAndCleanDisplayName(device.nickname, 'nickname', device.nickname);
234
239
  // accessory.context.FirmwareRevision = device.firmware ?? await this.getVersion();
235
240
  // the accessory does not yet exist, so we need to create it
236
- await this.infoLog(`Adding new accessory: ${device.nickname}`);
237
241
  // create the accessory handler for the newly create accessory
238
242
  // this is imported from `platformAccessory.ts`
239
243
  new SmartHQDishWasher(this, accessory, device);
240
- await this.debugLog(`${device.nickname} uuid: ${device.device_id}`);
244
+ this.debugLog(`${device.nickname} uuid: ${device.jid}`);
241
245
  // link the accessory to your platform
242
246
  this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
243
247
  this.accessories.push(accessory);
@@ -261,7 +265,7 @@ export class SmartHQPlatform {
261
265
  // existingAccessory.context.FirmwareRevision = device.firmware ?? await this.getVersion();
262
266
  this.api.updatePlatformAccessories([existingAccessory]);
263
267
  // Restore accessory
264
- await this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName}`);
268
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName}`);
265
269
  // create the accessory handler for the restored accessory
266
270
  // this is imported from `platformAccessory.ts`
267
271
  new SmartHQOven(this, existingAccessory, device);
@@ -272,7 +276,7 @@ export class SmartHQPlatform {
272
276
  }
273
277
  }
274
278
  else if (!device.hide_device && !existingAccessory) {
275
- this.log.info('Adding new accessory:', device.nickname);
279
+ this.infoLog(`Adding new accessory: ${device.nickname}`);
276
280
  const accessory = new this.api.platformAccessory(device.nickname, uuid);
277
281
  // store a copy of the device object in the `accessory.context`
278
282
  // the `context` property can be used to store any data about the accessory you may need
@@ -281,11 +285,57 @@ export class SmartHQPlatform {
281
285
  accessory.displayName = await this.validateAndCleanDisplayName(device.nickname, 'nickname', device.nickname);
282
286
  // accessory.context.FirmwareRevision = device.firmware ?? await this.getVersion();
283
287
  // the accessory does not yet exist, so we need to create it
284
- await this.infoLog(`Adding new accessory: ${device.nickname}`);
285
288
  // create the accessory handler for the newly create accessory
286
289
  // this is imported from `platformAccessory.ts`
287
290
  new SmartHQOven(this, accessory, device);
288
- await this.debugLog(`${device.nickname} uuid: ${device.device_id}`);
291
+ this.debugLog(`${device.nickname} uuid: ${device.device_id}`);
292
+ // link the accessory to your platform
293
+ this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
294
+ this.accessories.push(accessory);
295
+ }
296
+ else {
297
+ this.debugErrorLog(`Unable to Register new device: ${JSON.stringify(device.nickname)}`);
298
+ }
299
+ }
300
+ async createSmartHQRefrigerator(userId, device, details, features) {
301
+ const uuid = this.api.hap.uuid.generate(device.jid);
302
+ // see if an accessory with the same uuid has already been registered and restored from
303
+ // the cached devices we stored in the `configureAccessory` method above
304
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
305
+ if (existingAccessory) {
306
+ // the accessory already exists
307
+ if (!device.hide_device) {
308
+ // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
309
+ existingAccessory.context.device = device;
310
+ existingAccessory.context = { device: { ...details, ...features }, userId };
311
+ existingAccessory.displayName = await this.validateAndCleanDisplayName(device.nickname, 'nickname', device.nickname);
312
+ // existingAccessory.context.FirmwareRevision = device.firmware ?? await this.getVersion();
313
+ this.api.updatePlatformAccessories([existingAccessory]);
314
+ // Restore accessory
315
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName}`);
316
+ // create the accessory handler for the restored accessory
317
+ // this is imported from `platformAccessory.ts`
318
+ new SmartHQRefrigerator(this, existingAccessory, device);
319
+ await this.debugLog(`${device.nickname} uuid: ${device.device_id}`);
320
+ }
321
+ else {
322
+ this.unregisterPlatformAccessories(existingAccessory);
323
+ }
324
+ }
325
+ else if (!device.hide_device && !existingAccessory) {
326
+ this.infoLog(`Adding new accessory: ${device.nickname}`);
327
+ const accessory = new this.api.platformAccessory(device.nickname, uuid);
328
+ // store a copy of the device object in the `accessory.context`
329
+ // the `context` property can be used to store any data about the accessory you may need
330
+ accessory.context.device = device;
331
+ accessory.context = { device: { ...details, ...features }, userId };
332
+ accessory.displayName = await this.validateAndCleanDisplayName(device.nickname, 'nickname', device.nickname);
333
+ // accessory.context.FirmwareRevision = device.firmware ?? await this.getVersion();
334
+ // the accessory does not yet exist, so we need to create it
335
+ // create the accessory handler for the newly create accessory
336
+ // this is imported from `platformAccessory.ts`
337
+ new SmartHQRefrigerator(this, accessory, device);
338
+ this.debugLog(`${device.nickname} uuid: ${device.device_id}`);
289
339
  // link the accessory to your platform
290
340
  this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
291
341
  this.accessories.push(accessory);