From 88dbf2489387bca9a6f7d6421f63c4e518666c17 Mon Sep 17 00:00:00 2001 From: Black-Thunder Date: Mon, 25 May 2020 14:34:45 +0200 Subject: [PATCH] 0.0.2-alpha4: - operation modes "Dry" and "Vent" added, removed confusing mode "Off" - control of fan speed, horizontal and vertical vane direction added - reduced amount of logging entries --- README.md | 5 ++ io-package.json | 2 +- lib/commonDefines.js | 14 +++-- lib/jsonHelper.js | 2 +- lib/melcloudDevice.js | 119 ++++++++++++++++++++++++++++++++++++---- lib/melcloudPlatform.js | 4 ++ main.js | 25 +++++++-- package.json | 2 +- 8 files changed, 149 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 7202026b..bacc5571 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,11 @@ TODO ## Changelog +### 0.0.2-alpha4 25.05.2020 +* (Black-Thunder) operation modes "Dry" and "Vent" added, removed confusing mode "Off" (device state is now only controlled by "power") +* (Black-Thunder) control of fan speed, horizontal and vertical vane direction added +* (Black-Thunder) reduced amount of logging entries + ### 0.0.2-alpha3 24.05.2020 * (Black-Thunder) fixed 'request' dependency diff --git a/io-package.json b/io-package.json index 24b99782..e5c221d1 100644 --- a/io-package.json +++ b/io-package.json @@ -1,7 +1,7 @@ { "common": { "name": "melcloud", - "version": "0.0.2-alpha3", + "version": "0.0.2-alpha4", "news": { "0.0.2": { "en": "first implementation of device control, added more device options, extended and optimized logging (e.g. when logging into MelCloud), implemented polling of cloud data", diff --git a/lib/commonDefines.js b/lib/commonDefines.js index d4d5af05..472b8a7f 100644 --- a/lib/commonDefines.js +++ b/lib/commonDefines.js @@ -25,26 +25,32 @@ exports.AdapterStateIDs = Object.freeze({ MinTempAuto: "minTempAuto", MaxTempAuto: "maxTempAuto", RoomTemp: "roomTemp", + NumberOfFanSpeeds: "numberOfFanSpeeds", LastCommunication: "lastCommunication", NextCommunication: "nextCommunication", // device.XXX.control Power: "power", Mode: "mode", - TargetTemp: "targetTemp" + TargetTemp: "targetTemp", + FanSpeed: "fanSpeed", + VaneHorizontalDirection: "vaneHorizontalDirection", + VaneVerticalDirection: "vaneVerticalDirection" }); exports.DeviceOperationModes = Object.freeze({ UNDEF: { power: false, value: -1, effectiveFlags: -1 }, OFF: { power: false, value: 0, effectiveFlags: 1 }, HEAT: { power: true, value: 1, effectiveFlags: 1 + 2 }, + DRY: { power: true, value: 2, effectiveFlags: 1 + 2 }, COOL: { power: true, value: 3, effectiveFlags: 1 + 2 }, + VENT: { power: true, value: 7, effectiveFlags: 1 + 2 }, AUTO: { power: true, value: 8, effectiveFlags: 1 + 2 } }); exports.DeviceOptions = Object.freeze({ TargetHeatingCoolingState : { id: "TargetHeatingCoolingState" }, TargetTemperature: { id: "TargetTemperature", effectiveFlags: 4 }, - RotationSpeed: { id: "RotationSpeed", effectiveFlags: 8 }, - TargetHorizontalTiltAngle: { id: "TargetHorizontalTiltAngle", effectiveFlags: 256 }, - TargetVerticalTiltAngle: { id: "TargetVerticalTiltAngle", effectiveFlags: 16 } + FanSpeed: { id: "FanSpeed", effectiveFlags: 8 }, + VaneHorizontalDirection: { id: "VaneHorizontalDirection", effectiveFlags: 256 }, + VaneVerticalDirection: { id: "VaneVerticalDirection", effectiveFlags: 16 } }); \ No newline at end of file diff --git a/lib/jsonHelper.js b/lib/jsonHelper.js index dd3c836a..319911c3 100644 --- a/lib/jsonHelper.js +++ b/lib/jsonHelper.js @@ -3,7 +3,7 @@ class JSONHelper { static ParseCloudResponse(raw, loggingInstance) { try { - loggingInstance.log.debug("Response from cloud: " + raw); + loggingInstance.log.silly("Response from cloud: " + raw); const parsedRaw = JSON.parse(raw); loggingInstance.log.debug("Parsed response from cloud: " + JSON.stringify(parsedRaw)); return parsedRaw; diff --git a/lib/melcloudDevice.js b/lib/melcloudDevice.js index b728c926..629e4c44 100644 --- a/lib/melcloudDevice.js +++ b/lib/melcloudDevice.js @@ -30,6 +30,7 @@ class MelcloudDevice { this.minTempAuto = 0; this.maxTempAuto = 0; this.roomTemp = 0; + this.numberOfFanSpeeds = 0; this.lastCommunication = null; this.nextCommunication = null; @@ -37,6 +38,9 @@ class MelcloudDevice { this.power = false; this.operationMode = commonDefines.DeviceOperationModes.UNDEF.value; this.targetTemp = 0; + this.fanSpeed = 0; + this.vaneVerticalDirection = 0; + this.vaneHorizontalDirection = 0; } async Save() { @@ -246,6 +250,20 @@ class MelcloudDevice { }); await gthat.setStateAsync(infoPrefix + commonDefines.AdapterStateIDs.RoomTemp, this.roomTemp, true); + await gthat.setObjectNotExistsAsync(infoPrefix + commonDefines.AdapterStateIDs.NumberOfFanSpeeds, { + type: "state", + common: { + name: "Number of fan speeds", + type: "number", + role: "value", + read: true, + write: false, + desc: "Number of available fan speeds" + }, + native: {} + }); + await gthat.setStateAsync(infoPrefix + commonDefines.AdapterStateIDs.NumberOfFanSpeeds, this.numberOfFanSpeeds, true); + await gthat.setObjectNotExistsAsync(infoPrefix + commonDefines.AdapterStateIDs.LastCommunication, { type: "state", common: { @@ -303,9 +321,10 @@ class MelcloudDevice { write: true, desc: "Operation mode of the device", "states": { - 0: "OFF", 1: "HEAT", + 2: "DRY", 3: "COOL", + 7: "VENT", 8: "AUTO" } }, @@ -328,6 +347,54 @@ class MelcloudDevice { }); await gthat.setStateAsync(controlPrefix + commonDefines.AdapterStateIDs.TargetTemp, this.targetTemp, true); + await gthat.setObjectNotExistsAsync(controlPrefix + commonDefines.AdapterStateIDs.FanSpeed, { + type: "state", + common: { + name: "Fan speed", + type: "number", + role: "value", + min: 0, + max: this.numberOfFanSpeeds, + read: true, + write: true, + desc: "Current fan speed of the device (0 = auto, 1...numberOfFanSpeeds = fan speed low to max)" + }, + native: {} + }); + await gthat.setStateAsync(controlPrefix + commonDefines.AdapterStateIDs.FanSpeed, this.fanSpeed, true); + + await gthat.setObjectNotExistsAsync(controlPrefix + commonDefines.AdapterStateIDs.VaneVerticalDirection, { + type: "state", + common: { + name: "Vane vertical direction", + type: "number", + role: "value", + min: 0, + max: 5, + read: true, + write: true, + desc: "Current vertical direction of the device's vane (0 = swing, 1...5 = vane lowest to highest position)" + }, + native: {} + }); + await gthat.setStateAsync(controlPrefix + commonDefines.AdapterStateIDs.VaneVerticalDirection, this.vaneVerticalDirection, true); + + await gthat.setObjectNotExistsAsync(controlPrefix + commonDefines.AdapterStateIDs.VaneHorizontalDirection, { + type: "state", + common: { + name: "Vane horizontal direction", + type: "number", + role: "value", + min: 0, + max: 5, + read: true, + write: true, + desc: "Current horizontal direction of the device's vane (0 = swing, 1...5 = vane lowest to highest position)" + }, + native: {} + }); + await gthat.setStateAsync(controlPrefix + commonDefines.AdapterStateIDs.VaneHorizontalDirection, this.vaneHorizontalDirection, true); + //// END CONTROL gthat.log.debug("Saved device: " + this.id + " (" + this.name + ")"); @@ -341,6 +408,7 @@ class MelcloudDevice { this.log("Dequeuing remote request for. " + args[3].name + " - " + args[1].displayName); this.proxyAirInfo.apply(this, args); }*/ + callback && callback(deviceOption, value); return; } @@ -403,11 +471,21 @@ class MelcloudDevice { r.OperationMode = commonDefines.DeviceOperationModes.HEAT.value; r.EffectiveFlags = commonDefines.DeviceOperationModes.HEAT.effectiveFlags; break; + case commonDefines.DeviceOperationModes.DRY: + r.Power = commonDefines.DeviceOperationModes.DRY.power; + r.OperationMode = commonDefines.DeviceOperationModes.DRY.value; + r.EffectiveFlags = commonDefines.DeviceOperationModes.DRY.effectiveFlags; + break; case commonDefines.DeviceOperationModes.COOL: r.Power = commonDefines.DeviceOperationModes.COOL.power; r.OperationMode = commonDefines.DeviceOperationModes.COOL.value; r.EffectiveFlags = commonDefines.DeviceOperationModes.COOL.effectiveFlags; break; + case commonDefines.DeviceOperationModes.VENT: + r.Power = commonDefines.DeviceOperationModes.VENT.power; + r.OperationMode = commonDefines.DeviceOperationModes.VENT.value; + r.EffectiveFlags = commonDefines.DeviceOperationModes.VENT.effectiveFlags; + break; case commonDefines.DeviceOperationModes.AUTO: r.Power = commonDefines.DeviceOperationModes.AUTO.power; r.OperationMode = commonDefines.DeviceOperationModes.AUTO.value; @@ -430,21 +508,38 @@ class MelcloudDevice { callback(); return; }*/ - else if (deviceOption == commonDefines.DeviceOptions.RotationSpeed) { - r.SetFanSpeed = (value / 100.0 * r.NumberOfFanSpeeds).toFixed(0); - r.EffectiveFlags = commonDefines.DeviceOptions.RotationSpeed.effectiveFlags; + else if (deviceOption == commonDefines.DeviceOptions.FanSpeed) { + if(value > r.NumberOfFanSpeeds) { + gthat.log.info("Fan speed limited to " + r.NumberOfFanSpeeds + " because device can't handle more than that!"); + value = r.NumberOfFanSpeeds; + } + r.SetFanSpeed = value; + r.EffectiveFlags = commonDefines.DeviceOptions.FanSpeed.effectiveFlags; } - else if (deviceOption == commonDefines.DeviceOptions.TargetHorizontalTiltAngle) { - r.VaneHorizontal = ((value + 90.0) / 45.0 + 1.0).toFixed(0); - r.EffectiveFlags = commonDefines.DeviceOptions.TargetHorizontalTiltAngle.effectiveFlags; + else if (deviceOption == commonDefines.DeviceOptions.VaneHorizontalDirection) { + //r.VaneHorizontal = ((value + 90.0) / 45.0 + 1.0).toFixed(0); + if(value > 5) { + gthat.log.info("Vane horizontal direction limited to 5 because device can't handle more than that!"); + value = 5; + } + r.VaneHorizontal = value; + r.EffectiveFlags = commonDefines.DeviceOptions.VaneHorizontalDirection.effectiveFlags; } - else if (deviceOption == commonDefines.DeviceOptions.TargetVerticalTiltAngle) { - r.VaneVertical = ((value + 90.0) / 45.0 + 1.0).toFixed(0); - r.EffectiveFlags = commonDefines.DeviceOptions.TargetVerticalTiltAngle.effectiveFlags; + else if (deviceOption == commonDefines.DeviceOptions.VaneVerticalDirection) { + //r.VaneVertical = ((value + 90.0) / 45.0 + 1.0).toFixed(0); + if(value > 5) { + gthat.log.info("Vane vertical direction limited to 5 because device can't handle more than that!"); + value = 5; + } + r.VaneVertical = value; + r.EffectiveFlags = commonDefines.DeviceOptions.VaneVerticalDirection.effectiveFlags; } else { + gthat.log.error("Unsupported device option - report this to the developer!"); return; } + + r.HasPendingCommand = true; const url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta"; const method = "post"; const body = JSON.stringify(gthis.airInfo); @@ -472,7 +567,9 @@ class MelcloudDevice { gthis.targetTemp = jsonObject.SetTemperature; gthis.roomTemp = jsonObject.RoomTemperature; gthis.power = jsonObject.Power; - // TODO SetFanSpeed etc... + gthis.fanSpeed = jsonObject.SetFanSpeed; + gthis.vaneVerticalDirection = jsonObject.VaneVertical; + gthis.vaneHorizontalDirection = jsonObject.VaneHorizontal; gthis.Save(); // write updated values } }); diff --git a/lib/melcloudPlatform.js b/lib/melcloudPlatform.js index 867b2264..6bf4d716 100644 --- a/lib/melcloudPlatform.js +++ b/lib/melcloudPlatform.js @@ -155,12 +155,16 @@ class MelcloudPlatform { newDevice.minTempAuto = device.Device.MinTempAutomatic; newDevice.maxTempAuto = device.Device.MaxTempAutomatic; newDevice.roomTemp = device.Device.RoomTemperature; + newDevice.numberOfFanSpeeds = device.Device.NumberOfFanSpeeds; newDevice.lastCommunication = device.Device.LastTimeStamp; // "control" newDevice.power = device.Device.Power; newDevice.operationMode = device.Device.OperationMode; newDevice.targetTemp = device.Device.SetTemperature; + newDevice.fanSpeed = device.Device.FanSpeed; + newDevice.vaneVerticalDirection = device.Device.VaneVerticalDirection; + newDevice.vaneHorizontalDirection = device.Device.VaneHorizontalDirection; gthat.log.debug("Got device from cloud: " + device.DeviceID + " (" + device.DeviceName + ")"); foundDevices.push(newDevice); diff --git a/main.js b/main.js index 98936478..3eebcf59 100644 --- a/main.js +++ b/main.js @@ -136,14 +136,18 @@ class Melcloud extends utils.Adapter { mapDeviceOperationMode(value) { switch (value) { - case (commonDefines.DeviceOperationModes.AUTO.value): - return commonDefines.DeviceOperationModes.AUTO; - case (commonDefines.DeviceOperationModes.COOL.value): - return commonDefines.DeviceOperationModes.COOL; - case (commonDefines.DeviceOperationModes.HEAT.value): - return commonDefines.DeviceOperationModes.HEAT; case (commonDefines.DeviceOperationModes.OFF.value): return commonDefines.DeviceOperationModes.OFF; + case (commonDefines.DeviceOperationModes.HEAT.value): + return commonDefines.DeviceOperationModes.HEAT; + case (commonDefines.DeviceOperationModes.DRY.value): + return commonDefines.DeviceOperationModes.DRY; + case (commonDefines.DeviceOperationModes.COOL.value): + return commonDefines.DeviceOperationModes.COOL; + case (commonDefines.DeviceOperationModes.VENT.value): + return commonDefines.DeviceOperationModes.VENT; + case (commonDefines.DeviceOperationModes.AUTO.value): + return commonDefines.DeviceOperationModes.AUTO; default: this.log.error("Unsupported operation mode: " + value + " - Please report this to the developer!"); return commonDefines.DeviceOperationModes.UNDEF; @@ -259,6 +263,15 @@ class Melcloud extends utils.Adapter { case (commonDefines.AdapterStateIDs.TargetTemp): device.getDeviceInfo(device.setDevice, commonDefines.DeviceOptions.TargetTemperature, state.val); break; + case (commonDefines.AdapterStateIDs.FanSpeed): + device.getDeviceInfo(device.setDevice, commonDefines.DeviceOptions.FanSpeed, state.val); + break; + case (commonDefines.AdapterStateIDs.VaneVerticalDirection): + device.getDeviceInfo(device.setDevice, commonDefines.DeviceOptions.VaneVerticalDirection, state.val); + break; + case (commonDefines.AdapterStateIDs.VaneHorizontalDirection): + device.getDeviceInfo(device.setDevice, commonDefines.DeviceOptions.VaneHorizontalDirection, state.val); + break; default: this.log.error("Unsupported control option: " + controlOption + " - Please report this to the developer!"); break; diff --git a/package.json b/package.json index 9f70459c..66e8feeb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iobroker.melcloud", - "version": "0.0.2-alpha3", + "version": "0.0.2-alpha4", "description": "melcloud", "author": { "name": "BlackThunder",