@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.
- package/.github/FUNDING.yml +4 -0
- package/.github/ISSUE_TEMPLATE/bug-report.yml +97 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature-request.yml +38 -0
- package/.github/ISSUE_TEMPLATE/support-request.yml +85 -0
- package/.github/ISSUE_TEMPLATE.md +52 -0
- package/.github/PULL_REQUEST_TEMPLATE/pull_request.md +27 -0
- package/.github/auto-merge.yml +3 -0
- package/.github/dependabot.yml +17 -0
- package/.github/labeler.yml +38 -0
- package/.github/npm-version-script-esm.js +85 -0
- package/.github/release-drafter.yml +33 -0
- package/.github/workflows/beta-release.yml +55 -0
- package/.github/workflows/build.yml +18 -0
- package/.github/workflows/changerelease.yml +11 -0
- package/.github/workflows/labeler.yml +9 -0
- package/.github/workflows/release-drafter.yml +14 -0
- package/.github/workflows/release.yml +35 -0
- package/.github/workflows/stale.yml +12 -0
- package/CHANGELOG.md +161 -0
- package/LICENSE +14 -0
- package/README.md +67 -0
- package/SECURITY.md +19 -0
- package/branding/Homebridge_x_Resideo.svg +28 -0
- package/branding/honeywell/Homebridge_x_Honeywell.svg +1 -0
- package/branding/honeywell/homebridge-honeywell-home-changelog.md +851 -0
- package/branding/icon.png +0 -0
- package/config.schema.json +611 -0
- package/dist/devices/device.d.ts +41 -0
- package/dist/devices/device.d.ts.map +1 -0
- package/dist/devices/device.js +279 -0
- package/dist/devices/device.js.map +1 -0
- package/dist/devices/leaksensors.d.ts +34 -0
- package/dist/devices/leaksensors.d.ts.map +1 -0
- package/dist/devices/leaksensors.js +300 -0
- package/dist/devices/leaksensors.js.map +1 -0
- package/dist/devices/roomsensors.d.ts +38 -0
- package/dist/devices/roomsensors.d.ts.map +1 -0
- package/dist/devices/roomsensors.js +274 -0
- package/dist/devices/roomsensors.js.map +1 -0
- package/dist/devices/roomsensorthermostats.d.ts +57 -0
- package/dist/devices/roomsensorthermostats.d.ts.map +1 -0
- package/dist/devices/roomsensorthermostats.js +700 -0
- package/dist/devices/roomsensorthermostats.js.map +1 -0
- package/dist/devices/thermostats.d.ts +73 -0
- package/dist/devices/thermostats.d.ts.map +1 -0
- package/dist/devices/thermostats.js +930 -0
- package/dist/devices/thermostats.js.map +1 -0
- package/dist/devices/valve.d.ts +21 -0
- package/dist/devices/valve.d.ts.map +1 -0
- package/dist/devices/valve.js +151 -0
- package/dist/devices/valve.js.map +1 -0
- package/dist/homebridge-ui/public/index.html +423 -0
- package/dist/homebridge-ui/server.d.ts +2 -0
- package/dist/homebridge-ui/server.d.ts.map +1 -0
- package/dist/homebridge-ui/server.js +131 -0
- package/dist/homebridge-ui/server.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +94 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +890 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +409 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +25 -0
- package/dist/settings.js.map +1 -0
- package/dist/utils.d.ts +21 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +58 -0
- package/dist/utils.js.map +1 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/highlight.css +22 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1493 -0
- package/docs/functions/default.html +1 -0
- package/docs/index.html +73 -0
- package/docs/modules.html +2 -0
- package/eslint.config.js +50 -0
- package/package.json +102 -0
- package/typedoc.json +22 -0
|
@@ -0,0 +1,930 @@
|
|
|
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 Thermostats extends deviceBase {
|
|
13
|
+
platform;
|
|
14
|
+
// Services
|
|
15
|
+
Thermostat;
|
|
16
|
+
Fan;
|
|
17
|
+
HumiditySensor;
|
|
18
|
+
StatefulProgrammableSwitch;
|
|
19
|
+
// Config
|
|
20
|
+
thermostatSetpointStatus;
|
|
21
|
+
// Thermostat Updates
|
|
22
|
+
thermostatUpdateInProgress;
|
|
23
|
+
doThermostatUpdate;
|
|
24
|
+
// Fan Updates
|
|
25
|
+
fanStatus;
|
|
26
|
+
fanUpdateInProgress;
|
|
27
|
+
doFanUpdate;
|
|
28
|
+
// Room Updates - T9 Only
|
|
29
|
+
roomPriorityStatus;
|
|
30
|
+
roomUpdateInProgress;
|
|
31
|
+
doRoomUpdate;
|
|
32
|
+
constructor(platform, accessory, location, device) {
|
|
33
|
+
super(platform, accessory, location, device);
|
|
34
|
+
this.platform = platform;
|
|
35
|
+
this.getThermostatConfigSettings(accessory, device);
|
|
36
|
+
// this is subject we use to track when we need to POST Room Priority changes to the Resideo API for Room Changes - T9 Only
|
|
37
|
+
this.doRoomUpdate = new Subject();
|
|
38
|
+
this.roomUpdateInProgress = false;
|
|
39
|
+
// this is subject we use to track when we need to POST Thermostat changes to the Resideo API
|
|
40
|
+
this.doThermostatUpdate = new Subject();
|
|
41
|
+
this.thermostatUpdateInProgress = false;
|
|
42
|
+
// this is subject we use to track when we need to POST Fan changes to the Resideo API
|
|
43
|
+
this.doFanUpdate = new Subject();
|
|
44
|
+
this.fanUpdateInProgress = false;
|
|
45
|
+
// Initialize Thermostat Service
|
|
46
|
+
accessory.context.Thermostat = accessory.context.Thermostat ?? {};
|
|
47
|
+
this.Thermostat = {
|
|
48
|
+
Name: accessory.context.Thermostat.Name ?? accessory.displayName,
|
|
49
|
+
Service: accessory.getService(this.hap.Service.Thermostat) ?? this.accessory.addService(this.hap.Service.Thermostat),
|
|
50
|
+
TargetTemperature: accessory.context.TargetTemperature ?? 20,
|
|
51
|
+
CurrentTemperature: accessory.context.CurrentTemperature ?? 20,
|
|
52
|
+
TemperatureDisplayUnits: accessory.context.TemperatureDisplayUnits,
|
|
53
|
+
TargetHeatingCoolingState: accessory.context.TargetHeatingCoolingState ?? this.hap.Characteristic.TargetHeatingCoolingState.AUTO,
|
|
54
|
+
CurrentHeatingCoolingState: accessory.context.CurrentHeatingCoolingState ?? this.hap.Characteristic.CurrentHeatingCoolingState.OFF,
|
|
55
|
+
CoolingThresholdTemperature: accessory.context.CoolingThresholdTemperature ?? 20,
|
|
56
|
+
HeatingThresholdTemperature: accessory.context.HeatingThresholdTemperature ?? 22,
|
|
57
|
+
};
|
|
58
|
+
accessory.context.Thermostat = this.Thermostat;
|
|
59
|
+
// Service Name
|
|
60
|
+
this.Thermostat.Service
|
|
61
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Thermostat.Name)
|
|
62
|
+
.setCharacteristic(this.hap.Characteristic.CurrentHeatingCoolingState, this.Thermostat.CurrentHeatingCoolingState)
|
|
63
|
+
.getCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits)
|
|
64
|
+
.onGet(() => {
|
|
65
|
+
this.Thermostat.TemperatureDisplayUnits = device.units === 'Celsius'
|
|
66
|
+
? this.hap.Characteristic.TemperatureDisplayUnits.CELSIUS
|
|
67
|
+
: this.hap.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
|
|
68
|
+
accessory.context.TemperatureDisplayUnits = this.Thermostat.TemperatureDisplayUnits;
|
|
69
|
+
this.debugLog(`${this.device.deviceClass} ${accessory.displayName} TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
|
|
70
|
+
return this.Thermostat.TemperatureDisplayUnits;
|
|
71
|
+
})
|
|
72
|
+
.onSet(this.setTemperatureDisplayUnits.bind(this));
|
|
73
|
+
// Set Min and Max
|
|
74
|
+
if (device.minHeatSetpoint && device.maxHeatSetpoint) {
|
|
75
|
+
this.debugLog(`${this.device.deviceClass} ${accessory.displayName} minHeatSetpoint: ${device.minHeatSetpoint}, maxHeatSetpoint: ${device.maxHeatSetpoint}, TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
|
|
76
|
+
const minValue = toCelsius(device.minHeatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
77
|
+
const maxValue = toCelsius(device.maxHeatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
78
|
+
this.debugLog(`${this.device.deviceClass} ${accessory.displayName} minValue: ${minValue}, maxValue: ${maxValue}`);
|
|
79
|
+
if (device.changeableValues.heatCoolMode === 'Heat') {
|
|
80
|
+
this.debugLog(`${device.deviceClass} ${accessory.displayName} is in "${device.changeableValues?.heatCoolMode}" mode`);
|
|
81
|
+
this.Thermostat.Service
|
|
82
|
+
.getCharacteristic(this.hap.Characteristic.TargetTemperature)
|
|
83
|
+
.setProps({
|
|
84
|
+
minValue,
|
|
85
|
+
maxValue,
|
|
86
|
+
minStep: 0.1,
|
|
87
|
+
})
|
|
88
|
+
.onGet(() => {
|
|
89
|
+
return this.Thermostat.TargetTemperature;
|
|
90
|
+
});
|
|
91
|
+
this.debugWarnLog(`${device.deviceClass} ${accessory.displayName} (HEAT) Min Heat Setpoint: ${device.minHeatSetpoint}. Max Heat Setpoint: ${device.maxHeatSetpoint} TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
this.debugLog(`${device.deviceClass} ${accessory.displayName} is in "${device.changeableValues?.heatCoolMode}" mode`);
|
|
95
|
+
this.Thermostat.Service
|
|
96
|
+
.getCharacteristic(this.hap.Characteristic.TargetTemperature)
|
|
97
|
+
.setProps({
|
|
98
|
+
minValue,
|
|
99
|
+
maxValue,
|
|
100
|
+
minStep: 0.1,
|
|
101
|
+
})
|
|
102
|
+
.onGet(() => {
|
|
103
|
+
return this.Thermostat.TargetTemperature;
|
|
104
|
+
});
|
|
105
|
+
this.debugWarnLog(`${device.deviceClass} ${accessory.displayName} (NOT HEAT) Min Heat Setpoint: ${device.minHeatSetpoint}. Max Heat Setpoint: ${device.maxHeatSetpoint} TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// The value property of TargetHeaterCoolerState must be one of the following:
|
|
109
|
+
// AUTO = 3; HEAT = 1; COOL = 2; OFF = 0;
|
|
110
|
+
// Set control bindings
|
|
111
|
+
const TargetState = [4];
|
|
112
|
+
TargetState.pop();
|
|
113
|
+
if (this.device.allowedModes?.includes('Cool')) {
|
|
114
|
+
TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.COOL);
|
|
115
|
+
}
|
|
116
|
+
if (this.device.allowedModes?.includes('Heat')) {
|
|
117
|
+
TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.HEAT);
|
|
118
|
+
}
|
|
119
|
+
if (this.device.allowedModes?.includes('Off')) {
|
|
120
|
+
TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.OFF);
|
|
121
|
+
}
|
|
122
|
+
if (this.device.allowedModes?.includes('Auto') || this.device.thermostat?.show_auto) {
|
|
123
|
+
TargetState.push(this.hap.Characteristic.TargetHeatingCoolingState.AUTO);
|
|
124
|
+
}
|
|
125
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} allowedModes: ${this.device.allowedModes}`);
|
|
126
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Only Show These Modes: ${JSON.stringify(TargetState)}`);
|
|
127
|
+
this.Thermostat.Service
|
|
128
|
+
.getCharacteristic(this.hap.Characteristic.TargetHeatingCoolingState)
|
|
129
|
+
.setProps({
|
|
130
|
+
validValues: TargetState,
|
|
131
|
+
})
|
|
132
|
+
.onGet(() => {
|
|
133
|
+
return this.Thermostat.TargetHeatingCoolingState;
|
|
134
|
+
})
|
|
135
|
+
.onSet(this.setTargetHeatingCoolingState.bind(this));
|
|
136
|
+
this.Thermostat.Service
|
|
137
|
+
.getCharacteristic(this.hap.Characteristic.HeatingThresholdTemperature)
|
|
138
|
+
.onGet(() => {
|
|
139
|
+
return this.Thermostat.HeatingThresholdTemperature;
|
|
140
|
+
})
|
|
141
|
+
.onSet(this.setHeatingThresholdTemperature.bind(this));
|
|
142
|
+
this.Thermostat.Service
|
|
143
|
+
.getCharacteristic(this.hap.Characteristic.CoolingThresholdTemperature)
|
|
144
|
+
.onGet(() => {
|
|
145
|
+
return this.Thermostat.CoolingThresholdTemperature;
|
|
146
|
+
})
|
|
147
|
+
.onSet(this.setCoolingThresholdTemperature.bind(this));
|
|
148
|
+
this.Thermostat.Service
|
|
149
|
+
.getCharacteristic(this.hap.Characteristic.TargetTemperature)
|
|
150
|
+
.onGet(() => {
|
|
151
|
+
return this.Thermostat.TargetTemperature;
|
|
152
|
+
})
|
|
153
|
+
.onSet(this.setTargetTemperature.bind(this));
|
|
154
|
+
// Initialize Fan Service
|
|
155
|
+
if (device.thermostat?.hide_fan) {
|
|
156
|
+
if (this.Fan) {
|
|
157
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Fan Service`);
|
|
158
|
+
this.Fan.Service = accessory.getService(this.hap.Service.Fanv2);
|
|
159
|
+
accessory.removeService(this.Fan.Service);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Fan Service Not Found`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else if (device.settings?.fan) {
|
|
166
|
+
this.debugLog(`${device.deviceClass} ${accessory.displayName} Available Fan Settings ${JSON.stringify(device.settings.fan)}`);
|
|
167
|
+
accessory.context.Fan = accessory.context.Fan ?? {};
|
|
168
|
+
this.Fan = {
|
|
169
|
+
Name: accessory.context.Fan.Name ?? `${accessory.displayName} Fan`,
|
|
170
|
+
Service: accessory.getService(this.hap.Service.Fanv2) ?? accessory.addService(this.hap.Service.Fanv2),
|
|
171
|
+
Active: accessory.context.Active ?? this.hap.Characteristic.Active.ACTIVE,
|
|
172
|
+
TargetFanState: accessory.context.TargetFanState ?? this.hap.Characteristic.TargetFanState.MANUAL,
|
|
173
|
+
};
|
|
174
|
+
accessory.context.Fan = this.Fan;
|
|
175
|
+
// Initialize Fan Characteristic
|
|
176
|
+
this.Fan.Service
|
|
177
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Fan.Name)
|
|
178
|
+
.getCharacteristic(this.hap.Characteristic.Active)
|
|
179
|
+
.onGet(() => {
|
|
180
|
+
return this.Fan.Active;
|
|
181
|
+
})
|
|
182
|
+
.onSet(this.setActive.bind(this));
|
|
183
|
+
this.Fan.Service
|
|
184
|
+
.getCharacteristic(this.hap.Characteristic.TargetFanState)
|
|
185
|
+
.onGet(() => {
|
|
186
|
+
return this.Fan.TargetFanState;
|
|
187
|
+
})
|
|
188
|
+
.onSet(this.setTargetFanState.bind(this));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this.debugLog(`${device.deviceClass} ${accessory.displayName} Fanv2 Service Not Added`);
|
|
192
|
+
}
|
|
193
|
+
// Initialize Humidity Sensor Service
|
|
194
|
+
if (device.thermostat?.hide_humidity) {
|
|
195
|
+
if (this.HumiditySensor) {
|
|
196
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
|
|
197
|
+
this.HumiditySensor.Service = this.accessory.getService(this.hap.Service.HumiditySensor);
|
|
198
|
+
accessory.removeService(this.HumiditySensor.Service);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Humidity Sensor Service Not Found`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else if (device.indoorHumidity) {
|
|
205
|
+
this.debugLog(`${device.deviceClass} ${accessory.displayName} Add Humidity Sensor Service`);
|
|
206
|
+
accessory.context.HumiditySensor = accessory.context.HumiditySensor ?? {};
|
|
207
|
+
this.HumiditySensor = {
|
|
208
|
+
Name: accessory.context.HumiditySensor.Name ?? `${accessory.displayName} Humidity Sensor`,
|
|
209
|
+
Service: accessory.getService(this.hap.Service.HumiditySensor) ?? accessory.addService(this.hap.Service.HumiditySensor),
|
|
210
|
+
CurrentRelativeHumidity: accessory.context.CurrentRelativeHumidity ?? 50,
|
|
211
|
+
};
|
|
212
|
+
accessory.context.HumiditySensor = this.HumiditySensor;
|
|
213
|
+
// Initialize Humidity Sensor Characteristic
|
|
214
|
+
this.HumiditySensor.Service
|
|
215
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.HumiditySensor.Name);
|
|
216
|
+
this.HumiditySensor.Service
|
|
217
|
+
.getCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity)
|
|
218
|
+
.setProps({
|
|
219
|
+
minStep: 0.1,
|
|
220
|
+
})
|
|
221
|
+
.onGet(() => {
|
|
222
|
+
return this.HumiditySensor.CurrentRelativeHumidity;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
this.debugLog(`${device.deviceClass} ${accessory.displayName} Humidity Sensor Service Not Added`);
|
|
227
|
+
}
|
|
228
|
+
// Initialize StatefulProgrammableSwitch property
|
|
229
|
+
accessory.context.StatefulProgrammableSwitch = accessory.context.StatefulProgrammableSwitch ?? {};
|
|
230
|
+
this.StatefulProgrammableSwitch = {
|
|
231
|
+
Name: accessory.context.StatefulProgrammableSwitch.Name ?? accessory.displayName,
|
|
232
|
+
Service: accessory.getService(this.hap.Service.StatefulProgrammableSwitch) ?? accessory.addService(this.hap.Service.StatefulProgrammableSwitch),
|
|
233
|
+
ProgrammableSwitchEvent: accessory.context.ProgrammableSwitchEvent ?? this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS,
|
|
234
|
+
ProgrammableSwitchOutputState: accessory.context.ProgrammableSwitchOutputState ?? 0,
|
|
235
|
+
};
|
|
236
|
+
accessory.context.StatefulProgrammableSwitch = this.StatefulProgrammableSwitch;
|
|
237
|
+
this.StatefulProgrammableSwitch.Service
|
|
238
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.StatefulProgrammableSwitch.Name)
|
|
239
|
+
.getCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent)
|
|
240
|
+
.setProps({
|
|
241
|
+
validValues: [this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS],
|
|
242
|
+
})
|
|
243
|
+
.onGet(() => {
|
|
244
|
+
return this.StatefulProgrammableSwitch.ProgrammableSwitchEvent;
|
|
245
|
+
});
|
|
246
|
+
this.StatefulProgrammableSwitch.Service
|
|
247
|
+
.getCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState)
|
|
248
|
+
.onGet(() => {
|
|
249
|
+
return this.StatefulProgrammableSwitch.ProgrammableSwitchOutputState;
|
|
250
|
+
})
|
|
251
|
+
.onSet(this.handleProgrammableSwitchOutputStateSet.bind(this));
|
|
252
|
+
// Intial Refresh
|
|
253
|
+
this.refreshStatus();
|
|
254
|
+
// Start an update interval
|
|
255
|
+
interval(this.config.options.refreshRate * 1000)
|
|
256
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
257
|
+
.subscribe(async () => {
|
|
258
|
+
await this.refreshStatus();
|
|
259
|
+
});
|
|
260
|
+
// Watch for thermostat change events
|
|
261
|
+
// We put in a debounce of 100ms so we don't make duplicate calls
|
|
262
|
+
if (device.thermostat?.roompriority?.deviceType === 'Thermostat' && device.deviceModel === 'T9-T10') {
|
|
263
|
+
this.doRoomUpdate
|
|
264
|
+
.pipe(tap(() => {
|
|
265
|
+
this.roomUpdateInProgress = true;
|
|
266
|
+
}), debounceTime(this.devicePushRate * 500))
|
|
267
|
+
.subscribe(async () => {
|
|
268
|
+
try {
|
|
269
|
+
await this.pushRoomChanges();
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
const action = 'pushRoomChanges';
|
|
273
|
+
if (this.device.retry) {
|
|
274
|
+
// Refresh the status from the API
|
|
275
|
+
interval(5000)
|
|
276
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
277
|
+
.pipe(take(1))
|
|
278
|
+
.subscribe(async () => {
|
|
279
|
+
await this.pushRoomChanges();
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
this.resideoAPIError(e, action);
|
|
283
|
+
this.platform.refreshAccessToken();
|
|
284
|
+
this.apiError(e);
|
|
285
|
+
}
|
|
286
|
+
this.roomUpdateInProgress = false;
|
|
287
|
+
// Refresh the status from the API
|
|
288
|
+
interval(5000)
|
|
289
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
290
|
+
.pipe(take(1))
|
|
291
|
+
.subscribe(async () => {
|
|
292
|
+
await this.refreshStatus();
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
this.doThermostatUpdate
|
|
297
|
+
.pipe(tap(() => {
|
|
298
|
+
this.thermostatUpdateInProgress = true;
|
|
299
|
+
}), debounceTime(this.devicePushRate * 1000))
|
|
300
|
+
.subscribe(async () => {
|
|
301
|
+
try {
|
|
302
|
+
await this.pushChanges();
|
|
303
|
+
}
|
|
304
|
+
catch (e) {
|
|
305
|
+
const action = 'pushChanges';
|
|
306
|
+
if (this.device.retry) {
|
|
307
|
+
// Refresh the status from the API
|
|
308
|
+
interval(5000)
|
|
309
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
310
|
+
.pipe(take(1))
|
|
311
|
+
.subscribe(async () => {
|
|
312
|
+
await this.pushChanges();
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
this.resideoAPIError(e, action);
|
|
316
|
+
this.platform.refreshAccessToken();
|
|
317
|
+
this.apiError(e);
|
|
318
|
+
}
|
|
319
|
+
this.thermostatUpdateInProgress = false;
|
|
320
|
+
// Refresh the status from the API
|
|
321
|
+
interval(15000)
|
|
322
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
323
|
+
.pipe(take(1))
|
|
324
|
+
.subscribe(async () => {
|
|
325
|
+
await this.refreshStatus();
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
if (device.settings?.fan && !device.thermostat?.hide_fan) {
|
|
329
|
+
this.doFanUpdate
|
|
330
|
+
.pipe(tap(() => {
|
|
331
|
+
this.fanUpdateInProgress = true;
|
|
332
|
+
}), debounceTime(this.devicePushRate * 1000))
|
|
333
|
+
.subscribe(async () => {
|
|
334
|
+
try {
|
|
335
|
+
await this.pushFanChanges();
|
|
336
|
+
}
|
|
337
|
+
catch (e) {
|
|
338
|
+
const action = 'pushFanChanges';
|
|
339
|
+
if (this.device.retry) {
|
|
340
|
+
// Refresh the status from the API
|
|
341
|
+
interval(5000)
|
|
342
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
343
|
+
.pipe(take(1))
|
|
344
|
+
.subscribe(async () => {
|
|
345
|
+
await this.pushFanChanges();
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
this.resideoAPIError(e, action);
|
|
349
|
+
this.platform.refreshAccessToken();
|
|
350
|
+
this.apiError(e);
|
|
351
|
+
}
|
|
352
|
+
this.fanUpdateInProgress = false;
|
|
353
|
+
// Refresh the status from the API
|
|
354
|
+
interval(5000)
|
|
355
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
356
|
+
.pipe(take(1))
|
|
357
|
+
.subscribe(async () => {
|
|
358
|
+
await this.refreshStatus();
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Parse the device status from the Resideo api
|
|
365
|
+
*/
|
|
366
|
+
async parseStatus() {
|
|
367
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus`);
|
|
368
|
+
if (this.device.units === 'Fahrenheit') {
|
|
369
|
+
this.Thermostat.TemperatureDisplayUnits = this.hap.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
|
|
370
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus TemperatureDisplayUnits: ${this.hap.Characteristic.TemperatureDisplayUnits.FAHRENHEIT}`);
|
|
371
|
+
}
|
|
372
|
+
if (this.device.units === 'Celsius') {
|
|
373
|
+
this.Thermostat.TemperatureDisplayUnits = this.hap.Characteristic.TemperatureDisplayUnits.CELSIUS;
|
|
374
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus TemperatureDisplayUnits: ${this.hap.Characteristic.TemperatureDisplayUnits.CELSIUS}`);
|
|
375
|
+
}
|
|
376
|
+
this.Thermostat.CurrentTemperature = toCelsius(this.device.indoorTemperature, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
377
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus CurrentTemperature: ${toCelsius(this.device.indoorTemperature, Number(this.Thermostat.TemperatureDisplayUnits))}`);
|
|
378
|
+
if (this.device.indoorHumidity) {
|
|
379
|
+
if (this.HumiditySensor) {
|
|
380
|
+
this.HumiditySensor.CurrentRelativeHumidity = this.device.indoorHumidity;
|
|
381
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (this.device.changeableValues.heatSetpoint > 0) {
|
|
385
|
+
this.Thermostat.HeatingThresholdTemperature = toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
386
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus HeatingThresholdTemperature: ${toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits))}`);
|
|
387
|
+
}
|
|
388
|
+
if (this.device.changeableValues.coolSetpoint > 0) {
|
|
389
|
+
this.Thermostat.CoolingThresholdTemperature = toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
390
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus CoolingThresholdTemperature: ${toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits))}`);
|
|
391
|
+
}
|
|
392
|
+
this.Thermostat.TargetHeatingCoolingState = HomeKitModes[this.device.changeableValues.mode];
|
|
393
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus TargetHeatingCoolingState: ${HomeKitModes[this.device.changeableValues.mode]}`);
|
|
394
|
+
/**
|
|
395
|
+
* The CurrentHeatingCoolingState is either 'Heat', 'Cool', or 'Off'
|
|
396
|
+
* CurrentHeatingCoolingState = OFF = 0, HEAT = 1, COOL = 2
|
|
397
|
+
*/
|
|
398
|
+
switch (this.device.operationStatus.mode) {
|
|
399
|
+
case 'Heat':
|
|
400
|
+
this.Thermostat.CurrentHeatingCoolingState = this.hap.Characteristic.CurrentHeatingCoolingState.HEAT;
|
|
401
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus Currently Mode (HEAT): ${this.device.operationStatus.mode}(${this.Thermostat.CurrentHeatingCoolingState})`);
|
|
402
|
+
break;
|
|
403
|
+
case 'Cool':
|
|
404
|
+
this.Thermostat.CurrentHeatingCoolingState = this.hap.Characteristic.CurrentHeatingCoolingState.COOL;
|
|
405
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus Currently Mode (COOL): ${this.device.operationStatus.mode}(${this.Thermostat.CurrentHeatingCoolingState})`);
|
|
406
|
+
break;
|
|
407
|
+
default:
|
|
408
|
+
this.Thermostat.CurrentHeatingCoolingState = this.hap.Characteristic.CurrentHeatingCoolingState.OFF;
|
|
409
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus Currently Mode (OFF): ${this.device.operationStatus.mode}(${this.Thermostat.CurrentHeatingCoolingState})`);
|
|
410
|
+
}
|
|
411
|
+
// Set the TargetTemperature value based on the current mode
|
|
412
|
+
if (this.Thermostat.TargetHeatingCoolingState === this.hap.Characteristic.TargetHeatingCoolingState.HEAT) {
|
|
413
|
+
if (this.device.changeableValues.heatSetpoint > 0) {
|
|
414
|
+
this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
415
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus TargetTemperature (HEAT): ${toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits))})`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
if (this.device.changeableValues) {
|
|
420
|
+
if (this.device.changeableValues.coolSetpoint > 0) {
|
|
421
|
+
this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
422
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} parseStatus TargetTemperature (OFF/COOL): ${toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits))})`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
// Set the Target Fan State
|
|
427
|
+
if (this.device.settings?.fan && !this.device.thermostat?.hide_fan) {
|
|
428
|
+
if (this.Fan) {
|
|
429
|
+
if (this.fanStatus) {
|
|
430
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} fanStatus: ${JSON.stringify(this.fanStatus)}`);
|
|
431
|
+
if (this.fanStatus.changeableValues.mode === 'Auto') {
|
|
432
|
+
this.Fan.TargetFanState = this.hap.Characteristic.TargetFanState.AUTO;
|
|
433
|
+
this.Fan.Active = this.hap.Characteristic.Active.INACTIVE;
|
|
434
|
+
}
|
|
435
|
+
else if (this.fanStatus.changeableValues.mode === 'On') {
|
|
436
|
+
this.Fan.TargetFanState = this.hap.Characteristic.TargetFanState.MANUAL;
|
|
437
|
+
this.Fan.Active = this.hap.Characteristic.Active.ACTIVE;
|
|
438
|
+
}
|
|
439
|
+
else if (this.fanStatus.changeableValues.mode === 'Circulate') {
|
|
440
|
+
this.Fan.TargetFanState = this.hap.Characteristic.TargetFanState.MANUAL;
|
|
441
|
+
this.Fan.Active = this.hap.Characteristic.Active.INACTIVE;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// Set the Room Priority Status - T9 Only
|
|
447
|
+
if (this.device.thermostat?.roompriority?.deviceType === 'Thermostat' && this.device.deviceModel === 'T9-T10') {
|
|
448
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} roomPriorityStatus: ${JSON.stringify(this.roomPriorityStatus)}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Asks the Resideo Home API for the latest device information
|
|
453
|
+
*/
|
|
454
|
+
async refreshStatus() {
|
|
455
|
+
try {
|
|
456
|
+
const device = await this.getDeviceStatus();
|
|
457
|
+
const fanStatus = await this.getFanStatus();
|
|
458
|
+
const roomPriorityStatus = await this.getRoomPriorityStatus();
|
|
459
|
+
this.device = device;
|
|
460
|
+
this.fanStatus = fanStatus;
|
|
461
|
+
this.roomPriorityStatus = roomPriorityStatus;
|
|
462
|
+
this.parseStatus();
|
|
463
|
+
this.updateHomeKitCharacteristics();
|
|
464
|
+
}
|
|
465
|
+
catch (e) {
|
|
466
|
+
const action = 'refreshStatus';
|
|
467
|
+
if (this.device.retry) {
|
|
468
|
+
// Refresh the status from the API
|
|
469
|
+
interval(5000)
|
|
470
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
471
|
+
.pipe(take(1))
|
|
472
|
+
.subscribe(async () => {
|
|
473
|
+
await this.refreshStatus();
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
this.resideoAPIError(e, action);
|
|
477
|
+
this.apiError(e);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
async getDeviceStatus() {
|
|
481
|
+
const device = (await this.platform.axios.get(`${DeviceURL}/thermostats/${this.device.deviceID}`, {
|
|
482
|
+
params: {
|
|
483
|
+
locationId: this.location.locationID,
|
|
484
|
+
},
|
|
485
|
+
})).data;
|
|
486
|
+
this.debugLog(`(refreshStatus) ${device.deviceClass} device: ${JSON.stringify(device)}`);
|
|
487
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} refreshStatus for ${this.device.name} from Resideo API: ${JSON.stringify(this.device.changeableValues)}`);
|
|
488
|
+
return device;
|
|
489
|
+
}
|
|
490
|
+
async getRoomPriorityStatus() {
|
|
491
|
+
if (this.device.thermostat?.roompriority?.deviceType === 'Thermostat' && this.device.deviceModel === 'T9-T10') {
|
|
492
|
+
const roompriority = (await this.platform.axios.get(`${DeviceURL}/thermostats/${this.device.deviceID}/priority`, {
|
|
493
|
+
params: {
|
|
494
|
+
locationId: this.location.locationID,
|
|
495
|
+
},
|
|
496
|
+
})).data;
|
|
497
|
+
this.debugLog(`Thermostat: ${this.accessory.displayName} Priority: ${JSON.stringify(roompriority.data)}`);
|
|
498
|
+
const action = 'refreshRoomPriority';
|
|
499
|
+
await this.statusCode(200, action);
|
|
500
|
+
return roompriority;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
async getFanStatus() {
|
|
504
|
+
if (this.device.settings?.fan && !this.device.thermostat?.hide_fan) {
|
|
505
|
+
const fan = (await this.platform.axios.get(`${DeviceURL}/thermostats/${this.device.deviceID}/fan`, {
|
|
506
|
+
params: {
|
|
507
|
+
locationId: this.location.locationID,
|
|
508
|
+
},
|
|
509
|
+
})).data;
|
|
510
|
+
const action = 'refreshFanStatus';
|
|
511
|
+
await this.statusCode(200, action);
|
|
512
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} (refreshFanStatus) fanMode: ${JSON.stringify(fan)}`);
|
|
513
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} fanMode: ${JSON.stringify(fan)}`);
|
|
514
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} refreshStatus for ${this.device.name} Fan from Resideo Fan API: ${JSON.stringify(fan)}`);
|
|
515
|
+
return fan;
|
|
516
|
+
}
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Pushes the requested changes to the Resideo API
|
|
521
|
+
*/
|
|
522
|
+
async pushChanges() {
|
|
523
|
+
try {
|
|
524
|
+
const payload = {};
|
|
525
|
+
// Only include mode on certain models
|
|
526
|
+
switch (this.device.deviceModel) {
|
|
527
|
+
case 'Unknown':
|
|
528
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} didn't send TargetHeatingCoolingState, Model: ${this.device.deviceModel}`);
|
|
529
|
+
break;
|
|
530
|
+
default:
|
|
531
|
+
payload.mode = await this.ResideoMode();
|
|
532
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} send TargetHeatingCoolingState: ${payload.mode}`);
|
|
533
|
+
}
|
|
534
|
+
// Only include thermostatSetpointStatus on certain models
|
|
535
|
+
switch (this.device.deviceModel) {
|
|
536
|
+
case 'Round':
|
|
537
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} didn't send thermostatSetpointStatus, Model: ${this.device.deviceModel}`);
|
|
538
|
+
break;
|
|
539
|
+
default:
|
|
540
|
+
this.pushChangesthermostatSetpointStatus();
|
|
541
|
+
payload.thermostatSetpointStatus = this.thermostatSetpointStatus;
|
|
542
|
+
if (this.thermostatSetpointStatus === 'TemporaryHold') {
|
|
543
|
+
this.warnLog(`${this.device.deviceClass} ${this.accessory.displayName} send thermostatSetpointStatus: `
|
|
544
|
+
+ `${payload.thermostatSetpointStatus}, Model: ${this.device.deviceModel}`);
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} send thermostatSetpointStatus: `
|
|
548
|
+
+ `${payload.thermostatSetpointStatus}, Model: ${this.device.deviceModel}`);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
switch (this.device.deviceModel) {
|
|
552
|
+
case 'Round':
|
|
553
|
+
case 'D6':
|
|
554
|
+
if (this.deviceLogging.includes('debug')) {
|
|
555
|
+
this.warnLog(`${this.device.deviceClass} ${this.accessory.displayName} set autoChangeoverActive, Model: ${this.device.deviceModel}`);
|
|
556
|
+
}
|
|
557
|
+
// for Round the 'Auto' feature is enabled via the special mode so only flip this bit when
|
|
558
|
+
// the heating/cooling state is set to `Auto
|
|
559
|
+
if (this.Thermostat.TargetHeatingCoolingState === this.hap.Characteristic.TargetHeatingCoolingState.AUTO) {
|
|
560
|
+
payload.autoChangeoverActive = true;
|
|
561
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Heating/Cooling state set to Auto for`
|
|
562
|
+
+ ` Model: ${this.device.deviceModel}, Force autoChangeoverActive: ${payload.autoChangeoverActive}`);
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
payload.autoChangeoverActive = this.device.changeableValues?.autoChangeoverActive;
|
|
566
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Heating/cooling state not set to Auto for`
|
|
567
|
+
+ ` Model: ${this.device.deviceModel}, Using device setting`
|
|
568
|
+
+ ` autoChangeoverActive: ${this.device.changeableValues.autoChangeoverActive}`);
|
|
569
|
+
}
|
|
570
|
+
break;
|
|
571
|
+
case 'Unknown':
|
|
572
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} do not send autoChangeoverActive, Model: ${this.device.deviceModel}`);
|
|
573
|
+
break;
|
|
574
|
+
default:
|
|
575
|
+
payload.autoChangeoverActive = this.device.changeableValues.autoChangeoverActive;
|
|
576
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} set autoChangeoverActive to ${this.device.changeableValues.autoChangeoverActive} for Model: ${this.device.deviceModel}`);
|
|
577
|
+
}
|
|
578
|
+
switch (this.device.deviceModel) {
|
|
579
|
+
case 'Unknown':
|
|
580
|
+
this.errorLog(JSON.stringify(this.device));
|
|
581
|
+
payload.thermostatSetpoint = toFahrenheit(Number(this.Thermostat.TargetTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
582
|
+
switch (this.device.units) {
|
|
583
|
+
case 'Fahrenheit':
|
|
584
|
+
payload.unit = 'Fahrenheit';
|
|
585
|
+
break;
|
|
586
|
+
case 'Celsius':
|
|
587
|
+
payload.unit = 'Celsius';
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
this.successLog(`${this.device.deviceClass} ${this.accessory.displayName} sent request to Resideo API thermostatSetpoint: ${payload.thermostatSetpoint}, unit: ${payload.unit}`);
|
|
591
|
+
break;
|
|
592
|
+
default:
|
|
593
|
+
// Set the heat and cool set point value based on the selected mode
|
|
594
|
+
switch (this.Thermostat.TargetHeatingCoolingState) {
|
|
595
|
+
case this.hap.Characteristic.TargetHeatingCoolingState.HEAT:
|
|
596
|
+
payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.TargetTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
597
|
+
payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
598
|
+
this.debugLog(`${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`);
|
|
599
|
+
break;
|
|
600
|
+
case this.hap.Characteristic.TargetHeatingCoolingState.COOL:
|
|
601
|
+
payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.TargetTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
602
|
+
payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
603
|
+
this.debugLog(`${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`);
|
|
604
|
+
break;
|
|
605
|
+
case this.hap.Characteristic.TargetHeatingCoolingState.AUTO:
|
|
606
|
+
payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
607
|
+
payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
608
|
+
this.debugLog(`${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`);
|
|
609
|
+
break;
|
|
610
|
+
default:
|
|
611
|
+
payload.coolSetpoint = toFahrenheit(Number(this.Thermostat.CoolingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
612
|
+
payload.heatSetpoint = toFahrenheit(Number(this.Thermostat.HeatingThresholdTemperature), Number(this.Thermostat.TemperatureDisplayUnits));
|
|
613
|
+
this.debugLog(`${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`);
|
|
614
|
+
}
|
|
615
|
+
this.successLog(`${this.device.deviceClass} ${this.accessory.displayName} set request (${JSON.stringify(payload)}) to Resideo API.`);
|
|
616
|
+
}
|
|
617
|
+
// Attempt to make the API request
|
|
618
|
+
await this.platform.axios.post(`${DeviceURL}/thermostats/${this.device.deviceID}`, payload, {
|
|
619
|
+
params: {
|
|
620
|
+
locationId: this.location.locationID,
|
|
621
|
+
},
|
|
622
|
+
});
|
|
623
|
+
const action = 'pushChanges';
|
|
624
|
+
await this.statusCode(200, action);
|
|
625
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} pushChanges: ${JSON.stringify(payload)}`);
|
|
626
|
+
await this.updateHomeKitCharacteristics();
|
|
627
|
+
}
|
|
628
|
+
catch (e) {
|
|
629
|
+
const action = 'pushChanges';
|
|
630
|
+
if (this.device.retry) {
|
|
631
|
+
// Refresh the status from the API
|
|
632
|
+
interval(5000)
|
|
633
|
+
.pipe(skipWhile(() => this.thermostatUpdateInProgress))
|
|
634
|
+
.pipe(take(1))
|
|
635
|
+
.subscribe(async () => {
|
|
636
|
+
await this.pushChanges();
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
this.resideoAPIError(e, action);
|
|
640
|
+
this.apiError(e);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
async ResideoMode() {
|
|
644
|
+
let resideoMode;
|
|
645
|
+
switch (this.Thermostat.TargetHeatingCoolingState) {
|
|
646
|
+
case this.hap.Characteristic.TargetHeatingCoolingState.HEAT:
|
|
647
|
+
resideoMode = ResideoModes.Heat;
|
|
648
|
+
break;
|
|
649
|
+
case this.hap.Characteristic.TargetHeatingCoolingState.COOL:
|
|
650
|
+
resideoMode = ResideoModes.Cool;
|
|
651
|
+
break;
|
|
652
|
+
case this.hap.Characteristic.TargetHeatingCoolingState.AUTO:
|
|
653
|
+
resideoMode = ResideoModes.Auto;
|
|
654
|
+
break;
|
|
655
|
+
case this.hap.Characteristic.TargetHeatingCoolingState.OFF:
|
|
656
|
+
resideoMode = ResideoModes.Off;
|
|
657
|
+
break;
|
|
658
|
+
default:
|
|
659
|
+
resideoMode = 'Unknown';
|
|
660
|
+
this.debugErrorLog(`${this.device.deviceClass} ${this.accessory.displayName} Unknown TargetHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
|
|
661
|
+
}
|
|
662
|
+
return resideoMode;
|
|
663
|
+
}
|
|
664
|
+
async pushChangesthermostatSetpointStatus() {
|
|
665
|
+
if (this.thermostatSetpointStatus) {
|
|
666
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} thermostatSetpointStatus config set to ${this.thermostatSetpointStatus}`);
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
this.thermostatSetpointStatus = 'PermanentHold';
|
|
670
|
+
this.accessory.context.thermostatSetpointStatus = this.thermostatSetpointStatus;
|
|
671
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} thermostatSetpointStatus config not set`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Pushes the requested changes for Room Priority to the Resideo API
|
|
676
|
+
*/
|
|
677
|
+
async pushRoomChanges() {
|
|
678
|
+
this.debugLog(`Thermostat Room Priority for ${this.accessory.displayName}
|
|
679
|
+
Current Room: ${JSON.stringify(this.roomPriorityStatus.currentPriority.selectedRooms)},
|
|
680
|
+
Changing Room: [${this.device.inBuiltSensorState.roomId}]`);
|
|
681
|
+
if (`[${this.device.inBuiltSensorState.roomId}]` !== `[${this.roomPriorityStatus.currentPriority.selectedRooms}]`) {
|
|
682
|
+
const payload = {
|
|
683
|
+
currentPriority: {
|
|
684
|
+
priorityType: this.device.thermostat?.roompriority?.priorityType,
|
|
685
|
+
},
|
|
686
|
+
};
|
|
687
|
+
if (this.device.thermostat?.roompriority?.priorityType === 'PickARoom') {
|
|
688
|
+
payload.currentPriority.selectedRooms = [this.device.inBuiltSensorState.roomId];
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* For "LCC-" devices only.
|
|
692
|
+
* "NoHold" will return to schedule.
|
|
693
|
+
* "TemporaryHold" will hold the set temperature until next schedule.
|
|
694
|
+
* "PermanentHold" will hold the setpoint until user requests another change.
|
|
695
|
+
*/
|
|
696
|
+
if (this.device.thermostat?.roompriority?.deviceType === 'Thermostat') {
|
|
697
|
+
if (this.device.priorityType === 'FollowMe') {
|
|
698
|
+
this.successLog(`Sending request for ${this.accessory.displayName} to Resideo API Priority Type: ${this.device.priorityType}, Built-in Occupancy Sensor(s) Will be used to set Priority Automatically`);
|
|
699
|
+
}
|
|
700
|
+
else if (this.device.priorityType === 'WholeHouse') {
|
|
701
|
+
this.successLog(`Sending request for ${this.accessory.displayName} to Resideo API Priority Type:` + ` ${this.device.priorityType}`);
|
|
702
|
+
}
|
|
703
|
+
else if (this.device.priorityType === 'PickARoom') {
|
|
704
|
+
this.successLog(`Sending request for ${this.accessory.displayName} to Resideo API Room Priority: ${this.device.inBuiltSensorState.roomName}, Priority Type: ${this.device.thermostat?.roompriority.priorityType}`);
|
|
705
|
+
}
|
|
706
|
+
// Make the API request
|
|
707
|
+
await this.platform.axios.put(`${DeviceURL}/thermostats/${this.device.deviceID}/priority`, payload, {
|
|
708
|
+
params: {
|
|
709
|
+
locationId: this.location.locationID,
|
|
710
|
+
},
|
|
711
|
+
});
|
|
712
|
+
const action = 'pushRoomChanges';
|
|
713
|
+
await this.statusCode(200, action);
|
|
714
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} pushRoomChanges: ${JSON.stringify(payload)}`);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Updates the status for each of the HomeKit Characteristics
|
|
720
|
+
*/
|
|
721
|
+
async updateHomeKitCharacteristics() {
|
|
722
|
+
if (this.Thermostat.TemperatureDisplayUnits === undefined) {
|
|
723
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
727
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic TemperatureDisplayUnits: ${this.Thermostat.TemperatureDisplayUnits}`);
|
|
728
|
+
}
|
|
729
|
+
if (this.Thermostat.CurrentTemperature === undefined) {
|
|
730
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} CurrentTemperature: ${this.Thermostat.CurrentTemperature}`);
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.Thermostat.CurrentTemperature);
|
|
734
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.Thermostat.CurrentTemperature}`);
|
|
735
|
+
}
|
|
736
|
+
if (this.Thermostat.TargetTemperature === undefined) {
|
|
737
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} TargetTemperature: ${this.Thermostat.TargetTemperature}`);
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetTemperature, this.Thermostat.TargetTemperature);
|
|
741
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic TargetTemperature: ${this.Thermostat.TargetTemperature}`);
|
|
742
|
+
}
|
|
743
|
+
if (this.Thermostat.HeatingThresholdTemperature === undefined) {
|
|
744
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} HeatingThresholdTemperature: ${this.Thermostat.HeatingThresholdTemperature}`);
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.HeatingThresholdTemperature, this.Thermostat.HeatingThresholdTemperature);
|
|
748
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic HeatingThresholdTemperature: ${this.Thermostat.HeatingThresholdTemperature}`);
|
|
749
|
+
}
|
|
750
|
+
if (this.Thermostat.CoolingThresholdTemperature === undefined) {
|
|
751
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} CoolingThresholdTemperature: ${this.Thermostat.CoolingThresholdTemperature}`);
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CoolingThresholdTemperature, this.Thermostat.CoolingThresholdTemperature);
|
|
755
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CoolingThresholdTemperature: ${this.Thermostat.CoolingThresholdTemperature}`);
|
|
756
|
+
}
|
|
757
|
+
if (this.Thermostat.TargetHeatingCoolingState === undefined) {
|
|
758
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} TargetHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetHeatingCoolingState, this.Thermostat.TargetHeatingCoolingState);
|
|
762
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic TargetHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
|
|
763
|
+
}
|
|
764
|
+
if (this.Thermostat.CurrentHeatingCoolingState === undefined) {
|
|
765
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} CurrentHeatingCoolingState: ${this.Thermostat.CurrentHeatingCoolingState}`);
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentHeatingCoolingState, this.Thermostat.CurrentHeatingCoolingState);
|
|
769
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CurrentHeatingCoolingState: ${this.Thermostat.TargetHeatingCoolingState}`);
|
|
770
|
+
}
|
|
771
|
+
if (!this.device.thermostat?.hide_humidity) {
|
|
772
|
+
if (this.device.indoorHumidity) {
|
|
773
|
+
if (this.HumiditySensor?.CurrentRelativeHumidity === undefined) {
|
|
774
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} CurrentRelativeHumidity: ${this.HumiditySensor?.CurrentRelativeHumidity}`);
|
|
775
|
+
}
|
|
776
|
+
else {
|
|
777
|
+
this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.HumiditySensor.CurrentRelativeHumidity);
|
|
778
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
if (!this.device.thermostat?.hide_fan) {
|
|
783
|
+
if (this.device.settings?.fan) {
|
|
784
|
+
if (this.Fan?.TargetFanState === undefined) {
|
|
785
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Fan TargetFanState: ${this.Fan?.TargetFanState}`);
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
this.Fan.Service.updateCharacteristic(this.hap.Characteristic.TargetFanState, this.Fan.TargetFanState);
|
|
789
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Fan updateCharacteristic TargetFanState: ${this.Fan.TargetFanState}`);
|
|
790
|
+
}
|
|
791
|
+
if (this.Fan?.Active === undefined) {
|
|
792
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Fan Active: ${this.Fan?.Active}`);
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
this.Fan.Service.updateCharacteristic(this.hap.Characteristic.Active, this.Fan.Active);
|
|
796
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Fan updateCharacteristic Active: ${this.Fan.Active}`);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
async apiError(e) {
|
|
802
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits, e);
|
|
803
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
|
|
804
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetTemperature, e);
|
|
805
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.HeatingThresholdTemperature, e);
|
|
806
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CoolingThresholdTemperature, e);
|
|
807
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetHeatingCoolingState, e);
|
|
808
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.CurrentHeatingCoolingState, e);
|
|
809
|
+
if (!this.device.thermostat?.hide_humidity) {
|
|
810
|
+
if (this.device.indoorHumidity) {
|
|
811
|
+
this.HumiditySensor?.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (!this.device.thermostat?.hide_fan) {
|
|
815
|
+
if (this.device.settings?.fan) {
|
|
816
|
+
this.Fan?.Service.updateCharacteristic(this.hap.Characteristic.TargetFanState, e);
|
|
817
|
+
this.Fan?.Service.updateCharacteristic(this.hap.Characteristic.Active, e);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
async getThermostatConfigSettings(accessory, device) {
|
|
822
|
+
if (this.thermostatSetpointStatus === undefined) {
|
|
823
|
+
accessory.context.thermostatSetpointStatus = device.thermostat?.thermostatSetpointStatus;
|
|
824
|
+
this.thermostatSetpointStatus = accessory.context.thermostatSetpointStatus;
|
|
825
|
+
this.debugLog(`${device.deviceClass} ${accessory.displayName} thermostatSetpointStatus: ${this.thermostatSetpointStatus}`);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
async setTargetHeatingCoolingState(value) {
|
|
829
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set TargetHeatingCoolingState: ${value}`);
|
|
830
|
+
this.Thermostat.TargetHeatingCoolingState = value;
|
|
831
|
+
// Set the TargetTemperature value based on the selected mode
|
|
832
|
+
if (this.Thermostat.TargetHeatingCoolingState === this.hap.Characteristic.TargetHeatingCoolingState.HEAT) {
|
|
833
|
+
this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.heatSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
834
|
+
}
|
|
835
|
+
else {
|
|
836
|
+
this.Thermostat.TargetTemperature = toCelsius(this.device.changeableValues.coolSetpoint, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
837
|
+
}
|
|
838
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TargetTemperature, this.Thermostat.TargetTemperature);
|
|
839
|
+
if (this.device.thermostat?.roompriority?.deviceType === 'Thermostat' && this.device.deviceModel === 'T9-T10') {
|
|
840
|
+
this.doRoomUpdate.next();
|
|
841
|
+
}
|
|
842
|
+
if (this.Thermostat.TargetHeatingCoolingState !== HomeKitModes[this.device.changeableValues.mode]) {
|
|
843
|
+
this.doThermostatUpdate.next();
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
async setHeatingThresholdTemperature(value) {
|
|
847
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set HeatingThresholdTemperature: ${value}`);
|
|
848
|
+
this.Thermostat.HeatingThresholdTemperature = value;
|
|
849
|
+
this.doThermostatUpdate.next();
|
|
850
|
+
}
|
|
851
|
+
async setCoolingThresholdTemperature(value) {
|
|
852
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set CoolingThresholdTemperature: ${value}`);
|
|
853
|
+
this.Thermostat.CoolingThresholdTemperature = value;
|
|
854
|
+
this.doThermostatUpdate.next();
|
|
855
|
+
}
|
|
856
|
+
async setTargetTemperature(value) {
|
|
857
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set TargetTemperature: ${value}`);
|
|
858
|
+
this.Thermostat.TargetTemperature = value;
|
|
859
|
+
this.doThermostatUpdate.next();
|
|
860
|
+
}
|
|
861
|
+
async setTemperatureDisplayUnits(value) {
|
|
862
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set TemperatureDisplayUnits: ${value}`);
|
|
863
|
+
this.warnLog('Changing the Hardware Display Units from HomeKit is not supported.');
|
|
864
|
+
this.Thermostat.TemperatureDisplayUnits = this.device.units === 'Celsius'
|
|
865
|
+
? this.hap.Characteristic.TemperatureDisplayUnits.CELSIUS
|
|
866
|
+
: this.hap.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
|
|
867
|
+
// change the temp units back to the one the Resideo API said the thermostat was set to
|
|
868
|
+
setTimeout(() => {
|
|
869
|
+
this.Thermostat.Service.updateCharacteristic(this.hap.Characteristic.TemperatureDisplayUnits, Number(this.Thermostat.TemperatureDisplayUnits));
|
|
870
|
+
}, 100);
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Handle requests to set the "Programmable Switch Output State" characteristic
|
|
874
|
+
*/
|
|
875
|
+
handleProgrammableSwitchOutputStateSet(value) {
|
|
876
|
+
this.debugLog('Triggered SET ProgrammableSwitchOutputState:', value);
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Pushes the requested changes for Fan to the Resideo API
|
|
880
|
+
*/
|
|
881
|
+
async pushFanChanges() {
|
|
882
|
+
let payload = {
|
|
883
|
+
mode: 'Auto', // default to Auto
|
|
884
|
+
};
|
|
885
|
+
if (this.device.settings?.fan && !this.device.thermostat?.hide_fan) {
|
|
886
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} TargetFanState: ${this.Fan?.TargetFanState}, Active: ${this.Fan?.Active}`);
|
|
887
|
+
if (this.Fan?.TargetFanState === this.hap.Characteristic.TargetFanState.AUTO) {
|
|
888
|
+
payload = {
|
|
889
|
+
mode: 'Auto',
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
else if (this.Fan?.TargetFanState === this.hap.Characteristic.TargetFanState.MANUAL
|
|
893
|
+
&& this.Fan?.Active === this.hap.Characteristic.Active.ACTIVE) {
|
|
894
|
+
payload = {
|
|
895
|
+
mode: 'On',
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
else if (this.Fan?.TargetFanState === this.hap.Characteristic.TargetFanState.MANUAL
|
|
899
|
+
&& this.Fan?.Active === this.hap.Characteristic.Active.INACTIVE) {
|
|
900
|
+
payload = {
|
|
901
|
+
mode: 'Circulate',
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
this.successLog(`Sending request for ${this.accessory.displayName} to Resideo API Fan Mode: ${payload.mode}`);
|
|
905
|
+
// Make the API request
|
|
906
|
+
await this.platform.axios.post(`${DeviceURL}/thermostats/${this.device.deviceID}/fan`, payload, {
|
|
907
|
+
params: {
|
|
908
|
+
locationId: this.location.locationID,
|
|
909
|
+
},
|
|
910
|
+
});
|
|
911
|
+
const action = 'pushFanChanges';
|
|
912
|
+
await this.statusCode(200, action);
|
|
913
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} pushChanges: ${JSON.stringify(payload)}`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* Updates the status for each of the HomeKit Characteristics
|
|
918
|
+
*/
|
|
919
|
+
async setActive(value) {
|
|
920
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set Active: ${value}`);
|
|
921
|
+
this.Fan.Active = value;
|
|
922
|
+
this.doFanUpdate.next();
|
|
923
|
+
}
|
|
924
|
+
async setTargetFanState(value) {
|
|
925
|
+
this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set TargetFanState: ${value}`);
|
|
926
|
+
this.Fan.TargetFanState = value;
|
|
927
|
+
this.doFanUpdate.next();
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
//# sourceMappingURL=thermostats.js.map
|