/* Kasa Device Driver Series Copyright Dave Gutheinz License: https://github.com/DaveGut/HubitatActive/blob/master/KasaDevices/License.md ===== Link to list of changes ===== https://github.com/DaveGut/HubitatActive/blob/master/KasaDevices/Changes.pdf ===== Link to Documentation ===== https://github.com/DaveGut/HubitatActive/blob/master/KasaDevices/Documentation.pdf ===================================================================================================*/ def driverVer() { return "2.3.6" } def type() { return "Plug Switch" } //def type() { return "EM Plug" } //def type() { return "Multi Plug" } //def type() { return "EM Multi Plug" } def file() { return type().replaceAll(" ", "-") } metadata { definition (name: "Kasa Plug Switch", namespace: nameSpace(), author: "Dave Gutheinz", importUrl: "https://raw.githubusercontent.com/DaveGut/HubitatActive/master/KasaDevices/DeviceDrivers/${file()}.groovy" ) { capability "Switch" capability "Actuator" capability "Configuration" capability "Refresh" command "ledOn" command "ledOff" attribute "led", "string" command "setPollInterval", [[ name: "Poll Interval in seconds", constraints: ["default", "5 seconds", "10 seconds", "15 seconds", "30 seconds", "1 minute", "5 minutes", "10 minutes", "30 minutes"], type: "ENUM"]] capability "Power Meter" capability "Energy Meter" attribute "currMonthTotal", "number" attribute "currMonthAvg", "number" attribute "lastMonthTotal", "number" attribute "lastMonthAvg", "number" attribute "connection", "string" attribute "commsError", "string" } // 6.7.2 Change B. change logging names and titles to match other built-in drivers. preferences { input ("textEnable", "bool", title: "Enable descriptionText logging", defaultValue: true) input ("logEnable", "bool", title: "Enable debug logging", defaultValue: false) if (getDataValue("feature") == "TIM:ENE") { input ("emFunction", "bool", title: "Enable Energy Monitor", defaultValue: false) if (emFunction) { input ("energyPollInt", "enum", title: "Energy Poll Interval (minutes)", options: ["1 minute", "5 minutes", "30 minutes"], defaultValue: "30 minutes") } } if (getDataValue("deviceIP") != "CLOUD" && getDataValue("model") == "HS200") { input ("altLan", "bool", title: "Alternate LAN Comms (for comms problems only)", defaultValue: false) } input ("bind", "bool", title: "Kasa Cloud Binding", defalutValue: true) input ("useCloud", "bool", title: "Use Kasa Cloud for device control", defaultValue: false) input ("nameSync", "enum", title: "Synchronize Names", options: ["none": "Don't synchronize", "device" : "Kasa device name master", "Hubitat" : "Hubitat label master"], defaultValue: "none") input ("manualIp", "string", title: "Manual IP Update [Caution]", defaultValue: getDataValue("deviceIP")) input ("manualPort", "string", title: "Manual Port Update [Caution]", defaultValue: getDataValue("devicePort")) input ("rebootDev", "bool", title: "Reboot device [Caution]", defaultValue: false) } } def installed() { device.updateSetting("nameSync",[type:"enum", value:"device"]) def instStatus = installCommon() logInfo("installed: ${instStatus}") } def updated() { def updStatus = updateCommon() if (getDataValue("feature") == "TIM:ENE") { updStatus << [emFunction: setupEmFunction()] } logInfo("updated: ${updStatus}") if (getDataValue("model") == "HS300") { updateDataValue("altComms", "false") state.remove("response") } refresh() } def setSysInfo(status) { def switchStatus = status.relay_state def ledStatus = status.led_off def logData = [:] if (getDataValue("plugNo") != null) { def childStatus = status.children.find { it.id == getDataValue("plugNo") } if (childStatus == null) { childStatus = status.children.find { it.id == getDataValue("plugId") } } status = childStatus switchStatus = status.state } def onOff = "on" if (switchStatus == 0) { onOff = "off" } if (device.currentValue("switch") != onOff) { sendEvent(name: "switch", value: onOff, type: "digital") logData << [switch: onOff] } def ledOnOff = "on" if (ledStatus == 1) { ledOnOff = "off" } if (device.currentValue("led") != ledOnOff) { sendEvent(name: "led", value: ledOnOff) logData << [led: ledOnOff] } if (logData != [:]) { logInfo("setSysinfo: ${logData}") } if (nameSync == "device" || nameSync == "Hubitat") { updateName(status) } getPower() } def coordUpdate(cType, coordData) { def msg = "coordinateUpdate: " if (cType == "commsData") { device.updateSetting("bind", [type:"bool", value: coordData.bind]) device.updateSetting("useCloud", [type:"bool", value: coordData.useCloud]) sendEvent(name: "connection", value: coordData.connection) device.updateSetting("altLan", [type:"bool", value: coordData.altLan]) msg += "[commsData: ${coordData}]" } else { msg += "Not updated." } logInfo(msg) } // ~~~~~ start include (1359) davegut.kasaCommon ~~~~~ library ( // library marker davegut.kasaCommon, line 1 name: "kasaCommon", // library marker davegut.kasaCommon, line 2 namespace: "davegut", // library marker davegut.kasaCommon, line 3 author: "Dave Gutheinz", // library marker davegut.kasaCommon, line 4 description: "Kasa Device Common Methods", // library marker davegut.kasaCommon, line 5 category: "utilities", // library marker davegut.kasaCommon, line 6 documentationLink: "" // library marker davegut.kasaCommon, line 7 ) // library marker davegut.kasaCommon, line 8 def nameSpace() { return "davegut" } // library marker davegut.kasaCommon, line 10 def installCommon() { // library marker davegut.kasaCommon, line 12 pauseExecution(3000) // library marker davegut.kasaCommon, line 13 def instStatus = [:] // library marker davegut.kasaCommon, line 14 if (getDataValue("deviceIP") == "CLOUD") { // library marker davegut.kasaCommon, line 15 sendEvent(name: "connection", value: "CLOUD") // library marker davegut.kasaCommon, line 16 device.updateSetting("useCloud", [type:"bool", value: true]) // library marker davegut.kasaCommon, line 17 instStatus << [useCloud: true, connection: "CLOUD"] // library marker davegut.kasaCommon, line 18 } else { // library marker davegut.kasaCommon, line 19 sendEvent(name: "connection", value: "LAN") // library marker davegut.kasaCommon, line 20 device.updateSetting("useCloud", [type:"bool", value: false]) // library marker davegut.kasaCommon, line 21 instStatus << [useCloud: false, connection: "LAN"] // library marker davegut.kasaCommon, line 22 } // library marker davegut.kasaCommon, line 23 sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommon, line 25 state.errorCount = 0 // library marker davegut.kasaCommon, line 26 state.pollInterval = "30 minutes" // library marker davegut.kasaCommon, line 27 runIn(1, updated) // library marker davegut.kasaCommon, line 28 return instStatus // library marker davegut.kasaCommon, line 29 } // library marker davegut.kasaCommon, line 30 def updateCommon() { // library marker davegut.kasaCommon, line 32 def updStatus = [:] // library marker davegut.kasaCommon, line 33 if (rebootDev) { // library marker davegut.kasaCommon, line 34 updStatus << [rebootDev: rebootDevice()] // library marker davegut.kasaCommon, line 35 return updStatus // library marker davegut.kasaCommon, line 36 } // library marker davegut.kasaCommon, line 37 unschedule() // library marker davegut.kasaCommon, line 38 updStatus << [bind: bindUnbind()] // library marker davegut.kasaCommon, line 39 if (nameSync != "none") { // library marker davegut.kasaCommon, line 40 updStatus << [nameSync: syncName()] // library marker davegut.kasaCommon, line 41 } // library marker davegut.kasaCommon, line 42 if (logEnable) { runIn(1800, debugLogOff) } // library marker davegut.kasaCommon, line 43 updStatus << [textEnable: textEnable, logEnable: logEnable] // library marker davegut.kasaCommon, line 44 if (manualIp != getDataValue("deviceIP")) { // library marker davegut.kasaCommon, line 45 updateDataValue("deviceIP", manualIp) // library marker davegut.kasaCommon, line 46 updStatus << [ipUpdate: manualIp] // library marker davegut.kasaCommon, line 47 } // library marker davegut.kasaCommon, line 48 if (manualPort != getDataValue("devicePort")) { // library marker davegut.kasaCommon, line 49 updateDataValue("devicePort", manualPort) // library marker davegut.kasaCommon, line 50 updStatus << [portUpdate: manualPort] // library marker davegut.kasaCommon, line 51 } // library marker davegut.kasaCommon, line 52 state.errorCount = 0 // library marker davegut.kasaCommon, line 53 sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommon, line 54 def pollInterval = state.pollInterval // library marker davegut.kasaCommon, line 55 if (pollInterval == null) { pollInterval = "30 minutes" } // library marker davegut.kasaCommon, line 56 updStatus << [pollInterval: setPollInterval(pollInterval)] // library marker davegut.kasaCommon, line 57 state.remove("UPDATE_AVAILABLE") // library marker davegut.kasaCommon, line 58 state.remove("releaseNotes") // library marker davegut.kasaCommon, line 59 removeDataValue("driverVersion") // library marker davegut.kasaCommon, line 60 if (emFunction) { // library marker davegut.kasaCommon, line 61 scheduleEnergyAttrs() // library marker davegut.kasaCommon, line 62 state.getEnergy = "This Month" // library marker davegut.kasaCommon, line 63 updStatus << [emFunction: "scheduled"] // library marker davegut.kasaCommon, line 64 } // library marker davegut.kasaCommon, line 65 runIn(5, listAttributes) // library marker davegut.kasaCommon, line 66 return updStatus // library marker davegut.kasaCommon, line 67 } // library marker davegut.kasaCommon, line 68 def configure() { // library marker davegut.kasaCommon, line 70 if (parent == null) { // library marker davegut.kasaCommon, line 71 logWarn("configure: No Parent Detected. Configure function ABORTED. Use Save Preferences instead.") // library marker davegut.kasaCommon, line 72 } else { // library marker davegut.kasaCommon, line 73 def confStatus = parent.updateConfigurations() // library marker davegut.kasaCommon, line 74 logInfo("configure: ${confStatus}") // library marker davegut.kasaCommon, line 75 } // library marker davegut.kasaCommon, line 76 } // library marker davegut.kasaCommon, line 77 def refresh() { poll() } // library marker davegut.kasaCommon, line 79 def poll() { getSysinfo() } // library marker davegut.kasaCommon, line 81 def setPollInterval(interval = state.pollInterval) { // library marker davegut.kasaCommon, line 83 if (interval == "default" || interval == "off" || interval == null) { // library marker davegut.kasaCommon, line 84 interval = "30 minutes" // library marker davegut.kasaCommon, line 85 } else if (useCloud || altLan || getDataValue("altComms") == "true") { // library marker davegut.kasaCommon, line 86 if (interval.contains("sec")) { // library marker davegut.kasaCommon, line 87 interval = "1 minute" // library marker davegut.kasaCommon, line 88 logWarn("setPollInterval: Device using Cloud or rawSocket. Poll interval reset to minimum value of 1 minute.") // library marker davegut.kasaCommon, line 89 } // library marker davegut.kasaCommon, line 90 } // library marker davegut.kasaCommon, line 91 state.pollInterval = interval // library marker davegut.kasaCommon, line 92 def pollInterval = interval.substring(0,2).toInteger() // library marker davegut.kasaCommon, line 93 if (interval.contains("sec")) { // library marker davegut.kasaCommon, line 94 def start = Math.round((pollInterval-1) * Math.random()).toInteger() // library marker davegut.kasaCommon, line 95 schedule("${start}/${pollInterval} * * * * ?", "poll") // library marker davegut.kasaCommon, line 96 logWarn("setPollInterval: Polling intervals of less than one minute " + // library marker davegut.kasaCommon, line 97 "can take high resources and may impact hub performance.") // library marker davegut.kasaCommon, line 98 } else { // library marker davegut.kasaCommon, line 99 def start = Math.round(59 * Math.random()).toInteger() // library marker davegut.kasaCommon, line 100 schedule("${start} */${pollInterval} * * * ?", "poll") // library marker davegut.kasaCommon, line 101 } // library marker davegut.kasaCommon, line 102 logDebug("setPollInterval: interval = ${interval}.") // library marker davegut.kasaCommon, line 103 return interval // library marker davegut.kasaCommon, line 104 } // library marker davegut.kasaCommon, line 105 def rebootDevice() { // library marker davegut.kasaCommon, line 107 device.updateSetting("rebootDev", [type:"bool", value: false]) // library marker davegut.kasaCommon, line 108 reboot() // library marker davegut.kasaCommon, line 109 pauseExecution(10000) // library marker davegut.kasaCommon, line 110 return "REBOOTING DEVICE" // library marker davegut.kasaCommon, line 111 } // library marker davegut.kasaCommon, line 112 def bindUnbind() { // library marker davegut.kasaCommon, line 114 def message // library marker davegut.kasaCommon, line 115 if (getDataValue("deviceIP") == "CLOUD") { // library marker davegut.kasaCommon, line 116 device.updateSetting("bind", [type:"bool", value: true]) // library marker davegut.kasaCommon, line 117 device.updateSetting("useCloud", [type:"bool", value: true]) // library marker davegut.kasaCommon, line 118 message = "No deviceIp. Bind not modified." // library marker davegut.kasaCommon, line 119 } else if (bind == null || getDataValue("feature") == "lightStrip") { // library marker davegut.kasaCommon, line 120 message = "Getting current bind state" // library marker davegut.kasaCommon, line 121 getBind() // library marker davegut.kasaCommon, line 122 } else if (bind == true) { // library marker davegut.kasaCommon, line 123 if (!parent.kasaToken || parent.userName == null || parent.userPassword == null) { // library marker davegut.kasaCommon, line 124 message = "Username/pwd not set." // library marker davegut.kasaCommon, line 125 getBind() // library marker davegut.kasaCommon, line 126 } else { // library marker davegut.kasaCommon, line 127 message = "Binding device to the Kasa Cloud." // library marker davegut.kasaCommon, line 128 setBind(parent.userName, parent.userPassword) // library marker davegut.kasaCommon, line 129 } // library marker davegut.kasaCommon, line 130 } else if (bind == false) { // library marker davegut.kasaCommon, line 131 message = "Unbinding device from the Kasa Cloud." // library marker davegut.kasaCommon, line 132 setUnbind() // library marker davegut.kasaCommon, line 133 } // library marker davegut.kasaCommon, line 134 pauseExecution(5000) // library marker davegut.kasaCommon, line 135 return message // library marker davegut.kasaCommon, line 136 } // library marker davegut.kasaCommon, line 137 def setBindUnbind(cmdResp) { // library marker davegut.kasaCommon, line 139 def bindState = true // library marker davegut.kasaCommon, line 140 if (cmdResp.get_info) { // library marker davegut.kasaCommon, line 141 if (cmdResp.get_info.binded == 0) { bindState = false } // library marker davegut.kasaCommon, line 142 logInfo("setBindUnbind: Bind status set to ${bindState}") // library marker davegut.kasaCommon, line 143 setCommsType(bindState) // library marker davegut.kasaCommon, line 144 } else if (cmdResp.bind.err_code == 0){ // library marker davegut.kasaCommon, line 145 getBind() // library marker davegut.kasaCommon, line 146 } else { // library marker davegut.kasaCommon, line 147 logWarn("setBindUnbind: Unhandled response: ${cmdResp}") // library marker davegut.kasaCommon, line 148 } // library marker davegut.kasaCommon, line 149 } // library marker davegut.kasaCommon, line 150 def setCommsType(bindState) { // library marker davegut.kasaCommon, line 152 def commsType = "LAN" // library marker davegut.kasaCommon, line 153 def cloudCtrl = false // library marker davegut.kasaCommon, line 154 if (bindState == false && useCloud == true) { // library marker davegut.kasaCommon, line 155 logWarn("setCommsType: Can not use cloud. Device is not bound to Kasa cloud.") // library marker davegut.kasaCommon, line 156 } else if (bindState == true && useCloud == true && parent.kasaToken) { // library marker davegut.kasaCommon, line 157 commsType = "CLOUD" // library marker davegut.kasaCommon, line 158 cloudCtrl = true // library marker davegut.kasaCommon, line 159 } else if (altLan == true) { // library marker davegut.kasaCommon, line 160 commsType = "AltLAN" // library marker davegut.kasaCommon, line 161 state.response = "" // library marker davegut.kasaCommon, line 162 } // library marker davegut.kasaCommon, line 163 def commsSettings = [bind: bindState, useCloud: cloudCtrl, commsType: commsType] // library marker davegut.kasaCommon, line 164 device.updateSetting("bind", [type:"bool", value: bindState]) // library marker davegut.kasaCommon, line 165 device.updateSetting("useCloud", [type:"bool", value: cloudCtrl]) // library marker davegut.kasaCommon, line 166 sendEvent(name: "connection", value: "${commsType}") // library marker davegut.kasaCommon, line 167 logInfo("setCommsType: ${commsSettings}") // library marker davegut.kasaCommon, line 168 if (getDataValue("plugNo") != null) { // library marker davegut.kasaCommon, line 169 def coordData = [:] // library marker davegut.kasaCommon, line 170 coordData << [bind: bindState] // library marker davegut.kasaCommon, line 171 coordData << [useCloud: cloudCtrl] // library marker davegut.kasaCommon, line 172 coordData << [connection: commsType] // library marker davegut.kasaCommon, line 173 coordData << [altLan: altLan] // library marker davegut.kasaCommon, line 174 parent.coordinate("commsData", coordData, getDataValue("deviceId"), getDataValue("plugNo")) // library marker davegut.kasaCommon, line 175 } // library marker davegut.kasaCommon, line 176 pauseExecution(1000) // library marker davegut.kasaCommon, line 177 } // library marker davegut.kasaCommon, line 178 def syncName() { // library marker davegut.kasaCommon, line 180 def message // library marker davegut.kasaCommon, line 181 if (nameSync == "Hubitat") { // library marker davegut.kasaCommon, line 182 message = "Hubitat Label Sync" // library marker davegut.kasaCommon, line 183 setDeviceAlias(device.getLabel()) // library marker davegut.kasaCommon, line 184 } else if (nameSync == "device") { // library marker davegut.kasaCommon, line 185 message = "Device Alias Sync" // library marker davegut.kasaCommon, line 186 } else { // library marker davegut.kasaCommon, line 187 message = "Not Syncing" // library marker davegut.kasaCommon, line 188 } // library marker davegut.kasaCommon, line 189 device.updateSetting("nameSync",[type:"enum", value:"none"]) // library marker davegut.kasaCommon, line 190 return message // library marker davegut.kasaCommon, line 191 } // library marker davegut.kasaCommon, line 192 def updateName(response) { // library marker davegut.kasaCommon, line 194 def name = device.getLabel() // library marker davegut.kasaCommon, line 195 if (response.alias) { // library marker davegut.kasaCommon, line 196 name = response.alias // library marker davegut.kasaCommon, line 197 device.setLabel(name) // library marker davegut.kasaCommon, line 198 } else if (response.err_code != 0) { // library marker davegut.kasaCommon, line 199 def msg = "updateName: Name Sync from Hubitat to Device returned an error." // library marker davegut.kasaCommon, line 200 msg+= "\n\rNote: Some devices do not support syncing name from the hub.\n\r" // library marker davegut.kasaCommon, line 201 logWarn(msg) // library marker davegut.kasaCommon, line 202 return // library marker davegut.kasaCommon, line 203 } // library marker davegut.kasaCommon, line 204 logInfo("updateName: Hubitat and Kasa device name synchronized to ${name}") // library marker davegut.kasaCommon, line 205 } // library marker davegut.kasaCommon, line 206 def getSysinfo() { // library marker davegut.kasaCommon, line 208 if (getDataValue("altComms") == "true") { // library marker davegut.kasaCommon, line 209 sendTcpCmd("""{"system":{"get_sysinfo":{}}}""") // library marker davegut.kasaCommon, line 210 } else { // library marker davegut.kasaCommon, line 211 sendCmd("""{"system":{"get_sysinfo":{}}}""") // library marker davegut.kasaCommon, line 212 } // library marker davegut.kasaCommon, line 213 } // library marker davegut.kasaCommon, line 214 def bindService() { // library marker davegut.kasaCommon, line 216 def service = "cnCloud" // library marker davegut.kasaCommon, line 217 def feature = getDataValue("feature") // library marker davegut.kasaCommon, line 218 if (feature.contains("Bulb") || feature == "lightStrip") { // library marker davegut.kasaCommon, line 219 service = "smartlife.iot.common.cloud" // library marker davegut.kasaCommon, line 220 } // library marker davegut.kasaCommon, line 221 return service // library marker davegut.kasaCommon, line 222 } // library marker davegut.kasaCommon, line 223 def getBind() { // library marker davegut.kasaCommon, line 225 if (getDataValue("deviceIP") == "CLOUD") { // library marker davegut.kasaCommon, line 226 logDebug("getBind: [status: notRun, reason: [deviceIP: CLOUD]]") // library marker davegut.kasaCommon, line 227 } else { // library marker davegut.kasaCommon, line 228 sendLanCmd("""{"${bindService()}":{"get_info":{}}}""") // library marker davegut.kasaCommon, line 229 } // library marker davegut.kasaCommon, line 230 } // library marker davegut.kasaCommon, line 231 def setBind(userName, password) { // library marker davegut.kasaCommon, line 233 if (getDataValue("deviceIP") == "CLOUD") { // library marker davegut.kasaCommon, line 234 logDebug("setBind: [status: notRun, reason: [deviceIP: CLOUD]]") // library marker davegut.kasaCommon, line 235 } else { // library marker davegut.kasaCommon, line 236 sendLanCmd("""{"${bindService()}":{"bind":{"username":"${userName}",""" + // library marker davegut.kasaCommon, line 237 """"password":"${password}"}},""" + // library marker davegut.kasaCommon, line 238 """"${bindService()}":{"get_info":{}}}""") // library marker davegut.kasaCommon, line 239 } // library marker davegut.kasaCommon, line 240 } // library marker davegut.kasaCommon, line 241 def setUnbind() { // library marker davegut.kasaCommon, line 243 if (getDataValue("deviceIP") == "CLOUD") { // library marker davegut.kasaCommon, line 244 logDebug("setUnbind: [status: notRun, reason: [deviceIP: CLOUD]]") // library marker davegut.kasaCommon, line 245 } else { // library marker davegut.kasaCommon, line 246 sendLanCmd("""{"${bindService()}":{"unbind":""},""" + // library marker davegut.kasaCommon, line 247 """"${bindService()}":{"get_info":{}}}""") // library marker davegut.kasaCommon, line 248 } // library marker davegut.kasaCommon, line 249 } // library marker davegut.kasaCommon, line 250 def sysService() { // library marker davegut.kasaCommon, line 252 def service = "system" // library marker davegut.kasaCommon, line 253 def feature = getDataValue("feature") // library marker davegut.kasaCommon, line 254 if (feature.contains("Bulb") || feature == "lightStrip") { // library marker davegut.kasaCommon, line 255 service = "smartlife.iot.common.system" // library marker davegut.kasaCommon, line 256 } // library marker davegut.kasaCommon, line 257 return service // library marker davegut.kasaCommon, line 258 } // library marker davegut.kasaCommon, line 259 def reboot() { // library marker davegut.kasaCommon, line 261 sendCmd("""{"${sysService()}":{"reboot":{"delay":1}}}""") // library marker davegut.kasaCommon, line 262 } // library marker davegut.kasaCommon, line 263 def setDeviceAlias(newAlias) { // library marker davegut.kasaCommon, line 265 if (getDataValue("plugNo") != null) { // library marker davegut.kasaCommon, line 266 sendCmd("""{"context":{"child_ids":["${getDataValue("plugId")}"]},""" + // library marker davegut.kasaCommon, line 267 """"system":{"set_dev_alias":{"alias":"${device.getLabel()}"}}}""") // library marker davegut.kasaCommon, line 268 } else { // library marker davegut.kasaCommon, line 269 sendCmd("""{"${sysService()}":{"set_dev_alias":{"alias":"${device.getLabel()}"}}}""") // library marker davegut.kasaCommon, line 270 } // library marker davegut.kasaCommon, line 271 } // library marker davegut.kasaCommon, line 272 // ~~~~~ end include (1359) davegut.kasaCommon ~~~~~ // ~~~~~ start include (1360) davegut.kasaCommunications ~~~~~ library ( // library marker davegut.kasaCommunications, line 1 name: "kasaCommunications", // library marker davegut.kasaCommunications, line 2 namespace: "davegut", // library marker davegut.kasaCommunications, line 3 author: "Dave Gutheinz", // library marker davegut.kasaCommunications, line 4 description: "Kasa Communications Methods", // library marker davegut.kasaCommunications, line 5 category: "communications", // library marker davegut.kasaCommunications, line 6 documentationLink: "" // library marker davegut.kasaCommunications, line 7 ) // library marker davegut.kasaCommunications, line 8 import groovy.json.JsonSlurper // library marker davegut.kasaCommunications, line 10 import org.json.JSONObject // library marker davegut.kasaCommunications, line 11 def getPort() { // library marker davegut.kasaCommunications, line 13 def port = 9999 // library marker davegut.kasaCommunications, line 14 if (getDataValue("devicePort")) { // library marker davegut.kasaCommunications, line 15 port = getDataValue("devicePort") // library marker davegut.kasaCommunications, line 16 } // library marker davegut.kasaCommunications, line 17 return port // library marker davegut.kasaCommunications, line 18 } // library marker davegut.kasaCommunications, line 19 def sendCmd(command) { // library marker davegut.kasaCommunications, line 21 state.lastCommand = command // library marker davegut.kasaCommunications, line 22 def connection = device.currentValue("connection") // library marker davegut.kasaCommunications, line 23 if (connection == "LAN") { // library marker davegut.kasaCommunications, line 24 sendLanCmd(command) // library marker davegut.kasaCommunications, line 25 } else if (connection == "CLOUD") { // library marker davegut.kasaCommunications, line 26 sendKasaCmd(command) // library marker davegut.kasaCommunications, line 27 } else if (connection == "AltLAN") { // library marker davegut.kasaCommunications, line 28 sendTcpCmd(command) // library marker davegut.kasaCommunications, line 29 } else { // library marker davegut.kasaCommunications, line 30 logWarn("sendCmd: attribute connection is not set.") // library marker davegut.kasaCommunications, line 31 } // library marker davegut.kasaCommunications, line 32 } // library marker davegut.kasaCommunications, line 33 /////////////////////////////////// // library marker davegut.kasaCommunications, line 35 def sendLanCmd(command) { // library marker davegut.kasaCommunications, line 36 logDebug("sendLanCmd: [ip: ${getDataValue("deviceIP")}, cmd: ${command}]") // library marker davegut.kasaCommunications, line 37 def myHubAction = new hubitat.device.HubAction( // library marker davegut.kasaCommunications, line 38 outputXOR(command), // library marker davegut.kasaCommunications, line 39 hubitat.device.Protocol.LAN, // library marker davegut.kasaCommunications, line 40 [type: hubitat.device.HubAction.Type.LAN_TYPE_UDPCLIENT, // library marker davegut.kasaCommunications, line 41 destinationAddress: "${getDataValue("deviceIP")}:${getPort()}", // library marker davegut.kasaCommunications, line 42 encoding: hubitat.device.HubAction.Encoding.HEX_STRING, // library marker davegut.kasaCommunications, line 43 parseWarning: true, // library marker davegut.kasaCommunications, line 44 timeout: 9, // library marker davegut.kasaCommunications, line 45 ignoreResponse: false, // library marker davegut.kasaCommunications, line 46 callback: "parseUdp"]) // library marker davegut.kasaCommunications, line 47 try { // library marker davegut.kasaCommunications, line 48 sendHubCommand(myHubAction) // library marker davegut.kasaCommunications, line 49 } catch (e) { // library marker davegut.kasaCommunications, line 50 handleCommsError() // library marker davegut.kasaCommunications, line 51 logWarn("sendLanCmd: LAN Error = ${e}.\n\rNo retry on this error.") // library marker davegut.kasaCommunications, line 52 } // library marker davegut.kasaCommunications, line 53 } // library marker davegut.kasaCommunications, line 54 def parseUdp(message) { // library marker davegut.kasaCommunications, line 55 def resp = parseLanMessage(message) // library marker davegut.kasaCommunications, line 56 if (resp.type == "LAN_TYPE_UDPCLIENT") { // library marker davegut.kasaCommunications, line 57 def clearResp = inputXOR(resp.payload) // library marker davegut.kasaCommunications, line 58 if (clearResp.length() > 1023) { // library marker davegut.kasaCommunications, line 59 if (clearResp.contains("preferred")) { // library marker davegut.kasaCommunications, line 60 clearResp = clearResp.substring(0,clearResp.indexOf("preferred")-2) + "}}}" // library marker davegut.kasaCommunications, line 61 } else if (clearResp.contains("child_num")) { // library marker davegut.kasaCommunications, line 62 clearResp = clearResp.substring(0,clearResp.indexOf("child_num") -2) + "}}}" // library marker davegut.kasaCommunications, line 63 } else { // library marker davegut.kasaCommunications, line 64 logWarn("parseUdp: [status: converting to altComms, error: udp msg can not be parsed]") // library marker davegut.kasaCommunications, line 65 logDebug("parseUdp: [messageData: ${clearResp}]") // library marker davegut.kasaCommunications, line 66 updateDataValue("altComms", "true") // library marker davegut.kasaCommunications, line 67 sendTcpCmd(state.lastCommand) // library marker davegut.kasaCommunications, line 68 return // library marker davegut.kasaCommunications, line 69 } // library marker davegut.kasaCommunications, line 70 } // library marker davegut.kasaCommunications, line 71 def cmdResp = new JsonSlurper().parseText(clearResp) // library marker davegut.kasaCommunications, line 72 logDebug("parseUdp: ${cmdResp}") // library marker davegut.kasaCommunications, line 73 distResp(cmdResp) // library marker davegut.kasaCommunications, line 74 setCommsError(false) // library marker davegut.kasaCommunications, line 75 } else { // library marker davegut.kasaCommunications, line 76 logDebug("parseUdp: [error: error, reason: not LAN_TYPE_UDPCLIENT, respType: ${resp.type}]") // library marker davegut.kasaCommunications, line 77 handleCommsError() // library marker davegut.kasaCommunications, line 78 } // library marker davegut.kasaCommunications, line 79 } // library marker davegut.kasaCommunications, line 80 def sendKasaCmd(command) { // library marker davegut.kasaCommunications, line 82 logDebug("sendKasaCmd: ${command}") // library marker davegut.kasaCommunications, line 83 def cmdResponse = "" // library marker davegut.kasaCommunications, line 84 def cmdBody = [ // library marker davegut.kasaCommunications, line 85 method: "passthrough", // library marker davegut.kasaCommunications, line 86 params: [ // library marker davegut.kasaCommunications, line 87 deviceId: getDataValue("deviceId"), // library marker davegut.kasaCommunications, line 88 requestData: "${command}" // library marker davegut.kasaCommunications, line 89 ] // library marker davegut.kasaCommunications, line 90 ] // library marker davegut.kasaCommunications, line 91 if (!parent.kasaCloudUrl || !parent.kasaToken) { // library marker davegut.kasaCommunications, line 92 logWarn("sendKasaCmd: Cloud interface not properly set up.") // library marker davegut.kasaCommunications, line 93 return // library marker davegut.kasaCommunications, line 94 } // library marker davegut.kasaCommunications, line 95 def sendCloudCmdParams = [ // library marker davegut.kasaCommunications, line 96 uri: "${parent.kasaCloudUrl}/?token=${parent.kasaToken}", // library marker davegut.kasaCommunications, line 97 requestContentType: 'application/json', // library marker davegut.kasaCommunications, line 98 contentType: 'application/json', // library marker davegut.kasaCommunications, line 99 headers: ['Accept':'application/json; version=1, */*; q=0.01'], // library marker davegut.kasaCommunications, line 100 timeout: 10, // library marker davegut.kasaCommunications, line 101 body : new groovy.json.JsonBuilder(cmdBody).toString() // library marker davegut.kasaCommunications, line 102 ] // library marker davegut.kasaCommunications, line 103 try { // library marker davegut.kasaCommunications, line 104 asynchttpPost("cloudParse", sendCloudCmdParams) // library marker davegut.kasaCommunications, line 105 } catch (e) { // library marker davegut.kasaCommunications, line 106 def msg = "sendKasaCmd: Error in Cloud Communications. The Kasa Cloud is unreachable." // library marker davegut.kasaCommunications, line 107 msg += "\nAdditional Data: Error = ${e}\n\n" // library marker davegut.kasaCommunications, line 108 logWarn(msg) // library marker davegut.kasaCommunications, line 109 } // library marker davegut.kasaCommunications, line 110 } // library marker davegut.kasaCommunications, line 111 def cloudParse(resp, data = null) { // library marker davegut.kasaCommunications, line 112 try { // library marker davegut.kasaCommunications, line 113 response = new JsonSlurper().parseText(resp.data) // library marker davegut.kasaCommunications, line 114 } catch (e) { // library marker davegut.kasaCommunications, line 115 response = [error_code: 9999, data: e] // library marker davegut.kasaCommunications, line 116 } // library marker davegut.kasaCommunications, line 117 if (resp.status == 200 && response.error_code == 0 && resp != []) { // library marker davegut.kasaCommunications, line 118 def cmdResp = new JsonSlurper().parseText(response.result.responseData) // library marker davegut.kasaCommunications, line 119 logDebug("cloudParse: ${cmdResp}") // library marker davegut.kasaCommunications, line 120 distResp(cmdResp) // library marker davegut.kasaCommunications, line 121 } else { // library marker davegut.kasaCommunications, line 122 def msg = "cloudParse:\nError from the Kasa Cloud. Most common cause is " // library marker davegut.kasaCommunications, line 123 msg += "your Kasa Token has expired. Run Kasa Login and Token update and try again." // library marker davegut.kasaCommunications, line 124 msg += "\nAdditional Data: Error = ${resp.data}\n\n" // library marker davegut.kasaCommunications, line 125 logDebug(msg) // library marker davegut.kasaCommunications, line 126 } // library marker davegut.kasaCommunications, line 127 } // library marker davegut.kasaCommunications, line 128 def sendTcpCmd(command) { // library marker davegut.kasaCommunications, line 130 logDebug("sendTcpCmd: ${command}") // library marker davegut.kasaCommunications, line 131 try { // library marker davegut.kasaCommunications, line 132 interfaces.rawSocket.connect("${getDataValue("deviceIP")}", // library marker davegut.kasaCommunications, line 133 getPort().toInteger(), byteInterface: true) // library marker davegut.kasaCommunications, line 134 } catch (error) { // library marker davegut.kasaCommunications, line 135 logDebug("SendTcpCmd: [connectFailed: [ip: ${getDataValue("deviceIP")}, Error = ${error}]]") // library marker davegut.kasaCommunications, line 136 } // library marker davegut.kasaCommunications, line 137 state.response = "" // library marker davegut.kasaCommunications, line 138 interfaces.rawSocket.sendMessage(outputXorTcp(command)) // library marker davegut.kasaCommunications, line 139 } // library marker davegut.kasaCommunications, line 140 def close() { interfaces.rawSocket.close() } // library marker davegut.kasaCommunications, line 141 def socketStatus(message) { // library marker davegut.kasaCommunications, line 142 if (message != "receive error: Stream closed.") { // library marker davegut.kasaCommunications, line 143 logDebug("socketStatus: Socket Established") // library marker davegut.kasaCommunications, line 144 } else { // library marker davegut.kasaCommunications, line 145 logWarn("socketStatus = ${message}") // library marker davegut.kasaCommunications, line 146 } // library marker davegut.kasaCommunications, line 147 } // library marker davegut.kasaCommunications, line 148 def parse(message) { // library marker davegut.kasaCommunications, line 149 if (message != null || message != "") { // library marker davegut.kasaCommunications, line 150 def response = state.response.concat(message) // library marker davegut.kasaCommunications, line 151 state.response = response // library marker davegut.kasaCommunications, line 152 extractTcpResp(response) // library marker davegut.kasaCommunications, line 153 } // library marker davegut.kasaCommunications, line 154 } // library marker davegut.kasaCommunications, line 155 def extractTcpResp(response) { // library marker davegut.kasaCommunications, line 156 def cmdResp // library marker davegut.kasaCommunications, line 157 def clearResp = inputXorTcp(response) // library marker davegut.kasaCommunications, line 158 if (clearResp.endsWith("}}}")) { // library marker davegut.kasaCommunications, line 159 interfaces.rawSocket.close() // library marker davegut.kasaCommunications, line 160 try { // library marker davegut.kasaCommunications, line 161 cmdResp = parseJson(clearResp) // library marker davegut.kasaCommunications, line 162 distResp(cmdResp) // library marker davegut.kasaCommunications, line 163 } catch (e) { // library marker davegut.kasaCommunications, line 164 logWarn("extractTcpResp: [length: ${clearResp.length()}, clearResp: ${clearResp}, comms error: ${e}]") // library marker davegut.kasaCommunications, line 165 } // library marker davegut.kasaCommunications, line 166 } else if (clearResp.length() > 2000) { // library marker davegut.kasaCommunications, line 167 interfaces.rawSocket.close() // library marker davegut.kasaCommunications, line 168 } // library marker davegut.kasaCommunications, line 169 } // library marker davegut.kasaCommunications, line 170 //////////////////////////////////////// // library marker davegut.kasaCommunications, line 175 def handleCommsError() { // library marker davegut.kasaCommunications, line 176 Map logData = [:] // library marker davegut.kasaCommunications, line 177 if (state.lastCommand != "") { // library marker davegut.kasaCommunications, line 178 def count = state.errorCount + 1 // library marker davegut.kasaCommunications, line 179 state.errorCount = count // library marker davegut.kasaCommunications, line 180 def retry = true // library marker davegut.kasaCommunications, line 181 def cmdData = new JSONObject(state.lastCmd) // library marker davegut.kasaCommunications, line 182 def cmdBody = parseJson(cmdData.cmdBody.toString()) // library marker davegut.kasaCommunications, line 183 logData << [count: count, command: state.lastCommand] // library marker davegut.kasaCommunications, line 184 switch (count) { // library marker davegut.kasaCommunications, line 185 case 1: // library marker davegut.kasaCommunications, line 186 case 2: // library marker davegut.kasaCommunications, line 187 if (getDataValue("altComms") == "true") { // library marker davegut.kasaCommunications, line 188 sendTcpCmd(state.lastCommand) // library marker davegut.kasaCommunications, line 189 } else { // library marker davegut.kasaCommunications, line 190 sendCmd(state.lastCommand) // library marker davegut.kasaCommunications, line 191 } // library marker davegut.kasaCommunications, line 192 logDebug("handleCommsError: ${logData}") // library marker davegut.kasaCommunications, line 193 break // library marker davegut.kasaCommunications, line 194 case 3: // library marker davegut.kasaCommunications, line 195 logData << [setCommsError: setCommsError(true), status: "retriesDisabled"] // library marker davegut.kasaCommunications, line 196 logError("handleCommsError: ${logData}") // library marker davegut.kasaCommunications, line 197 break // library marker davegut.kasaCommunications, line 198 default: // library marker davegut.kasaCommunications, line 199 break // library marker davegut.kasaCommunications, line 200 } // library marker davegut.kasaCommunications, line 201 } // library marker davegut.kasaCommunications, line 202 } // library marker davegut.kasaCommunications, line 203 ///////////////////////////////////////////// // library marker davegut.kasaCommunications, line 204 def setCommsError(status) { // library marker davegut.kasaCommunications, line 205 if (!status) { // library marker davegut.kasaCommunications, line 206 sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommunications, line 207 state.errorCount = 0 // library marker davegut.kasaCommunications, line 208 } else { // library marker davegut.kasaCommunications, line 209 sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommunications, line 210 return "commsErrorSet" // library marker davegut.kasaCommunications, line 211 } // library marker davegut.kasaCommunications, line 212 } // library marker davegut.kasaCommunications, line 213 //////////////////////////////////////////////////////////////////// // library marker davegut.kasaCommunications, line 216 def xxhandleCommsError() { // library marker davegut.kasaCommunications, line 217 if (state.lastCommand == "") { return } // library marker davegut.kasaCommunications, line 218 def count = state.errorCount + 1 // library marker davegut.kasaCommunications, line 219 state.errorCount = count // library marker davegut.kasaCommunications, line 220 def retry = true // library marker davegut.kasaCommunications, line 221 def status = [count: count, command: state.lastCommand] // library marker davegut.kasaCommunications, line 222 if (count == 3) { // library marker davegut.kasaCommunications, line 223 def attemptFix = parent.fixConnection() // library marker davegut.kasaCommunications, line 224 status << [attemptFixResult: [attemptFix]] // library marker davegut.kasaCommunications, line 225 } else if (count >= 4) { // library marker davegut.kasaCommunications, line 226 retry = false // library marker davegut.kasaCommunications, line 227 } // library marker davegut.kasaCommunications, line 228 if (retry == true) { // library marker davegut.kasaCommunications, line 229 if (state.lastCommand != null) { // library marker davegut.kasaCommunications, line 230 if (getDataValue("altComms") == "true") { // library marker davegut.kasaCommunications, line 231 sendTcpCmd(state.lastCommand) // library marker davegut.kasaCommunications, line 232 } else { // library marker davegut.kasaCommunications, line 233 sendCmd(state.lastCommand) // library marker davegut.kasaCommunications, line 234 } // library marker davegut.kasaCommunications, line 235 } // library marker davegut.kasaCommunications, line 236 } else { // library marker davegut.kasaCommunications, line 237 setCommsError() // library marker davegut.kasaCommunications, line 238 } // library marker davegut.kasaCommunications, line 239 status << [retry: retry] // library marker davegut.kasaCommunications, line 240 if (status.count > 2) { // library marker davegut.kasaCommunications, line 241 logWarn("handleCommsError: ${status}") // library marker davegut.kasaCommunications, line 242 } else { // library marker davegut.kasaCommunications, line 243 logDebug("handleCommsError: ${status}") // library marker davegut.kasaCommunications, line 244 } // library marker davegut.kasaCommunications, line 245 } // library marker davegut.kasaCommunications, line 246 /////////////////////////////////////////////////////// // library marker davegut.kasaCommunications, line 247 def xxsetCommsError() { // library marker davegut.kasaCommunications, line 248 if (device.currentValue("commsError") == "false") { // library marker davegut.kasaCommunications, line 249 def message = "Can't connect to your device at ${getDataValue("deviceIP")}:${getPort()}. " // library marker davegut.kasaCommunications, line 250 message += "Refer to troubleshooting guide commsError section." // library marker davegut.kasaCommunications, line 251 sendEvent(name: "commsError", value: "true") // library marker davegut.kasaCommunications, line 252 state.COMMS_ERROR = message // library marker davegut.kasaCommunications, line 253 logWarn("setCommsError: ${message}") // library marker davegut.kasaCommunications, line 254 runIn(15, limitPollInterval) // library marker davegut.kasaCommunications, line 255 } // library marker davegut.kasaCommunications, line 256 } // library marker davegut.kasaCommunications, line 257 ///////////////////////////////////////////////////////////////// // library marker davegut.kasaCommunications, line 258 def xxlimitPollInterval() { // library marker davegut.kasaCommunications, line 259 state.nonErrorPollInterval = state.pollInterval // library marker davegut.kasaCommunications, line 260 setPollInterval("30 minutes") // library marker davegut.kasaCommunications, line 261 } // library marker davegut.kasaCommunications, line 262 //////////////////////////////////////////////////////////////// // library marker davegut.kasaCommunications, line 263 def xxresetCommsError() { // library marker davegut.kasaCommunications, line 264 state.errorCount = 0 // library marker davegut.kasaCommunications, line 265 if (device.currentValue("commsError") == "true") { // library marker davegut.kasaCommunications, line 266 sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommunications, line 267 setPollInterval(state.nonErrorPollInterval) // library marker davegut.kasaCommunications, line 268 state.remove("nonErrorPollInterval") // library marker davegut.kasaCommunications, line 269 state.remove("COMMS_ERROR") // library marker davegut.kasaCommunications, line 270 logInfo("resetCommsError: Comms error cleared!") // library marker davegut.kasaCommunications, line 271 } // library marker davegut.kasaCommunications, line 272 } // library marker davegut.kasaCommunications, line 273 private outputXOR(command) { // library marker davegut.kasaCommunications, line 277 def str = "" // library marker davegut.kasaCommunications, line 278 def encrCmd = "" // library marker davegut.kasaCommunications, line 279 def key = 0xAB // library marker davegut.kasaCommunications, line 280 for (int i = 0; i < command.length(); i++) { // library marker davegut.kasaCommunications, line 281 str = (command.charAt(i) as byte) ^ key // library marker davegut.kasaCommunications, line 282 key = str // library marker davegut.kasaCommunications, line 283 encrCmd += Integer.toHexString(str) // library marker davegut.kasaCommunications, line 284 } // library marker davegut.kasaCommunications, line 285 return encrCmd // library marker davegut.kasaCommunications, line 286 } // library marker davegut.kasaCommunications, line 287 private inputXOR(encrResponse) { // library marker davegut.kasaCommunications, line 289 String[] strBytes = encrResponse.split("(?<=\\G.{2})") // library marker davegut.kasaCommunications, line 290 def cmdResponse = "" // library marker davegut.kasaCommunications, line 291 def key = 0xAB // library marker davegut.kasaCommunications, line 292 def nextKey // library marker davegut.kasaCommunications, line 293 byte[] XORtemp // library marker davegut.kasaCommunications, line 294 for(int i = 0; i < strBytes.length; i++) { // library marker davegut.kasaCommunications, line 295 nextKey = (byte)Integer.parseInt(strBytes[i], 16) // could be negative // library marker davegut.kasaCommunications, line 296 XORtemp = nextKey ^ key // library marker davegut.kasaCommunications, line 297 key = nextKey // library marker davegut.kasaCommunications, line 298 cmdResponse += new String(XORtemp) // library marker davegut.kasaCommunications, line 299 } // library marker davegut.kasaCommunications, line 300 return cmdResponse // library marker davegut.kasaCommunications, line 301 } // library marker davegut.kasaCommunications, line 302 private outputXorTcp(command) { // library marker davegut.kasaCommunications, line 304 def str = "" // library marker davegut.kasaCommunications, line 305 def encrCmd = "000000" + Integer.toHexString(command.length()) // library marker davegut.kasaCommunications, line 306 def key = 0xAB // library marker davegut.kasaCommunications, line 307 for (int i = 0; i < command.length(); i++) { // library marker davegut.kasaCommunications, line 308 str = (command.charAt(i) as byte) ^ key // library marker davegut.kasaCommunications, line 309 key = str // library marker davegut.kasaCommunications, line 310 encrCmd += Integer.toHexString(str) // library marker davegut.kasaCommunications, line 311 } // library marker davegut.kasaCommunications, line 312 return encrCmd // library marker davegut.kasaCommunications, line 313 } // library marker davegut.kasaCommunications, line 314 private inputXorTcp(resp) { // library marker davegut.kasaCommunications, line 316 String[] strBytes = resp.substring(8).split("(?<=\\G.{2})") // library marker davegut.kasaCommunications, line 317 def cmdResponse = "" // library marker davegut.kasaCommunications, line 318 def key = 0xAB // library marker davegut.kasaCommunications, line 319 def nextKey // library marker davegut.kasaCommunications, line 320 byte[] XORtemp // library marker davegut.kasaCommunications, line 321 for(int i = 0; i < strBytes.length; i++) { // library marker davegut.kasaCommunications, line 322 nextKey = (byte)Integer.parseInt(strBytes[i], 16) // could be negative // library marker davegut.kasaCommunications, line 323 XORtemp = nextKey ^ key // library marker davegut.kasaCommunications, line 324 key = nextKey // library marker davegut.kasaCommunications, line 325 cmdResponse += new String(XORtemp) // library marker davegut.kasaCommunications, line 326 } // library marker davegut.kasaCommunications, line 327 return cmdResponse // library marker davegut.kasaCommunications, line 328 } // library marker davegut.kasaCommunications, line 329 // ~~~~~ end include (1360) davegut.kasaCommunications ~~~~~ // ~~~~~ start include (1357) davegut.commonLogging ~~~~~ library ( // library marker davegut.commonLogging, line 1 name: "commonLogging", // library marker davegut.commonLogging, line 2 namespace: "davegut", // library marker davegut.commonLogging, line 3 author: "Dave Gutheinz", // library marker davegut.commonLogging, line 4 description: "Common Logging Methods", // library marker davegut.commonLogging, line 5 category: "utilities", // library marker davegut.commonLogging, line 6 documentationLink: "" // library marker davegut.commonLogging, line 7 ) // library marker davegut.commonLogging, line 8 // Logging during development // library marker davegut.commonLogging, line 10 def listAttributes(trace = false) { // library marker davegut.commonLogging, line 11 def attrs = device.getSupportedAttributes() // library marker davegut.commonLogging, line 12 def attrList = [:] // library marker davegut.commonLogging, line 13 attrs.each { // library marker davegut.commonLogging, line 14 def val = device.currentValue("${it}") // library marker davegut.commonLogging, line 15 attrList << ["${it}": val] // library marker davegut.commonLogging, line 16 } // library marker davegut.commonLogging, line 17 if (trace == true) { // library marker davegut.commonLogging, line 18 logInfo("Attributes: ${attrList}") // library marker davegut.commonLogging, line 19 } else { // library marker davegut.commonLogging, line 20 logDebug("Attributes: ${attrList}") // library marker davegut.commonLogging, line 21 } // library marker davegut.commonLogging, line 22 } // library marker davegut.commonLogging, line 23 // 6.7.2 Change B. Remove driverVer() // library marker davegut.commonLogging, line 25 def logTrace(msg){ // library marker davegut.commonLogging, line 26 log.trace "${device.displayName}-${driverVer()}: ${msg}" // library marker davegut.commonLogging, line 27 } // library marker davegut.commonLogging, line 28 def logInfo(msg) { // library marker davegut.commonLogging, line 30 if (textEnable || infoLog) { // library marker davegut.commonLogging, line 31 log.info "${device.displayName}-${driverVer()}: ${msg}" // library marker davegut.commonLogging, line 32 } // library marker davegut.commonLogging, line 33 } // library marker davegut.commonLogging, line 34 def debugLogOff() { // library marker davegut.commonLogging, line 36 if (logEnable) { // library marker davegut.commonLogging, line 37 device.updateSetting("logEnable", [type:"bool", value: false]) // library marker davegut.commonLogging, line 38 } // library marker davegut.commonLogging, line 39 logInfo("debugLogOff") // library marker davegut.commonLogging, line 40 } // library marker davegut.commonLogging, line 41 def logDebug(msg) { // library marker davegut.commonLogging, line 43 if (logEnable || debugLog) { // library marker davegut.commonLogging, line 44 log.debug "${device.displayName}-${driverVer()}: ${msg}" // library marker davegut.commonLogging, line 45 } // library marker davegut.commonLogging, line 46 } // library marker davegut.commonLogging, line 47 def logWarn(msg) { log.warn "${device.displayName}-${driverVer()}: ${msg}" } // library marker davegut.commonLogging, line 49 // ~~~~~ end include (1357) davegut.commonLogging ~~~~~ // ~~~~~ start include (1363) davegut.kasaPlugs ~~~~~ library ( // library marker davegut.kasaPlugs, line 1 name: "kasaPlugs", // library marker davegut.kasaPlugs, line 2 namespace: "davegut", // library marker davegut.kasaPlugs, line 3 author: "Dave Gutheinz", // library marker davegut.kasaPlugs, line 4 description: "Kasa Plug and Switches Common Methods", // library marker davegut.kasaPlugs, line 5 category: "utilities", // library marker davegut.kasaPlugs, line 6 documentationLink: "" // library marker davegut.kasaPlugs, line 7 ) // library marker davegut.kasaPlugs, line 8 def on() { setRelayState(1) } // library marker davegut.kasaPlugs, line 10 def off() { setRelayState(0) } // library marker davegut.kasaPlugs, line 12 def ledOn() { setLedOff(0) } // library marker davegut.kasaPlugs, line 14 def ledOff() { setLedOff(1) } // library marker davegut.kasaPlugs, line 16 def distResp(response) { // library marker davegut.kasaPlugs, line 18 if (response.system) { // library marker davegut.kasaPlugs, line 19 if (response.system.get_sysinfo) { // library marker davegut.kasaPlugs, line 20 setSysInfo(response.system.get_sysinfo) // library marker davegut.kasaPlugs, line 21 } else if (response.system.set_relay_state || // library marker davegut.kasaPlugs, line 22 response.system.set_led_off) { // library marker davegut.kasaPlugs, line 23 if (getDataValue("model") == "HS210") { // library marker davegut.kasaPlugs, line 24 runIn(2, getSysinfo) // library marker davegut.kasaPlugs, line 25 } else { // library marker davegut.kasaPlugs, line 26 getSysinfo() // library marker davegut.kasaPlugs, line 27 } // library marker davegut.kasaPlugs, line 28 } else if (response.system.reboot) { // library marker davegut.kasaPlugs, line 29 logWarn("distResp: Rebooting device.") // library marker davegut.kasaPlugs, line 30 } else if (response.system.set_dev_alias) { // library marker davegut.kasaPlugs, line 31 updateName(response.system.set_dev_alias) // library marker davegut.kasaPlugs, line 32 } else { // library marker davegut.kasaPlugs, line 33 logDebug("distResp: Unhandled response = ${response}") // library marker davegut.kasaPlugs, line 34 } // library marker davegut.kasaPlugs, line 35 } else if (response["smartlife.iot.dimmer"]) { // library marker davegut.kasaPlugs, line 36 if (response["smartlife.iot.dimmer"].get_dimmer_parameters) { // library marker davegut.kasaPlugs, line 37 setDimmerConfig(response["smartlife.iot.dimmer"]) // library marker davegut.kasaPlugs, line 38 } else { // library marker davegut.kasaPlugs, line 39 logDebug("distResp: Unhandled response: ${response["smartlife.iot.dimmer"]}") // library marker davegut.kasaPlugs, line 40 } // library marker davegut.kasaPlugs, line 41 } else if (response.emeter) { // library marker davegut.kasaPlugs, line 42 distEmeter(response.emeter) // library marker davegut.kasaPlugs, line 43 } else if (response.cnCloud) { // library marker davegut.kasaPlugs, line 44 setBindUnbind(response.cnCloud) // library marker davegut.kasaPlugs, line 45 } else { // library marker davegut.kasaPlugs, line 46 logDebug("distResp: Unhandled response = ${response}") // library marker davegut.kasaPlugs, line 47 } // library marker davegut.kasaPlugs, line 48 } // library marker davegut.kasaPlugs, line 49 def setRelayState(onOff) { // library marker davegut.kasaPlugs, line 51 logDebug("setRelayState: [switch: ${onOff}]") // library marker davegut.kasaPlugs, line 52 if (getDataValue("plugNo") == null) { // library marker davegut.kasaPlugs, line 53 sendCmd("""{"system":{"set_relay_state":{"state":${onOff}}}}""") // library marker davegut.kasaPlugs, line 54 } else { // library marker davegut.kasaPlugs, line 55 sendCmd("""{"context":{"child_ids":["${getDataValue("plugId")}"]},""" + // library marker davegut.kasaPlugs, line 56 """"system":{"set_relay_state":{"state":${onOff}}}}""") // library marker davegut.kasaPlugs, line 57 } // library marker davegut.kasaPlugs, line 58 } // library marker davegut.kasaPlugs, line 59 def setLedOff(onOff) { // library marker davegut.kasaPlugs, line 61 logDebug("setLedOff: [ledOff: ${onOff}]") // library marker davegut.kasaPlugs, line 62 sendCmd("""{"system":{"set_led_off":{"off":${onOff}}}}""") // library marker davegut.kasaPlugs, line 63 } // library marker davegut.kasaPlugs, line 64 // ~~~~~ end include (1363) davegut.kasaPlugs ~~~~~ // ~~~~~ start include (1361) davegut.kasaEnergyMonitor ~~~~~ library ( // library marker davegut.kasaEnergyMonitor, line 1 name: "kasaEnergyMonitor", // library marker davegut.kasaEnergyMonitor, line 2 namespace: "davegut", // library marker davegut.kasaEnergyMonitor, line 3 author: "Dave Gutheinz", // library marker davegut.kasaEnergyMonitor, line 4 description: "Kasa Device Energy Monitor Methods", // library marker davegut.kasaEnergyMonitor, line 5 category: "energyMonitor", // library marker davegut.kasaEnergyMonitor, line 6 documentationLink: "" // library marker davegut.kasaEnergyMonitor, line 7 ) // library marker davegut.kasaEnergyMonitor, line 8 def setupEmFunction() { // library marker davegut.kasaEnergyMonitor, line 10 if (emFunction && device.currentValue("currMonthTotal") > 0) { // library marker davegut.kasaEnergyMonitor, line 11 state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 12 return "Continuing EM Function" // library marker davegut.kasaEnergyMonitor, line 13 } else if (emFunction) { // library marker davegut.kasaEnergyMonitor, line 14 zeroizeEnergyAttrs() // library marker davegut.kasaEnergyMonitor, line 15 state.response = "" // library marker davegut.kasaEnergyMonitor, line 16 state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 17 // Run order / delay is critical for successful operation. // library marker davegut.kasaEnergyMonitor, line 18 getEnergyThisMonth() // library marker davegut.kasaEnergyMonitor, line 19 runIn(10, getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 20 return "Initialized" // library marker davegut.kasaEnergyMonitor, line 21 } else if (emFunction && device.currentValue("power") != null) { // library marker davegut.kasaEnergyMonitor, line 22 // for power != null, EM had to be enabled at one time. Set values to 0. // library marker davegut.kasaEnergyMonitor, line 23 zeroizeEnergyAttrs() // library marker davegut.kasaEnergyMonitor, line 24 state.remove("getEnergy") // library marker davegut.kasaEnergyMonitor, line 25 return "Disabled" // library marker davegut.kasaEnergyMonitor, line 26 } else { // library marker davegut.kasaEnergyMonitor, line 27 return "Not initialized" // library marker davegut.kasaEnergyMonitor, line 28 } // library marker davegut.kasaEnergyMonitor, line 29 } // library marker davegut.kasaEnergyMonitor, line 30 def scheduleEnergyAttrs() { // library marker davegut.kasaEnergyMonitor, line 32 schedule("10 0 0 * * ?", getEnergyThisMonth) // library marker davegut.kasaEnergyMonitor, line 33 schedule("15 2 0 1 * ?", getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 34 switch(energyPollInt) { // library marker davegut.kasaEnergyMonitor, line 35 case "1 minute": // library marker davegut.kasaEnergyMonitor, line 36 runEvery1Minute(getEnergyToday) // library marker davegut.kasaEnergyMonitor, line 37 break // library marker davegut.kasaEnergyMonitor, line 38 case "5 minutes": // library marker davegut.kasaEnergyMonitor, line 39 runEvery5Minutes(getEnergyToday) // library marker davegut.kasaEnergyMonitor, line 40 break // library marker davegut.kasaEnergyMonitor, line 41 default: // library marker davegut.kasaEnergyMonitor, line 42 runEvery30Minutes(getEnergyToday) // library marker davegut.kasaEnergyMonitor, line 43 } // library marker davegut.kasaEnergyMonitor, line 44 } // library marker davegut.kasaEnergyMonitor, line 45 def zeroizeEnergyAttrs() { // library marker davegut.kasaEnergyMonitor, line 47 sendEvent(name: "power", value: 0, unit: "W") // library marker davegut.kasaEnergyMonitor, line 48 sendEvent(name: "energy", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 49 sendEvent(name: "currMonthTotal", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 50 sendEvent(name: "currMonthAvg", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 51 sendEvent(name: "lastMonthTotal", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 52 sendEvent(name: "lastMonthAvg", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 53 } // library marker davegut.kasaEnergyMonitor, line 54 def getDate() { // library marker davegut.kasaEnergyMonitor, line 56 def currDate = new Date() // library marker davegut.kasaEnergyMonitor, line 57 int year = currDate.format("yyyy").toInteger() // library marker davegut.kasaEnergyMonitor, line 58 int month = currDate.format("M").toInteger() // library marker davegut.kasaEnergyMonitor, line 59 int day = currDate.format("d").toInteger() // library marker davegut.kasaEnergyMonitor, line 60 return [year: year, month: month, day: day] // library marker davegut.kasaEnergyMonitor, line 61 } // library marker davegut.kasaEnergyMonitor, line 62 def distEmeter(emeterResp) { // library marker davegut.kasaEnergyMonitor, line 64 def date = getDate() // library marker davegut.kasaEnergyMonitor, line 65 logDebug("distEmeter: ${emeterResp}, ${date}, ${state.getEnergy}") // library marker davegut.kasaEnergyMonitor, line 66 def lastYear = date.year - 1 // library marker davegut.kasaEnergyMonitor, line 67 if (emeterResp.get_realtime) { // library marker davegut.kasaEnergyMonitor, line 68 setPower(emeterResp.get_realtime) // library marker davegut.kasaEnergyMonitor, line 69 } else if (emeterResp.get_monthstat) { // library marker davegut.kasaEnergyMonitor, line 70 def monthList = emeterResp.get_monthstat.month_list // library marker davegut.kasaEnergyMonitor, line 71 if (state.getEnergy == "Today") { // library marker davegut.kasaEnergyMonitor, line 72 setEnergyToday(monthList, date) // library marker davegut.kasaEnergyMonitor, line 73 } else if (state.getEnergy == "This Month") { // library marker davegut.kasaEnergyMonitor, line 74 setThisMonth(monthList, date) // library marker davegut.kasaEnergyMonitor, line 75 } else if (state.getEnergy == "Last Month") { // library marker davegut.kasaEnergyMonitor, line 76 setLastMonth(monthList, date) // library marker davegut.kasaEnergyMonitor, line 77 } else if (monthList == []) { // library marker davegut.kasaEnergyMonitor, line 78 logDebug("distEmeter: monthList Empty. No data for year.") // library marker davegut.kasaEnergyMonitor, line 79 } // library marker davegut.kasaEnergyMonitor, line 80 } else { // library marker davegut.kasaEnergyMonitor, line 81 logWarn("distEmeter: Unhandled response = ${emeterResp}") // library marker davegut.kasaEnergyMonitor, line 82 } // library marker davegut.kasaEnergyMonitor, line 83 } // library marker davegut.kasaEnergyMonitor, line 84 def getPower() { // library marker davegut.kasaEnergyMonitor, line 86 if (emFunction) { // library marker davegut.kasaEnergyMonitor, line 87 if (device.currentValue("switch") == "on") { // library marker davegut.kasaEnergyMonitor, line 88 getRealtime() // library marker davegut.kasaEnergyMonitor, line 89 } else if (device.currentValue("power") != 0) { // library marker davegut.kasaEnergyMonitor, line 90 sendEvent(name: "power", value: 0, descriptionText: "Watts", unit: "W", type: "digital") // library marker davegut.kasaEnergyMonitor, line 91 } // library marker davegut.kasaEnergyMonitor, line 92 } // library marker davegut.kasaEnergyMonitor, line 93 } // library marker davegut.kasaEnergyMonitor, line 94 def setPower(response) { // library marker davegut.kasaEnergyMonitor, line 96 logDebug("setPower: ${response}") // library marker davegut.kasaEnergyMonitor, line 97 def power = response.power // library marker davegut.kasaEnergyMonitor, line 98 if (power == null) { power = response.power_mw / 1000 } // library marker davegut.kasaEnergyMonitor, line 99 power = (power + 0.5).toInteger() // library marker davegut.kasaEnergyMonitor, line 100 def curPwr = device.currentValue("power") // library marker davegut.kasaEnergyMonitor, line 101 def pwrChange = false // library marker davegut.kasaEnergyMonitor, line 102 if (curPwr != power) { // library marker davegut.kasaEnergyMonitor, line 103 if (curPwr == null || (curPwr == 0 && power > 0)) { // library marker davegut.kasaEnergyMonitor, line 104 pwrChange = true // library marker davegut.kasaEnergyMonitor, line 105 } else { // library marker davegut.kasaEnergyMonitor, line 106 def changeRatio = Math.abs((power - curPwr) / curPwr) // library marker davegut.kasaEnergyMonitor, line 107 if (changeRatio > 0.03) { // library marker davegut.kasaEnergyMonitor, line 108 pwrChange = true // library marker davegut.kasaEnergyMonitor, line 109 } // library marker davegut.kasaEnergyMonitor, line 110 } // library marker davegut.kasaEnergyMonitor, line 111 } // library marker davegut.kasaEnergyMonitor, line 112 if (pwrChange == true) { // library marker davegut.kasaEnergyMonitor, line 113 sendEvent(name: "power", value: power, descriptionText: "Watts", unit: "W", type: "digital") // library marker davegut.kasaEnergyMonitor, line 114 } // library marker davegut.kasaEnergyMonitor, line 115 } // library marker davegut.kasaEnergyMonitor, line 116 def getEnergyToday() { // library marker davegut.kasaEnergyMonitor, line 118 if (device.currentValue("switch") == "on") { // library marker davegut.kasaEnergyMonitor, line 119 state.getEnergy = "Today" // library marker davegut.kasaEnergyMonitor, line 120 def year = getDate().year // library marker davegut.kasaEnergyMonitor, line 121 logDebug("getEnergyToday: ${year}") // library marker davegut.kasaEnergyMonitor, line 122 runIn(5, getMonthstat, [data: year]) // library marker davegut.kasaEnergyMonitor, line 123 } // library marker davegut.kasaEnergyMonitor, line 124 } // library marker davegut.kasaEnergyMonitor, line 125 def setEnergyToday(monthList, date) { // library marker davegut.kasaEnergyMonitor, line 127 logDebug("setEnergyToday: ${date}, ${monthList}") // library marker davegut.kasaEnergyMonitor, line 128 def data = monthList.find { it.month == date.month && it.year == date.year} // library marker davegut.kasaEnergyMonitor, line 129 def status = [:] // library marker davegut.kasaEnergyMonitor, line 130 def energy = 0 // library marker davegut.kasaEnergyMonitor, line 131 if (data == null) { // library marker davegut.kasaEnergyMonitor, line 132 status << [msgError: "Return Data Null"] // library marker davegut.kasaEnergyMonitor, line 133 } else { // library marker davegut.kasaEnergyMonitor, line 134 energy = data.energy // library marker davegut.kasaEnergyMonitor, line 135 if (energy == null) { energy = data.energy_wh/1000 } // library marker davegut.kasaEnergyMonitor, line 136 energy = Math.round(100*energy)/100 - device.currentValue("currMonthTotal") // library marker davegut.kasaEnergyMonitor, line 137 } // library marker davegut.kasaEnergyMonitor, line 138 if (device.currentValue("energy") != energy) { // library marker davegut.kasaEnergyMonitor, line 139 sendEvent(name: "energy", value: energy, descriptionText: "KiloWatt Hours", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 140 status << [energy: energy] // library marker davegut.kasaEnergyMonitor, line 141 } // library marker davegut.kasaEnergyMonitor, line 142 if (status != [:]) { logInfo("setEnergyToday: ${status}") } // library marker davegut.kasaEnergyMonitor, line 143 if (!state.getEnergy) { // library marker davegut.kasaEnergyMonitor, line 144 schedule("10 0 0 * * ?", getEnergyThisMonth) // library marker davegut.kasaEnergyMonitor, line 145 schedule("15 2 0 1 * ?", getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 146 state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 147 getEnergyThisMonth() // library marker davegut.kasaEnergyMonitor, line 148 runIn(10, getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 149 } // library marker davegut.kasaEnergyMonitor, line 150 } // library marker davegut.kasaEnergyMonitor, line 151 def getEnergyThisMonth() { // library marker davegut.kasaEnergyMonitor, line 153 state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 154 def year = getDate().year // library marker davegut.kasaEnergyMonitor, line 155 logDebug("getEnergyThisMonth: ${year}") // library marker davegut.kasaEnergyMonitor, line 156 runIn(5, getMonthstat, [data: year]) // library marker davegut.kasaEnergyMonitor, line 157 } // library marker davegut.kasaEnergyMonitor, line 158 def setThisMonth(monthList, date) { // library marker davegut.kasaEnergyMonitor, line 160 logDebug("setThisMonth: ${date} // ${monthList}") // library marker davegut.kasaEnergyMonitor, line 161 def data = monthList.find { it.month == date.month && it.year == date.year} // library marker davegut.kasaEnergyMonitor, line 162 def status = [:] // library marker davegut.kasaEnergyMonitor, line 163 def totEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 164 def avgEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 165 if (data == null) { // library marker davegut.kasaEnergyMonitor, line 166 status << [msgError: "Return Data Null"] // library marker davegut.kasaEnergyMonitor, line 167 } else { // library marker davegut.kasaEnergyMonitor, line 168 status << [msgError: "OK"] // library marker davegut.kasaEnergyMonitor, line 169 totEnergy = data.energy // library marker davegut.kasaEnergyMonitor, line 170 if (totEnergy == null) { totEnergy = data.energy_wh/1000 } // library marker davegut.kasaEnergyMonitor, line 171 if (date.day == 1) { // library marker davegut.kasaEnergyMonitor, line 172 avgEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 173 } else { // library marker davegut.kasaEnergyMonitor, line 174 avgEnergy = totEnergy /(date.day - 1) // library marker davegut.kasaEnergyMonitor, line 175 } // library marker davegut.kasaEnergyMonitor, line 176 } // library marker davegut.kasaEnergyMonitor, line 177 totEnergy = Math.round(100*totEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 178 avgEnergy = Math.round(100*avgEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 179 sendEvent(name: "currMonthTotal", value: totEnergy, // library marker davegut.kasaEnergyMonitor, line 180 descriptionText: "KiloWatt Hours", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 181 status << [currMonthTotal: totEnergy] // library marker davegut.kasaEnergyMonitor, line 182 sendEvent(name: "currMonthAvg", value: avgEnergy, // library marker davegut.kasaEnergyMonitor, line 183 descriptionText: "KiloWatt Hours per Day", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 184 status << [currMonthAvg: avgEnergy] // library marker davegut.kasaEnergyMonitor, line 185 getEnergyToday() // library marker davegut.kasaEnergyMonitor, line 186 logInfo("setThisMonth: ${status}") // library marker davegut.kasaEnergyMonitor, line 187 } // library marker davegut.kasaEnergyMonitor, line 188 def getEnergyLastMonth() { // library marker davegut.kasaEnergyMonitor, line 190 state.getEnergy = "Last Month" // library marker davegut.kasaEnergyMonitor, line 191 def date = getDate() // library marker davegut.kasaEnergyMonitor, line 192 def year = date.year // library marker davegut.kasaEnergyMonitor, line 193 if (date.month == 1) { // library marker davegut.kasaEnergyMonitor, line 194 year = year - 1 // library marker davegut.kasaEnergyMonitor, line 195 } // library marker davegut.kasaEnergyMonitor, line 196 logDebug("getEnergyLastMonth: ${year}") // library marker davegut.kasaEnergyMonitor, line 197 runIn(5, getMonthstat, [data: year]) // library marker davegut.kasaEnergyMonitor, line 198 } // library marker davegut.kasaEnergyMonitor, line 199 def setLastMonth(monthList, date) { // library marker davegut.kasaEnergyMonitor, line 201 logDebug("setLastMonth: ${date} // ${monthList}") // library marker davegut.kasaEnergyMonitor, line 202 def lastMonthYear = date.year // library marker davegut.kasaEnergyMonitor, line 203 def lastMonth = date.month - 1 // library marker davegut.kasaEnergyMonitor, line 204 if (date.month == 1) { // library marker davegut.kasaEnergyMonitor, line 205 lastMonthYear -+ 1 // library marker davegut.kasaEnergyMonitor, line 206 lastMonth = 12 // library marker davegut.kasaEnergyMonitor, line 207 } // library marker davegut.kasaEnergyMonitor, line 208 def data = monthList.find { it.month == lastMonth } // library marker davegut.kasaEnergyMonitor, line 209 def status = [:] // library marker davegut.kasaEnergyMonitor, line 210 def totEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 211 def avgEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 212 if (data == null) { // library marker davegut.kasaEnergyMonitor, line 213 status << [msgError: "Return Data Null"] // library marker davegut.kasaEnergyMonitor, line 214 } else { // library marker davegut.kasaEnergyMonitor, line 215 status << [msgError: "OK"] // library marker davegut.kasaEnergyMonitor, line 216 def monthLength // library marker davegut.kasaEnergyMonitor, line 217 switch(lastMonth) { // library marker davegut.kasaEnergyMonitor, line 218 case 4: // library marker davegut.kasaEnergyMonitor, line 219 case 6: // library marker davegut.kasaEnergyMonitor, line 220 case 9: // library marker davegut.kasaEnergyMonitor, line 221 case 11: // library marker davegut.kasaEnergyMonitor, line 222 monthLength = 30 // library marker davegut.kasaEnergyMonitor, line 223 break // library marker davegut.kasaEnergyMonitor, line 224 case 2: // library marker davegut.kasaEnergyMonitor, line 225 monthLength = 28 // library marker davegut.kasaEnergyMonitor, line 226 if (lastMonthYear == 2020 || lastMonthYear == 2024 || lastMonthYear == 2028) { // library marker davegut.kasaEnergyMonitor, line 227 monthLength = 29 // library marker davegut.kasaEnergyMonitor, line 228 } // library marker davegut.kasaEnergyMonitor, line 229 break // library marker davegut.kasaEnergyMonitor, line 230 default: // library marker davegut.kasaEnergyMonitor, line 231 monthLength = 31 // library marker davegut.kasaEnergyMonitor, line 232 } // library marker davegut.kasaEnergyMonitor, line 233 totEnergy = data.energy // library marker davegut.kasaEnergyMonitor, line 234 if (totEnergy == null) { totEnergy = data.energy_wh/1000 } // library marker davegut.kasaEnergyMonitor, line 235 avgEnergy = totEnergy / monthLength // library marker davegut.kasaEnergyMonitor, line 236 } // library marker davegut.kasaEnergyMonitor, line 237 totEnergy = Math.round(100*totEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 238 avgEnergy = Math.round(100*avgEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 239 sendEvent(name: "lastMonthTotal", value: totEnergy, // library marker davegut.kasaEnergyMonitor, line 240 descriptionText: "KiloWatt Hours", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 241 status << [lastMonthTotal: totEnergy] // library marker davegut.kasaEnergyMonitor, line 242 sendEvent(name: "lastMonthAvg", value: avgEnergy, // library marker davegut.kasaEnergyMonitor, line 243 descriptionText: "KiloWatt Hoursper Day", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 244 status << [lastMonthAvg: avgEnergy] // library marker davegut.kasaEnergyMonitor, line 245 logInfo("setLastMonth: ${status}") // library marker davegut.kasaEnergyMonitor, line 246 } // library marker davegut.kasaEnergyMonitor, line 247 def getRealtime() { // library marker davegut.kasaEnergyMonitor, line 249 def feature = getDataValue("feature") // library marker davegut.kasaEnergyMonitor, line 250 if (getDataValue("plugNo") != null) { // library marker davegut.kasaEnergyMonitor, line 251 sendCmd("""{"context":{"child_ids":["${getDataValue("plugId")}"]},""" + // library marker davegut.kasaEnergyMonitor, line 252 """"emeter":{"get_realtime":{}}}""") // library marker davegut.kasaEnergyMonitor, line 253 } else if (feature.contains("Bulb") || feature == "lightStrip") { // library marker davegut.kasaEnergyMonitor, line 254 sendCmd("""{"smartlife.iot.common.emeter":{"get_realtime":{}}}""") // library marker davegut.kasaEnergyMonitor, line 255 } else { // library marker davegut.kasaEnergyMonitor, line 256 sendCmd("""{"emeter":{"get_realtime":{}}}""") // library marker davegut.kasaEnergyMonitor, line 257 } // library marker davegut.kasaEnergyMonitor, line 258 } // library marker davegut.kasaEnergyMonitor, line 259 def getMonthstat(year) { // library marker davegut.kasaEnergyMonitor, line 261 def feature = getDataValue("feature") // library marker davegut.kasaEnergyMonitor, line 262 if (getDataValue("plugNo") != null) { // library marker davegut.kasaEnergyMonitor, line 263 sendCmd("""{"context":{"child_ids":["${getDataValue("plugId")}"]},""" + // library marker davegut.kasaEnergyMonitor, line 264 """"emeter":{"get_monthstat":{"year": ${year}}}}""") // library marker davegut.kasaEnergyMonitor, line 265 } else if (feature.contains("Bulb") || feature == "lightStrip") { // library marker davegut.kasaEnergyMonitor, line 266 sendCmd("""{"smartlife.iot.common.emeter":{"get_monthstat":{"year": ${year}}}}""") // library marker davegut.kasaEnergyMonitor, line 267 } else { // library marker davegut.kasaEnergyMonitor, line 268 sendCmd("""{"emeter":{"get_monthstat":{"year": ${year}}}}""") // library marker davegut.kasaEnergyMonitor, line 269 } // library marker davegut.kasaEnergyMonitor, line 270 } // library marker davegut.kasaEnergyMonitor, line 271 // ~~~~~ end include (1361) davegut.kasaEnergyMonitor ~~~~~