homebridge-melcloud-control 3.5.0 → 3.5.2
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/index.js +5 -5
- package/package.json +2 -2
- package/src/deviceata.js +725 -724
- package/src/deviceatw.js +1670 -1669
- package/src/deviceerv.js +1002 -1001
- package/src/impulsegenerator.js +14 -13
package/src/deviceerv.js
CHANGED
|
@@ -94,649 +94,156 @@ class DeviceErv extends EventEmitter {
|
|
|
94
94
|
this.accessory.temperatureUnit = TemperatureDisplayUnits[this.accessory.useFahrenheit];
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
-
async
|
|
97
|
+
async setOverExternalIntegration(integration, deviceData, key, value) {
|
|
98
98
|
try {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
99
|
+
let set = false
|
|
100
|
+
switch (key) {
|
|
101
|
+
case 'Power':
|
|
102
|
+
deviceData.Device[key] = value;
|
|
103
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
104
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
105
|
+
break;
|
|
106
|
+
case 'OperationMode':
|
|
107
|
+
deviceData.Device[key] = value;
|
|
108
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.OperationMode;
|
|
109
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
110
|
+
break;
|
|
111
|
+
case 'VentilationMode':
|
|
112
|
+
deviceData.Device[key] = value;
|
|
113
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.VentilationMode;
|
|
114
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
115
|
+
break;
|
|
116
|
+
case 'SetTemperature':
|
|
117
|
+
deviceData.Device[key] = value;
|
|
118
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetTemperature;
|
|
119
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
120
|
+
break;
|
|
121
|
+
case 'DefaultCoolingSetTemperature':
|
|
122
|
+
deviceData.Device[key] = value;
|
|
123
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetTemperature;
|
|
124
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
125
|
+
break;
|
|
126
|
+
case 'DefaultHeatingSetTemperature':
|
|
127
|
+
deviceData.Device[key] = value;
|
|
128
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetTemperature;
|
|
129
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
130
|
+
break;
|
|
131
|
+
case 'NightPurgeMode':
|
|
132
|
+
deviceData.Device[key] = value;
|
|
133
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.NightPurgeMode;
|
|
134
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
135
|
+
break;
|
|
136
|
+
case 'SetFanSpeed':
|
|
137
|
+
deviceData.Device[key] = value;
|
|
138
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetFanSpeed;
|
|
139
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
140
|
+
break;
|
|
141
|
+
case 'HideRoomTemperature':
|
|
142
|
+
deviceData[key] = value;
|
|
143
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
144
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
145
|
+
break;
|
|
146
|
+
case 'HideSupplyTemperature':
|
|
147
|
+
deviceData[key] = value;
|
|
148
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
149
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
150
|
+
break;
|
|
151
|
+
case 'HideOutdoorTemperature':
|
|
152
|
+
deviceData[key] = value;
|
|
153
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
154
|
+
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
this.emit('warn', `${integration}, received key: ${key}, value: ${value}`);
|
|
158
|
+
break;
|
|
159
|
+
};
|
|
160
|
+
return set;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
throw new Error(`${integration} set key: ${key}, value: ${value}, error: ${error.message ?? error}`);
|
|
163
|
+
};
|
|
164
|
+
}
|
|
153
165
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
this.emit('debug', debug);
|
|
170
|
-
})
|
|
171
|
-
.on('error', (error) => {
|
|
172
|
-
this.emit('warn', error);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
const mqtt0 = this.mqttConnected ? this.mqtt1.emit('publish', `Info`, deviceData) : false;
|
|
176
|
-
const mqtt1 = this.mqttConnected ? this.mqtt1.emit('publish', `State`, deviceData.Device) : false;
|
|
177
|
-
}
|
|
178
|
-
} catch (error) {
|
|
179
|
-
this.emit('warn', `External integration start error: ${error}.`);
|
|
180
|
-
};
|
|
181
|
-
})
|
|
182
|
-
.on('deviceInfo', (manufacturer, modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
183
|
-
if (!this.displayDeviceInfo) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
166
|
+
//prepare accessory
|
|
167
|
+
async prepareAccessory(accountInfo, deviceData, deviceId, deviceTypeText, deviceName, accountName) {
|
|
168
|
+
try {
|
|
169
|
+
const presetsOnServer = this.accessory.presets;
|
|
170
|
+
const hasRoomTemperature = this.accessory.hasRoomTemperature;
|
|
171
|
+
const hasSupplyTemperature = this.accessory.hasSupplyTemperature;
|
|
172
|
+
const hasOutdoorTemperature = this.accessory.hasOutdoorTemperature;
|
|
173
|
+
const hasCoolOperationMode = this.accessory.hasCoolOperationMode;
|
|
174
|
+
const hasHeatOperationMode = this.accessory.hasHeatOperationMode;
|
|
175
|
+
const hasAutoVentilationMode = this.accessory.hasAutoVentilationMode;
|
|
176
|
+
const hasBypassVentilationMode = this.accessory.hasBypassVentilationMode;
|
|
177
|
+
const hasAutomaticFanSpeed = this.accessory.hasAutomaticFanSpeed;
|
|
178
|
+
const hasCO2Sensor = this.accessory.hasCO2Sensor;
|
|
179
|
+
const hasPM25Sensor = this.accessory.hasPM25Sensor;
|
|
180
|
+
const numberOfFanSpeeds = this.accessory.numberOfFanSpeeds;
|
|
186
181
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
this.emit('devInfo', `Firmware: ${firmwareAppVersion}`);
|
|
194
|
-
this.emit('devInfo', `Manufacturer: ${manufacturer}`);
|
|
195
|
-
this.emit('devInfo', '----------------------------------');
|
|
196
|
-
};
|
|
182
|
+
//accessory
|
|
183
|
+
const debug = this.enableDebugMode ? this.emit('debug', `Prepare accessory`) : false;
|
|
184
|
+
const accessoryName = deviceName;
|
|
185
|
+
const accessoryUUID = AccessoryUUID.generate(accountName + deviceId.toString());
|
|
186
|
+
const accessoryCategory = Categories.AIR_PURIFIER;
|
|
187
|
+
const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
|
|
197
188
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
.
|
|
206
|
-
//presets
|
|
207
|
-
const presetsOnServer = deviceData.Presets ?? [];
|
|
189
|
+
//information service
|
|
190
|
+
const debug1 = this.enableDebugMode ? this.emit('debug', `Prepare information service`) : false;
|
|
191
|
+
accessory.getService(Service.AccessoryInformation)
|
|
192
|
+
.setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
|
|
193
|
+
.setCharacteristic(Characteristic.Model, this.model)
|
|
194
|
+
.setCharacteristic(Characteristic.SerialNumber, this.serialNumber)
|
|
195
|
+
.setCharacteristic(Characteristic.FirmwareRevision, this.firmwareRevision)
|
|
196
|
+
.setCharacteristic(Characteristic.ConfiguredName, accessoryName);
|
|
208
197
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
this.accessory.hasOutdoorTemperature = hasOutdoorTemperature;
|
|
259
|
-
this.accessory.hasCoolOperationMode = hasCoolOperationMode;
|
|
260
|
-
this.accessory.hasHeatOperationMode = hasHeatOperationMode;
|
|
261
|
-
this.accessory.hasCO2Sensor = hasCO2Sensor;
|
|
262
|
-
this.accessory.roomCO2Level = roomCO2Level;
|
|
263
|
-
this.accessory.roomCO2Detected = roomCO2Detected;
|
|
264
|
-
this.accessory.hasPM25Sensor = hasPM25Sensor;
|
|
265
|
-
this.accessory.pM25SensorStatus = pM25SensorStatus;
|
|
266
|
-
this.accessory.pM25Level = pM25Level;
|
|
267
|
-
this.accessory.pM25AirQuality = pM25AirQuality;
|
|
268
|
-
this.accessory.hasAutoVentilationMode = hasAutoVentilationMode;
|
|
269
|
-
this.accessory.hasBypassVentilationMode = hasBypassVentilationMode;
|
|
270
|
-
this.accessory.hasAutomaticFanSpeed = hasAutomaticFanSpeed;
|
|
271
|
-
this.accessory.coreMaintenanceRequired = coreMaintenanceRequired;
|
|
272
|
-
this.accessory.filterMaintenanceRequired = filterMaintenanceRequired;
|
|
273
|
-
this.accessory.actualVentilationMode = actualVentilationMode;
|
|
274
|
-
this.accessory.numberOfFanSpeeds = numberOfFanSpeeds;
|
|
275
|
-
this.accessory.power = power ? 1 : 0;
|
|
276
|
-
this.accessory.operationMode = operationMode;
|
|
277
|
-
this.accessory.ventilationMode = ventilationMode;
|
|
278
|
-
this.accessory.roomTemperature = roomTemperature;
|
|
279
|
-
this.accessory.supplyTemperature = supplyTemperature;
|
|
280
|
-
this.accessory.outdoorTemperature = outdoorTemperature;
|
|
281
|
-
this.accessory.setTemperature = setTemperature;
|
|
282
|
-
this.accessory.defaultHeatingSetTemperature = defaultHeatingSetTemperature;
|
|
283
|
-
this.accessory.defaultCoolingSetTemperature = defaultCoolingSetTemperature;
|
|
284
|
-
this.accessory.lockPhysicalControl = 0;
|
|
285
|
-
this.accessory.temperatureIncrement = temperatureIncrement;
|
|
286
|
-
this.accessory.minTempHeat = minTempHeat;
|
|
287
|
-
this.accessory.temperatureIncrement = maxTempHeat;
|
|
288
|
-
this.accessory.minTempCoolDry = minTempCoolDry;
|
|
289
|
-
this.accessory.maxTempCoolDry = maxTempCoolDry;
|
|
290
|
-
|
|
291
|
-
//ventilation mode - 0, HEAT, 2, COOL, 4, 5, 6, FAN, AUTO
|
|
292
|
-
switch (this.displayMode) {
|
|
293
|
-
case 1: //Heater Cooler
|
|
294
|
-
switch (ventilationMode) {
|
|
295
|
-
case 0: //LOSSNAY
|
|
296
|
-
this.accessory.currentOperationMode = 2; //INACTIVE, IDLE, HEATING, COOLIN
|
|
297
|
-
this.accessory.targetOperationMode = 1; //AUTO, HEAT, COOL
|
|
298
|
-
break;
|
|
299
|
-
case 1: //BYPASS
|
|
300
|
-
this.accessory.currentOperationMode = 3;
|
|
301
|
-
this.accessory.targetOperationMode = 2;
|
|
302
|
-
break;
|
|
303
|
-
case 2: //AUTO
|
|
304
|
-
switch (actualVentilationMode) {
|
|
305
|
-
case 0: //LOSSNAY
|
|
306
|
-
this.accessory.currentOperationMode = 2;
|
|
307
|
-
break;
|
|
308
|
-
case 1: //BYPASS
|
|
309
|
-
this.accessory.currentOperationMode = 3;
|
|
310
|
-
break;
|
|
311
|
-
default:
|
|
312
|
-
this.emit('warn', `Unknown actual ventilation mode: ${actualVentilationMode}`);
|
|
313
|
-
break;
|
|
314
|
-
};
|
|
315
|
-
this.accessory.targetOperationMode = 0;
|
|
316
|
-
break;
|
|
317
|
-
default:
|
|
318
|
-
this.emit('warn', `Unknown ventilation mode: ${ventilationMode}`);
|
|
319
|
-
break;
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
this.accessory.currentOperationMode = !power ? 0 : this.accessory.currentOperationMode;
|
|
323
|
-
this.accessory.operationModeSetPropsMinValue = hasAutoVentilationMode ? 0 : 1;
|
|
324
|
-
this.accessory.operationModeSetPropsMaxValue = hasAutoVentilationMode ? 2 : 2;
|
|
325
|
-
this.accessory.operationModeSetPropsValidValues = hasAutoVentilationMode ? (hasBypassVentilationMode ? [0, 1, 2] : [0, 2]) : (hasBypassVentilationMode ? [1, 2] : [2]);
|
|
326
|
-
|
|
327
|
-
//fan speed mode
|
|
328
|
-
this.accessory.fanSpeedSetPropsMaxValue = 2;
|
|
329
|
-
switch (numberOfFanSpeeds) {
|
|
330
|
-
case 2: //Fan speed mode 2
|
|
331
|
-
this.accessory.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][setFanSpeed] : [0, 1, 2][setFanSpeed];
|
|
332
|
-
this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
|
|
333
|
-
break;
|
|
334
|
-
case 3: //Fan speed mode 3
|
|
335
|
-
this.this.accessory.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][setFanSpeed] : [0, 1, 2, 3][setFanSpeed];
|
|
336
|
-
this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
|
|
337
|
-
break;
|
|
338
|
-
case 4: //Fan speed mode 4
|
|
339
|
-
this.accessory.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][setFanSpeed] : [0, 1, 2, 3, 4][setFanSpeed];
|
|
340
|
-
this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
|
|
341
|
-
break;
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
//update characteristics
|
|
345
|
-
if (this.melCloudService) {
|
|
346
|
-
this.melCloudService
|
|
347
|
-
.updateCharacteristic(Characteristic.Active, power)
|
|
348
|
-
.updateCharacteristic(Characteristic.CurrentHeaterCoolerState, this.accessory.currentOperationMode)
|
|
349
|
-
.updateCharacteristic(Characteristic.TargetHeaterCoolerState, this.accessory.targetOperationMode)
|
|
350
|
-
.updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
|
|
351
|
-
.updateCharacteristic(Characteristic.RotationSpeed, this.accessory.fanSpeed)
|
|
352
|
-
.updateCharacteristic(Characteristic.LockPhysicalControls, this.accessory.lockPhysicalControl)
|
|
353
|
-
.updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit);
|
|
354
|
-
const updateDefCool = hasCoolOperationMode ? this.melCloudService.updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature) : false;
|
|
355
|
-
const updateDefHeat = hasHeatOperationMode ? this.melCloudService.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
|
|
356
|
-
};
|
|
357
|
-
break;
|
|
358
|
-
case 2: //Thermostat
|
|
359
|
-
//operation mode - 0, HEAT, 2, COOL, 4, 5, 6, FAN, AUTO
|
|
360
|
-
switch (ventilationMode) {
|
|
361
|
-
case 0: //LOSSNAY
|
|
362
|
-
this.accessory.currentOperationMode = 1; //OFF, HEAT, COOL
|
|
363
|
-
this.accessory.targetOperationMode = 1; //OFF, HEAT, COOL, AUTO
|
|
364
|
-
break;
|
|
365
|
-
case 1: //BYPASS
|
|
366
|
-
this.accessory.currentOperationMode = 2;
|
|
367
|
-
this.accessory.targetOperationMode = 2;
|
|
368
|
-
break;
|
|
369
|
-
case 2: //AUTO
|
|
370
|
-
switch (actualVentilationMode) {
|
|
371
|
-
case 0: //LOSSNAY
|
|
372
|
-
this.accessory.currentOperationMode = 1;
|
|
373
|
-
break;
|
|
374
|
-
case 1: //BYPASS
|
|
375
|
-
this.accessory.currentOperationMode = 2;
|
|
376
|
-
break;
|
|
377
|
-
default:
|
|
378
|
-
this.emit('warn', `Unknown actual ventilation mode: ${actualVentilationMode}`);
|
|
379
|
-
break;
|
|
380
|
-
};
|
|
381
|
-
this.accessory.targetOperationMode = 3;
|
|
382
|
-
break;
|
|
383
|
-
default:
|
|
384
|
-
this.emit('warn', `Unknown ventilation mode: ${ventilationMode}`);
|
|
385
|
-
break;
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
this.accessory.currentOperationMode = !power ? 0 : this.accessory.currentOperationMode;
|
|
389
|
-
this.accessory.targetOperationMode = !power ? 0 : this.accessory.targetOperationMode;
|
|
390
|
-
this.accessory.operationModeSetPropsMinValue = hasAutoVentilationMode ? 0 : 0;
|
|
391
|
-
this.accessory.operationModeSetPropsMaxValue = hasAutoVentilationMode ? 3 : 2;
|
|
392
|
-
this.accessory.operationModeSetPropsValidValues = hasAutoVentilationMode ? (hasBypassVentilationMode ? [0, 1, 2, 3] : [0, 2, 3]) : (hasBypassVentilationMode ? [0, 1, 2] : [0, 2]);
|
|
393
|
-
|
|
394
|
-
//update characteristics
|
|
395
|
-
if (this.melCloudService) {
|
|
396
|
-
this.melCloudService
|
|
397
|
-
.updateCharacteristic(Characteristic.CurrentHeatingCoolingState, this.accessory.currentOperationMode)
|
|
398
|
-
.updateCharacteristic(Characteristic.TargetHeatingCoolingState, this.accessory.targetOperationMode)
|
|
399
|
-
.updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
|
|
400
|
-
.updateCharacteristic(Characteristic.TargetTemperature, setTemperature)
|
|
401
|
-
.updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit);
|
|
402
|
-
};
|
|
403
|
-
break;
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
//update temperature sensors
|
|
407
|
-
if (this.roomTemperatureSensorService) {
|
|
408
|
-
this.roomTemperatureSensorService
|
|
409
|
-
.updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
if (this.outdoorTemperatureSensorService) {
|
|
413
|
-
this.outdoorTemperatureSensorService
|
|
414
|
-
.updateCharacteristic(Characteristic.CurrentTemperature, outdoorTemperature)
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
if (this.supplyTemperatureSensorService) {
|
|
418
|
-
this.supplyTemperatureSensorService
|
|
419
|
-
.updateCharacteristic(Characteristic.CurrentTemperature, supplyTemperature)
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
//update core maintenance
|
|
423
|
-
if (this.coreMaintenanceService) {
|
|
424
|
-
this.coreMaintenanceService
|
|
425
|
-
.updateCharacteristic(Characteristic.FilterChangeIndication, coreMaintenanceRequired)
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
//update filter maintenance
|
|
429
|
-
if (this.filterMaintenanceService) {
|
|
430
|
-
this.filterMaintenanceService
|
|
431
|
-
.updateCharacteristic(Characteristic.FilterChangeIndication, filterMaintenanceRequired)
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
//update CO2 sensor
|
|
435
|
-
if (this.carbonDioxideSensorService) {
|
|
436
|
-
this.carbonDioxideSensorService
|
|
437
|
-
.updateCharacteristic(Characteristic.CarbonDioxideDetected, roomCO2Detected)
|
|
438
|
-
.updateCharacteristic(Characteristic.CarbonDioxideLevel, roomCO2Level)
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
//update PM2.5 sensor
|
|
442
|
-
if (this.airQualitySensorService) {
|
|
443
|
-
this.airQualitySensorService
|
|
444
|
-
.updateCharacteristic(Characteristic.AirQuality, pM25AirQuality)
|
|
445
|
-
.updateCharacteristic(Characteristic.PM2_5Density, pM25Level)
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
//update presets state
|
|
449
|
-
if (this.presetsConfigured.length > 0) {
|
|
450
|
-
for (let i = 0; i < this.presetsConfigured.length; i++) {
|
|
451
|
-
const preset = this.presetsConfigured[i];
|
|
452
|
-
const presetData = presetsOnServer.find(p => p.ID === preset.Id);
|
|
453
|
-
|
|
454
|
-
preset.state = presetData ? (presetData.Power === power
|
|
455
|
-
&& presetData.SetTemperature === setTemperature
|
|
456
|
-
&& presetData.OperationMode === operationMode
|
|
457
|
-
&& presetData.VentilationMode === ventilationMode
|
|
458
|
-
&& presetData.FanSpeed === setFanSpeed) : false;
|
|
459
|
-
|
|
460
|
-
if (this.presetsServices) {
|
|
461
|
-
const characteristicType = preset.characteristicType;
|
|
462
|
-
this.presetsServices[i]
|
|
463
|
-
.updateCharacteristic(characteristicType, preset.state)
|
|
464
|
-
};
|
|
465
|
-
};
|
|
466
|
-
};
|
|
467
|
-
|
|
468
|
-
//update buttons state
|
|
469
|
-
if (this.buttonsConfiguredCount > 0) {
|
|
470
|
-
for (let i = 0; i < this.buttonsConfiguredCount; i++) {
|
|
471
|
-
const button = this.buttonsConfigured[i];
|
|
472
|
-
const mode = button.mode;;
|
|
473
|
-
switch (mode) {
|
|
474
|
-
case 0: //POWER ON,OFF
|
|
475
|
-
button.state = (power === true);
|
|
476
|
-
break;
|
|
477
|
-
case 1: //OPERATION MODE RECOVERY
|
|
478
|
-
button.state = power ? (ventilationMode === 0) : false;
|
|
479
|
-
break;
|
|
480
|
-
case 2: //OPERATION MODE BYPASS
|
|
481
|
-
button.state = power ? (ventilationMode === 1) : false;
|
|
482
|
-
break;
|
|
483
|
-
case 3: //OPERATION MODE AUTO
|
|
484
|
-
button.state = power ? (ventilationMode === 2) : false;
|
|
485
|
-
break;
|
|
486
|
-
case 4: //NIGHT PURGE MODE
|
|
487
|
-
button.state = power ? (nightPurgeMode === true) : false;
|
|
488
|
-
break;
|
|
489
|
-
case 10: //FAN SPEED MODE AUTO
|
|
490
|
-
button.state = power ? (setFanSpeed === 0) : false;
|
|
491
|
-
break;
|
|
492
|
-
case 11: //FAN SPEED MODE 1
|
|
493
|
-
button.state = power ? (setFanSpeed === 1) : false;
|
|
494
|
-
break;
|
|
495
|
-
case 12: //FAN SPEED MODE 2
|
|
496
|
-
button.state = power ? (setFanSpeed === 2) : false;
|
|
497
|
-
break;
|
|
498
|
-
case 13: //FAN SPEED MODE 3
|
|
499
|
-
button.state = power ? (setFanSpeed === 3) : false;
|
|
500
|
-
break;
|
|
501
|
-
case 14: //FAN SPEED MODE 4
|
|
502
|
-
button.state = power ? (setFanSpeed === 4) : false;
|
|
503
|
-
break;
|
|
504
|
-
case 15: //PHYSICAL LOCK CONTROLS
|
|
505
|
-
button.state = (this.accessory.lockPhysicalControl === 1);
|
|
506
|
-
break;
|
|
507
|
-
case 16: //ROOM TEMP HIDE
|
|
508
|
-
button.state = (hideRoomTemperature === true);
|
|
509
|
-
break;
|
|
510
|
-
case 17: //SUPPLY TEMP HIDE
|
|
511
|
-
button.state = (hideSupplyTemperature === true);
|
|
512
|
-
break;
|
|
513
|
-
case 18: //OUTDOOR TEMP HIDE
|
|
514
|
-
button.state = (hideOutdoorTemperature === true);
|
|
515
|
-
break;
|
|
516
|
-
default: //Unknown button
|
|
517
|
-
this.emit('warn', `Unknown button mode: ${mode} detected.`);
|
|
518
|
-
break;
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
//update services
|
|
522
|
-
if (this.buttonsServices) {
|
|
523
|
-
const characteristicType = button.characteristicType;
|
|
524
|
-
this.buttonsServices[i]
|
|
525
|
-
.updateCharacteristic(characteristicType, button.state)
|
|
526
|
-
};
|
|
527
|
-
};
|
|
528
|
-
};
|
|
529
|
-
|
|
530
|
-
//log current state
|
|
531
|
-
if (!this.disableLogInfo) {
|
|
532
|
-
this.emit('message', `Power: ${power ? 'ON' : 'OFF'}`);
|
|
533
|
-
this.emit('message', `Target ventilation mode: ${Ventilation.OperationMode[ventilationMode]}`);
|
|
534
|
-
this.emit('message', `Current ventilation mode: ${Ventilation.OperationMode[actualVentilationMode]}`);
|
|
535
|
-
this.emit('message', `Target temperature: ${setTemperature}${this.accessory.temperatureUnit}`);
|
|
536
|
-
this.emit('message', `Room temperature: ${roomTemperature}${this.accessory.temperatureUnit}`);
|
|
537
|
-
const info1 = hasSupplyTemperature && deviceData.Device.SupplyTemperature !== null ? this.emit('message', `Supply temperature: ${roomTemperature}${this.accessory.temperatureUnit}`) : false;
|
|
538
|
-
const info2 = hasOutdoorTemperature && deviceData.Device.OutdoorTemperature !== null ? this.emit('message', `Outdoor temperature: ${roomTemperature}${this.accessory.temperatureUnit}`) : false;
|
|
539
|
-
this.emit('message', `Fan speed mode: ${Ventilation.FanSpeed[setFanSpeed]}`);
|
|
540
|
-
this.emit('message', `Temperature display unit: ${this.accessory.temperatureUnit}`);
|
|
541
|
-
this.emit('message', `Core maintenance: ${Ventilation.CoreMaintenance[coreMaintenanceRequired]}`);
|
|
542
|
-
this.emit('message', `Filter maintenance: ${Ventilation.FilterMaintenance[filterMaintenanceRequired]}`);
|
|
543
|
-
const info5 = hasCO2Sensor ? this.emit('message', `CO2 detected: ${Ventilation.Co2Detected[roomCO2Detected]}`) : false;
|
|
544
|
-
const info6 = hasCO2Sensor ? this.emit('message', `CO2 level: ${roomCO2Level} ppm`) : false;
|
|
545
|
-
const info7 = hasPM25Sensor ? this.emit('message', `PM2.5 air quality: ${Ventilation.PM25AirQuality[pM25AirQuality]}`) : false;
|
|
546
|
-
const info8 = hasPM25Sensor ? this.emit('message', `PM2.5 level: ${pM25Level} µg/m`) : false;
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
//start prepare accessory
|
|
550
|
-
if (!this.startPrepareAccessory) {
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
try {
|
|
555
|
-
const accessory = await this.prepareAccessory(this.accountInfo, deviceData, this.deviceId, this.deviceTypeText, this.deviceName, this.accountName);
|
|
556
|
-
this.emit('publishAccessory', accessory);
|
|
557
|
-
this.startPrepareAccessory = false;
|
|
558
|
-
} catch (error) {
|
|
559
|
-
this.emit('error', error);
|
|
560
|
-
};
|
|
561
|
-
})
|
|
562
|
-
.on('success', (message) => {
|
|
563
|
-
this.emit('success', message);
|
|
564
|
-
})
|
|
565
|
-
.on('message', (message) => {
|
|
566
|
-
this.emit('message', message);
|
|
567
|
-
})
|
|
568
|
-
.on('debug', (debug) => {
|
|
569
|
-
this.emit('debug', debug);
|
|
570
|
-
})
|
|
571
|
-
.on('warn', async (warn) => {
|
|
572
|
-
this.emit('warn', warn);
|
|
573
|
-
})
|
|
574
|
-
.on('error', async (error) => {
|
|
575
|
-
this.emit('error', error);
|
|
576
|
-
});
|
|
577
|
-
|
|
578
|
-
//check state
|
|
579
|
-
await this.melCloudErv.checkState();
|
|
580
|
-
|
|
581
|
-
//start impule generator
|
|
582
|
-
await this.melCloudErv.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
|
|
583
|
-
|
|
584
|
-
return true;
|
|
585
|
-
} catch (error) {
|
|
586
|
-
throw new Error(`Start error: ${error}`);
|
|
587
|
-
};
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
async setOverExternalIntegration(integration, deviceData, key, value) {
|
|
591
|
-
try {
|
|
592
|
-
let set = false
|
|
593
|
-
switch (key) {
|
|
594
|
-
case 'Power':
|
|
595
|
-
deviceData.Device[key] = value;
|
|
596
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
597
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
598
|
-
break;
|
|
599
|
-
case 'OperationMode':
|
|
600
|
-
deviceData.Device[key] = value;
|
|
601
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.OperationMode;
|
|
602
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
603
|
-
break;
|
|
604
|
-
case 'VentilationMode':
|
|
605
|
-
deviceData.Device[key] = value;
|
|
606
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.VentilationMode;
|
|
607
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
608
|
-
break;
|
|
609
|
-
case 'SetTemperature':
|
|
610
|
-
deviceData.Device[key] = value;
|
|
611
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetTemperature;
|
|
612
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
613
|
-
break;
|
|
614
|
-
case 'DefaultCoolingSetTemperature':
|
|
615
|
-
deviceData.Device[key] = value;
|
|
616
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetTemperature;
|
|
617
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
618
|
-
break;
|
|
619
|
-
case 'DefaultHeatingSetTemperature':
|
|
620
|
-
deviceData.Device[key] = value;
|
|
621
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetTemperature;
|
|
622
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
623
|
-
break;
|
|
624
|
-
case 'NightPurgeMode':
|
|
625
|
-
deviceData.Device[key] = value;
|
|
626
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.NightPurgeMode;
|
|
627
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
628
|
-
break;
|
|
629
|
-
case 'SetFanSpeed':
|
|
630
|
-
deviceData.Device[key] = value;
|
|
631
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetFanSpeed;
|
|
632
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
633
|
-
break;
|
|
634
|
-
case 'HideRoomTemperature':
|
|
635
|
-
deviceData[key] = value;
|
|
636
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
637
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
638
|
-
break;
|
|
639
|
-
case 'HideSupplyTemperature':
|
|
640
|
-
deviceData[key] = value;
|
|
641
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
642
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
643
|
-
break;
|
|
644
|
-
case 'HideOutdoorTemperature':
|
|
645
|
-
deviceData[key] = value;
|
|
646
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
647
|
-
set = await this.melCloudErv.send(deviceData, this.displayMode);
|
|
648
|
-
break;
|
|
649
|
-
default:
|
|
650
|
-
this.emit('warn', `${integration}, received key: ${key}, value: ${value}`);
|
|
651
|
-
break;
|
|
652
|
-
};
|
|
653
|
-
return set;
|
|
654
|
-
} catch (error) {
|
|
655
|
-
throw new Error(`${integration} set key: ${key}, value: ${value}, error: ${error.message ?? error}`);
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
//prepare accessory
|
|
660
|
-
async prepareAccessory(accountInfo, deviceData, deviceId, deviceTypeText, deviceName, accountName) {
|
|
661
|
-
try {
|
|
662
|
-
const presetsOnServer = this.accessory.presets;
|
|
663
|
-
const hasRoomTemperature = this.accessory.hasRoomTemperature;
|
|
664
|
-
const hasSupplyTemperature = this.accessory.hasSupplyTemperature;
|
|
665
|
-
const hasOutdoorTemperature = this.accessory.hasOutdoorTemperature;
|
|
666
|
-
const hasCoolOperationMode = this.accessory.hasCoolOperationMode;
|
|
667
|
-
const hasHeatOperationMode = this.accessory.hasHeatOperationMode;
|
|
668
|
-
const hasAutoVentilationMode = this.accessory.hasAutoVentilationMode;
|
|
669
|
-
const hasBypassVentilationMode = this.accessory.hasBypassVentilationMode;
|
|
670
|
-
const hasAutomaticFanSpeed = this.accessory.hasAutomaticFanSpeed;
|
|
671
|
-
const hasCO2Sensor = this.accessory.hasCO2Sensor;
|
|
672
|
-
const hasPM25Sensor = this.accessory.hasPM25Sensor;
|
|
673
|
-
const numberOfFanSpeeds = this.accessory.numberOfFanSpeeds;
|
|
674
|
-
|
|
675
|
-
//accessory
|
|
676
|
-
const debug = this.enableDebugMode ? this.emit('debug', `Prepare accessory`) : false;
|
|
677
|
-
const accessoryName = deviceName;
|
|
678
|
-
const accessoryUUID = AccessoryUUID.generate(accountName + deviceId.toString());
|
|
679
|
-
const accessoryCategory = Categories.AIR_PURIFIER;
|
|
680
|
-
const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
|
|
681
|
-
|
|
682
|
-
//information service
|
|
683
|
-
const debug1 = this.enableDebugMode ? this.emit('debug', `Prepare information service`) : false;
|
|
684
|
-
accessory.getService(Service.AccessoryInformation)
|
|
685
|
-
.setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
|
|
686
|
-
.setCharacteristic(Characteristic.Model, this.model)
|
|
687
|
-
.setCharacteristic(Characteristic.SerialNumber, this.serialNumber)
|
|
688
|
-
.setCharacteristic(Characteristic.FirmwareRevision, this.firmwareRevision)
|
|
689
|
-
.setCharacteristic(Characteristic.ConfiguredName, accessoryName);
|
|
690
|
-
|
|
691
|
-
//services
|
|
692
|
-
const serviceName = `${deviceTypeText} ${accessoryName}`;
|
|
693
|
-
switch (this.displayMode) {
|
|
694
|
-
case 1: //Heater Cooler
|
|
695
|
-
const debug = this.enableDebugMode ? this.emit('debug', `Prepare heather/cooler service`) : false;
|
|
696
|
-
this.melCloudService = new Service.HeaterCooler(serviceName, `HeaterCooler ${deviceId}`);
|
|
697
|
-
this.melCloudService.getCharacteristic(Characteristic.Active)
|
|
698
|
-
.onGet(async () => {
|
|
699
|
-
const state = this.accessory.power;
|
|
700
|
-
return state;
|
|
701
|
-
})
|
|
702
|
-
.onSet(async (state) => {
|
|
703
|
-
try {
|
|
704
|
-
deviceData.Device.Power = [false, true][state];
|
|
705
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
706
|
-
await this.melCloudErv.send(deviceData, this.displayMode);
|
|
707
|
-
const info = this.disableLogInfo ? false : this.emit('message', `Set power: ${state ? 'ON' : 'OFF'}`);
|
|
708
|
-
} catch (error) {
|
|
709
|
-
this.emit('warn', `Set power error: ${error}`);
|
|
710
|
-
};
|
|
711
|
-
});
|
|
712
|
-
this.melCloudService.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
|
|
713
|
-
.onGet(async () => {
|
|
714
|
-
const value = this.accessory.currentOperationMode;
|
|
715
|
-
return value;
|
|
716
|
-
});
|
|
717
|
-
this.melCloudService.getCharacteristic(Characteristic.TargetHeaterCoolerState)
|
|
718
|
-
.setProps({
|
|
719
|
-
minValue: this.accessory.operationModeSetPropsMinValue,
|
|
720
|
-
maxValue: this.accessory.operationModeSetPropsMaxValue,
|
|
721
|
-
validValues: this.accessory.operationModeSetPropsValidValues
|
|
722
|
-
})
|
|
723
|
-
.onGet(async () => {
|
|
724
|
-
const value = this.accessory.targetOperationMode ?? 0; //LOSSNAY, BYPASS, AUTO
|
|
725
|
-
return value;
|
|
726
|
-
})
|
|
727
|
-
.onSet(async (value) => {
|
|
728
|
-
try {
|
|
729
|
-
switch (value) {
|
|
730
|
-
case 0: //AUTO - AUTO
|
|
731
|
-
deviceData.Device.VentilationMode = hasAutoVentilationMode ? 2 : 0;
|
|
732
|
-
break;
|
|
733
|
-
case 1: //HEAT - LOSSNAY
|
|
734
|
-
deviceData.Device.VentilationMode = 0;
|
|
735
|
-
break;
|
|
736
|
-
case 2: //COOL - BYPASS
|
|
737
|
-
deviceData.Device.VentilationMode = hasBypassVentilationMode ? 1 : 0;
|
|
738
|
-
break;
|
|
739
|
-
};
|
|
198
|
+
//services
|
|
199
|
+
const serviceName = `${deviceTypeText} ${accessoryName}`;
|
|
200
|
+
switch (this.displayMode) {
|
|
201
|
+
case 1: //Heater Cooler
|
|
202
|
+
const debug = this.enableDebugMode ? this.emit('debug', `Prepare heather/cooler service`) : false;
|
|
203
|
+
this.melCloudService = new Service.HeaterCooler(serviceName, `HeaterCooler ${deviceId}`);
|
|
204
|
+
this.melCloudService.getCharacteristic(Characteristic.Active)
|
|
205
|
+
.onGet(async () => {
|
|
206
|
+
const state = this.accessory.power;
|
|
207
|
+
return state;
|
|
208
|
+
})
|
|
209
|
+
.onSet(async (state) => {
|
|
210
|
+
try {
|
|
211
|
+
deviceData.Device.Power = [false, true][state];
|
|
212
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
213
|
+
await this.melCloudErv.send(deviceData, this.displayMode);
|
|
214
|
+
const info = this.disableLogInfo ? false : this.emit('message', `Set power: ${state ? 'ON' : 'OFF'}`);
|
|
215
|
+
} catch (error) {
|
|
216
|
+
this.emit('warn', `Set power error: ${error}`);
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
this.melCloudService.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
|
|
220
|
+
.onGet(async () => {
|
|
221
|
+
const value = this.accessory.currentOperationMode;
|
|
222
|
+
return value;
|
|
223
|
+
});
|
|
224
|
+
this.melCloudService.getCharacteristic(Characteristic.TargetHeaterCoolerState)
|
|
225
|
+
.setProps({
|
|
226
|
+
minValue: this.accessory.operationModeSetPropsMinValue,
|
|
227
|
+
maxValue: this.accessory.operationModeSetPropsMaxValue,
|
|
228
|
+
validValues: this.accessory.operationModeSetPropsValidValues
|
|
229
|
+
})
|
|
230
|
+
.onGet(async () => {
|
|
231
|
+
const value = this.accessory.targetOperationMode ?? 0; //LOSSNAY, BYPASS, AUTO
|
|
232
|
+
return value;
|
|
233
|
+
})
|
|
234
|
+
.onSet(async (value) => {
|
|
235
|
+
try {
|
|
236
|
+
switch (value) {
|
|
237
|
+
case 0: //AUTO - AUTO
|
|
238
|
+
deviceData.Device.VentilationMode = hasAutoVentilationMode ? 2 : 0;
|
|
239
|
+
break;
|
|
240
|
+
case 1: //HEAT - LOSSNAY
|
|
241
|
+
deviceData.Device.VentilationMode = 0;
|
|
242
|
+
break;
|
|
243
|
+
case 2: //COOL - BYPASS
|
|
244
|
+
deviceData.Device.VentilationMode = hasBypassVentilationMode ? 1 : 0;
|
|
245
|
+
break;
|
|
246
|
+
};
|
|
740
247
|
|
|
741
248
|
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.VentilationMode;
|
|
742
249
|
await this.melCloudErv.send(deviceData, this.displayMode);
|
|
@@ -854,414 +361,908 @@ class DeviceErv extends EventEmitter {
|
|
|
854
361
|
// });
|
|
855
362
|
this.melCloudService.getCharacteristic(Characteristic.TemperatureDisplayUnits)
|
|
856
363
|
.onGet(async () => {
|
|
857
|
-
const value = this.accessory.useFahrenheit;
|
|
858
|
-
return value;
|
|
364
|
+
const value = this.accessory.useFahrenheit;
|
|
365
|
+
return value;
|
|
366
|
+
})
|
|
367
|
+
.onSet(async (value) => {
|
|
368
|
+
try {
|
|
369
|
+
accountInfo.UseFahrenheit = [false, true][value];
|
|
370
|
+
await this.melCloud.send(accountInfo);
|
|
371
|
+
this.accessory.useFahrenheit = value;
|
|
372
|
+
const info = this.disableLogInfo ? false : this.emit('message', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
373
|
+
} catch (error) {
|
|
374
|
+
this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
375
|
+
};
|
|
376
|
+
});
|
|
377
|
+
accessory.addService(this.melCloudService);
|
|
378
|
+
break;
|
|
379
|
+
case 2: //Thermostat
|
|
380
|
+
const debug1 = this.enableDebugMode ? this.emit('debug', `Prepare thermostat service`) : false;
|
|
381
|
+
this.melCloudService = new Service.Thermostat(serviceName, `Thermostat ${deviceId}`);
|
|
382
|
+
this.melCloudService.getCharacteristic(Characteristic.CurrentHeatingCoolingState)
|
|
383
|
+
.onGet(async () => {
|
|
384
|
+
const value = this.accessory.currentOperationMode;
|
|
385
|
+
return value;
|
|
386
|
+
});
|
|
387
|
+
this.melCloudService.getCharacteristic(Characteristic.TargetHeatingCoolingState)
|
|
388
|
+
.setProps({
|
|
389
|
+
minValue: this.accessory.operationModeSetPropsMinValue,
|
|
390
|
+
maxValue: this.accessory.operationModeSetPropsMaxValue,
|
|
391
|
+
validValues: this.accessory.operationModeSetPropsValidValues
|
|
392
|
+
})
|
|
393
|
+
.onGet(async () => {
|
|
394
|
+
const value = this.accessory.targetOperationMode ?? 0; //LOSSNAY, BYPASS, AUTO
|
|
395
|
+
return value;
|
|
396
|
+
})
|
|
397
|
+
.onSet(async (value) => {
|
|
398
|
+
try {
|
|
399
|
+
switch (value) {
|
|
400
|
+
case 0: //OFF - POWER OFF
|
|
401
|
+
deviceData.Device.Power = false;
|
|
402
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
403
|
+
break;
|
|
404
|
+
case 1: //HEAT - LOSSNAY
|
|
405
|
+
deviceData.Device.Power = true;
|
|
406
|
+
deviceData.Device.VentilationMode = 0;
|
|
407
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
408
|
+
break;
|
|
409
|
+
case 2: //COOL - BYPASS
|
|
410
|
+
deviceData.Device.Power = true;
|
|
411
|
+
deviceData.Device.VentilationMode = hasBypassVentilationMode ? 1 : 0;
|
|
412
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
413
|
+
break;
|
|
414
|
+
case 3: //AUTO - AUTO
|
|
415
|
+
deviceData.Device.Power = true;
|
|
416
|
+
deviceData.Device.VentilationMode = hasAutoVentilationMode ? 2 : 0;
|
|
417
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
418
|
+
break;
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
await this.melCloudErv.send(deviceData, this.displayMode);
|
|
422
|
+
const operationModeText = Ventilation.VentilationMode[deviceData.Device.VentilationMode];
|
|
423
|
+
const info = this.disableLogInfo ? false : this.emit('message', `Set operation mode: ${operationModeText}`);
|
|
424
|
+
} catch (error) {
|
|
425
|
+
this.emit('warn', `Set operation mode error: ${error}`);
|
|
426
|
+
};
|
|
427
|
+
});
|
|
428
|
+
this.melCloudService.getCharacteristic(Characteristic.CurrentTemperature)
|
|
429
|
+
.onGet(async () => {
|
|
430
|
+
const value = this.accessory.roomTemperature;
|
|
431
|
+
return value;
|
|
432
|
+
});
|
|
433
|
+
this.melCloudService.getCharacteristic(Characteristic.TargetTemperature)
|
|
434
|
+
.setProps({
|
|
435
|
+
minValue: this.accessory.minTempHeat,
|
|
436
|
+
maxValue: this.accessory.maxTempHeat,
|
|
437
|
+
minStep: this.accessory.temperatureIncrement
|
|
438
|
+
})
|
|
439
|
+
.onGet(async () => {
|
|
440
|
+
const value = this.accessory.setTemperature;
|
|
441
|
+
return value;
|
|
442
|
+
})
|
|
443
|
+
.onSet(async (value) => {
|
|
444
|
+
try {
|
|
445
|
+
deviceData.Device.SetTemperature = value;
|
|
446
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.SetTemperature;
|
|
447
|
+
await this.melCloudErv.send(deviceData, this.displayMode);
|
|
448
|
+
const info = this.disableLogInfo ? false : this.emit('message', `Set temperature: ${value}${this.accessory.temperatureUnit}`);
|
|
449
|
+
} catch (error) {
|
|
450
|
+
this.emit('warn', `Set temperature error: ${error}`);
|
|
451
|
+
};
|
|
452
|
+
});
|
|
453
|
+
this.melCloudService.getCharacteristic(Characteristic.TemperatureDisplayUnits)
|
|
454
|
+
.onGet(async () => {
|
|
455
|
+
const value = this.accessory.useFahrenheit;
|
|
456
|
+
return value;
|
|
457
|
+
})
|
|
458
|
+
.onSet(async (value) => {
|
|
459
|
+
try {
|
|
460
|
+
accountInfo.UseFahrenheit = [false, true][value];
|
|
461
|
+
await this.melCloud.send(accountInfo);
|
|
462
|
+
this.accessory.useFahrenheit = value;
|
|
463
|
+
const info = this.disableLogInfo ? false : this.emit('message', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
464
|
+
} catch (error) {
|
|
465
|
+
this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
466
|
+
};
|
|
467
|
+
});
|
|
468
|
+
accessory.addService(this.melCloudService);
|
|
469
|
+
break;
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
//temperature sensor service room
|
|
473
|
+
if (this.temperatureSensor && hasRoomTemperature && this.accessory.roomTemperature !== null) {
|
|
474
|
+
const debug = this.enableDebugMode ? this.emit('debug', `Prepare room temperature sensor service`) : false;
|
|
475
|
+
this.roomTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Room`, `Room Temperature Sensor ${deviceId}`);
|
|
476
|
+
this.roomTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
477
|
+
this.roomTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} Room`);
|
|
478
|
+
this.roomTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
|
|
479
|
+
.setProps({
|
|
480
|
+
minValue: -35,
|
|
481
|
+
maxValue: 150,
|
|
482
|
+
minStep: 0.5
|
|
483
|
+
})
|
|
484
|
+
.onGet(async () => {
|
|
485
|
+
const state = this.accessory.roomTemperature;
|
|
486
|
+
return state;
|
|
487
|
+
})
|
|
488
|
+
accessory.addService(this.roomTemperatureSensorService);
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
//temperature sensor service supply
|
|
492
|
+
if (this.temperatureSensorSupply && hasSupplyTemperature && this.accessory.supplyTemperature !== null) {
|
|
493
|
+
const debug = this.enableDebugMode ? this.emit('debug', `Prepare supply temperature sensor service`) : false;
|
|
494
|
+
this.supplyTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Supply`, `Supply Temperature Sensor ${deviceId}`);
|
|
495
|
+
this.supplyTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
496
|
+
this.supplyTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} Supply`);
|
|
497
|
+
this.supplyTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
|
|
498
|
+
.setProps({
|
|
499
|
+
minValue: -35,
|
|
500
|
+
maxValue: 150,
|
|
501
|
+
minStep: 0.5
|
|
502
|
+
})
|
|
503
|
+
.onGet(async () => {
|
|
504
|
+
const state = this.accessory.supplyTemperature;
|
|
505
|
+
return state;
|
|
506
|
+
})
|
|
507
|
+
accessory.addService(this.supplyTemperatureSensorService);
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
//temperature sensor service outdoor
|
|
511
|
+
if (this.temperatureSensorOutdoor && hasOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
|
|
512
|
+
const debug = this.enableDebugMode ? this.emit('debug', `Prepare outdoor temperature sensor service`) : false;
|
|
513
|
+
this.outdoorTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Outdoor`, `Outdoor Temperature Sensor ${deviceId}`);
|
|
514
|
+
this.outdoorTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
515
|
+
this.outdoorTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} Outdoor`);
|
|
516
|
+
this.outdoorTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
|
|
517
|
+
.setProps({
|
|
518
|
+
minValue: -35,
|
|
519
|
+
maxValue: 150,
|
|
520
|
+
minStep: 0.5
|
|
521
|
+
})
|
|
522
|
+
.onGet(async () => {
|
|
523
|
+
const state = this.accessory.outdoorTemperature;
|
|
524
|
+
return state;
|
|
525
|
+
})
|
|
526
|
+
accessory.addService(this.outdoorTemperatureSensorService);
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
//core maintenance
|
|
530
|
+
this.coreMaintenanceService = new Service.FilterMaintenance(`${serviceName} Core Maintenance`, `CoreMaintenance ${deviceId}`);
|
|
531
|
+
this.coreMaintenanceService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
532
|
+
this.coreMaintenanceService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} Core Maintenance`);
|
|
533
|
+
this.coreMaintenanceService.getCharacteristic(Characteristic.FilterChangeIndication)
|
|
534
|
+
.onGet(async () => {
|
|
535
|
+
const value = this.accessory.coreMaintenanceRequired;
|
|
536
|
+
return value;
|
|
537
|
+
});
|
|
538
|
+
this.coreMaintenanceService.getCharacteristic(Characteristic.ResetFilterIndication)
|
|
539
|
+
.onSet(async (state) => {
|
|
540
|
+
});
|
|
541
|
+
accessory.addService(this.coreMaintenanceService);
|
|
542
|
+
|
|
543
|
+
//filter maintenance
|
|
544
|
+
this.filterMaintenanceService = new Service.FilterMaintenance(`${serviceName} Filter Maintenance`, `FilterMaintenance ${deviceId}`);
|
|
545
|
+
this.filterMaintenanceService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
546
|
+
this.filterMaintenanceService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} Filter Maintenance`);
|
|
547
|
+
this.filterMaintenanceService.getCharacteristic(Characteristic.FilterChangeIndication)
|
|
548
|
+
.onGet(async () => {
|
|
549
|
+
const value = this.accessory.filterMaintenanceRequired;
|
|
550
|
+
return value;
|
|
551
|
+
});
|
|
552
|
+
this.filterMaintenanceService.getCharacteristic(Characteristic.ResetFilterIndication)
|
|
553
|
+
.onSet(async (state) => {
|
|
554
|
+
});
|
|
555
|
+
accessory.addService(this.filterMaintenanceService);
|
|
556
|
+
|
|
557
|
+
//room CO2 sensor
|
|
558
|
+
if (hasCO2Sensor) {
|
|
559
|
+
this.carbonDioxideSensorService = new Service.CarbonDioxideSensor(`${serviceName} CO2 Sensor`, `CO2Sensor ${deviceId}`);
|
|
560
|
+
this.carbonDioxideSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
561
|
+
this.carbonDioxideSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} CO2 Sensor`);
|
|
562
|
+
this.carbonDioxideSensorService.getCharacteristic(Characteristic.CarbonDioxideDetected)
|
|
563
|
+
.onGet(async () => {
|
|
564
|
+
const value = this.accessory.roomCO2Detected;
|
|
565
|
+
return value;
|
|
566
|
+
});
|
|
567
|
+
this.carbonDioxideSensorService.getCharacteristic(Characteristic.CarbonDioxideLevel)
|
|
568
|
+
.onGet(async () => {
|
|
569
|
+
const value = this.accessory.roomCO2Level;
|
|
570
|
+
return value;
|
|
571
|
+
});
|
|
572
|
+
accessory.addService(this.carbonDioxideSensorService);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
//room PM2.5 sensor
|
|
576
|
+
if (hasPM25Sensor) {
|
|
577
|
+
this.airQualitySensorService = new Service.AirQualitySensor(`${serviceName} PM2.5 Sensor`, `PM25Sensor ${deviceId}`);
|
|
578
|
+
this.airQualitySensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
579
|
+
this.airQualitySensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} PM2.5 Sensor`);
|
|
580
|
+
this.airQualitySensorService.getCharacteristic(Characteristic.AirQuality)
|
|
581
|
+
.onGet(async () => {
|
|
582
|
+
const value = this.accessory.pM25AirQuality;
|
|
583
|
+
return value;
|
|
584
|
+
});
|
|
585
|
+
this.airQualitySensorService.getCharacteristic(Characteristic.PM2_5Density)
|
|
586
|
+
.onGet(async () => {
|
|
587
|
+
const value = this.accessory.pM25Level;
|
|
588
|
+
return value;
|
|
589
|
+
});
|
|
590
|
+
accessory.addService(this.airQualitySensorService);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
//presets services
|
|
594
|
+
if (this.presetsConfiguredCount > 0) {
|
|
595
|
+
const debug = this.enableDebugMode ? this.emit('debug', `Prepare presets services`) : false;
|
|
596
|
+
this.presetsServices = [];
|
|
597
|
+
|
|
598
|
+
for (let i = 0; i < this.presetsConfiguredCount; i++) {
|
|
599
|
+
const preset = this.presetsConfigured[i];
|
|
600
|
+
const presetData = presetsOnServer.find(p => p.ID === preset.Id);
|
|
601
|
+
|
|
602
|
+
//get preset name
|
|
603
|
+
const presetName = preset.name;
|
|
604
|
+
|
|
605
|
+
//get preset name prefix
|
|
606
|
+
const presetNamePrefix = preset.namePrefix;
|
|
607
|
+
|
|
608
|
+
const serviceName = presetNamePrefix ? `${accessoryName} ${presetName}` : presetName;
|
|
609
|
+
const serviceType = preset.serviceType;
|
|
610
|
+
const characteristicType = preset.characteristicType;
|
|
611
|
+
const presetService = new serviceType(serviceName, `Preset ${deviceId} ${i}`);
|
|
612
|
+
presetService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
613
|
+
presetService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
614
|
+
presetService.getCharacteristic(characteristicType)
|
|
615
|
+
.onGet(async () => {
|
|
616
|
+
const state = preset.state;
|
|
617
|
+
return state;
|
|
859
618
|
})
|
|
860
|
-
.onSet(async (
|
|
619
|
+
.onSet(async (state) => {
|
|
861
620
|
try {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
621
|
+
switch (state) {
|
|
622
|
+
case true:
|
|
623
|
+
preset.previousSettings = deviceData.Device;
|
|
624
|
+
deviceData.Device.SetTemperature = presetData.SetTemperature;
|
|
625
|
+
deviceData.Device.Power = presetData.Power;
|
|
626
|
+
deviceData.Device.OperationMode = presetData.OperationMode;
|
|
627
|
+
deviceData.Device.VentilationMode = presetData.VentilationMode;
|
|
628
|
+
deviceData.Device.SetFanSpeed = presetData.FanSpeed;
|
|
629
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
630
|
+
break;
|
|
631
|
+
case false:
|
|
632
|
+
deviceData.Device.SetTemperature = preset.previousSettings.SetTemperature;
|
|
633
|
+
deviceData.Device.Power = preset.previousSettings.Power;
|
|
634
|
+
deviceData.Device.OperationMode = preset.previousSettings.OperationMode;
|
|
635
|
+
deviceData.Device.VentilationMode = preset.previousSettings.VentilationMode;
|
|
636
|
+
deviceData.Device.SetFanSpeed = preset.previousSettings.FanSpeed;
|
|
637
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
638
|
+
break;
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
await this.melCloudErv.send(deviceData, this.displayMode);
|
|
642
|
+
const info = this.disableLogInfo ? false : this.emit('message', `${state ? 'Set:' : 'Unset:'} ${presetName}`);
|
|
866
643
|
} catch (error) {
|
|
867
|
-
this.emit('warn', `Set
|
|
644
|
+
this.emit('warn', `Set preset error: ${error}`);
|
|
868
645
|
};
|
|
869
646
|
});
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
647
|
+
};
|
|
648
|
+
this.presetsServices.push(presetService);
|
|
649
|
+
accessory.addService(presetService);
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
//buttons services
|
|
653
|
+
if (this.buttonsConfiguredCount > 0) {
|
|
654
|
+
const debug = this.enableDebugMode ? this.emit('debug', `Prepare buttons services`) : false;
|
|
655
|
+
this.buttonsServices = [];
|
|
656
|
+
|
|
657
|
+
for (let i = 0; i < this.buttonsConfiguredCount; i++) {
|
|
658
|
+
const button = this.buttonsConfigured[i];
|
|
659
|
+
|
|
660
|
+
//get button mode
|
|
661
|
+
const mode = button.mode;
|
|
662
|
+
|
|
663
|
+
//get button name
|
|
664
|
+
const buttonName = button.name;
|
|
665
|
+
|
|
666
|
+
//get button name prefix
|
|
667
|
+
const buttonNamePrefix = button.namePrefix;
|
|
668
|
+
|
|
669
|
+
const serviceName = buttonNamePrefix ? `${accessoryName} ${buttonName}` : buttonName;
|
|
670
|
+
const serviceType = button.serviceType;
|
|
671
|
+
const characteristicType = button.characteristicType;
|
|
672
|
+
const buttonService = new serviceType(serviceName, `Button ${deviceId} ${i}`);
|
|
673
|
+
buttonService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
674
|
+
buttonService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
675
|
+
buttonService.getCharacteristic(characteristicType)
|
|
886
676
|
.onGet(async () => {
|
|
887
|
-
const
|
|
888
|
-
return
|
|
677
|
+
const state = button.state;
|
|
678
|
+
return state;
|
|
889
679
|
})
|
|
890
|
-
.onSet(async (
|
|
680
|
+
.onSet(async (state) => {
|
|
891
681
|
try {
|
|
892
|
-
switch (
|
|
893
|
-
case 0: //
|
|
894
|
-
deviceData.Device.Power =
|
|
682
|
+
switch (mode) {
|
|
683
|
+
case 0: //POWER ON,OFF
|
|
684
|
+
deviceData.Device.Power = state;
|
|
895
685
|
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
896
686
|
break;
|
|
897
|
-
case 1: //
|
|
687
|
+
case 1: //OPERATING MODE RECOVERY
|
|
688
|
+
button.previousValue = state ? deviceData.Device.VentilationMode : button.previousValue ?? deviceData.Device.VentilationMode;
|
|
898
689
|
deviceData.Device.Power = true;
|
|
899
|
-
deviceData.Device.VentilationMode = 0;
|
|
690
|
+
deviceData.Device.VentilationMode = state ? 0 : button.previousValue;
|
|
900
691
|
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
901
692
|
break;
|
|
902
|
-
case 2: //
|
|
693
|
+
case 2: //OPERATING MODE BYPASS
|
|
694
|
+
button.previousValue = state ? deviceData.Device.VentilationMode : button.previousValue ?? deviceData.Device.VentilationMode;
|
|
903
695
|
deviceData.Device.Power = true;
|
|
904
|
-
deviceData.Device.VentilationMode =
|
|
696
|
+
deviceData.Device.VentilationMode = state ? 1 : button.previousValue;
|
|
905
697
|
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
906
|
-
break
|
|
907
|
-
case 3: //
|
|
698
|
+
break
|
|
699
|
+
case 3: //OPERATING MODE AUTO
|
|
700
|
+
button.previousValue = state ? deviceData.Device.VentilationMode : button.previousValue ?? deviceData.Device.VentilationMode;
|
|
908
701
|
deviceData.Device.Power = true;
|
|
909
|
-
deviceData.Device.VentilationMode =
|
|
702
|
+
deviceData.Device.VentilationMode = state ? 2 : button.previousValue;
|
|
910
703
|
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
911
704
|
break;
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
705
|
+
case 4: //NIGHT PURGE MODE
|
|
706
|
+
deviceData.Device.Power = true;
|
|
707
|
+
deviceData.Device.NightPurgeMode = state;
|
|
708
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power
|
|
709
|
+
break;
|
|
710
|
+
case 10: //FAN SPEED MODE AUTO
|
|
711
|
+
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
712
|
+
deviceData.Device.Power = true;
|
|
713
|
+
deviceData.Device.SetFanSpeed = state ? 0 : button.previousValue;
|
|
714
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
715
|
+
break;
|
|
716
|
+
case 11: //FAN SPEED MODE 1
|
|
717
|
+
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
718
|
+
deviceData.Device.Power = true;
|
|
719
|
+
deviceData.Device.SetFanSpeed = state ? 1 : button.previousValue;
|
|
720
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
721
|
+
break;
|
|
722
|
+
case 12: //FAN SPEED MODE 2
|
|
723
|
+
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
724
|
+
deviceData.Device.Power = true;
|
|
725
|
+
deviceData.Device.SetFanSpeed = state ? 2 : button.previousValue;
|
|
726
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
727
|
+
break;
|
|
728
|
+
case 13: //FAN SPEED MODE 3
|
|
729
|
+
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
730
|
+
deviceData.Device.Power = true;
|
|
731
|
+
deviceData.Device.SetFanSpeed = state ? 3 : button.previousValue;
|
|
732
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
733
|
+
break;
|
|
734
|
+
case 14: //FAN MODE 4
|
|
735
|
+
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
736
|
+
deviceData.Device.Power = true;
|
|
737
|
+
deviceData.Device.SetFanSpeed = state ? 4 : button.previousValue;
|
|
738
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
739
|
+
break;
|
|
740
|
+
case 15: //PHYSICAL LOCK CONTROLS
|
|
741
|
+
deviceData.Device = deviceData.Device;
|
|
742
|
+
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
743
|
+
break;
|
|
744
|
+
case 16: //ROOM TEMP HIDE
|
|
745
|
+
deviceData.HideRoomTemperature = state;
|
|
746
|
+
break;
|
|
747
|
+
case 17: //SUPPLY TEMP HIDE
|
|
748
|
+
deviceData.HideSupplyTemperature = state;
|
|
749
|
+
break;
|
|
750
|
+
case 18: //OUTDOOR EMP HIDE
|
|
751
|
+
deviceData.hideOutdoorTemperature = state;
|
|
752
|
+
break;
|
|
753
|
+
default:
|
|
754
|
+
this.emit('message', `Unknown button mode: ${mode}`);
|
|
755
|
+
break;
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
await this.melCloudErv.send(deviceData, this.displayMode);
|
|
759
|
+
const info = this.disableLogInfo ? false : this.emit('message', `${state ? `Set: ${buttonName}` : `Unset: ${buttonName}, Set: ${button.previousValue}`}`);
|
|
957
760
|
} catch (error) {
|
|
958
|
-
this.emit('warn', `Set
|
|
761
|
+
this.emit('warn', `Set button error: ${error}`);
|
|
959
762
|
};
|
|
960
763
|
});
|
|
961
|
-
|
|
962
|
-
|
|
764
|
+
this.buttonsServices.push(buttonService);
|
|
765
|
+
accessory.addService(buttonService);
|
|
766
|
+
};
|
|
963
767
|
};
|
|
964
768
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
769
|
+
return accessory;
|
|
770
|
+
} catch (error) {
|
|
771
|
+
throw new Error(`Prepare accessory error: ${error.message || error}`);
|
|
772
|
+
};
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
//start
|
|
776
|
+
async start() {
|
|
777
|
+
try {
|
|
778
|
+
//melcloud device
|
|
779
|
+
this.melCloudErv = new MelCloudErv({
|
|
780
|
+
contextKey: this.contextKey,
|
|
781
|
+
devicesFile: this.devicesFile,
|
|
782
|
+
deviceId: this.deviceId,
|
|
783
|
+
debugLog: this.enableDebugMode
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
this.melCloudErv.on('externalIntegrations', (deviceData) => {
|
|
787
|
+
try {
|
|
788
|
+
//RESTFul server
|
|
789
|
+
const restFulEnabled = this.restFul.enable || false;
|
|
790
|
+
if (restFulEnabled) {
|
|
791
|
+
if (!this.restFulConnected) {
|
|
792
|
+
this.restFul1 = new RestFul({
|
|
793
|
+
port: this.deviceId.slice(-4),
|
|
794
|
+
debug: this.restFul.debug || false
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
this.restFul1.on('connected', (message) => {
|
|
798
|
+
this.restFulConnected = true;
|
|
799
|
+
this.emit('success', message);
|
|
800
|
+
})
|
|
801
|
+
.on('set', async (key, value) => {
|
|
802
|
+
try {
|
|
803
|
+
await this.setOverExternalIntegration('RESTFul', deviceData, key, value);
|
|
804
|
+
} catch (error) {
|
|
805
|
+
this.emit('warn', error);
|
|
806
|
+
};
|
|
807
|
+
})
|
|
808
|
+
.on('debug', (debug) => {
|
|
809
|
+
this.emit('debug', debug);
|
|
810
|
+
})
|
|
811
|
+
.on('error', (error) => {
|
|
812
|
+
this.emit('warn', error);
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
const restFul0 = this.restFulConnected ? this.restFul1.update('info', deviceData) : false;
|
|
816
|
+
const restFul1 = this.restFulConnected ? this.restFul1.update('state', deviceData.Device) : false;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
//MQTT client
|
|
820
|
+
const mqttEnabled = this.mqtt.enable || false;
|
|
821
|
+
if (mqttEnabled) {
|
|
822
|
+
if (!this.mqttConnected) {
|
|
823
|
+
this.mqtt1 = new Mqtt({
|
|
824
|
+
host: this.mqtt.host,
|
|
825
|
+
port: this.mqtt.port || 1883,
|
|
826
|
+
clientId: `${this.mqtt.clientId}_${this.deviceId}` || `${this.deviceTypeText}_${this.deviceName}_${this.deviceId}`,
|
|
827
|
+
prefix: `${this.mqtt.prefix}/${this.deviceTypeText}/${this.deviceName}`,
|
|
828
|
+
user: this.mqtt.user,
|
|
829
|
+
passwd: this.mqtt.pass,
|
|
830
|
+
debug: this.mqtt.debug || false
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
this.mqtt1.on('connected', (message) => {
|
|
834
|
+
this.mqttConnected = true;
|
|
835
|
+
this.emit('success', message);
|
|
836
|
+
})
|
|
837
|
+
.on('subscribed', (message) => {
|
|
838
|
+
this.emit('success', message);
|
|
839
|
+
})
|
|
840
|
+
.on('set', async (key, value) => {
|
|
841
|
+
try {
|
|
842
|
+
await this.setOverExternalIntegration('MQTT', deviceData, key, value);
|
|
843
|
+
} catch (error) {
|
|
844
|
+
this.emit('warn', error);
|
|
845
|
+
};
|
|
846
|
+
})
|
|
847
|
+
.on('debug', (debug) => {
|
|
848
|
+
this.emit('debug', debug);
|
|
849
|
+
})
|
|
850
|
+
.on('error', (error) => {
|
|
851
|
+
this.emit('warn', error);
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
const mqtt0 = this.mqttConnected ? this.mqtt1.emit('publish', `Info`, deviceData) : false;
|
|
855
|
+
const mqtt1 = this.mqttConnected ? this.mqtt1.emit('publish', `State`, deviceData.Device) : false;
|
|
856
|
+
}
|
|
857
|
+
} catch (error) {
|
|
858
|
+
this.emit('warn', `External integration start error: ${error}.`);
|
|
859
|
+
};
|
|
860
|
+
})
|
|
861
|
+
.on('deviceInfo', (manufacturer, modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
862
|
+
if (!this.displayDeviceInfo) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
if (!this.disableLogDeviceInfo) {
|
|
867
|
+
this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
|
|
868
|
+
this.emit('devInfo', `Account: ${this.accountName}`);
|
|
869
|
+
const indoor = modelIndoor ? this.emit('devInfo', `Indoor: ${modelIndoor}`) : false;
|
|
870
|
+
const outdoor = modelOutdoor ? this.emit('devInfo', `Outdoor: ${modelOutdoor}`) : false;
|
|
871
|
+
this.emit('devInfo', `Serial: ${serialNumber}`);
|
|
872
|
+
this.emit('devInfo', `Firmware: ${firmwareAppVersion}`);
|
|
873
|
+
this.emit('devInfo', `Manufacturer: ${manufacturer}`);
|
|
874
|
+
this.emit('devInfo', '----------------------------------');
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
//accessory info
|
|
878
|
+
this.manufacturer = manufacturer;
|
|
879
|
+
this.model = modelIndoor ? modelIndoor : modelOutdoor ? modelOutdoor : `${this.deviceTypeText} ${this.deviceId}`;
|
|
880
|
+
this.serialNumber = serialNumber;
|
|
881
|
+
this.firmwareRevision = firmwareAppVersion;
|
|
882
|
+
this.displayDeviceInfo = false;
|
|
883
|
+
})
|
|
884
|
+
.on('deviceState', async (deviceData) => {
|
|
885
|
+
//presets
|
|
886
|
+
const presetsOnServer = deviceData.Presets ?? [];
|
|
887
|
+
|
|
888
|
+
//device control
|
|
889
|
+
const hideRoomTemperature = deviceData.HideRoomTemperature;
|
|
890
|
+
const hideSupplyTemperature = deviceData.HideSupplyTemperature;
|
|
891
|
+
const hideOutdoorTemperature = deviceData.HideOutdoorTemperature;
|
|
892
|
+
|
|
893
|
+
//device info
|
|
894
|
+
const hasCoolOperationMode = deviceData.Device.HasCoolOperationMode ?? false;
|
|
895
|
+
const hasHeatOperationMode = deviceData.Device.HasHeatOperationMode ?? false;
|
|
896
|
+
const hasAutoOperationMode = deviceData.Device.HasAutoOperationMode ?? false;
|
|
897
|
+
const hasRoomTemperature = deviceData.Device.HasRoomTemperature ?? false;
|
|
898
|
+
const hasSupplyTemperature = deviceData.Device.HasSupplyTemperature ?? false;
|
|
899
|
+
const hasOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
|
|
900
|
+
const hasCO2Sensor = deviceData.Device.HasCO2Sensor ?? false;
|
|
901
|
+
const roomCO2Level = deviceData.Device.RoomCO2Level ?? false;
|
|
902
|
+
const roomCO2Detected = hasCO2Sensor && roomCO2Level > 1000 ? true : false;
|
|
903
|
+
const hasPM25Sensor = deviceData.Device.HasPM25Sensor ?? false;
|
|
904
|
+
const pM25SensorStatus = hasPM25Sensor ? deviceData.Device.PM25SensorStatus : 0;
|
|
905
|
+
const pM25Level = hasPM25Sensor ? deviceData.Device.PM25Level : 0;
|
|
906
|
+
const pM25AirQuality = hasPM25Sensor ? pM25Level <= 13 ? 1 : pM25Level <= 35 ? 2 : pM25Level <= 55 ? 3 : pM25Level <= 75 ? 4 : pM25Level <= 110 ? 5 : 0 : 0;
|
|
907
|
+
const hasAutoVentilationMode = deviceData.Device.HasAutoVentilationMode ?? false;
|
|
908
|
+
const hasBypassVentilationMode = deviceData.Device.HasBypassVentilationMode ?? false;
|
|
909
|
+
const hasAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
|
|
910
|
+
const coreMaintenanceRequired = deviceData.Device.CoreMaintenanceRequired ? 1 : 0;
|
|
911
|
+
const filterMaintenanceRequired = deviceData.Device.FilterMaintenanceRequired ? 1 : 0;
|
|
912
|
+
const actualVentilationMode = deviceData.Device.ActualVentilationMode;
|
|
913
|
+
const numberOfFanSpeeds = deviceData.Device.NumberOfFanSpeeds ?? 0;
|
|
914
|
+
const temperatureIncrement = deviceData.Device.TemperatureIncrement ?? 1;
|
|
915
|
+
const minTempHeat = 10;
|
|
916
|
+
const maxTempHeat = 31;
|
|
917
|
+
const minTempCoolDry = 16;
|
|
918
|
+
const maxTempCoolDry = 31;
|
|
919
|
+
|
|
920
|
+
//device state
|
|
921
|
+
const power = deviceData.Device.Power ?? false;
|
|
922
|
+
const roomTemperature = deviceData.Device.RoomTemperature;
|
|
923
|
+
const supplyTemperature = deviceData.Device.SupplyTemperature;
|
|
924
|
+
const outdoorTemperature = deviceData.Device.OutdoorTemperature;
|
|
925
|
+
const nightPurgeMode = deviceData.Device.NightPurgeMode;
|
|
926
|
+
const setTemperature = deviceData.Device.SetTemperature ?? 20;
|
|
927
|
+
const defaultHeatingSetTemperature = deviceData.Device.DefaultHeatingSetTemperature ?? 20;
|
|
928
|
+
const defaultCoolingSetTemperature = deviceData.Device.DefaultCoolingSetTemperature ?? 23;
|
|
929
|
+
const setFanSpeed = deviceData.Device.SetFanSpeed;
|
|
930
|
+
const operationMode = deviceData.Device.OperationMode;
|
|
931
|
+
const ventilationMode = deviceData.Device.VentilationMode;
|
|
932
|
+
|
|
933
|
+
//accessory
|
|
934
|
+
this.accessory.presets = presetsOnServer;
|
|
935
|
+
this.accessory.hasRoomTemperature = hasRoomTemperature;
|
|
936
|
+
this.accessory.hasSupplyTemperature = hasSupplyTemperature;
|
|
937
|
+
this.accessory.hasOutdoorTemperature = hasOutdoorTemperature;
|
|
938
|
+
this.accessory.hasCoolOperationMode = hasCoolOperationMode;
|
|
939
|
+
this.accessory.hasHeatOperationMode = hasHeatOperationMode;
|
|
940
|
+
this.accessory.hasCO2Sensor = hasCO2Sensor;
|
|
941
|
+
this.accessory.roomCO2Level = roomCO2Level;
|
|
942
|
+
this.accessory.roomCO2Detected = roomCO2Detected;
|
|
943
|
+
this.accessory.hasPM25Sensor = hasPM25Sensor;
|
|
944
|
+
this.accessory.pM25SensorStatus = pM25SensorStatus;
|
|
945
|
+
this.accessory.pM25Level = pM25Level;
|
|
946
|
+
this.accessory.pM25AirQuality = pM25AirQuality;
|
|
947
|
+
this.accessory.hasAutoVentilationMode = hasAutoVentilationMode;
|
|
948
|
+
this.accessory.hasBypassVentilationMode = hasBypassVentilationMode;
|
|
949
|
+
this.accessory.hasAutomaticFanSpeed = hasAutomaticFanSpeed;
|
|
950
|
+
this.accessory.coreMaintenanceRequired = coreMaintenanceRequired;
|
|
951
|
+
this.accessory.filterMaintenanceRequired = filterMaintenanceRequired;
|
|
952
|
+
this.accessory.actualVentilationMode = actualVentilationMode;
|
|
953
|
+
this.accessory.numberOfFanSpeeds = numberOfFanSpeeds;
|
|
954
|
+
this.accessory.power = power ? 1 : 0;
|
|
955
|
+
this.accessory.operationMode = operationMode;
|
|
956
|
+
this.accessory.ventilationMode = ventilationMode;
|
|
957
|
+
this.accessory.roomTemperature = roomTemperature;
|
|
958
|
+
this.accessory.supplyTemperature = supplyTemperature;
|
|
959
|
+
this.accessory.outdoorTemperature = outdoorTemperature;
|
|
960
|
+
this.accessory.setTemperature = setTemperature;
|
|
961
|
+
this.accessory.defaultHeatingSetTemperature = defaultHeatingSetTemperature;
|
|
962
|
+
this.accessory.defaultCoolingSetTemperature = defaultCoolingSetTemperature;
|
|
963
|
+
this.accessory.lockPhysicalControl = 0;
|
|
964
|
+
this.accessory.temperatureIncrement = temperatureIncrement;
|
|
965
|
+
this.accessory.minTempHeat = minTempHeat;
|
|
966
|
+
this.accessory.temperatureIncrement = maxTempHeat;
|
|
967
|
+
this.accessory.minTempCoolDry = minTempCoolDry;
|
|
968
|
+
this.accessory.maxTempCoolDry = maxTempCoolDry;
|
|
969
|
+
|
|
970
|
+
//ventilation mode - 0, HEAT, 2, COOL, 4, 5, 6, FAN, AUTO
|
|
971
|
+
switch (this.displayMode) {
|
|
972
|
+
case 1: //Heater Cooler
|
|
973
|
+
switch (ventilationMode) {
|
|
974
|
+
case 0: //LOSSNAY
|
|
975
|
+
this.accessory.currentOperationMode = 2; //INACTIVE, IDLE, HEATING, COOLIN
|
|
976
|
+
this.accessory.targetOperationMode = 1; //AUTO, HEAT, COOL
|
|
977
|
+
break;
|
|
978
|
+
case 1: //BYPASS
|
|
979
|
+
this.accessory.currentOperationMode = 3;
|
|
980
|
+
this.accessory.targetOperationMode = 2;
|
|
981
|
+
break;
|
|
982
|
+
case 2: //AUTO
|
|
983
|
+
switch (actualVentilationMode) {
|
|
984
|
+
case 0: //LOSSNAY
|
|
985
|
+
this.accessory.currentOperationMode = 2;
|
|
986
|
+
break;
|
|
987
|
+
case 1: //BYPASS
|
|
988
|
+
this.accessory.currentOperationMode = 3;
|
|
989
|
+
break;
|
|
990
|
+
default:
|
|
991
|
+
this.emit('warn', `Unknown actual ventilation mode: ${actualVentilationMode}`);
|
|
992
|
+
break;
|
|
993
|
+
};
|
|
994
|
+
this.accessory.targetOperationMode = 0;
|
|
995
|
+
break;
|
|
996
|
+
default:
|
|
997
|
+
this.emit('warn', `Unknown ventilation mode: ${ventilationMode}`);
|
|
998
|
+
break;
|
|
999
|
+
};
|
|
983
1000
|
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
this.supplyTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
989
|
-
this.supplyTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName} Supply`);
|
|
990
|
-
this.supplyTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
|
|
991
|
-
.setProps({
|
|
992
|
-
minValue: -35,
|
|
993
|
-
maxValue: 150,
|
|
994
|
-
minStep: 0.5
|
|
995
|
-
})
|
|
996
|
-
.onGet(async () => {
|
|
997
|
-
const state = this.accessory.supplyTemperature;
|
|
998
|
-
return state;
|
|
999
|
-
})
|
|
1000
|
-
accessory.addService(this.supplyTemperatureSensorService);
|
|
1001
|
-
};
|
|
1001
|
+
this.accessory.currentOperationMode = !power ? 0 : this.accessory.currentOperationMode;
|
|
1002
|
+
this.accessory.operationModeSetPropsMinValue = hasAutoVentilationMode ? 0 : 1;
|
|
1003
|
+
this.accessory.operationModeSetPropsMaxValue = hasAutoVentilationMode ? 2 : 2;
|
|
1004
|
+
this.accessory.operationModeSetPropsValidValues = hasAutoVentilationMode ? (hasBypassVentilationMode ? [0, 1, 2] : [0, 2]) : (hasBypassVentilationMode ? [1, 2] : [2]);
|
|
1002
1005
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
accessory.addService(this.outdoorTemperatureSensorService);
|
|
1020
|
-
};
|
|
1006
|
+
//fan speed mode
|
|
1007
|
+
this.accessory.fanSpeedSetPropsMaxValue = 2;
|
|
1008
|
+
switch (numberOfFanSpeeds) {
|
|
1009
|
+
case 2: //Fan speed mode 2
|
|
1010
|
+
this.accessory.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][setFanSpeed] : [0, 1, 2][setFanSpeed];
|
|
1011
|
+
this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
|
|
1012
|
+
break;
|
|
1013
|
+
case 3: //Fan speed mode 3
|
|
1014
|
+
this.this.accessory.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][setFanSpeed] : [0, 1, 2, 3][setFanSpeed];
|
|
1015
|
+
this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
|
|
1016
|
+
break;
|
|
1017
|
+
case 4: //Fan speed mode 4
|
|
1018
|
+
this.accessory.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][setFanSpeed] : [0, 1, 2, 3, 4][setFanSpeed];
|
|
1019
|
+
this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
|
|
1020
|
+
break;
|
|
1021
|
+
};
|
|
1021
1022
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1023
|
+
//update characteristics
|
|
1024
|
+
if (this.melCloudService) {
|
|
1025
|
+
this.melCloudService
|
|
1026
|
+
.updateCharacteristic(Characteristic.Active, power)
|
|
1027
|
+
.updateCharacteristic(Characteristic.CurrentHeaterCoolerState, this.accessory.currentOperationMode)
|
|
1028
|
+
.updateCharacteristic(Characteristic.TargetHeaterCoolerState, this.accessory.targetOperationMode)
|
|
1029
|
+
.updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
|
|
1030
|
+
.updateCharacteristic(Characteristic.RotationSpeed, this.accessory.fanSpeed)
|
|
1031
|
+
.updateCharacteristic(Characteristic.LockPhysicalControls, this.accessory.lockPhysicalControl)
|
|
1032
|
+
.updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit);
|
|
1033
|
+
const updateDefCool = hasCoolOperationMode ? this.melCloudService.updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature) : false;
|
|
1034
|
+
const updateDefHeat = hasHeatOperationMode ? this.melCloudService.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
|
|
1035
|
+
};
|
|
1036
|
+
break;
|
|
1037
|
+
case 2: //Thermostat
|
|
1038
|
+
//operation mode - 0, HEAT, 2, COOL, 4, 5, 6, FAN, AUTO
|
|
1039
|
+
switch (ventilationMode) {
|
|
1040
|
+
case 0: //LOSSNAY
|
|
1041
|
+
this.accessory.currentOperationMode = 1; //OFF, HEAT, COOL
|
|
1042
|
+
this.accessory.targetOperationMode = 1; //OFF, HEAT, COOL, AUTO
|
|
1043
|
+
break;
|
|
1044
|
+
case 1: //BYPASS
|
|
1045
|
+
this.accessory.currentOperationMode = 2;
|
|
1046
|
+
this.accessory.targetOperationMode = 2;
|
|
1047
|
+
break;
|
|
1048
|
+
case 2: //AUTO
|
|
1049
|
+
switch (actualVentilationMode) {
|
|
1050
|
+
case 0: //LOSSNAY
|
|
1051
|
+
this.accessory.currentOperationMode = 1;
|
|
1052
|
+
break;
|
|
1053
|
+
case 1: //BYPASS
|
|
1054
|
+
this.accessory.currentOperationMode = 2;
|
|
1055
|
+
break;
|
|
1056
|
+
default:
|
|
1057
|
+
this.emit('warn', `Unknown actual ventilation mode: ${actualVentilationMode}`);
|
|
1058
|
+
break;
|
|
1059
|
+
};
|
|
1060
|
+
this.accessory.targetOperationMode = 3;
|
|
1061
|
+
break;
|
|
1062
|
+
default:
|
|
1063
|
+
this.emit('warn', `Unknown ventilation mode: ${ventilationMode}`);
|
|
1064
|
+
break;
|
|
1065
|
+
};
|
|
1035
1066
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
.onGet(async () => {
|
|
1042
|
-
const value = this.accessory.filterMaintenanceRequired;
|
|
1043
|
-
return value;
|
|
1044
|
-
});
|
|
1045
|
-
this.filterMaintenanceService.getCharacteristic(Characteristic.ResetFilterIndication)
|
|
1046
|
-
.onSet(async (state) => {
|
|
1047
|
-
});
|
|
1048
|
-
accessory.addService(this.filterMaintenanceService);
|
|
1067
|
+
this.accessory.currentOperationMode = !power ? 0 : this.accessory.currentOperationMode;
|
|
1068
|
+
this.accessory.targetOperationMode = !power ? 0 : this.accessory.targetOperationMode;
|
|
1069
|
+
this.accessory.operationModeSetPropsMinValue = hasAutoVentilationMode ? 0 : 0;
|
|
1070
|
+
this.accessory.operationModeSetPropsMaxValue = hasAutoVentilationMode ? 3 : 2;
|
|
1071
|
+
this.accessory.operationModeSetPropsValidValues = hasAutoVentilationMode ? (hasBypassVentilationMode ? [0, 1, 2, 3] : [0, 2, 3]) : (hasBypassVentilationMode ? [0, 1, 2] : [0, 2]);
|
|
1049
1072
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
.onGet(async () => {
|
|
1062
|
-
const value = this.accessory.roomCO2Level;
|
|
1063
|
-
return value;
|
|
1064
|
-
});
|
|
1065
|
-
accessory.addService(this.carbonDioxideSensorService);
|
|
1066
|
-
}
|
|
1073
|
+
//update characteristics
|
|
1074
|
+
if (this.melCloudService) {
|
|
1075
|
+
this.melCloudService
|
|
1076
|
+
.updateCharacteristic(Characteristic.CurrentHeatingCoolingState, this.accessory.currentOperationMode)
|
|
1077
|
+
.updateCharacteristic(Characteristic.TargetHeatingCoolingState, this.accessory.targetOperationMode)
|
|
1078
|
+
.updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
|
|
1079
|
+
.updateCharacteristic(Characteristic.TargetTemperature, setTemperature)
|
|
1080
|
+
.updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit);
|
|
1081
|
+
};
|
|
1082
|
+
break;
|
|
1083
|
+
};
|
|
1067
1084
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
this.airQualitySensorService.getCharacteristic(Characteristic.AirQuality)
|
|
1074
|
-
.onGet(async () => {
|
|
1075
|
-
const value = this.accessory.pM25AirQuality;
|
|
1076
|
-
return value;
|
|
1077
|
-
});
|
|
1078
|
-
this.airQualitySensorService.getCharacteristic(Characteristic.PM2_5Density)
|
|
1079
|
-
.onGet(async () => {
|
|
1080
|
-
const value = this.accessory.pM25Level;
|
|
1081
|
-
return value;
|
|
1082
|
-
});
|
|
1083
|
-
accessory.addService(this.airQualitySensorService);
|
|
1084
|
-
}
|
|
1085
|
+
//update temperature sensors
|
|
1086
|
+
if (this.roomTemperatureSensorService) {
|
|
1087
|
+
this.roomTemperatureSensorService
|
|
1088
|
+
.updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
|
|
1089
|
+
};
|
|
1085
1090
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1091
|
+
if (this.outdoorTemperatureSensorService) {
|
|
1092
|
+
this.outdoorTemperatureSensorService
|
|
1093
|
+
.updateCharacteristic(Characteristic.CurrentTemperature, outdoorTemperature)
|
|
1094
|
+
};
|
|
1090
1095
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1096
|
+
if (this.supplyTemperatureSensorService) {
|
|
1097
|
+
this.supplyTemperatureSensorService
|
|
1098
|
+
.updateCharacteristic(Characteristic.CurrentTemperature, supplyTemperature)
|
|
1099
|
+
};
|
|
1094
1100
|
|
|
1095
|
-
//
|
|
1096
|
-
|
|
1101
|
+
//update core maintenance
|
|
1102
|
+
if (this.coreMaintenanceService) {
|
|
1103
|
+
this.coreMaintenanceService
|
|
1104
|
+
.updateCharacteristic(Characteristic.FilterChangeIndication, coreMaintenanceRequired)
|
|
1105
|
+
}
|
|
1097
1106
|
|
|
1098
|
-
//
|
|
1099
|
-
|
|
1107
|
+
//update filter maintenance
|
|
1108
|
+
if (this.filterMaintenanceService) {
|
|
1109
|
+
this.filterMaintenanceService
|
|
1110
|
+
.updateCharacteristic(Characteristic.FilterChangeIndication, filterMaintenanceRequired)
|
|
1111
|
+
}
|
|
1100
1112
|
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
switch (state) {
|
|
1115
|
-
case true:
|
|
1116
|
-
preset.previousSettings = deviceData.Device;
|
|
1117
|
-
deviceData.Device.SetTemperature = presetData.SetTemperature;
|
|
1118
|
-
deviceData.Device.Power = presetData.Power;
|
|
1119
|
-
deviceData.Device.OperationMode = presetData.OperationMode;
|
|
1120
|
-
deviceData.Device.VentilationMode = presetData.VentilationMode;
|
|
1121
|
-
deviceData.Device.SetFanSpeed = presetData.FanSpeed;
|
|
1122
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
1123
|
-
break;
|
|
1124
|
-
case false:
|
|
1125
|
-
deviceData.Device.SetTemperature = preset.previousSettings.SetTemperature;
|
|
1126
|
-
deviceData.Device.Power = preset.previousSettings.Power;
|
|
1127
|
-
deviceData.Device.OperationMode = preset.previousSettings.OperationMode;
|
|
1128
|
-
deviceData.Device.VentilationMode = preset.previousSettings.VentilationMode;
|
|
1129
|
-
deviceData.Device.SetFanSpeed = preset.previousSettings.FanSpeed;
|
|
1130
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
1131
|
-
break;
|
|
1132
|
-
};
|
|
1113
|
+
//update CO2 sensor
|
|
1114
|
+
if (this.carbonDioxideSensorService) {
|
|
1115
|
+
this.carbonDioxideSensorService
|
|
1116
|
+
.updateCharacteristic(Characteristic.CarbonDioxideDetected, roomCO2Detected)
|
|
1117
|
+
.updateCharacteristic(Characteristic.CarbonDioxideLevel, roomCO2Level)
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
//update PM2.5 sensor
|
|
1121
|
+
if (this.airQualitySensorService) {
|
|
1122
|
+
this.airQualitySensorService
|
|
1123
|
+
.updateCharacteristic(Characteristic.AirQuality, pM25AirQuality)
|
|
1124
|
+
.updateCharacteristic(Characteristic.PM2_5Density, pM25Level)
|
|
1125
|
+
}
|
|
1133
1126
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1127
|
+
//update presets state
|
|
1128
|
+
if (this.presetsConfigured.length > 0) {
|
|
1129
|
+
for (let i = 0; i < this.presetsConfigured.length; i++) {
|
|
1130
|
+
const preset = this.presetsConfigured[i];
|
|
1131
|
+
const presetData = presetsOnServer.find(p => p.ID === preset.Id);
|
|
1132
|
+
|
|
1133
|
+
preset.state = presetData ? (presetData.Power === power
|
|
1134
|
+
&& presetData.SetTemperature === setTemperature
|
|
1135
|
+
&& presetData.OperationMode === operationMode
|
|
1136
|
+
&& presetData.VentilationMode === ventilationMode
|
|
1137
|
+
&& presetData.FanSpeed === setFanSpeed) : false;
|
|
1138
|
+
|
|
1139
|
+
if (this.presetsServices) {
|
|
1140
|
+
const characteristicType = preset.characteristicType;
|
|
1141
|
+
this.presetsServices[i]
|
|
1142
|
+
.updateCharacteristic(characteristicType, preset.state)
|
|
1138
1143
|
};
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
this.presetsServices.push(presetService);
|
|
1142
|
-
accessory.addService(presetService);
|
|
1143
|
-
};
|
|
1144
|
+
};
|
|
1145
|
+
};
|
|
1144
1146
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1147
|
+
//update buttons state
|
|
1148
|
+
if (this.buttonsConfiguredCount > 0) {
|
|
1149
|
+
for (let i = 0; i < this.buttonsConfiguredCount; i++) {
|
|
1150
|
+
const button = this.buttonsConfigured[i];
|
|
1151
|
+
const mode = button.mode;;
|
|
1152
|
+
switch (mode) {
|
|
1153
|
+
case 0: //POWER ON,OFF
|
|
1154
|
+
button.state = (power === true);
|
|
1155
|
+
break;
|
|
1156
|
+
case 1: //OPERATION MODE RECOVERY
|
|
1157
|
+
button.state = power ? (ventilationMode === 0) : false;
|
|
1158
|
+
break;
|
|
1159
|
+
case 2: //OPERATION MODE BYPASS
|
|
1160
|
+
button.state = power ? (ventilationMode === 1) : false;
|
|
1161
|
+
break;
|
|
1162
|
+
case 3: //OPERATION MODE AUTO
|
|
1163
|
+
button.state = power ? (ventilationMode === 2) : false;
|
|
1164
|
+
break;
|
|
1165
|
+
case 4: //NIGHT PURGE MODE
|
|
1166
|
+
button.state = power ? (nightPurgeMode === true) : false;
|
|
1167
|
+
break;
|
|
1168
|
+
case 10: //FAN SPEED MODE AUTO
|
|
1169
|
+
button.state = power ? (setFanSpeed === 0) : false;
|
|
1170
|
+
break;
|
|
1171
|
+
case 11: //FAN SPEED MODE 1
|
|
1172
|
+
button.state = power ? (setFanSpeed === 1) : false;
|
|
1173
|
+
break;
|
|
1174
|
+
case 12: //FAN SPEED MODE 2
|
|
1175
|
+
button.state = power ? (setFanSpeed === 2) : false;
|
|
1176
|
+
break;
|
|
1177
|
+
case 13: //FAN SPEED MODE 3
|
|
1178
|
+
button.state = power ? (setFanSpeed === 3) : false;
|
|
1179
|
+
break;
|
|
1180
|
+
case 14: //FAN SPEED MODE 4
|
|
1181
|
+
button.state = power ? (setFanSpeed === 4) : false;
|
|
1182
|
+
break;
|
|
1183
|
+
case 15: //PHYSICAL LOCK CONTROLS
|
|
1184
|
+
button.state = (this.accessory.lockPhysicalControl === 1);
|
|
1185
|
+
break;
|
|
1186
|
+
case 16: //ROOM TEMP HIDE
|
|
1187
|
+
button.state = (hideRoomTemperature === true);
|
|
1188
|
+
break;
|
|
1189
|
+
case 17: //SUPPLY TEMP HIDE
|
|
1190
|
+
button.state = (hideSupplyTemperature === true);
|
|
1191
|
+
break;
|
|
1192
|
+
case 18: //OUTDOOR TEMP HIDE
|
|
1193
|
+
button.state = (hideOutdoorTemperature === true);
|
|
1194
|
+
break;
|
|
1195
|
+
default: //Unknown button
|
|
1196
|
+
this.emit('warn', `Unknown button mode: ${mode} detected.`);
|
|
1197
|
+
break;
|
|
1198
|
+
};
|
|
1149
1199
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1200
|
+
//update services
|
|
1201
|
+
if (this.buttonsServices) {
|
|
1202
|
+
const characteristicType = button.characteristicType;
|
|
1203
|
+
this.buttonsServices[i]
|
|
1204
|
+
.updateCharacteristic(characteristicType, button.state)
|
|
1205
|
+
};
|
|
1206
|
+
};
|
|
1207
|
+
};
|
|
1152
1208
|
|
|
1153
|
-
//
|
|
1154
|
-
|
|
1209
|
+
//log current state
|
|
1210
|
+
if (!this.disableLogInfo) {
|
|
1211
|
+
this.emit('message', `Power: ${power ? 'ON' : 'OFF'}`);
|
|
1212
|
+
this.emit('message', `Target ventilation mode: ${Ventilation.OperationMode[ventilationMode]}`);
|
|
1213
|
+
this.emit('message', `Current ventilation mode: ${Ventilation.OperationMode[actualVentilationMode]}`);
|
|
1214
|
+
this.emit('message', `Target temperature: ${setTemperature}${this.accessory.temperatureUnit}`);
|
|
1215
|
+
this.emit('message', `Room temperature: ${roomTemperature}${this.accessory.temperatureUnit}`);
|
|
1216
|
+
const info1 = hasSupplyTemperature && deviceData.Device.SupplyTemperature !== null ? this.emit('message', `Supply temperature: ${roomTemperature}${this.accessory.temperatureUnit}`) : false;
|
|
1217
|
+
const info2 = hasOutdoorTemperature && deviceData.Device.OutdoorTemperature !== null ? this.emit('message', `Outdoor temperature: ${roomTemperature}${this.accessory.temperatureUnit}`) : false;
|
|
1218
|
+
this.emit('message', `Fan speed mode: ${Ventilation.FanSpeed[setFanSpeed]}`);
|
|
1219
|
+
this.emit('message', `Temperature display unit: ${this.accessory.temperatureUnit}`);
|
|
1220
|
+
this.emit('message', `Core maintenance: ${Ventilation.CoreMaintenance[coreMaintenanceRequired]}`);
|
|
1221
|
+
this.emit('message', `Filter maintenance: ${Ventilation.FilterMaintenance[filterMaintenanceRequired]}`);
|
|
1222
|
+
const info5 = hasCO2Sensor ? this.emit('message', `CO2 detected: ${Ventilation.Co2Detected[roomCO2Detected]}`) : false;
|
|
1223
|
+
const info6 = hasCO2Sensor ? this.emit('message', `CO2 level: ${roomCO2Level} ppm`) : false;
|
|
1224
|
+
const info7 = hasPM25Sensor ? this.emit('message', `PM2.5 air quality: ${Ventilation.PM25AirQuality[pM25AirQuality]}`) : false;
|
|
1225
|
+
const info8 = hasPM25Sensor ? this.emit('message', `PM2.5 level: ${pM25Level} µg/m`) : false;
|
|
1226
|
+
};
|
|
1155
1227
|
|
|
1156
|
-
//
|
|
1157
|
-
|
|
1228
|
+
//start prepare accessory
|
|
1229
|
+
if (!this.startPrepareAccessory) {
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1158
1232
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1233
|
+
try {
|
|
1234
|
+
const accessory = await this.prepareAccessory(this.accountInfo, deviceData, this.deviceId, this.deviceTypeText, this.deviceName, this.accountName);
|
|
1235
|
+
this.emit('publishAccessory', accessory);
|
|
1236
|
+
this.startPrepareAccessory = false;
|
|
1237
|
+
} catch (error) {
|
|
1238
|
+
this.emit('error', error);
|
|
1239
|
+
};
|
|
1240
|
+
})
|
|
1241
|
+
.on('success', (message) => {
|
|
1242
|
+
this.emit('success', message);
|
|
1243
|
+
})
|
|
1244
|
+
.on('message', (message) => {
|
|
1245
|
+
this.emit('message', message);
|
|
1246
|
+
})
|
|
1247
|
+
.on('debug', (debug) => {
|
|
1248
|
+
this.emit('debug', debug);
|
|
1249
|
+
})
|
|
1250
|
+
.on('warn', async (warn) => {
|
|
1251
|
+
this.emit('warn', warn);
|
|
1252
|
+
})
|
|
1253
|
+
.on('error', async (error) => {
|
|
1254
|
+
this.emit('error', error);
|
|
1255
|
+
});
|
|
1161
1256
|
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
const characteristicType = button.characteristicType;
|
|
1165
|
-
const buttonService = new serviceType(serviceName, `Button ${deviceId} ${i}`);
|
|
1166
|
-
buttonService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
1167
|
-
buttonService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
1168
|
-
buttonService.getCharacteristic(characteristicType)
|
|
1169
|
-
.onGet(async () => {
|
|
1170
|
-
const state = button.state;
|
|
1171
|
-
return state;
|
|
1172
|
-
})
|
|
1173
|
-
.onSet(async (state) => {
|
|
1174
|
-
try {
|
|
1175
|
-
switch (mode) {
|
|
1176
|
-
case 0: //POWER ON,OFF
|
|
1177
|
-
deviceData.Device.Power = state;
|
|
1178
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power;
|
|
1179
|
-
break;
|
|
1180
|
-
case 1: //OPERATING MODE RECOVERY
|
|
1181
|
-
button.previousValue = state ? deviceData.Device.VentilationMode : button.previousValue ?? deviceData.Device.VentilationMode;
|
|
1182
|
-
deviceData.Device.Power = true;
|
|
1183
|
-
deviceData.Device.VentilationMode = state ? 0 : button.previousValue;
|
|
1184
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
1185
|
-
break;
|
|
1186
|
-
case 2: //OPERATING MODE BYPASS
|
|
1187
|
-
button.previousValue = state ? deviceData.Device.VentilationMode : button.previousValue ?? deviceData.Device.VentilationMode;
|
|
1188
|
-
deviceData.Device.Power = true;
|
|
1189
|
-
deviceData.Device.VentilationMode = state ? 1 : button.previousValue;
|
|
1190
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
1191
|
-
break
|
|
1192
|
-
case 3: //OPERATING MODE AUTO
|
|
1193
|
-
button.previousValue = state ? deviceData.Device.VentilationMode : button.previousValue ?? deviceData.Device.VentilationMode;
|
|
1194
|
-
deviceData.Device.Power = true;
|
|
1195
|
-
deviceData.Device.VentilationMode = state ? 2 : button.previousValue;
|
|
1196
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
1197
|
-
break;
|
|
1198
|
-
case 4: //NIGHT PURGE MODE
|
|
1199
|
-
deviceData.Device.Power = true;
|
|
1200
|
-
deviceData.Device.NightPurgeMode = state;
|
|
1201
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power
|
|
1202
|
-
break;
|
|
1203
|
-
case 10: //FAN SPEED MODE AUTO
|
|
1204
|
-
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
1205
|
-
deviceData.Device.Power = true;
|
|
1206
|
-
deviceData.Device.SetFanSpeed = state ? 0 : button.previousValue;
|
|
1207
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
1208
|
-
break;
|
|
1209
|
-
case 11: //FAN SPEED MODE 1
|
|
1210
|
-
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
1211
|
-
deviceData.Device.Power = true;
|
|
1212
|
-
deviceData.Device.SetFanSpeed = state ? 1 : button.previousValue;
|
|
1213
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
1214
|
-
break;
|
|
1215
|
-
case 12: //FAN SPEED MODE 2
|
|
1216
|
-
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
1217
|
-
deviceData.Device.Power = true;
|
|
1218
|
-
deviceData.Device.SetFanSpeed = state ? 2 : button.previousValue;
|
|
1219
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
1220
|
-
break;
|
|
1221
|
-
case 13: //FAN SPEED MODE 3
|
|
1222
|
-
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
1223
|
-
deviceData.Device.Power = true;
|
|
1224
|
-
deviceData.Device.SetFanSpeed = state ? 3 : button.previousValue;
|
|
1225
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
1226
|
-
break;
|
|
1227
|
-
case 14: //FAN MODE 4
|
|
1228
|
-
button.previousValue = state ? deviceData.Device.SetFanSpeed : button.previousValue ?? deviceData.Device.SetFanSpeed;
|
|
1229
|
-
deviceData.Device.Power = true;
|
|
1230
|
-
deviceData.Device.SetFanSpeed = state ? 4 : button.previousValue;
|
|
1231
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.SetFanSpeed;
|
|
1232
|
-
break;
|
|
1233
|
-
case 15: //PHYSICAL LOCK CONTROLS
|
|
1234
|
-
deviceData.Device = deviceData.Device;
|
|
1235
|
-
deviceData.Device.EffectiveFlags = Ventilation.EffectiveFlags.Prohibit;
|
|
1236
|
-
break;
|
|
1237
|
-
case 16: //ROOM TEMP HIDE
|
|
1238
|
-
deviceData.HideRoomTemperature = state;
|
|
1239
|
-
break;
|
|
1240
|
-
case 17: //SUPPLY TEMP HIDE
|
|
1241
|
-
deviceData.HideSupplyTemperature = state;
|
|
1242
|
-
break;
|
|
1243
|
-
case 18: //OUTDOOR EMP HIDE
|
|
1244
|
-
deviceData.hideOutdoorTemperature = state;
|
|
1245
|
-
break;
|
|
1246
|
-
default:
|
|
1247
|
-
this.emit('message', `Unknown button mode: ${mode}`);
|
|
1248
|
-
break;
|
|
1249
|
-
};
|
|
1257
|
+
//check state
|
|
1258
|
+
await this.melCloudErv.checkState();
|
|
1250
1259
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
} catch (error) {
|
|
1254
|
-
this.emit('warn', `Set button error: ${error}`);
|
|
1255
|
-
};
|
|
1256
|
-
});
|
|
1257
|
-
this.buttonsServices.push(buttonService);
|
|
1258
|
-
accessory.addService(buttonService);
|
|
1259
|
-
};
|
|
1260
|
-
};
|
|
1260
|
+
//start impule generator
|
|
1261
|
+
await this.melCloudErv.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
|
|
1261
1262
|
|
|
1262
|
-
return
|
|
1263
|
+
return true;
|
|
1263
1264
|
} catch (error) {
|
|
1264
|
-
throw new Error(`
|
|
1265
|
+
throw new Error(`Start error: ${error}`);
|
|
1265
1266
|
};
|
|
1266
1267
|
};
|
|
1267
1268
|
};
|