Open Lcstyle opened 1 year ago
could it be something as simple as the field names you're looking for have been renamed, and without finding them, the default temp of 0C or 32F is being set?
reportedProfile:[fan_speed_stages:5, has_air_direction:true, has_auto_fan_speed:true, has_dry_function:true, has_extended_temp_range:true, has_heat_function:true, has_swing_direction:true, has_test_run:false, has_unit_function_setting:false, has_ventilation_function:true, display_setting_temp_of_dry:true, maximum_auto_temp:31, maximum_cool_or_dry_temp:31, maximum_heat_temp:31, minimum_auto_temp:16, minimum_cool_or_dry_temp:16, minimum_heat_temp:10], sendDesiredConditionsPending:true, sendDesiredConditionsTime:2021-12-21T20:02:36.533Z, systemChangeoverEnabled:false, minCoolSetpoint:16, maxHeatSetpoint:31, kumoSensorSettings:null, address:10.0.1.56, _requestRescan:0, _isRespondingLocally:null, autoChangeoverEnabled:false, optimalStart:false]]```
@sburke781 your latest update overwrote my code and broke my temperatures again, since package manager was set to auto update. I pasted my code back in and turned off auto updates in package manager.
your fan modes and auto detection are broken as well BTW. You can refer to the following operating manual for modes/fan modes: https://www.powerequipmentdirect.com/manuals/b68b8fa4726e60c17e68db8751659837.pdf
If you need me to provide you with a raw data dump of the kumo cloud calls, kindly let me know, I would be happy to share with you in private.
import java.text.DecimalFormat;
metadata {
definition (name: "Unified Thermostat Unit Child Driver", namespace: "simnet", author: "Simon Burke") {
capability "Refresh"
capability "Initialize"
capability "Thermostat"
capability "FanControl"
capability "TemperatureMeasurement"
preferences {
input(name: "AutoStatusPolling", type: "bool", title:"Automatic Status Polling", description: "Enable / Disable automatic polling of unit status", defaultValue: true, required: true, displayDuringSetup: true)
input(name: "StatusPollingInterval", type: "ENUM", multiple: false, options: ["1", "2", "5", "10", "30", "60"], title:"Status Polling Interval", description: "Number of minutes between automatic status updates", defaultValue: 10, required: true, displayDuringSetup: true)
input(name: "FansTextOrNumbers", type: "bool", title: "Fan Modes: Text or Numbers?", description: "Use Text for Fan Modes (ON) or Numbers (OFF)?", defaultValue: true, required: true, displayDuringSetup: true)
}
attribute "unitId", "string"
attribute "TemperatureIncrement", "number" // e.g. 0.5
//Temperature Ranges
attribute "MinTempCool", "number" // e.g. 16.0
attribute "MaxTempCool", "number" // e.g. 31.0
attribute "MinTempDry", "number" // e.g. 16.0
attribute "MaxTempDry", "number" // e.g. 31.0
attribute "MinTempHeat", "number" // e.g. 10.0
attribute "MaxTempHeat", "number" // e.g. 31.0
attribute "MinTempAuto", "number" // e.g. 16.0
attribute "MaxTempAuto", "number" // e.g. 31.0
//Modes and Features
attribute "CanHeat", "string" // e.g. true / false
attribute "CanDry", "string" // e.g. true / false
attribute "CanCool", "string" // e.g. true / false
attribute "HasAutomaticFanSpeed", "string" // e.g. true / false
attribute "NumberOfFanSpeeds", "number" // e.g. 5
attribute "lastRunningMode", "STRING"
attribute "lastCommandUTC", "STRING"
}
}
def getUnitId() {
return state.unitId
}
def setUnitId(pUnitId) {
state.unitId = pUnitId
}
// Standard Driver Methods
/* Initialize() To-Do
1. Come up with updated logic for handling high set point to take into account
Celsius and Fahrenheit
*/
def initialize() {
parent.debugLog("initialize: Initialize process started for unit ${getUnitId()}...")
//update unit settings and status polling
updated()
//Run refresh process, including status updates for power, mode, temperatures, etc
refresh()
parent.debugLog("initialize: Initialize process completed for unit ${getUnitId()}...")
}
def refresh() {
parent.debugLog("refresh: Refresh process called")
// Retrieve current state information and apply updates
// to HE device attributes
applyStatusUpdates(retrieveStatusInfo())
}
// Updated - Run when the Save Preferences button is pressed on the Device Edit page
// and when device is initialized
// To-Do: Turn on polling
def updated() {
// Retrieve current unit settings and features, applying updates
// to HE device attributes
parent.debugLog("updated: Applying Unit Settings and Features for unit ${getUnitId()}...")
applyUnitSettings(retrieveUnitSettings())
parent.debugLog("updated: AutoStatusPolling = ${AutoStatusPolling}, StatusPollingInterval = ${StatusPollingInterval}")
updateStatusPolling()
}
// Mode and Fan Mode Maps and Conversions
/* getFanModeMap() To-Do: Review these values for Kumo and MelView */
def getFanModeMap() {
if (FansTextOrNumbers == true) {
[
"0":"Auto",
"1":"Quiet",
"2":"Low",
"3":"Medium",
"5":"High",
"6":"Very High"
]
}
else {
[
"0":"auto",
"1":"1",
"2":"2",
"3":"3",
"5":"5",
"6":"6"
]
}
}
/* convertFanModeToKey() To-Do: Confirm mode values across each platform */
def convertFanModeToKey(pFanMode) {
String vFanMode = "${pFanMode}";
vFanMode = vFanMode.trim().toLowerCase();
def vModeKey = null
if(vFanMode == "auto" || vFanMode == "auto") { vModeKey = 0 }
if(vFanMode == "quiet" || vFanMode == "1" ) { vModeKey = 1 }
if(vFanMode == "low" || vFanMode == "2" ) { vModeKey = 2 }
if(vFanMode == "medium" || vFanMode == "3" ) { vModeKey = 3 }
if(vFanMode == "high" || vFanMode == "5" ) { vModeKey = 5 }
if(vFanMode == "very-high" || vFanMode == "6" ) { vModeKey = 6 }
return vModeKey
}
def adjustFanModes(pNumberOfFanSpeeds, pHasAutomaticFanSpeed) {
def fanModes = []
//Text or Numbers?
if (FansTextOrNumbers == true || FansTextOrNumbers == "1") {
log.debug("adjustFanModes:Text-based Fan Modes")
fanModes.add("\"Auto\"")
fanModes.add("\"Quiet\"")
fanModes.add("\"Low\"")
fanModes.add("\"Medium\"")
fanModes.add("\"High\"")
fanModes.add("\"Very High\"")
}
else {
fanModes.add("\"0\"")
fanModes.add("\"1\"")
fanModes.add("\"2\"")
fanModes.add("\"3\"")
fanModes.add("\"5\"")
fanModes.add("\"6\"")
}
log.debug("adjustFanModes: fanModes detected are ${fanModes}")
//Apply settings
sendEvent(name: 'supportedThermostatFanModes', value: fanModes)
parent.debugLog("adjustFanModes: fanModes detected are ${fanModes}")
//Apply settings
sendEvent(name: 'supportedThermostatFanModes', value: fanModes)
}
/* getModeMap() To-Do: Review these values for Kumo and MelView */
def getModeMap() {
[
"1" : "heat",
"2" : "dry",
"3" : "cool",
"7" : "fan",
"8" : "auto",
"16" : "off",
"33" : "auto",
"35" : "auto"
]
}
def getOperatingStateMap() {
[
"1" : "heating",
"2" : "drying",
"3" : "cooling",
"7" : "fan only",
"8" : "auto",
"16" : "idle",
"33" : "heating",
"35" : "cooling"
]
}
def adjustThermostatModes(pCanHeat,pCanCool,pCanDry, pCanAuto) {
parent.debugLog("adjustThermostatModes: Adjusting Thermostat Modes...")
def thermostatModes = []
parent.debugLog("adjustThermostatModes: CanHeat = ${pCanHeat}, CanCool = ${pCanCool}, CanDry = ${pCanDry}, CanAuto = ${pCanAuto}")
thermostatModes.add("\"heat\"")
thermostatModes.add("\"cool\"")
thermostatModes.add("\"dry\"")
thermostatModes.add("\"auto\"")
thermostatModes.add("\"fan\"")
thermostatModes.add("\"off\"")
parent.debugLog("adjustThermostatModes: thermostatModes detected are ${thermostatModes}")
sendEvent(name: 'supportedThermostatModes', value: thermostatModes)
}
/* convertThermostatModeToKey() To-Do: Confirm mode values across each platform */
def convertThermostatModeToKey(pThermostatMode) {
def vModeKey = null
if(pThermostatMode.trim() == "heat") vModeKey = 1
if(pThermostatMode.trim() == "dry") vModeKey = 2
if(pThermostatMode.trim() == "cool") vModeKey = 3
if(pThermostatMode.trim() == "fan") vModeKey = 7
if(pThermostatMode.trim() == "auto") vModeKey = 8
return vModeKey
}
// Unit Settings and Status
def retrieveUnitSettings() {
//Returns current features and settings information for the ac unit
def settings = [:]
parent.debugLog("retrieveUnitSettings: Retrieving unit features and settings")
settings = "retrieveUnitSettings_${parent.getPlatform()}"()
parent.debugLog("retrieveUnitSettings: pre-conversion")
settings.minTempCool = settings.minTempCool
settings.maxTempCool = settings.maxTempCool
settings.minTempDry = settings.minTempDry
settings.maxTempDry = settings.maxTempDry
settings.minTempHeat = settings.minTempHeat
settings.maxTempHeat = settings.maxTempHeat
settings.minTempAuto = settings.minTempAuto
settings.maxTempAuto = settings.maxTempAuto
parent.debugLog("retrieveUnitSettings: Settings to be returned = ${settings}")
return settings
}
def retrieveUnitSettings_KumoCloud() {
parent.debugLog("retrieveUnitSettings_KumoCloud: Retrieval process started...")
def settings = [:]
def postParams = [
uri: "${parent.getBaseURL()}/getInfrequentDeviceUpdates",
headers: parent.getStandardHTTPHeaders_KumoCloud("no"),
contentType: "application/json; charset=UTF-8",
body : "[ \"${parent.getAuthCode()}\",[\"${getUnitId()}\"] ]"
]
try {
httpPost(postParams) { resp ->
parent.debugLog("retrieveUnitSettings_KumoCloud: Initial data returned: ${resp.data}")
//Temperature Ranges Configured
settings.minTempCool = "60"
settings.maxTempCool = "60"
settings.minTempDry = "60"
settings.maxTempDry = "60"
settings.minTempHeat = "50"
settings.maxTempHeat = "88"
settings.minTempAuto = "60"
settings.maxTempAuto = "88"
//Modes and Features
settings.canHeat = "true"
settings.canDry = "true"
settings.canCool = "true"
settings.canAuto = "true"
settings.hasAutomaticFanSpeed = "true"
settings.numberOfFanSpeeds = "5"
}
}
catch (Exception e) {
parent.errorLog "retrieveUnitSettings_KumoCloud : Unable to query Mitsubishi Electric KumoCloud: ${e}"
}
return settings
}
def applyUnitSettings(givenSettings) {
parent.debugLog("applyUnitSettings: Unit Settings are ${givenSettings}")
//Temperature Ranges Configured
sendEvent(name: "MinTempCool", value: givenSettings.minTempCool)
sendEvent(name: "MaxTempCool", value: givenSettings.maxTempCool)
sendEvent(name: "MinTempDry" , value: givenSettings.minTempDry)
sendEvent(name: "MaxTempDry" , value: givenSettings.maxTempDry)
sendEvent(name: "MinTempHeat", value: givenSettings.minTempHeat)
sendEvent(name: "MaxTempHeat", value: givenSettings.maxTempHeat)
sendEvent(name: "MinTempAuto", value: givenSettings.minTempAuto)
sendEvent(name: "MaxTempAuto", value: givenSettings.maxTempAuto)
//Modes and Features
sendEvent(name: "CanHeat", value: givenSettings.canHeat)
sendEvent(name: "CanCool", value: givenSettings.canCool)
sendEvent(name: "CanDry", value: givenSettings.canDry)
sendEvent(name: "CanAuto", value: givenSettings.canAuto)
sendEvent(name: "HasAutomaticFanSpeed", value: givenSettings.hasAutomaticFanSpeed)
sendEvent(name: "NumberOfFanSpeeds", value: givenSettings.numberOfFanSpeeds)
adjustFanModes(givenSettings.numberOfFanSpeeds, givenSettings.hasAutomaticFanSpeed)
adjustThermostatModes(givenSettings.canHeat, givenSettings.canCool, givenSettings.canDry, givenSettings.canAuto)
}
def retrieveStatusInfo() {
//Returns current status information for the ac unit
parent.debugLog("retrieveStatusInfo: Retrieving status info from ${parent.getPlatform()} ")
def statusInfo = "retrieveStatusInfo_${parent.getPlatform()}"()
statusInfo.setTemp = convertTemperatureIn(statusInfo.setTemp)
statusInfo.roomTemp = convertTemperatureIn(statusInfo.roomTemp)
return statusInfo
}
def retrieveStatusInfo_KumoCloud() {
def statusInfo = [:]
def postParams = [
uri: "${parent.getBaseURL()}/getDeviceUpdates",
headers: parent.getStandardHTTPHeaders_KumoCloud("no"),
contentType: "application/json",
body : "[ \"${parent.getAuthCode()}\",[\"${getUnitId()}\"] ]"
]
try {
httpPost(postParams) { acUnit ->
parent.debugLog("retrieveStatusInfo_KumoCloud: response - ${acUnit.data}")
statusInfo.unitId = "${acUnit.data[2][0].device_serial}".replace("[","").replace("]","")
statusInfo.statusAsAt = "${acUnit.data[2][0].record_time}".replace("[","").replace("]","")
//Current Status Information
statusInfo.power = "${acUnit.data[2][0].power}".replace("[","").replace("]","")
statusInfo.setMode = "${acUnit.data[2][0].operation_mode}".replace("[","").replace("]","")
statusInfo.roomTemp = "${acUnit.data[2][0].room_temp}".replace("[","").replace("]","")
if(statusInfo.setMode == "3" || statusInfo.setMode == "35") { statusInfo.setTemp = "${acUnit.data[2][0].sp_cool}".replace("[","").replace("]","") }
if(statusInfo.setMode == "1" || statusInfo.setMode == "33") { statusInfo.setTemp = "${acUnit.data[2][0].sp_heat}".replace("[","").replace("]","") }
//statusInfo.setTemp = "${acUnit.data[2][0].set_temp}".replace("[","").replace("]","")
statusInfo.setFan = "${acUnit.data[2][0].fan_speed}".replace("[","").replace("]","")
}
parent.debugLog("retrieveStatusInfo_KumoCloud: Status Info - ${statusInfo}")
}
catch (Exception e) {
parent.errorLog("retrieveStatusInfo_KumoCloud: Unable to query Mitsubishi Electric Kumo Cloud: ${e}")
}
return statusInfo
}
def applyStatusUpdates(statusInfo) {
def statusIsCurrent = 1
parent.debugLog("applyResponseStatus: Status Info: ${statusInfo}")
if (!statusInfo.isEmpty()) {
parent.debugLog("applyResponseStatus: lastCommandUTC = ${checkNull(device.currentValue("lastCommandUTC", true),"Null")}, ${checkNull(statusInfo.statusAsAt,"Null")}")
if (device.currentValue("lastCommandUTC") != null && statusInfo.containsKey("statusAsAt") ) {
def lastCommandUTC_Date = new java.text.SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS'Z'" ).parse(device.currentValue("lastCommandUTC", true))
def statusAsAt_Date = new java.text.SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" ).parse(statusInfo.statusAsAt)
parent.debugLog("applyResponseStatus: lastCommandUTC_Date = ${lastCommandUTC_Date}, statusAsAt_Date = ${statusAsAt_Date}")
if (lastCommandUTC_Date > statusAsAt_Date) {
statusIsCurrent = 0
}
else { statusIsCurrent = 1 }
}
else { statusIsCurrent = 1 }
parent.debugLog("applyStatusUpdates: statusIsCurrent = ${statusIsCurrent}")
if (statusIsCurrent == 1) {
parent.debugLog("applyStatusUpdates: About to adjust thermostat mode details...")
adjustThermostatMode(statusInfo.setMode, statusInfo.power)
parent.debugLog("applyStatusUpdates: About to adjust temperatures...")
adjustRoomTemperature(statusInfo.roomTemp)
adjustSetTemperature(statusInfo.setTemp, statusInfo.setMode, statusInfo.power)
adjustThermostatFanMode(statusInfo.setFan)
}
else { parent.debugLog("applyResponseStatus: Status information is out of date, a command must have been run recently") }
parent.debugLog("applyResponseStatus: Status update complete")
}
else { parent.debugLog("applyResponseStatus: No status information was provided, no further action was taken") }
}
// Unit Control Methods
// Temperature Control
def adjustRoomTemperature(pTemp) {
def vTempScaleUnit = "°${parent.getHETempScale()}"
def vRoomTempValue
parent.debugLog("adjustRoomTemperature: Temperature provided = ${pTemp}")
if(pTemp == null || !"${pTemp}".isNumber()) {
parent.warnLog("adjustRoomTemperature: Warning, The Room Temperature was either null or not a number")
}
else {
vRoomTempValue = pTemp.toFloat().round(1)
if (device.currentValue("temperature", true) == null || device.currentValue("temperature", true).toFloat().round(1) != vRoomTempValue) {
if (device.currentValue("temperature", true) != vRoomTempValue) { parent.debugLog("adjustRoomTemperature: Current Room Temperature value and value provided did not match") }
parent.debugLog("adjustRoomTemperature: updating room temperature from ${device.currentValue("temperature", true)} to ${vRoomTempValue}")
sendEvent(name: "temperature", value: vRoomTempValue)
}
else { parent.debugLog("adjustRoomTemperature: No action taken") }
}
}
// adjustHeatingSetpoint() To-Do: Use Minimum Heating Set Point instead of 23
def adjustHeatingSetpoint(givenTemp) {
def heatingSetTempValue = givenTemp.toFloat().round(1)
def currHeatingSetTempValue = checkNull(device.currentValue("heatingSetpoint", true),"23.0").toFloat().round(1)
def currThermSetTempValue = checkNull(device.currentValue("thermostatSetpoint", true),"23.0").toFloat().round(1)
parent.debugLog("adjustHeatingSetpoint: Current heatingSetpoint ${currHeatingSetTempValue}, Current ThermostatSetpoint = ${currThermSetTempValue}, New heatingSetpoint = ${heatingSetTempValue}")
if (currHeatingSetTempValue != heatingSetTempValue) {
sendEvent(name: "heatingSetpoint", value : heatingSetTempValue)
parent.infoLog("Heating Set Point adjusted to ${heatingSetTempValue} for ${device.label}")
}
}
def setHeatingSetpoint(givenTemp) {
def correctedTemp = givenTemp
parent.debugLog("setHeatingSetpoint: Setting Heating Set Point to ${givenTemp}, current minimum ${device.currentValue("MinTempHeat", true)}, current maximum ${device.currentValue("MaxTempHeat", true)}")
//Maximum
if (givenTemp > device.currentValue("MaxTempHeat", true)) {
correctedTemp = device.currentValue("MaxTempHeat", true)
parent.debugLog("setHeatingSetpoint: Temperature selected = ${givenTemp}, corrected to maximum heating set point ${correctedTemp}")
}
parent.debugLog("setHeatingSetpoint: Corrected Temp = ${correctedTemp}")
adjustHeatingSetpoint(correctedTemp)
if (device.currentValue("thermostatOperatingState", true) == "heating") { setTemperature(correctedTemp) }
}
// adjustCoolingSetpoint() To-Do: Use Maximum Heating Set Point instead of 23
def adjustCoolingSetpoint(givenTemp) {
def coolingSetTempValue = givenTemp.toFloat().round(1)
def currCoolingSetTempValue = checkNull(device.currentValue("coolingSetpoint", true),"23.0").toFloat().round(1)
def currThermSetTempValue = checkNull(device.currentValue("thermostatSetpoint", true),"23.0").toFloat().round(1)
parent.debugLog("adjustCoolingSetpoint: Current coolingSetpoint ${currCoolingSetTempValue}, Current ThermostatSetpoint = ${currThermSetTempValue}, New coolingSetpoint = ${coolingSetTempValue}")
if (currCoolingSetTempValue != coolingSetTempValue) {
sendEvent(name: "coolingSetpoint", value : coolingSetTempValue)
parent.infoLog("Cooling Set Point adjusted to ${coolingSetTempValue} for ${device.label}")
}
}
def setCoolingSetpoint(givenTemp) {
def correctedTemp = givenTemp
parent.debugLog("setCoolingSetpoint: Setting Cooling Set Point to ${givenTemp}, current minimum ${device.currentValue("MinTempCool", true)}, current maximum ${device.currentValue("MaxTempCool", true)}")
//Check allowable cooling temperature range and correct where necessary
//Minimum
if (givenTemp < device.currentValue("MinTempCool", true)) {
correctedTemp = device.currentValue("MinTempCool", true)
parent.debugLog("setCoolingSetpoint: Temperature selected = ${givenTemp}, corrected to minimum cooling set point ${correctedTemp}")
}
parent.debugLog("setCoolingSetpoint: Corrected Temp = ${correctedTemp}")
adjustCoolingSetpoint(correctedTemp)
if (device.currentValue("thermostatOperatingState", true) == "cooling" || device.currentValue("thermostatOperatingState", true) == "drying") { setTemperature(correctedTemp) }
}
// TO-DO: Look at use of the value 23.0 for the US
// Tidy up use of conversions and checks and logging, particularly when we get a null value returned from API
def adjustSetTemperature(pSetTemp, pThermostatMode, pPower) {
def vSetTemp
if ("${pSetTemp}".isNumber()) { vSetTemp = pSetTemp.toFloat().round(1) }
else { vSetTemp = null }
def vCurrentSetTempConv
def vCurrentSetTemp = device.currentValue("thermostatSetpoint", true)
if ("${vCurrentSetTemp}".isNumber()) { vCurrentSetTempConv = vCurrentSetTemp.toFloat().round(1)}
else { vCurrentSetTempConv = null }
parent.debugLog("adjustSetTemperature: Temperature passed in was ${pSetTemp} which was parsed as ${vSetTemp}, current set temperature is ${vCurrentSetTempConv}")
if (vSetTemp != null && (vCurrentSetTempConv == null || vCurrentSetTempConv != vSetTemp)) {
parent.debugLog("adjustSetTemperature: Changing Set Temperature from ${vCurrentSetTempConv} to ${vSetTemp}")
sendEvent(name: "thermostatSetpoint", value: vSetTemp)
def vMode
if (pMode == null) { vMode = device.currentValue("thermostatMode", true) }
else { vMode = deriveThermostatMode(pThermostatMode, pPower) }
parent.debugLog("adjustSetTemperature: Current mode is ${vMode}")
if (vMode == "heat") {
parent.debugLog("adjustSetTemperature: Heating mode detected, adjusting heating set point")
adjustHeatingSetpoint(vSetTemp)
}
if (vMode == "cool" || vMode == "dry") {
parent.debugLog("adjustSetTemperature: Cooling / Drying mode detected, adjusting cooling set point")
adjustCoolingSetpoint(vSetTemp)
}
}
else { parent.debugLog("adjustSetTemperature: No action taken, either no change in temperature or null temperature provided") }
}
def setTemperature(givenSetTemp) {
def vPlatform = parent.getPlatform()
def setTempValue = givenSetTemp.toFloat().round(1)
def currThermSetTempValue = checkNull(device.currentValue("thermostatSetpoint", true),"23.0").toFloat().round(1)
def convertedTemp = setTempValue
parent.debugLog("setTemperature: givenSetTemp = ${givenSetTemp}, currentThermSetTempValue = ${currThermSetTempValue}")
if(currThermSetTempValue != setTempValue) {
parent.debugLog("setTemperature: Setting Temperature to ${setTempValue} for ${device.label}")
adjustSetTemperature(givenSetTemp, null, null)
convertedTemp = convertTemperatureOut("${givenSetTemp}")
parent.debugLog("setTemperature: Set Temperature Provided = ${setTempValue}, converted to ${convertedTemp} for ${vPlatform}")
setTemperature_KumoCloud(convertedTemp)
parent.debugLog("setTemperature: Temperature adjusted to ${setTempValue} for ${device.label}")
}
else {
parent.debugLog("setTemperature: No action taken")
}
}
def setTemperature_KumoCloud(givenSetTemp) {
def setTempValue = givenSetTemp.toFloat()
def bodyJson = "{\"sp${device.currentValue("thermostatMode", true).toLowerCase().capitalize()}\":${setTempValue}}"
parent.debugLog("setTemperature_KumoCloud: Body JSON = ${bodyJson}")
unitCommand_KumoCloud("${bodyJson}")
parent.debugLog("setTemperature_KumoCloud: Unit Command submitted")
}
// Fan Mode Control
def adjustThermostatFanMode(pFanModeKey) {
// Convert the MEL Fan Mode Key provided to a Fan Mode and Speed recognised by HE
def vFanModeValue = fanModeMap["${pFanModeKey}"].trim()
def vFanControlSpeed = ""
if(vFanModeValue == "Auto" || vFanModeValue == "0") vFanControlSpeed = "auto"
if(vFanModeValue == "Quiet" || vFanModeValue == "1") vFanControlSpeed = "quiet"
if(vFanModeValue == "Low" || vFanModeValue == "2") vFanControlSpeed = "low"
if(vFanModeValue == "Medium" || vFanModeValue == "3") vFanControlSpeed = "medium"
if(vFanModeValue == "High" || vFanModeValue == "5") vFanControlSpeed = "high"
if(vFanModeValue == "Very High" || vFanModeValue == "6") vFanControlSpeed = "very high"
parent.debugLog("adjustThermostatFanMode: MEL Fan Mode Key ${checkNull(pFanModeKey,"")} parsed as HE Fan Mode Value ${checkNull(vFanModeValue,"")} and HE Fan Speed ${vFanControlSpeed}")
// Adjust the Fan Mode
if(vFanModeValue == null) { parent.warnLog("adjustThermostatFanMode: Warning - Unknown Fan Mode selected, no action taken") }
else {
// Adjust the thermostatFanMode Attribute
if (checkNull(device.currentValue("thermostatFanMode", true),"") != vFanModeValue) {
sendEvent(name: "thermostatFanMode", value: vFanModeValue)
parent.debugLog("adjustThermostatFanMode: Fan Mode adjusted to ${vFanModeValue} for ${device.label} (${getUnitId()})")
}
else { parent.debugLog("adjustThermostatFanMode: No change to Fan Mode detected, no action taken") }
}
// Adjust the Fan Speed
if(vFanControlSpeed == "") { parent.warnLog("adjustThermostatFanMode: Warning - Unknown Fan Speed selected, no action taken") }
else {
// Adjust the speed Attribute
if (checkNull(device.currentValue("speed", true),"") != vFanControlSpeed) {
sendEvent(name: "speed", value: vFanControlSpeed)
parent.infoLog("Fan Speed adjusted to ${vFanControlSpeed} for ${device.label} (${getUnitId()})")
}
else { parent.debugLog("adjustThermostatFanMode: No change to Fan Speed detected, no action taken") }
}
}
def setThermostatFanMode(pFanMode) {
def vPlatform = parent.getPlatform()
def vFanMode = pFanMode.trim()
def vFanModeKey = convertFanModeToKey(vFanMode)
parent.debugLog("setThermostatFanMode: HE Fan Mode ${pFanMode} parsed as Fan Mode Key ${vFanModeKey}")
if (vFanModeKey != null) {
if(checkNull(device.currentValue("thermostatFanMode", true),"") != vFanMode)
{
adjustThermostatFanMode(vFanModeKey)
parent.debugLog("setThermostatFanMode: Setting Fan Mode to ${vFanMode}(${vFanModeKey}) for ${device.label} (${getUnitId()})")
setThermostatFanMode_KumoCloud (vFanModeKey)
parent.infoLog("Fan Mode set to ${vFanMode} for ${device.label} (${getUnitId()})")
}
else { parent.debugLog("setThermostatFanMode: No action taken") }
}
else { parent.warnLog("setThermostatFanMode: Warning - Fan Mode ${pFanMode} not identified in Fan Mode List, no action taken") }
}
def setThermostatFanMode_KumoCloud (pFanModeKey) {
unitCommand_KumoCloud("{\"fanSpeed\":${pFanModeKey}}")
}
//Fan Speed method from the Fan Control capability
// Simply calling the Fan Mode method that is part of the Thermostat capability
def setSpeed(pFanspeed) { setThermostatFanMode("${pFanspeed}") }
// Thermostat Mode Control
def adjustThermostatMode(pThermostatMode, pPower) {
parent.debugLog("adjustThermostatMode: Adjust Thermostat Mode called")
def vModeDesc = deriveThermostatMode(pThermostatMode, pPower)
parent.debugLog("adjustThermostatMode: Thermostat Mode provided ${pThermostatMode}, Power provided ${pPower}, parsed as Mode Description ${vModeDesc}")
if (checkNull(device.currentValue("thermostatMode", true),"") != vModeDesc) {
sendEvent(name: "thermostatMode", value: vModeDesc)
if (vModeDesc != "off" && checkNull(device.currentValue("lastRunningMode", true),"") != vModeDesc) {
sendEvent(name: "lastRunningMode", value: vModeDesc)
}
}
adjustThermostatOperatingState(pThermostatMode,pPower)
}
/* adjustThermostatOperatingState To-Do: use map for mode to state translation */
def adjustThermostatOperatingState(pThermostatMode, pPower) {
def vOperatingState
if (pPower == "1") { vOperatingState = operatingStateMap["${pThermostatMode}"] }
else { vOperatingState = "idle" }
parent.debugLog("adjustThermostatOperatingState: Thermostat Mode passed in = ${pThermostatMode}, Power passed in ${pPower}, OperatingState: ${vOperatingState}")
if (checkNull(device.currentValue("thermostatOperatingState", true),"") != vOperatingState) {
sendEvent(name: "thermostatOperatingState", value: vOperatingState)
}
}
def deriveThermostatMode(pThermostatMode, pPower) {
def vModeDesc
if (pPower == "1" || pPower == "true") { vModeDesc = modeMap["${pThermostatMode}"] }
else { vModeDesc = "off" }
return vModeDesc
}
def setThermostatMode(pThermostatMode) {
parent.debugLog("setThermostatMode: Thermostat Mode passed in = ${pThermostatMode}")
"${pThermostatMode}"()
parent.debugLog("setThermostatMode: Thermostat Mode set")
}
def on() {
parent.debugLog("on: Turning ON device ${device.label} (${getUnitId()})")
"on_${parent.getPlatform()}"()
parent.infoLog("Power turned ON for ${device.label} (${getUnitId()})")
adjustThermostatMode(convertThermostatModeToKey("on"), "1")
parent.debugLog("on: Thermostat Mode adjusted")
}
def on_KumoCloud() {
unitCommand_KumoCloud("{\"power\":1}")
}
def off() {
log.debug("off: Turning OFF device ${device.label} (${getUnitId()})")
"off_${parent.getPlatform()}"()
parent.infoLog("Power turned OFF for ${device.label} (${getUnitId()})")
adjustThermostatMode(convertThermostatModeToKey("off"), "0")
log.debug("off: Thermostat Mode adjusted")
}
def off_KumoCloud() {
unitCommand_KumoCloud("{\"power\":0}")
}
def heat() {
adjustHeatingSetpoint(device.currentValue("thermostatSetpoint", true))
parent.debugLog("heat: Adjusting Thermostat Mode to Heating for ${device.label} (${getUnitId()})")
"heat_${parent.getPlatform()}"()
parent.infoLog("Thermostat Mode set to Heating for ${device.label} (${getUnitId()})")
adjustThermostatMode(convertThermostatModeToKey("heat"), "1")
parent.debugLog("heat: Thermostat Mode adjusted")
}
def heat_KumoCloud() {
unitCommand_KumoCloud("{\"power\":1,\"operationMode\":1}")
}
def dry() {
parent.debugLog("dry: Adjusting Thermostat Mode to Dry for ${device.label} (${getUnitId()})")
"dry_${parent.getPlatform()}"()
parent.infoLog("Thermostat Mode set to Dry for ${device.label} (${getUnitId()})")
adjustThermostatMode(convertThermostatModeToKey("dry"), "1")
parent.debugLog("dry: Thermostat Mode adjusted")
}
def dry_KumoCloud() {
unitCommand_KumoCloud("{\"power\":1,\"operationMode\":2}")
}
def cool_KumoCloud() {
unitCommand_KumoCloud("{\"power\":1,\"operationMode\":3}")
}
def fan() {
parent.debugLog("fan: Adjusting Thermostat Mode to Fan for ${device.label} (${getUnitId()})")
"fan_${parent.getPlatform()}"()
parent.infoLog("Thermostat Mode set to Fan for ${device.label} (${getUnitId()})")
adjustThermostatMode(convertThermostatModeToKey("fan"), "1")
parent.debugLog("fan: Thermostat Mode adjusted")
}
def fan_KumoCloud() {
unitCommand_KumoCloud("{\"power\":1,\"operationMode\":7}")
}
def auto() {
parent.debugLog("auto: Adjusting Thermostat Mode to Auto for ${device.label} (${getUnitId()})")
"auto_${parent.getPlatform()}"()
parent.infoLog("Thermostat Mode set to Auto for ${device.label} (${getUnitId()})")
adjustThermostatMode(convertThermostatModeToKey("auto"), "1")
parent.debugLog("auto: Thermostat Mode adjusted")
}
def auto_KumoCloud() {
unitCommand_KumoCloud("{\"power\":1,\"operationMode\":8}")
}
// Platform Specific API Command Methods
def unitCommand_KumoCloud(pCommand) {
def vBodyJson = "[\"${parent.getAuthCode()}\",{\"${getUnitId()}\":${pCommand}}]"
parent.debugLog("unitCommand_KumoCloud: Body of command = ${vBodyJson}")
def vPostParams = [
uri: "${parent.getBaseURL()}/sendDeviceCommands/v2",
headers: parent.getStandardHTTPHeaders_KumoCloud("no"),
contentType: "application/json; charset=UTF-8",
body : vBodyJson
]
try {
httpPost(vPostParams) { resp ->
sendEvent(name: "lastCommandUTC", value: "${new Date().format("yyyy-MM-dd HH:mm:ss.SSS'Z'", TimeZone.getTimeZone('UTC'))}")
parent.debugLog("unitCommand: Initial data returned from unitCommand: ${resp.data}, response received ${new Date().format("yyyy-MM-dd HH:mm:ss.SSS'Z'", TimeZone.getTimeZone('UTC'))}")
}
}
catch (Exception e) {
parent.errorLog "unitCommand_KumoCloud : Unable to query Mitsubishi Electric ${parent.getPlatform()}: ${e}"
}
}
// Scheduled Status Update Methods
def getSchedule() { }
def updateStatusPolling() {
def vSchedule
parent.debugLog("updateStatusPolling: Updating Status Polling called, about to unschedule refresh")
unschedule("refresh")
parent.debugLog("updateStatusPolling: Unscheduleing refresh complete")
if(AutoStatusPolling == true) {
vSchedule = "0 0/${StatusPollingInterval} * ? * * *"
parent.debugLog("updateStatusPolling: Setting up schedule with settings: schedule(\"${vSchedule}\",refresh)")
try{
schedule("${vSchedule}","refresh")
}
catch(Exception e) {
parent.debugLog("updateStatusPolling: Error - " + e)
}
parent.debugLog("updateStatusPolling: Scheduled refresh set")
}
else { parent.debugLog("updateStatusPolling: Automatic status polling is disabled, no further action was taken") }
}
// Utility Methods
def checkNull(value, alternative) {
if(value == null) { return alternative }
return value
}
def convertTemperatureIn(BigDecimal pTemp) { return convertTemperatureIn("${pTemp}") }
def convertTemperatureIn(String pTemp) {
def vPlatformScale = parent.getPlatformScale()
def vHEScale = parent.getHETempScale()
return convertTemperature(pTemp,vPlatformScale,vHEScale)
}
def convertTemperatureOut(BigDecimal pTemp) { return convertTemperatureOut("${pTemp}") }
def convertTemperatureOut(String pTemp) {
def vPlatformScale = parent.getPlatformScale()
def vHEScale = parent.getHETempScale()
return convertTemperature(pTemp,vHEScale,vPlatformScale)
}
def convertTemperature(String pTemp, String pSourceScale, String pTargetScale) {
def vTemp = pTemp
if (pTemp == null || !pTemp.isNumber() || pSourceScale == null || pTargetScale == null) { vTemp = null }
else {
if(pSourceScale != pTargetScale) {
if(pSourceScale == "C") { vTemp = (String) ((Float) ((int) (celsiusToFahrenheit(pTemp.toFloat()).toFloat().round(4) *2 + 0.5)) /2.0) }
else { vTemp = fahrenheitToCelsius(pTemp.toFloat()).toString() }
}
}
return vTemp
}
Apologies @Lcstyle , I should have mentioned the possibility of that happening. Glad you were able to recover from it.
Can't set correct temps in F
Looks like min max fields are interfering:
also noticed this little tidbit: