@homebridge-plugins/homebridge-resideo 2.1.7-beta.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 (87) hide show
  1. package/.github/FUNDING.yml +4 -0
  2. package/.github/ISSUE_TEMPLATE/bug-report.yml +97 -0
  3. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  4. package/.github/ISSUE_TEMPLATE/feature-request.yml +38 -0
  5. package/.github/ISSUE_TEMPLATE/support-request.yml +85 -0
  6. package/.github/ISSUE_TEMPLATE.md +52 -0
  7. package/.github/PULL_REQUEST_TEMPLATE/pull_request.md +27 -0
  8. package/.github/auto-merge.yml +3 -0
  9. package/.github/dependabot.yml +17 -0
  10. package/.github/labeler.yml +38 -0
  11. package/.github/npm-version-script-esm.js +85 -0
  12. package/.github/release-drafter.yml +33 -0
  13. package/.github/workflows/beta-release.yml +55 -0
  14. package/.github/workflows/build.yml +18 -0
  15. package/.github/workflows/changerelease.yml +11 -0
  16. package/.github/workflows/labeler.yml +9 -0
  17. package/.github/workflows/release-drafter.yml +14 -0
  18. package/.github/workflows/release.yml +35 -0
  19. package/.github/workflows/stale.yml +12 -0
  20. package/CHANGELOG.md +161 -0
  21. package/LICENSE +14 -0
  22. package/README.md +67 -0
  23. package/SECURITY.md +19 -0
  24. package/branding/Homebridge_x_Resideo.svg +28 -0
  25. package/branding/honeywell/Homebridge_x_Honeywell.svg +1 -0
  26. package/branding/honeywell/homebridge-honeywell-home-changelog.md +851 -0
  27. package/branding/icon.png +0 -0
  28. package/config.schema.json +611 -0
  29. package/dist/devices/device.d.ts +41 -0
  30. package/dist/devices/device.d.ts.map +1 -0
  31. package/dist/devices/device.js +279 -0
  32. package/dist/devices/device.js.map +1 -0
  33. package/dist/devices/leaksensors.d.ts +34 -0
  34. package/dist/devices/leaksensors.d.ts.map +1 -0
  35. package/dist/devices/leaksensors.js +300 -0
  36. package/dist/devices/leaksensors.js.map +1 -0
  37. package/dist/devices/roomsensors.d.ts +38 -0
  38. package/dist/devices/roomsensors.d.ts.map +1 -0
  39. package/dist/devices/roomsensors.js +274 -0
  40. package/dist/devices/roomsensors.js.map +1 -0
  41. package/dist/devices/roomsensorthermostats.d.ts +57 -0
  42. package/dist/devices/roomsensorthermostats.d.ts.map +1 -0
  43. package/dist/devices/roomsensorthermostats.js +700 -0
  44. package/dist/devices/roomsensorthermostats.js.map +1 -0
  45. package/dist/devices/thermostats.d.ts +73 -0
  46. package/dist/devices/thermostats.d.ts.map +1 -0
  47. package/dist/devices/thermostats.js +930 -0
  48. package/dist/devices/thermostats.js.map +1 -0
  49. package/dist/devices/valve.d.ts +21 -0
  50. package/dist/devices/valve.d.ts.map +1 -0
  51. package/dist/devices/valve.js +151 -0
  52. package/dist/devices/valve.js.map +1 -0
  53. package/dist/homebridge-ui/public/index.html +423 -0
  54. package/dist/homebridge-ui/server.d.ts +2 -0
  55. package/dist/homebridge-ui/server.d.ts.map +1 -0
  56. package/dist/homebridge-ui/server.js +131 -0
  57. package/dist/homebridge-ui/server.js.map +1 -0
  58. package/dist/index.d.ts +4 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +7 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/platform.d.ts +94 -0
  63. package/dist/platform.d.ts.map +1 -0
  64. package/dist/platform.js +890 -0
  65. package/dist/platform.js.map +1 -0
  66. package/dist/settings.d.ts +409 -0
  67. package/dist/settings.d.ts.map +1 -0
  68. package/dist/settings.js +25 -0
  69. package/dist/settings.js.map +1 -0
  70. package/dist/utils.d.ts +21 -0
  71. package/dist/utils.d.ts.map +1 -0
  72. package/dist/utils.js +58 -0
  73. package/dist/utils.js.map +1 -0
  74. package/docs/.nojekyll +1 -0
  75. package/docs/assets/highlight.css +22 -0
  76. package/docs/assets/icons.js +18 -0
  77. package/docs/assets/icons.svg +1 -0
  78. package/docs/assets/main.js +60 -0
  79. package/docs/assets/navigation.js +1 -0
  80. package/docs/assets/search.js +1 -0
  81. package/docs/assets/style.css +1493 -0
  82. package/docs/functions/default.html +1 -0
  83. package/docs/index.html +73 -0
  84. package/docs/modules.html +2 -0
  85. package/eslint.config.js +50 -0
  86. package/package.json +102 -0
  87. package/typedoc.json +22 -0
@@ -0,0 +1,700 @@
1
+ // import { request } from 'undici';
2
+ import { interval, Subject } from 'rxjs';
3
+ import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
4
+ import { DeviceURL } from '../settings.js';
5
+ import { HomeKitModes, ResideoModes, toCelsius, toFahrenheit } from '../utils.js';
6
+ import { deviceBase } from './device.js';
7
+ /**
8
+ * Platform Accessory
9
+ * An instance of this class is created for each accessory your platform registers
10
+ * Each accessory may expose multiple services of different service types.
11
+ */
12
+ export class RoomSensorThermostat extends deviceBase {
13
+ platform;
14
+ group;
15
+ // Services
16
+ Thermostat;
17
+ HumiditySensor;
18
+ // Others - T9 Only
19
+ roomPriorityStatus;
20
+ // Thermostat Update
21
+ thermostatUpdateInProgress;
22
+ doThermostatUpdate;
23
+ // Room Updates
24
+ roomUpdateInProgress;
25
+ doRoomUpdate;
26
+ // Fan Updates
27
+ fanUpdateInProgress;
28
+ doFanUpdate;
29
+ constructor(platform, accessory, location, device, sensorAccessory, group) {
30
+ super(platform, accessory, location, device, sensorAccessory, group);
31
+ this.platform = platform;
32
+ this.group = group;
33
+ // this is subject we use to track when we need to POST Room Priority changes to the Resideo API for Room Changes - T9 Only
34
+ this.doRoomUpdate = new Subject();
35
+ this.roomUpdateInProgress = false;
36
+ // this is subject we use to track when we need to POST Thermostat changes to the Resideo API
37
+ this.doThermostatUpdate = new Subject();
38
+ this.thermostatUpdateInProgress = false;
39
+ // Initialize Thermostat Service
40
+ accessory.context.Thermostat = accessory.context.Thermostat ?? {};
41
+ this.Thermostat = {
42
+ Name: accessory.context.Thermostat.Name ?? `${accessory.displayName} Thermostat`,
43
+ Service: accessory.getService(this.hap.Service.Thermostat) ?? this.accessory.addService(this.hap.Service.Thermostat),
44
+ TargetTemperature: accessory.context.TargetTemperature ?? 20,
45
+ CurrentTemperature: accessory.context.CurrentTemperature ?? 20,
46
+ TemperatureDisplayUnits: accessory.context.TemperatureDisplayUnits,
47
+ TargetHeatingCoolingState: accessory.context.TargetHeatingCoolingState ?? this.hap.Characteristic.TargetHeatingCoolingState.AUTO,
48
+ CurrentHeatingCoolingState: accessory.context.CurrentHeatingCoolingState ?? this.hap.Characteristic.CurrentHeatingCoolingState.OFF,
49
+ CoolingThresholdTemperature: accessory.context.CoolingThresholdTemperature ?? 20,
50
+ HeatingThresholdTemperature: accessory.context.HeatingThresholdTemperature ?? 22,
51
+ };
52
+ accessory.context.Thermostat = this.Thermostat;
53
+ // Service Name
54
+ this.Thermostat.Service
55
+ .setCharacteristic(this.hap.Characteristic.Name, this.Thermostat.Name)
56
+ .setCharacteristic(this.hap.Characteristic.CurrentHeatingCoolingState, this.Thermostat.CurrentHeatingCoolingState)
57
+ .getCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits)
58
+ .onGet(() => {
59
+ this.Thermostat.TemperatureDisplayUnits = device.units === 'Celsius'
60
+ ? this.hap.Characteristic.TemperatureDisplayUnits.CELSIUS
61
+ : this.hap.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
62
+ accessory.context.TemperatureDisplayUnits = this.Thermostat.TemperatureDisplayUnits;
63
+ this.debugLog(`${this.device.deviceClass} ${accessory.displayName} TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
64
+ return this.Thermostat.TemperatureDisplayUnits;
65
+ })
66
+ .onSet(this.setTemperatureDisplayUnits.bind(this));
67
+ // Set Min and Max
68
+ if (device.minHeatSetpoint && device.maxHeatSetpoint) {
69
+ this.debugLog(`${this.device.deviceClass} ${accessory.displayName} minHeatSetpoint: ${device.minHeatSetpoint}, maxHeatSetpoint: ${device.maxHeatSetpoint}, TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
70
+ const minValue = toCelsius(device.minHeatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
71
+ const maxValue = toCelsius(device.maxHeatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
72
+ this.debugLog(`${sensorAccessory.accessoryAttribute.type} ${this.device.deviceClass} ${accessory.displayName} minValue: ${minValue}, maxValue: ${maxValue}`);
73
+ if (device.changeableValues.heatCoolMode === 'Heat') {
74
+ this.debugLog(`${sensorAccessory.accessoryAttribute.type} ${this.device.deviceClass} ${accessory.displayName} mode: ${device.changeableValues.heatCoolMode}`);
75
+ this.Thermostat.Service
76
+ .getCharacteristic(this.hap.Characteristic.TargetTemperature)
77
+ .setProps({
78
+ minValue,
79
+ maxValue,
80
+ minStep: 0.5,
81
+ })
82
+ .onGet(() => {
83
+ return this.Thermostat.TargetTemperature;
84
+ });
85
+ }
86
+ else {
87
+ this.debugLog(`${sensorAccessory.accessoryAttribute.type} ${this.device.deviceClass} ${accessory.displayName} mode: ${device.changeableValues.heatCoolMode}`);
88
+ this.Thermostat.Service
89
+ .getCharacteristic(this.hap.Characteristic.TargetTemperature)
90
+ .setProps({
91
+ minValue,
92
+ maxValue,
93
+ minStep: 0.5,
94
+ })
95
+ .onGet(() => {
96
+ return this.Thermostat.TargetTemperature;
97
+ });
98
+ }
99
+ }
100
+ // The value property of TargetHeaterCoolerState must be one of the following:
101
+ // AUTO = 3; HEAT = 1; COOL = 2; OFF = 0;
102
+ // Set control bindings
103
+ const TargetState = [4];
104
+ TargetState.pop();
105
+ if (this.device.allowedModes?.includes('Cool')) {
106
+ TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.COOL);
107
+ }
108
+ if (this.device.allowedModes?.includes('Heat')) {
109
+ TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.HEAT);
110
+ }
111
+ if (this.device.allowedModes?.includes('Off')) {
112
+ TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.OFF);
113
+ }
114
+ if (this.device.allowedModes?.includes('Auto') || this.device.thermostat?.show_auto) {
115
+ TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.AUTO);
116
+ }
117
+ this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} allowedModes: ${this.device.allowedModes}`);
118
+ this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Only Show These Modes: ${JSON.stringify(TargetState)}`);
119
+ this.Thermostat.Service
120
+ .getCharacteristic(this.hap.Characteristic.TargetHeatingCoolingState)
121
+ .setProps({
122
+ validValues: TargetState,
123
+ })
124
+ .onGet(() => {
125
+ return this.Thermostat.TargetHeatingCoolingState;
126
+ })
127
+ .onSet(this.setTargetHeatingCoolingState.bind(this));
128
+ this.Thermostat.Service
129
+ .getCharacteristic(this.hap.Characteristic.HeatingThresholdTemperature)
130
+ .onGet(() => {
131
+ return this.Thermostat.HeatingThresholdTemperature;
132
+ })
133
+ .onSet(this.setHeatingThresholdTemperature.bind(this));
134
+ this.Thermostat.Service
135
+ .getCharacteristic(this.hap.Characteristic.CoolingThresholdTemperature)
136
+ .onGet(() => {
137
+ return this.Thermostat.CoolingThresholdTemperature;
138
+ })
139
+ .onSet(this.setCoolingThresholdTemperature.bind(this));
140
+ this.Thermostat.Service
141
+ .getCharacteristic(this.hap.Characteristic.TargetTemperature)
142
+ .onGet(() => {
143
+ return this.Thermostat.TargetTemperature;
144
+ })
145
+ .onSet(this.setTargetTemperature.bind(this));
146
+ // Initialize Humidity Sensor Service
147
+ if (device.thermostat?.hide_humidity) {
148
+ if (this.HumiditySensor) {
149
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
150
+ this.HumiditySensor.Service = this.accessory.getService(this.hap.Service.HumiditySensor);
151
+ accessory.removeService(this.HumiditySensor.Service);
152
+ }
153
+ else {
154
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Humidity Sensor Service Not Found`);
155
+ }
156
+ }
157
+ else if (device.indoorHumidity) {
158
+ this.debugLog(`Thermostat: ${accessory.displayName} Add Humidity Sensor Service`);
159
+ accessory.context.HumiditySensor = accessory.context.HumiditySensor ?? {};
160
+ this.HumiditySensor = {
161
+ Name: accessory.context.HumiditySensor.Name ?? `${accessory.displayName} Humidity Sensor`,
162
+ Service: accessory.getService(this.hap.Service.HumiditySensor) ?? accessory.addService(this.hap.Service.HumiditySensor),
163
+ CurrentRelativeHumidity: accessory.context.CurrentRelativeHumidity ?? 50,
164
+ };
165
+ accessory.context.HumiditySensor = this.HumiditySensor;
166
+ // Initialize Humidity Sensor Characteristic
167
+ this.HumiditySensor.Service
168
+ .setCharacteristic(this.hap.Characteristic.Name, this.HumiditySensor.Name);
169
+ this.HumiditySensor.Service
170
+ .getCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity)
171
+ .setProps({
172
+ minStep: 0.1,
173
+ })
174
+ .onGet(() => {
175
+ return this.HumiditySensor.CurrentRelativeHumidity;
176
+ });
177
+ }
178
+ else {
179
+ this.debugLog(`Thermostat: ${accessory.displayName} Humidity Sensor Service Not Added`);
180
+ }
181
+ // Initial Refresh
182
+ this.refreshStatus();
183
+ // Retrieve initial values and updateHomekit
184
+ this.updateHomeKitCharacteristics();
185
+ // Start an update interval
186
+ interval(this.config.options.refreshRate * 1000)
187
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
188
+ .subscribe(async () => {
189
+ await this.refreshStatus();
190
+ await this.refreshSensorStatus();
191
+ });
192
+ // Watch for thermostat change events
193
+ // We put in a debounce of 100ms so we don't make duplicate calls
194
+ if (device.thermostat?.roompriority?.deviceType === 'Thermostat') {
195
+ this.doRoomUpdate
196
+ .pipe(tap(() => {
197
+ this.roomUpdateInProgress = true;
198
+ }), debounceTime(this.devicePushRate * 500))
199
+ .subscribe(async () => {
200
+ try {
201
+ await this.refreshRoomPriority();
202
+ }
203
+ catch (e) {
204
+ const action = 'refreshRoomPriority';
205
+ if (this.device.retry) {
206
+ // Refresh the status from the API
207
+ interval(5000)
208
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
209
+ .pipe(take(1))
210
+ .subscribe(async () => {
211
+ await this.refreshRoomPriority();
212
+ });
213
+ }
214
+ this.resideoAPIError(e, action);
215
+ this.apiError(e);
216
+ }
217
+ try {
218
+ await this.pushRoomChanges();
219
+ }
220
+ catch (e) {
221
+ const action = 'pushRoomChanges';
222
+ if (this.device.retry) {
223
+ // Refresh the status from the API
224
+ interval(5000)
225
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
226
+ .pipe(take(1))
227
+ .subscribe(async () => {
228
+ await this.pushRoomChanges();
229
+ });
230
+ }
231
+ this.resideoAPIError(e, action);
232
+ this.apiError(e);
233
+ }
234
+ this.roomUpdateInProgress = false;
235
+ // Refresh the status from the API
236
+ interval(5000)
237
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
238
+ .pipe(take(1))
239
+ .subscribe(async () => {
240
+ await this.refreshStatus();
241
+ });
242
+ });
243
+ }
244
+ this.doThermostatUpdate
245
+ .pipe(tap(() => {
246
+ this.thermostatUpdateInProgress = true;
247
+ }), debounceTime(this.devicePushRate * 1000))
248
+ .subscribe(async () => {
249
+ try {
250
+ await this.pushChanges();
251
+ }
252
+ catch (e) {
253
+ const action = 'pushChanges';
254
+ if (this.device.retry) {
255
+ // Refresh the status from the API
256
+ interval(5000)
257
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
258
+ .pipe(take(1))
259
+ .subscribe(async () => {
260
+ await this.pushChanges();
261
+ });
262
+ }
263
+ this.resideoAPIError(e, action);
264
+ this.apiError(e);
265
+ }
266
+ this.thermostatUpdateInProgress = false;
267
+ // Refresh the status from the API
268
+ interval(5000)
269
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
270
+ .pipe(take(1))
271
+ .subscribe(async () => {
272
+ await this.refreshStatus();
273
+ });
274
+ });
275
+ }
276
+ /**
277
+ * Parse the device status from the Resideo api
278
+ */
279
+ async parseStatus() {
280
+ // Parse the device status
281
+ if (this.device.units === 'Fahrenheit') {
282
+ this.Thermostat.TemperatureDisplayUnits = this.hap.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
283
+ }
284
+ if (this.device.units === 'Celsius') {
285
+ this.Thermostat.TemperatureDisplayUnits = this.hap.Characteristic.TemperatureDisplayUnits.CELSIUS;
286
+ }
287
+ // Parse the Sensor Accessory status
288
+ if (this.sensorAccessory) {
289
+ const accessoryValue = this.sensorAccessory.accessoryValue
290
+ ?? { indoorTemperature: 20, indoorHumidity: 50 };
291
+ this.Thermostat.CurrentTemperature = toCelsius(accessoryValue.indoorTemperature, Number(this.Thermostat.TemperatureDisplayUnits));
292
+ this.debugLog(`${this.sensorAccessory.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} CurrentTemperature: ${this.Thermostat.CurrentTemperature}`);
293
+ if (!this.device.thermostat?.hide_humidity && accessoryValue.indoorHumidity) {
294
+ if (this.HumiditySensor) {
295
+ this.HumiditySensor.CurrentRelativeHumidity = accessoryValue.indoorHumidity;
296
+ this.debugLog(`${this.sensorAccessory.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
297
+ }
298
+ }
299
+ }
300
+ // Parse the Thermostat status
301
+ if (this.device.changeableValues.heatSetpoint > 0) {
302
+ this.Thermostat.HeatingThresholdTemperature = toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
303
+ }
304
+ if (this.device.changeableValues.coolSetpoint > 0) {
305
+ this.Thermostat.CoolingThresholdTemperature = toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
306
+ }
307
+ this.Thermostat.TargetHeatingCoolingState = HomeKitModes[this.device.changeableValues.mode];
308
+ /**
309
+ * The CurrentHeatingCoolingState is either 'Heat', 'Cool', or 'Off'
310
+ * CurrentHeatingCoolingState = OFF = 0, HEAT = 1, COOL = 2
311
+ */
312
+ switch (this.device.operationStatus.mode) {
313
+ case 'Heat':
314
+ this.Thermostat.CurrentHeatingCoolingState = this.hap.Characteristic.CurrentHeatingCoolingState.HEAT; // 1
315
+ break;
316
+ case 'Cool':
317
+ this.Thermostat.CurrentHeatingCoolingState = this.hap.Characteristic.CurrentHeatingCoolingState.COOL; // 2
318
+ break;
319
+ default:
320
+ this.Thermostat.CurrentHeatingCoolingState = this.hap.Characteristic.CurrentHeatingCoolingState.OFF; // 0
321
+ }
322
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} CurrentHeatingCoolingState: ${this.Thermostat.CurrentHeatingCoolingState}`);
323
+ // Set the TargetTemperature value based on the current mode
324
+ if (this.Thermostat.TargetHeatingCoolingState === this.hap.Characteristic.TargetHeatingCoolingState.HEAT) {
325
+ if (this.device.changeableValues.heatSetpoint > 0) {
326
+ this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
327
+ }
328
+ }
329
+ else {
330
+ if (this.device.changeableValues.coolSetpoint > 0) {
331
+ this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
332
+ }
333
+ }
334
+ }
335
+ /**
336
+ * Asks the Resideo Home API for the latest device information
337
+ */
338
+ async refreshStatus() {
339
+ try {
340
+ const device = (await this.platform.axios.get(`${DeviceURL}/thermostats/${this.device.deviceID}`, {
341
+ params: {
342
+ locationId: this.location.locationID,
343
+ },
344
+ })).data;
345
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${device.deviceClass} ${this.accessory.displayName} (refreshStatus) device: ${JSON.stringify(device)}`);
346
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${device.deviceClass} ${this.accessory.displayName} Fetched update for: ${this.device.name} from Resideo API: ${JSON.stringify(this.device.changeableValues)}`);
347
+ this.device = device;
348
+ this.parseStatus();
349
+ this.updateHomeKitCharacteristics();
350
+ }
351
+ catch (e) {
352
+ const action = 'refreshStatus';
353
+ if (this.device.retry) {
354
+ // Refresh the status from the API
355
+ interval(5000)
356
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
357
+ .pipe(take(1))
358
+ .subscribe(async () => {
359
+ await this.refreshStatus();
360
+ });
361
+ }
362
+ this.resideoAPIError(e, action);
363
+ this.apiError(e);
364
+ }
365
+ }
366
+ /**
367
+ * Asks the Resideo Home API for the latest device information
368
+ */
369
+ async refreshSensorStatus() {
370
+ try {
371
+ if (this.device.thermostat?.roompriority?.deviceType === 'Thermostat') {
372
+ if (typeof this.device.deviceID === 'string' && this.device.deviceID.startsWith('LCC')) {
373
+ if (this.device.deviceModel.startsWith('T9')) {
374
+ if (this.device.groups) {
375
+ const groups = this.device.groups;
376
+ for (const group of groups) {
377
+ const roomsensors = await this.platform.getCurrentSensorData(this.location, this.device, group);
378
+ if (roomsensors.rooms) {
379
+ const rooms = roomsensors.rooms;
380
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} roomsensors: ${JSON.stringify(roomsensors)}`);
381
+ for (const accessories of rooms) {
382
+ if (accessories) {
383
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} accessories: ${JSON.stringify(accessories)}`);
384
+ for (const sensorAccessory of accessories.accessories) {
385
+ if (sensorAccessory.accessoryAttribute) {
386
+ if (sensorAccessory.accessoryAttribute.type) {
387
+ if (sensorAccessory.accessoryAttribute.type.startsWith('IndoorAirSensor')) {
388
+ this.sensorAccessory = sensorAccessory;
389
+ this.parseStatus();
390
+ this.debugLog(`${sensorAccessory.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} accessoryAttribute: ${JSON.stringify(this.sensorAccessory?.accessoryAttribute)}`);
391
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} Name: ${this.sensorAccessory?.accessoryAttribute.name}, Software Version: ${this.sensorAccessory?.accessoryAttribute.softwareRevision}`);
392
+ }
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ }
399
+ }
400
+ }
401
+ }
402
+ }
403
+ }
404
+ this.updateHomeKitCharacteristics();
405
+ }
406
+ catch (e) {
407
+ const action = 'refreshSensorStatus';
408
+ if (this.device.retry) {
409
+ // Refresh the status from the API
410
+ interval(5000)
411
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
412
+ .pipe(take(1))
413
+ .subscribe(async () => {
414
+ await this.refreshSensorStatus();
415
+ });
416
+ }
417
+ this.resideoAPIError(e, action);
418
+ this.apiError(e);
419
+ }
420
+ }
421
+ async refreshRoomPriority() {
422
+ if (this.device.thermostat?.roompriority?.deviceType === 'Thermostat') {
423
+ try {
424
+ const roomPriorityStatus = (await this.platform.axios.get(`${DeviceURL}/thermostats/${this.device.deviceID}/priority`, {
425
+ params: {
426
+ locationId: this.location.locationID,
427
+ },
428
+ })).data;
429
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} (refreshRoomPriority) roomPriorityStatus: ${JSON.stringify(roomPriorityStatus)}`);
430
+ }
431
+ catch (e) {
432
+ const action = 'refreshRoomPriority';
433
+ if (this.device.retry) {
434
+ // Refresh the status from the API
435
+ interval(5000)
436
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
437
+ .pipe(take(1))
438
+ .subscribe(async () => {
439
+ await this.refreshRoomPriority();
440
+ });
441
+ }
442
+ this.resideoAPIError(e, action);
443
+ this.apiError(e);
444
+ }
445
+ }
446
+ this.parseStatus();
447
+ this.updateHomeKitCharacteristics();
448
+ }
449
+ /**
450
+ * Pushes the requested changes for Room Priority to the Resideo API
451
+ */
452
+ async pushRoomChanges() {
453
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} Room Priority,
454
+ Current Room: ${JSON.stringify(this.roomPriorityStatus.currentPriority.selectedRooms)}, Changing Room: [${this.sensorAccessory?.accessoryId}]`);
455
+ if (`[${this.sensorAccessory?.accessoryId}]` !== `[${this.roomPriorityStatus.currentPriority.selectedRooms}]`) {
456
+ const payload = {
457
+ currentPriority: {
458
+ priorityType: this.device.thermostat?.roompriority?.priorityType,
459
+ },
460
+ };
461
+ if (this.device.thermostat?.roompriority?.priorityType === 'PickARoom') {
462
+ payload.currentPriority.selectedRooms = [this.sensorAccessory?.accessoryId];
463
+ }
464
+ /**
465
+ * For "LCC-" devices only.
466
+ * "NoHold" will return to schedule.
467
+ * "TemporaryHold" will hold the set temperature until "nextPeriodTime".
468
+ * "PermanentHold" will hold the setpoint until user requests another change.
469
+ */
470
+ if (this.device.thermostat?.roompriority?.deviceType === 'Thermostat') {
471
+ if (this.device.thermostat?.roompriority.priorityType === 'FollowMe') {
472
+ this.successLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} sent request to Resideo API, Priority Type: ${this.device.thermostat?.roompriority.priorityType} Built-in Occupancy Sensor(s) Will be used to set Priority Automatically.`);
473
+ }
474
+ else if (this.device.thermostat?.roompriority.priorityType === 'WholeHouse') {
475
+ this.successLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} sent request to Resideo API, Priority Type: ${this.device.thermostat?.roompriority.priorityType}`);
476
+ }
477
+ else if (this.device.thermostat?.roompriority.priorityType === 'PickARoom') {
478
+ this.successLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} sent request to Resideo API, Room Priority: ${this.sensorAccessory?.accessoryAttribute.name}, Priority Type: ${this.device.thermostat?.roompriority.priorityType}`);
479
+ }
480
+ // Make the API request
481
+ try {
482
+ await this.platform.axios.put(`${DeviceURL}/thermostats/${this.device.deviceID}/priority`, payload, {
483
+ params: {
484
+ locationId: this.location.locationID,
485
+ },
486
+ });
487
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} pushRoomChanges: ${JSON.stringify(payload)}`);
488
+ }
489
+ catch (e) {
490
+ const action = 'pushRoomChanges';
491
+ if (this.device.retry) {
492
+ // Refresh the status from the API
493
+ interval(5000)
494
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
495
+ .pipe(take(1))
496
+ .subscribe(async () => {
497
+ await this.pushRoomChanges();
498
+ });
499
+ }
500
+ this.resideoAPIError(e, action);
501
+ this.apiError(e);
502
+ }
503
+ }
504
+ // Refresh the status from the API
505
+ await this.refreshSensorStatus();
506
+ }
507
+ }
508
+ /**
509
+ * Pushes the requested changes to the Resideo API
510
+ */
511
+ async pushChanges() {
512
+ try {
513
+ const payload = {
514
+ mode: await this.ResideoMode(),
515
+ thermostatSetpointStatus: this.device.thermostat?.thermostatSetpointStatus,
516
+ autoChangeoverActive: this.device.changeableValues.autoChangeoverActive,
517
+ };
518
+ // Set the heat and cool set point value based on the selected mode
519
+ switch (this.Thermostat.TargetHeatingCoolingState) {
520
+ case this.hap.Characteristic.TargetHeatingCoolingState.HEAT:
521
+ payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.TargetTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
522
+ payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
523
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} TargetHeatingCoolingState (HEAT): ${this.Thermostat.TargetHeatingCoolingState}, TargetTemperature: ${toFahrenheit(Number(this.Thermostat.TargetTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} heatSetpoint, CoolingThresholdTemperature: ${toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} coolSetpoint`);
524
+ break;
525
+ case this.hap.Characteristic.TargetHeatingCoolingState.COOL:
526
+ payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.TargetTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
527
+ payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
528
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} TargetHeatingCoolingState (COOL): ${this.Thermostat.TargetHeatingCoolingState}, TargetTemperature: ${toFahrenheit(Number(this.Thermostat.TargetTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} coolSetpoint, CoolingThresholdTemperature: ${toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} heatSetpoint`);
529
+ break;
530
+ case this.hap.Characteristic.TargetHeatingCoolingState.AUTO:
531
+ payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
532
+ payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
533
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} TargetHeatingCoolingState (AUTO): ${this.Thermostat.TargetHeatingCoolingState}, CoolingThresholdTemperature: ${toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} coolSetpoint, HeatingThresholdTemperature: ${toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} heatSetpoint`);
534
+ break;
535
+ default:
536
+ payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
537
+ payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
538
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} TargetHeatingCoolingState (OFF): ${this.Thermostat.TargetHeatingCoolingState}, CoolingThresholdTemperature: ${toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} coolSetpoint, HeatingThresholdTemperature: ${toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits))} heatSetpoint`);
539
+ }
540
+ this.successLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} set request (${JSON.stringify(payload)}) to Resideo API.`);
541
+ // Make the API request
542
+ await this.platform.axios.post(`${DeviceURL}/thermostats/${this.device.deviceID}`, payload, {
543
+ params: {
544
+ locationId: this.location.locationID,
545
+ },
546
+ });
547
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} pushChanges: ${JSON.stringify(payload)}`);
548
+ }
549
+ catch (e) {
550
+ const action = 'pushChanges';
551
+ if (this.device.retry) {
552
+ // Refresh the status from the API
553
+ interval(5000)
554
+ .pipe(skipWhile(() => this.thermostatUpdateInProgress))
555
+ .pipe(take(1))
556
+ .subscribe(async () => {
557
+ await this.pushChanges();
558
+ });
559
+ }
560
+ this.resideoAPIError(e, action);
561
+ this.apiError(e);
562
+ }
563
+ }
564
+ async ResideoMode() {
565
+ let resideoMode;
566
+ switch (this.Thermostat.TargetHeatingCoolingState) {
567
+ case this.hap.Characteristic.TargetHeatingCoolingState.HEAT:
568
+ resideoMode = ResideoModes.Heat;
569
+ break;
570
+ case this.hap.Characteristic.TargetHeatingCoolingState.COOL:
571
+ resideoMode = ResideoModes.Cool;
572
+ break;
573
+ case this.hap.Characteristic.TargetHeatingCoolingState.AUTO:
574
+ resideoMode = ResideoModes.Auto;
575
+ break;
576
+ case this.hap.Characteristic.TargetHeatingCoolingState.OFF:
577
+ resideoMode = ResideoModes.Off;
578
+ break;
579
+ default:
580
+ resideoMode = 'Unknown';
581
+ this.debugErrorLog(`${this.device.deviceClass} ${this.accessory.displayName} Unknown TargetHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
582
+ }
583
+ return resideoMode;
584
+ }
585
+ /**
586
+ * Updates the status for each of the HomeKit Characteristics
587
+ */
588
+ async updateHomeKitCharacteristics() {
589
+ if (this.Thermostat.TemperatureDisplayUnits === undefined) {
590
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
591
+ }
592
+ else {
593
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits, this.Thermostat.TemperatureDisplayUnits);
594
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
595
+ }
596
+ if (this.Thermostat.CurrentTemperature === undefined) {
597
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} CurrentTemperature: ${this.Thermostat.CurrentTemperature}`);
598
+ }
599
+ else {
600
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.Thermostat.CurrentTemperature);
601
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.Thermostat.CurrentTemperature}`);
602
+ }
603
+ if (this.HumiditySensor?.CurrentRelativeHumidity === undefined) {
604
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} CurrentRelativeHumidity: ${this.HumiditySensor?.CurrentRelativeHumidity}`);
605
+ }
606
+ else {
607
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.HumiditySensor.CurrentRelativeHumidity);
608
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
609
+ }
610
+ if (this.Thermostat.TargetTemperature === undefined) {
611
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} TargetTemperature: ${this.Thermostat.TargetTemperature}`);
612
+ }
613
+ else {
614
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetTemperature, this.Thermostat.TargetTemperature);
615
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic TargetTemperature: ${this.Thermostat.TargetTemperature}`);
616
+ }
617
+ if (this.Thermostat.HeatingThresholdTemperature === undefined) {
618
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} HeatingThresholdTemperature: ${this.Thermostat.HeatingThresholdTemperature}`);
619
+ }
620
+ else {
621
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.HeatingThresholdTemperature, this.Thermostat.HeatingThresholdTemperature);
622
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic HeatingThresholdTemperature: ${this.Thermostat.HeatingThresholdTemperature}`);
623
+ }
624
+ if (this.Thermostat.CoolingThresholdTemperature === undefined) {
625
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} CoolingThresholdTemperature: ${this.Thermostat.CoolingThresholdTemperature}`);
626
+ }
627
+ else {
628
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CoolingThresholdTemperature, this.Thermostat.CoolingThresholdTemperature);
629
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CoolingThresholdTemperature: ${this.Thermostat.CoolingThresholdTemperature}`);
630
+ }
631
+ if (this.Thermostat.TargetHeatingCoolingState === undefined) {
632
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} TargetHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
633
+ }
634
+ else {
635
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetHeatingCoolingState, this.Thermostat.TargetHeatingCoolingState);
636
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic TargetHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
637
+ }
638
+ if (this.Thermostat.CurrentHeatingCoolingState === undefined) {
639
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} CurrentHeatingCoolingState: ${this.Thermostat.CurrentHeatingCoolingState}`);
640
+ }
641
+ else {
642
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentHeatingCoolingState, this.Thermostat.CurrentHeatingCoolingState);
643
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CurrentHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
644
+ }
645
+ }
646
+ async apiError(e) {
647
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits, e);
648
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
649
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
650
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetTemperature, e);
651
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.HeatingThresholdTemperature, e);
652
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CoolingThresholdTemperature, e);
653
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetHeatingCoolingState, e);
654
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentHeatingCoolingState, e);
655
+ // throw new this.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
656
+ }
657
+ async setTargetHeatingCoolingState(value) {
658
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} Set TargetHeatingCoolingState: ${value}`);
659
+ this.Thermostat.TargetHeatingCoolingState = value;
660
+ // Set the TargetTemperature value based on the selected mode
661
+ if (this.Thermostat.TargetHeatingCoolingState === this.hap.Characteristic.TargetHeatingCoolingState.HEAT) {
662
+ this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
663
+ }
664
+ else {
665
+ this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
666
+ }
667
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetTemperature, this.Thermostat.TargetTemperature);
668
+ if (this.Thermostat.TargetHeatingCoolingState !== HomeKitModes[this.device.changeableValues.mode]) {
669
+ this.doRoomUpdate.next();
670
+ this.doThermostatUpdate.next();
671
+ }
672
+ }
673
+ async setHeatingThresholdTemperature(value) {
674
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} Set HeatingThresholdTemperature: ${value}`);
675
+ this.Thermostat.HeatingThresholdTemperature = value;
676
+ this.doThermostatUpdate.next();
677
+ }
678
+ async setCoolingThresholdTemperature(value) {
679
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} Set CoolingThresholdTemperature: ${value}`);
680
+ this.Thermostat.CoolingThresholdTemperature = value;
681
+ this.doThermostatUpdate.next();
682
+ }
683
+ async setTargetTemperature(value) {
684
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} Set TargetTemperature: ${value}`);
685
+ this.Thermostat.TargetTemperature = value;
686
+ this.doThermostatUpdate.next();
687
+ }
688
+ async setTemperatureDisplayUnits(value) {
689
+ this.debugLog(`${this.sensorAccessory?.accessoryAttribute.type} ${this.device.deviceClass} ${this.accessory.displayName} Set TemperatureDisplayUnits: ${value}`);
690
+ this.warnLog('Changing the Hardware Display Units from HomeKit is not supported.');
691
+ this.Thermostat.TemperatureDisplayUnits = this.device.units === 'Celsius'
692
+ ? this.hap.Characteristic.TemperatureDisplayUnits.CELSIUS
693
+ : this.hap.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
694
+ // change the temp units back to the one the Resideo API said the thermostat was set to
695
+ setTimeout(() => {
696
+ this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits, this.Thermostat.TemperatureDisplayUnits);
697
+ }, 100);
698
+ }
699
+ }
700
+ //# sourceMappingURL=roomsensorthermostats.js.map