/* 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" } metadata { definition (name: "Kasa Light Strip", namespace: nameSpace(), author: "Dave Gutheinz", importUrl: "https://raw.githubusercontent.com/DaveGut/HubitatActive/master/KasaDevices/DeviceDrivers/LightStrip.groovy" ) { capability "Light" capability "Switch" capability "Switch Level" capability "Change Level" capability "Refresh" capability "Actuator" capability "Configuration" capability "Color Temperature" capability "Color Mode" capability "Color Control" command "setRGB", [[ name: "red,green,blue", type: "STRING"]] command "bulbPresetCreate", [[ name: "Name for preset.", type: "STRING"]] command "bulbPresetDelete", [[ name: "Name for preset.", type: "STRING"]] command "bulbPresetSet", [[ name: "Name for preset.", type: "STRING"],[ name: "Transition Time (seconds).", type: "STRING"]] capability "Light Effects" command "effectSet", [[ name: "Name for effect.", type: "STRING"]] command "effectCreate" command "effectDelete", [[ name: "Name for effect to delete.", type: "STRING"]] command "setPollInterval", [[ name: "Poll Interval in seconds", constraints: ["default", "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" } preferences { input ("textEnable", "bool", title: "Enable descriptionText logging", defaultValue: true) input ("logEnable", "bool", title: "Enable debug logging", defaultValue: false) input ("syncBulbs", "bool", title: "Sync Bulb Preset Data", defaultValue: false) input ("syncEffects", "bool", title: "Sync Effect Preset Data", defaultValue: false) 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") } 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", defaultValue: "none", options: ["none": "Don't synchronize", "device" : "Kasa device name master", "Hubitat" : "Hubitat label master"]) 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() { def instStatus= installCommon() state.bulbPresets = [:] state.effectPresets = [] sendEvent(name: "lightEffects", value: []) logInfo("installed: ${instStatus}") } def updated() { def updStatus = updateCommon() if (syncBulbs) { updStatus << [syncBulbs: syncBulbPresets()] } if (syncEffects) { updStatus << [syncEffects: syncEffectPresets()] } updStatus << [emFunction: setupEmFunction()] if (!state.bulbPresets) { state.bulbPresets = [:] } if (!state.effectPresets) { state.effectPresets = [] } logInfo("updated: ${updStatus}") refresh() } def setColorTemperature(colorTemp, level = device.currentValue("level"), transTime = transition_Time) { def lowCt = 1000 def highCt = 12000 if (colorTemp < lowCt) { colorTemp = lowCt } else if (colorTemp > highCt) { colorTemp = highCt } def hsvData = getCtHslValue(colorTemp) setLightColor(level, colorTemp, hsvData.hue, hsvData.saturation, 0) state.currentCT = colorTemp } def distResp(response) { if (response.system) { if (response.system.get_sysinfo) { setSysInfo(response.system.get_sysinfo) if (nameSync == "device") { updateName(response.system.get_sysinfo) } } else if (response.system.set_dev_alias) { updateName(response.system.set_dev_alias) } else { logWarn("distResp: Unhandled response = ${response}") } } else if (response["smartlife.iot.smartbulb.lightingservice"]) { setSysInfo([light_state:response["smartlife.iot.smartbulb.lightingservice"].transition_light_state]) } else if (response["smartlife.iot.lightStrip"]) { getSysinfo() } else if (response["smartlife.iot.lighting_effect"]) { parseEffect(response["smartlife.iot.lighting_effect"]) } else if (response["smartlife.iot.common.emeter"]) { distEmeter(response["smartlife.iot.common.emeter"]) } else if (response["smartlife.iot.common.cloud"]) { setBindUnbind(response["smartlife.iot.common.cloud"]) } else if (response["smartlife.iot.common.system"]) { if (response["smartlife.iot.common.system"].reboot) { logWarn("distResp: Rebooting device") } else { logDebug("distResp: Unhandled reboot response: ${response}") } } else { logWarn("distResp: Unhandled response = ${response}") } } def setSysInfo(status) { def lightStatus = status.light_state if (state.lastStatus != lightStatus) { state.lastStatus = lightStatus logInfo("setSysinfo: [status: ${lightStatus}]") def onOff if (lightStatus.on_off == 0) { onOff = "off" } else { onOff = "on" int level = lightStatus.brightness sendEvent(name: "level", value: level, unit: "%") int colorTemp = lightStatus.color_temp int hue = lightStatus.hue int hubHue = (hue / 3.6).toInteger() int saturation = lightStatus.saturation def colorMode def colorName = " " def effectName = " " def color = "" def rgb = "" if (status.lighting_effect_state.enable == 1) { colorMode = "EFFECTS" effectName = status.lighting_effect_state.name colorTemp = 0 hubHue = 0 saturation = 0 } else if (colorTemp > 0) { colorMode = "CT" colorName = convertTemperatureToGenericColorName(colorTemp.toInteger()) } else { colorMode = "RGB" colorName = convertHueToGenericColorName(hubHue.toInteger()) color = "[hue: ${hubHue}, saturation: ${saturation}, level: ${level}]" rgb = hubitat.helper.ColorUtils.hsvToRGB([hubHue, saturation, level]) } if (device.currentValue("colorTemperature") != colorTemp || device.currentValue("color") != color) { sendEvent(name: "colorTemperature", value: colorTemp) sendEvent(name: "colorName", value: colorName) sendEvent(name: "color", value: color) sendEvent(name: "hue", value: hubHue) sendEvent(name: "saturation", value: saturation) sendEvent(name: "colorMode", value: colorMode) sendEvent(name: "RGB", value: rgb) } if (effectName != device.currentValue("effectName")) { sendEvent(name: "effectName", value: effectName) logInfo("setSysinfo: [effectName: ${effectName}]") } } sendEvent(name: "switch", value: onOff, type: "digital") } runIn(1, getPower) } def effectCreate() { state.createEffect = true sendCmd("""{"smartlife.iot.lighting_effect":{"get_lighting_effect":{}}}""") } def parseEffect(resp) { logDebug("parseEffect: ${resp}") if (resp.get_lighting_effect) { def effData = resp.get_lighting_effect def effName = effData.name if (state.createEffect == true) { def existngEffect = state.effectPresets.find { it.name == effName } if (existngEffect == null) { state.effectPresets << effData resetLightEffects() logDebug("parseEffect: ${effName} added to effectPresets") } else { logWarn("parseEffect: ${effName} already exists.") } state.remove("createEffect") } refresh() } else { if (resp.set_lighting_effect.err_code != 0) { logWarn("parseEffect: Error setting effect.") } sendCmd("""{"smartlife.iot.lighting_effect":{"get_lighting_effect":{}}}""") } } def resetLightEffects() { if (state.effectsPresets != [:]) { def lightEffects = [] state.effectPresets.each{ def name = """ "${it.name}" """ lightEffects << name } sendEvent(name: "lightEffects", value: lightEffects) } return "Updated lightEffects list" } def setEffect(index) { logDebug("setEffect: effNo = ${index}") index = index.toInteger() def effectPresets = state.effectPresets if (effectPresets == []) { logWarn("setEffect: effectPresets database is empty.") return } def effData = effectPresets[index] sendEffect(effData) } def setPreviousEffect() { def effectPresets = state.effectPresets if (device.currentValue("colorMode") != "EFFECTS" || effectPresets == []) { logWarn("setPreviousEffect: Not available. Either not in Effects or data is empty.") return } def effName = device.currentValue("effectName").trim() def index = effectPresets.findIndexOf { it.name == effName } if (index == -1) { logWarn("setPreviousEffect: ${effName} not found in effectPresets.") } else { def size = effectPresets.size() if (index == 0) { index = size - 1 } else { index = index-1 } def effData = effectPresets[index] sendEffect(effData) } } def setNextEffect() { def effectPresets = state.effectPresets if (device.currentValue("colorMode") != "EFFECTS" || effectPresets == []) { logWarn("setNextEffect: Not available. Either not in Effects or data is empty.") return } def effName = device.currentValue("effectName").trim() def index = effectPresets.findIndexOf { it.name == effName } if (index == -1) { logWarn("setNextEffect: ${effName} not found in effectPresets.") } else { def size = effectPresets.size() if (index == size - 1) { index = 0 } else { index = index + 1 } def effData = effectPresets[index] sendEffect(effData) } } def effectSet(effName) { if (state.effectPresets == []) { logWarn("effectSet: effectPresets database is empty.") return } effName = effName.trim() logDebug("effectSet: ${effName}.") def effData = state.effectPresets.find { it.name == effName } if (effData == null) { logWarn("effectSet: ${effName} not found.") return } sendEffect(effData) } def effectDelete(effName) { sendEvent(name: "lightEffects", value: []) effName = effName.trim() def index = state.effectPresets.findIndexOf { it.name == effName } if (index == -1 || nameIndex == -1) { logWarn("effectDelete: ${effName} not in effectPresets!") } else { state.effectPresets.remove(index) resetLightEffects() } logDebug("effectDelete: deleted effect ${effName}") } def syncEffectPresets() { device.updateSetting("syncEffects", [type:"bool", value: false]) parent.resetStates(device.deviceNetworkId) state.effectPresets.each{ def effData = it parent.syncEffectPreset(effData, device.deviceNetworkId) pauseExecution(1000) } return "Synching" } def resetStates() { state.effectPresets = [] } def updateEffectPreset(effData) { logDebug("updateEffectPreset: ${effData.name}") state.effectPresets << effData runIn(5, resetLightEffects) } def sendEffect(effData) { effData = new groovy.json.JsonBuilder(effData).toString() sendCmd("""{"smartlife.iot.lighting_effect":{"set_lighting_effect":""" + """${effData}},"context":{"source":""}}""") } def getCtHslValue(kelvin) { kelvin = (100 * Math.round(kelvin / 100)).toInteger() switch(kelvin) { case 1000: rgb= [255, 56, 0]; break case 1100: rgb= [255, 71, 0]; break case 1200: rgb= [255, 83, 0]; break case 1300: rgb= [255, 93, 0]; break case 1400: rgb= [255, 101, 0]; break case 1500: rgb= [255, 109, 0]; break case 1600: rgb= [255, 115, 0]; break case 1700: rgb= [255, 121, 0]; break case 1800: rgb= [255, 126, 0]; break case 1900: rgb= [255, 131, 0]; break case 2000: rgb= [255, 138, 18]; break case 2100: rgb= [255, 142, 33]; break case 2200: rgb= [255, 147, 44]; break case 2300: rgb= [255, 152, 54]; break case 2400: rgb= [255, 157, 63]; break case 2500: rgb= [255, 161, 72]; break case 2600: rgb= [255, 165, 79]; break case 2700: rgb= [255, 169, 87]; break case 2800: rgb= [255, 173, 94]; break case 2900: rgb= [255, 177, 101]; break case 3000: rgb= [255, 180, 107]; break case 3100: rgb= [255, 184, 114]; break case 3200: rgb= [255, 187, 120]; break case 3300: rgb= [255, 190, 126]; break case 3400: rgb= [255, 193, 132]; break case 3500: rgb= [255, 196, 137]; break case 3600: rgb= [255, 199, 143]; break case 3700: rgb= [255, 201, 148]; break case 3800: rgb= [255, 204, 153]; break case 3900: rgb= [255, 206, 159]; break case 4000: rgb= [100, 209, 200]; break case 4100: rgb= [255, 211, 168]; break case 4200: rgb= [255, 213, 173]; break case 4300: rgb= [255, 215, 177]; break case 4400: rgb= [255, 217, 182]; break case 4500: rgb= [255, 219, 186]; break case 4600: rgb= [255, 221, 190]; break case 4700: rgb= [255, 223, 194]; break case 4800: rgb= [255, 225, 198]; break case 4900: rgb= [255, 227, 202]; break case 5000: rgb= [255, 228, 206]; break case 5100: rgb= [255, 230, 210]; break case 5200: rgb= [255, 232, 213]; break case 5300: rgb= [255, 233, 217]; break case 5400: rgb= [255, 235, 220]; break case 5500: rgb= [255, 236, 224]; break case 5600: rgb= [255, 238, 227]; break case 5700: rgb= [255, 239, 230]; break case 5800: rgb= [255, 240, 233]; break case 5900: rgb= [255, 242, 236]; break case 6000: rgb= [255, 243, 239]; break case 6100: rgb= [255, 244, 242]; break case 6200: rgb= [255, 245, 245]; break case 6300: rgb= [255, 246, 247]; break case 6400: rgb= [255, 248, 251]; break case 6500: rgb= [255, 249, 253]; break case 6600: rgb= [254, 249, 255]; break case 6700: rgb= [252, 247, 255]; break case 6800: rgb= [249, 246, 255]; break case 6900: rgb= [247, 245, 255]; break case 7000: rgb= [245, 243, 255]; break case 7100: rgb= [243, 242, 255]; break case 7200: rgb= [240, 241, 255]; break case 7300: rgb= [239, 240, 255]; break case 7400: rgb= [237, 239, 255]; break case 7500: rgb= [235, 238, 255]; break case 7600: rgb= [233, 237, 255]; break case 7700: rgb= [231, 236, 255]; break case 7800: rgb= [230, 235, 255]; break case 7900: rgb= [228, 234, 255]; break case 8000: rgb= [227, 233, 255]; break case 8100: rgb= [225, 232, 255]; break case 8200: rgb= [224, 231, 255]; break case 8300: rgb= [222, 230, 255]; break case 8400: rgb= [221, 230, 255]; break case 8500: rgb= [220, 229, 255]; break case 8600: rgb= [218, 229, 255]; break case 8700: rgb= [217, 227, 255]; break case 8800: rgb= [216, 227, 255]; break case 8900: rgb= [215, 226, 255]; break case 9000: rgb= [214, 225, 255]; break case 9100: rgb= [212, 225, 255]; break case 9200: rgb= [211, 224, 255]; break case 9300: rgb= [210, 223, 255]; break case 9400: rgb= [209, 223, 255]; break case 9500: rgb= [208, 222, 255]; break case 9600: rgb= [207, 221, 255]; break case 9700: rgb= [207, 221, 255]; break case 9800: rgb= [206, 220, 255]; break case 9900: rgb= [205, 220, 255]; break case 10000: rgb= [207, 218, 255]; break case 10100: rgb= [207, 218, 255]; break case 10200: rgb= [206, 217, 255]; break case 10300: rgb= [205, 217, 255]; break case 10400: rgb= [204, 216, 255]; break case 10500: rgb= [204, 216, 255]; break case 10600: rgb= [203, 215, 255]; break case 10700: rgb= [202, 215, 255]; break case 10800: rgb= [202, 214, 255]; break case 10900: rgb= [201, 214, 255]; break case 11000: rgb= [200, 213, 255]; break case 11100: rgb= [200, 213, 255]; break case 11200: rgb= [199, 212, 255]; break case 11300: rgb= [198, 212, 255]; break case 11400: rgb= [198, 212, 255]; break case 11500: rgb= [197, 211, 255]; break case 11600: rgb= [197, 211, 255]; break case 11700: rgb= [197, 210, 255]; break case 11800: rgb= [196, 210, 255]; break case 11900: rgb= [195, 210, 255]; break case 12000: rgb= [195, 209, 255]; break default: logWarn("setRgbData: Unknown.") colorName = "Unknown" } def hsvData = hubitat.helper.ColorUtils.rgbToHSV([rgb[0].toInteger(), rgb[1].toInteger(), rgb[2].toInteger()]) def hue = (0.5 + hsvData[0]).toInteger() def saturation = (0.5 + hsvData[1]).toInteger() def level = (0.5 + hsvData[2]).toInteger() def hslData = [ hue: hue, saturation: saturation, level: level ] return hslData } // ~~~~~ 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 (1362) davegut.kasaLights ~~~~~ library ( // library marker davegut.kasaLights, line 1 name: "kasaLights", // library marker davegut.kasaLights, line 2 namespace: "davegut", // library marker davegut.kasaLights, line 3 author: "Dave Gutheinz", // library marker davegut.kasaLights, line 4 description: "Kasa Bulb and Light Common Methods", // library marker davegut.kasaLights, line 5 category: "utilities", // library marker davegut.kasaLights, line 6 documentationLink: "" // library marker davegut.kasaLights, line 7 ) // library marker davegut.kasaLights, line 8 def on() { setLightOnOff(1, transition_Time) } // library marker davegut.kasaLights, line 10 def off() { setLightOnOff(0, transition_Time) } // library marker davegut.kasaLights, line 12 def setLevel(level, transTime = transition_Time) { // library marker davegut.kasaLights, line 14 setLightLevel(level, transTime) // library marker davegut.kasaLights, line 15 } // library marker davegut.kasaLights, line 16 def startLevelChange(direction) { // library marker davegut.kasaLights, line 18 unschedule(levelUp) // library marker davegut.kasaLights, line 19 unschedule(levelDown) // library marker davegut.kasaLights, line 20 if (direction == "up") { levelUp() } // library marker davegut.kasaLights, line 21 else { levelDown() } // library marker davegut.kasaLights, line 22 } // library marker davegut.kasaLights, line 23 def stopLevelChange() { // library marker davegut.kasaLights, line 25 unschedule(levelUp) // library marker davegut.kasaLights, line 26 unschedule(levelDown) // library marker davegut.kasaLights, line 27 } // library marker davegut.kasaLights, line 28 def levelUp() { // library marker davegut.kasaLights, line 30 def curLevel = device.currentValue("level").toInteger() // library marker davegut.kasaLights, line 31 if (curLevel == 100) { return } // library marker davegut.kasaLights, line 32 def newLevel = curLevel + 4 // library marker davegut.kasaLights, line 33 if (newLevel > 100) { newLevel = 100 } // library marker davegut.kasaLights, line 34 setLevel(newLevel, 0) // library marker davegut.kasaLights, line 35 runIn(1, levelUp) // library marker davegut.kasaLights, line 36 } // library marker davegut.kasaLights, line 37 def levelDown() { // library marker davegut.kasaLights, line 39 def curLevel = device.currentValue("level").toInteger() // library marker davegut.kasaLights, line 40 if (curLevel == 0 || device.currentValue("switch") == "off") { return } // library marker davegut.kasaLights, line 41 def newLevel = curLevel - 4 // library marker davegut.kasaLights, line 42 if (newLevel < 0) { off() } // library marker davegut.kasaLights, line 43 else { // library marker davegut.kasaLights, line 44 setLevel(newLevel, 0) // library marker davegut.kasaLights, line 45 runIn(1, levelDown) // library marker davegut.kasaLights, line 46 } // library marker davegut.kasaLights, line 47 } // library marker davegut.kasaLights, line 48 def service() { // library marker davegut.kasaLights, line 50 def service = "smartlife.iot.smartbulb.lightingservice" // library marker davegut.kasaLights, line 51 if (getDataValue("feature") == "lightStrip") { service = "smartlife.iot.lightStrip" } // library marker davegut.kasaLights, line 52 return service // library marker davegut.kasaLights, line 53 } // library marker davegut.kasaLights, line 54 def method() { // library marker davegut.kasaLights, line 56 def method = "transition_light_state" // library marker davegut.kasaLights, line 57 if (getDataValue("feature") == "lightStrip") { method = "set_light_state" } // library marker davegut.kasaLights, line 58 return method // library marker davegut.kasaLights, line 59 } // library marker davegut.kasaLights, line 60 def checkTransTime(transTime) { // library marker davegut.kasaLights, line 62 if (transTime == null || transTime < 0) { transTime = 0 } // library marker davegut.kasaLights, line 63 transTime = 1000 * transTime.toInteger() // library marker davegut.kasaLights, line 64 if (transTime > 8000) { transTime = 8000 } // library marker davegut.kasaLights, line 65 return transTime // library marker davegut.kasaLights, line 66 } // library marker davegut.kasaLights, line 67 def checkLevel(level) { // library marker davegut.kasaLights, line 69 if (level == null || level < 0) { // library marker davegut.kasaLights, line 70 level = device.currentValue("level") // library marker davegut.kasaLights, line 71 logWarn("checkLevel: Entered level null or negative. Level set to ${level}") // library marker davegut.kasaLights, line 72 } else if (level > 100) { // library marker davegut.kasaLights, line 73 level = 100 // library marker davegut.kasaLights, line 74 logWarn("checkLevel: Entered level > 100. Level set to ${level}") // library marker davegut.kasaLights, line 75 } // library marker davegut.kasaLights, line 76 return level // library marker davegut.kasaLights, line 77 } // library marker davegut.kasaLights, line 78 def setLightOnOff(onOff, transTime = 0) { // library marker davegut.kasaLights, line 80 transTime = checkTransTime(transTime) // library marker davegut.kasaLights, line 81 sendCmd("""{"${service()}":{"${method()}":{"on_off":${onOff},""" + // library marker davegut.kasaLights, line 82 """"transition_period":${transTime}}}}""") // library marker davegut.kasaLights, line 83 } // library marker davegut.kasaLights, line 84 def setLightLevel(level, transTime = 0) { // library marker davegut.kasaLights, line 86 level = checkLevel(level) // library marker davegut.kasaLights, line 87 if (level == 0) { // library marker davegut.kasaLights, line 88 setLightOnOff(0, transTime) // library marker davegut.kasaLights, line 89 } else { // library marker davegut.kasaLights, line 90 transTime = checkTransTime(transTime) // library marker davegut.kasaLights, line 91 sendCmd("""{"${service()}":{"${method()}":{"ignore_default":1,"on_off":1,""" + // library marker davegut.kasaLights, line 92 """"brightness":${level},"transition_period":${transTime}}}}""") // library marker davegut.kasaLights, line 93 } // library marker davegut.kasaLights, line 94 } // library marker davegut.kasaLights, line 95 // ~~~~~ end include (1362) davegut.kasaLights ~~~~~ // ~~~~~ start include (1358) davegut.kasaColorLights ~~~~~ library ( // library marker davegut.kasaColorLights, line 1 name: "kasaColorLights", // library marker davegut.kasaColorLights, line 2 namespace: "davegut", // library marker davegut.kasaColorLights, line 3 author: "Dave Gutheinz", // library marker davegut.kasaColorLights, line 4 description: "Kasa Color/CT Bulb and Light Common Methods", // library marker davegut.kasaColorLights, line 5 category: "utilities", // library marker davegut.kasaColorLights, line 6 documentationLink: "" // library marker davegut.kasaColorLights, line 7 ) // library marker davegut.kasaColorLights, line 8 def setCircadian() { // library marker davegut.kasaColorLights, line 10 sendCmd("""{"${service()}":{"${method()}":{"mode":"circadian"}}}""") // library marker davegut.kasaColorLights, line 11 } // library marker davegut.kasaColorLights, line 12 def setHue(hue) { setColor([hue: hue]) } // library marker davegut.kasaColorLights, line 14 def setSaturation(saturation) { setColor([saturation: saturation]) } // library marker davegut.kasaColorLights, line 16 def setColor(Map color, transTime = transition_Time) { // library marker davegut.kasaColorLights, line 18 if (color == null) { // library marker davegut.kasaColorLights, line 19 LogWarn("setColor: Color map is null. Command not executed.") // library marker davegut.kasaColorLights, line 20 } else { // library marker davegut.kasaColorLights, line 21 def level = device.currentValue("level") // library marker davegut.kasaColorLights, line 22 if (color.level) { level = color.level } // library marker davegut.kasaColorLights, line 23 def hue = device.currentValue("hue") // library marker davegut.kasaColorLights, line 24 if (color.hue || color.hue == 0) { hue = color.hue.toInteger() } // library marker davegut.kasaColorLights, line 25 def saturation = device.currentValue("saturation") // library marker davegut.kasaColorLights, line 26 if (color.saturation || color.saturation == 0) { saturation = color.saturation } // library marker davegut.kasaColorLights, line 27 hue = Math.round(0.49 + hue * 3.6).toInteger() // library marker davegut.kasaColorLights, line 28 if (hue < 0 || hue > 360 || saturation < 0 || saturation > 100 || level < 0 || level > 100) { // library marker davegut.kasaColorLights, line 29 logWarn("setColor: Entered hue, saturation, or level out of range! (H:${hue}, S:${saturation}, L:${level}") // library marker davegut.kasaColorLights, line 30 } else { // library marker davegut.kasaColorLights, line 31 setLightColor(level, 0, hue, saturation, transTime) // library marker davegut.kasaColorLights, line 32 } // library marker davegut.kasaColorLights, line 33 } // library marker davegut.kasaColorLights, line 34 } // library marker davegut.kasaColorLights, line 35 def setRGB(rgb) { // library marker davegut.kasaColorLights, line 37 logDebug("setRGB: ${rgb}") // library marker davegut.kasaColorLights, line 38 def rgbArray = rgb.split('\\,') // library marker davegut.kasaColorLights, line 39 def hsvData = hubitat.helper.ColorUtils.rgbToHSV([rgbArray[0].toInteger(), rgbArray[1].toInteger(), rgbArray[2].toInteger()]) // library marker davegut.kasaColorLights, line 40 def hue = (0.5 + hsvData[0]).toInteger() // library marker davegut.kasaColorLights, line 41 def saturation = (0.5 + hsvData[1]).toInteger() // library marker davegut.kasaColorLights, line 42 def level = (0.5 + hsvData[2]).toInteger() // library marker davegut.kasaColorLights, line 43 def Map hslData = [ // library marker davegut.kasaColorLights, line 44 hue: hue, // library marker davegut.kasaColorLights, line 45 saturation: saturation, // library marker davegut.kasaColorLights, line 46 level: level // library marker davegut.kasaColorLights, line 47 ] // library marker davegut.kasaColorLights, line 48 setColor(hslData) // library marker davegut.kasaColorLights, line 49 } // library marker davegut.kasaColorLights, line 50 def setLightColor(level, colorTemp, hue, saturation, transTime = 0) { // library marker davegut.kasaColorLights, line 52 level = checkLevel(level) // library marker davegut.kasaColorLights, line 53 if (level == 0) { // library marker davegut.kasaColorLights, line 54 setLightOnOff(0, transTime) // library marker davegut.kasaColorLights, line 55 } else { // library marker davegut.kasaColorLights, line 56 transTime = checkTransTime(transTime) // library marker davegut.kasaColorLights, line 57 sendCmd("""{"${service()}":{"${method()}":{"ignore_default":1,"on_off":1,""" + // library marker davegut.kasaColorLights, line 58 """"brightness":${level},"color_temp":${colorTemp},""" + // library marker davegut.kasaColorLights, line 59 """"hue":${hue},"saturation":${saturation},"transition_period":${transTime}}}}""") // library marker davegut.kasaColorLights, line 60 } // library marker davegut.kasaColorLights, line 61 } // library marker davegut.kasaColorLights, line 62 def bulbPresetCreate(psName) { // library marker davegut.kasaColorLights, line 64 if (!state.bulbPresets) { state.bulbPresets = [:] } // library marker davegut.kasaColorLights, line 65 psName = psName.trim().toLowerCase() // library marker davegut.kasaColorLights, line 66 logDebug("bulbPresetCreate: ${psName}") // library marker davegut.kasaColorLights, line 67 def psData = [:] // library marker davegut.kasaColorLights, line 68 psData["hue"] = device.currentValue("hue") // library marker davegut.kasaColorLights, line 69 psData["saturation"] = device.currentValue("saturation") // library marker davegut.kasaColorLights, line 70 psData["level"] = device.currentValue("level") // library marker davegut.kasaColorLights, line 71 def colorTemp = device.currentValue("colorTemperature") // library marker davegut.kasaColorLights, line 72 if (colorTemp == null) { colorTemp = 0 } // library marker davegut.kasaColorLights, line 73 psData["colTemp"] = colorTemp // library marker davegut.kasaColorLights, line 74 state.bulbPresets << ["${psName}": psData] // library marker davegut.kasaColorLights, line 75 } // library marker davegut.kasaColorLights, line 76 def bulbPresetDelete(psName) { // library marker davegut.kasaColorLights, line 78 psName = psName.trim() // library marker davegut.kasaColorLights, line 79 logDebug("bulbPresetDelete: ${psName}") // library marker davegut.kasaColorLights, line 80 def presets = state.bulbPresets // library marker davegut.kasaColorLights, line 81 if (presets.toString().contains(psName)) { // library marker davegut.kasaColorLights, line 82 presets.remove(psName) // library marker davegut.kasaColorLights, line 83 } else { // library marker davegut.kasaColorLights, line 84 logWarn("bulbPresetDelete: ${psName} is not a valid name.") // library marker davegut.kasaColorLights, line 85 } // library marker davegut.kasaColorLights, line 86 } // library marker davegut.kasaColorLights, line 87 def syncBulbPresets() { // library marker davegut.kasaColorLights, line 89 device.updateSetting("syncBulbs", [type:"bool", value: false]) // library marker davegut.kasaColorLights, line 90 parent.syncBulbPresets(state.bulbPresets) // library marker davegut.kasaColorLights, line 91 return "Syncing" // library marker davegut.kasaColorLights, line 92 } // library marker davegut.kasaColorLights, line 93 def updatePresets(bulbPresets) { // library marker davegut.kasaColorLights, line 95 logInfo("updatePresets: ${bulbPresets}") // library marker davegut.kasaColorLights, line 96 state.bulbPresets = bulbPresets // library marker davegut.kasaColorLights, line 97 } // library marker davegut.kasaColorLights, line 98 def bulbPresetSet(psName, transTime = transition_Time) { // library marker davegut.kasaColorLights, line 100 psName = psName.trim() // library marker davegut.kasaColorLights, line 101 if (state.bulbPresets."${psName}") { // library marker davegut.kasaColorLights, line 102 def psData = state.bulbPresets."${psName}" // library marker davegut.kasaColorLights, line 103 def hue = Math.round(0.49 + psData.hue.toInteger() * 3.6).toInteger() // library marker davegut.kasaColorLights, line 104 setLightColor(psData.level, psData.colTemp, hue, psData.saturation, transTime) // library marker davegut.kasaColorLights, line 105 } else { // library marker davegut.kasaColorLights, line 106 logWarn("bulbPresetSet: ${psName} is not a valid name.") // library marker davegut.kasaColorLights, line 107 } // library marker davegut.kasaColorLights, line 108 } // library marker davegut.kasaColorLights, line 109 // ~~~~~ end include (1358) davegut.kasaColorLights ~~~~~ // ~~~~~ 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 ~~~~~