homebridge-melcloud-control 4.10.20-beta.1 → 4.10.20-beta.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.10.20-beta.1",
4
+ "version": "4.10.20-beta.3",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
package/src/deviceata.js CHANGED
@@ -319,6 +319,14 @@ class DeviceAta extends EventEmitter {
319
319
  const max = numberOfFanSpeeds;
320
320
  const minValue = supportsAutomaticFanSpeed ? 0 : 1;
321
321
  const clampedValue = Math.min(Math.max(value, minValue), max);
322
+
323
+ //Apple Home always resends its own remembered (non-zero) fan speed together with Active when powering on from off
324
+ //Auto (0) can't be represented on that dial, so ignore this phantom value while the unit is off and currently in Auto
325
+ if (!this.accessory.power && this.accessory.currentFanSpeed === 0 && clampedValue !== 0) {
326
+ if (this.logDebug) this.emit('debug', `Ignore set fan speed while powering on from Auto: ${clampedValue}`);
327
+ return;
328
+ }
329
+
322
330
  const payload = { setFanSpeed: clampedValue };
323
331
  if (this.logInfo) this.emit('info', `Set fan speed mode: ${AirConditioner.FanSpeedMapEnumToString[clampedValue]}`);
324
332
  await this.melCloudAta.send(this.accountType, this.displayType, deviceData, payload, AirConditioner.EffectiveFlags.SetFanSpeed);
package/src/deviceerv.js CHANGED
@@ -274,17 +274,23 @@ class DeviceErv extends EventEmitter {
274
274
  minStep: 1
275
275
  })
276
276
  .onGet(async () => {
277
- const value = this.accessory.fanSpeed;
277
+ const value = this.accessory.currentFanSpeed;
278
278
  return value;
279
279
  })
280
280
  .onSet(async (value) => {
281
281
  try {
282
- const payload = {};
283
282
  const max = numberOfFanSpeeds;
284
283
  const minValue = supportsAutomaticFanSpeed ? 0 : 1;
285
284
  const clampedValue = Math.min(Math.max(value, minValue), max);
286
285
 
287
- payload.setFanSpeed = clampedValue;
286
+ //Apple Home always resends its own remembered (non-zero) fan speed together with Active when powering on from off
287
+ //Auto (0) can't be represented on that dial, so ignore this phantom value while the unit is off and currently in Auto
288
+ if (!this.accessory.power && this.accessory.currentFanSpeed === 0 && clampedValue !== 0) {
289
+ if (this.logDebug) this.emit('debug', `Ignore set fan speed while powering on from Auto: ${clampedValue}`);
290
+ return;
291
+ }
292
+
293
+ const payload = { setFanSpeed: clampedValue };
288
294
  if (this.logInfo) this.emit('info', `Set fan speed mode: ${Ventilation.FanSpeedMapEnumToString[clampedValue]}`);
289
295
  await this.melCloudErv.send(this.accountType, this.displayType, deviceData, payload, Ventilation.EffectiveFlags.SetFanSpeed);
290
296
  } catch (error) {
@@ -1215,7 +1221,7 @@ class DeviceErv extends EventEmitter {
1215
1221
  { type: Characteristic.TemperatureDisplayUnits, value: obj.useFahrenheit },
1216
1222
  );
1217
1223
 
1218
- if (supportsFanSpeed) characteristics.push({ type: Characteristic.RotationSpeed, value: obj.fanSpeed });
1224
+ if (supportsFanSpeed) characteristics.push({ type: Characteristic.RotationSpeed, value: obj.currentFanSpeed });
1219
1225
  if (supportsCoolOperationMode) characteristics.push({ type: Characteristic.CoolingThresholdTemperature, value: Math.max(ventilationMode === 2 ? defaultCoolingSetTemperature : setTemperature, minTempCoolDryAuto) });
1220
1226
  if (supportsHeatOperationMode) characteristics.push({ type: Characteristic.HeatingThresholdTemperature, value: Math.max(ventilationMode === 2 ? defaultHeatingSetTemperature : setTemperature, minTempHeat) });
1221
1227
  break;
@@ -208,7 +208,8 @@ class MelCloudAta extends EventEmitter {
208
208
  path = ApiUrls.Post.UpdateApplicationOptions;
209
209
  break;
210
210
  default: {
211
- const changes = this.functions.filterChanges(payload, deviceData.Device);
211
+ //compare against the API wrapper's own live-polled state, not the caller's closure-captured (possibly stale) deviceData
212
+ const changes = this.functions.filterChanges(payload, this.deviceData.Device);
212
213
  if (Object.keys(changes).length === 0) {
213
214
  if (this.logDebug) this.emit('debug', `Ignore send, no changes: ${JSON.stringify(payload)}`);
214
215
  return true;
@@ -308,7 +309,8 @@ class MelCloudAta extends EventEmitter {
308
309
  payload = {};
309
310
  break;
310
311
  default: {
311
- const changes = this.functions.filterChanges(payload, deviceData.Device);
312
+ //compare against the API wrapper's own live-polled state, not the caller's closure-captured (possibly stale) deviceData
313
+ const changes = this.functions.filterChanges(payload, this.deviceData.Device);
312
314
  if (Object.keys(changes).length === 0) {
313
315
  if (this.logDebug) this.emit('debug', `Ignore send, no changes: ${JSON.stringify(payload)}`);
314
316
  return true;
@@ -340,7 +342,7 @@ class MelCloudAta extends EventEmitter {
340
342
  }
341
343
 
342
344
  //send payload
343
- if (this.logDebug) this.emit('debug', `Send data: ${JSON.stringify(payload, null, 2)}`);
345
+ if (!this.logDebug) this.emit('debug', `Send data: ${JSON.stringify(payload, null, 2)}`);
344
346
  await this.client(path, { method: method, data: payload });
345
347
  return true;
346
348
  default:
@@ -187,7 +187,8 @@ class MelCloudAtw extends EventEmitter {
187
187
  path = ApiUrls.Post.UpdateApplicationOptions;
188
188
  break;
189
189
  default:
190
- if (!this.functions.hasChanges(payload, deviceData.Device)) {
190
+ //compare against the API wrapper's own live-polled state, not the caller's closure-captured (possibly stale) deviceData
191
+ if (!this.functions.hasChanges(payload, this.deviceData.Device)) {
191
192
  if (this.logDebug) this.emit('debug', `Ignore send, no changes: ${JSON.stringify(payload)}`);
192
193
  return true;
193
194
  }
@@ -257,7 +258,8 @@ class MelCloudAtw extends EventEmitter {
257
258
  payload = {};
258
259
  break;
259
260
  default:
260
- if (!this.functions.hasChanges(payload, deviceData.Device)) {
261
+ //compare against the API wrapper's own live-polled state, not the caller's closure-captured (possibly stale) deviceData
262
+ if (!this.functions.hasChanges(payload, this.deviceData.Device)) {
261
263
  if (this.logDebug) this.emit('debug', `Ignore send, no changes: ${JSON.stringify(payload)}`);
262
264
  return true;
263
265
  }
@@ -183,7 +183,8 @@ class MelCloudErv extends EventEmitter {
183
183
  path = ApiUrls.Post.UpdateApplicationOptions;
184
184
  break;
185
185
  default: {
186
- const changes = this.functions.filterChanges(payload, deviceData.Device);
186
+ //compare against the API wrapper's own live-polled state, not the caller's closure-captured (possibly stale) deviceData
187
+ const changes = this.functions.filterChanges(payload, this.deviceData.Device);
187
188
  if (Object.keys(changes).length === 0) {
188
189
  if (this.logDebug) this.emit('debug', `Ignore send, no changes: ${JSON.stringify(payload)}`);
189
190
  return true;
@@ -273,7 +274,8 @@ class MelCloudErv extends EventEmitter {
273
274
  payload = {};
274
275
  break;
275
276
  default: {
276
- const changes = this.functions.filterChanges(payload, deviceData.Device);
277
+ //compare against the API wrapper's own live-polled state, not the caller's closure-captured (possibly stale) deviceData
278
+ const changes = this.functions.filterChanges(payload, this.deviceData.Device);
277
279
  if (Object.keys(changes).length === 0) {
278
280
  if (this.logDebug) this.emit('debug', `Ignore send, no changes: ${JSON.stringify(payload)}`);
279
281
  return true;