/* Kasa Device Driver Series
Copyright Dave Gutheinz
License Information: https://github.com/DaveGut/HubitatActive/blob/master/KasaDevices/License.md
6.5.1 Hot fix for loop in EM Month Stat Processing due to month = 1
6.5.2 Minor Changes: Energy Monitor Functios, Bulbs/Light Strips, Dimming Switch.
New Capability: Configuration. Selecting updates the version configuration of the APP and ALL
Kasa Devices.
6.5.3 Bug Fix in Sync Names for multi-plugs.
sendEvent for switch will be sent at each poll to update Hub LastActivity for the device
6.5.4 a. Bug fix to transition time.
b. Increased debug logging on Parse Methods.
c. Change setSysinfo method to call get power in all cases using runIn(2, getPower)
Link to change details:
https://github.com/DaveGut/HubitatActive/blob/master/KasaDevices/Change_Descriptions.pdf
===================================================================================================*/
def driverVer() { return "6.5.4" }
def type() { return "CT Bulb" }
metadata {
definition (name: "Kasa ${type()}",
namespace: "davegut",
author: "Dave Gutheinz",
importUrl: "https://raw.githubusercontent.com/DaveGut/HubitatActive/master/KasaDevices/DeviceDrivers/CTBulb.groovy"
) {
capability "Configuration"
capability "Light"
capability "Switch"
capability "Switch Level"
capability "Change Level"
capability "Refresh"
capability "Actuator"
attribute "colorName", "string"
capability "Color Temperature"
command "setCircadian"
attribute "circadianState", "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"
// Communications
attribute "connection", "string"
attribute "commsError", "string"
}
preferences {
input ("descriptionText", "bool",
title: "Enable information logging",
defaultValue: true)
input ("debug", "bool",
title: "30 minutes of debug logging",
defaultValue: false)
input ("transition_Time", "number",
title: "Default Transition time (seconds)",
defaultValue: 1)
input ("emFunction", "bool",
title: "Enable Energy Monitor",
defaultValue: false)
input ("bind", "bool",
title: "Kasa Cloud Binding",
defalutValue: true)
input ("useCloud", "bool",
title: "Use Kasa Cloud for device control",
defaultValue: false)
input ("nameSync", "enum", title: "Synchronize Names",
defaultValue: "none",
options: ["none": "Don't synchronize",
"device" : "Kasa device name master",
"Hubitat" : "Hubitat label master"])
input ("rebootDev", "bool",
title: "Reboot device [Caution]",
defaultValue: false)
}
}
def installed() {
def instStatus= installCommon()
logInfo("installed: ${instStatus}")
}
def updated() {
def updStatus = updateCommon()
updStatus << [transition_Time: "${transition_Time} seconds"]
updStatus << [emFunction: setupEmFunction()]
logInfo("updated: ${updStatus}")
}
def deviceConfigure() {
if (transition_Time == null) {
device.updateSetting("transition_Time", [type:"number", value: 1])
}
}
// ==================================================
def setColorTemperature(colorTemp, level = device.currentValue("level"), transTime = transition_Time) {
def lowCt = 2700
def highCt = 6500
if (colorTemp < lowCt) { colorTemp = lowCt }
else if (colorTemp > highCt) { colorTemp = highCt }
setLightColor(level, colorTemp, 0, 0, transTime)
}
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.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
if (device.currentValue("level") != level) {
sendEvent(name: "level", value: level, unit: "%")
}
if (device.currentValue("circadianState") != lightStatus.mode) {
sendEvent(name: "circadianState", value: lightStatus.mode)
}
int colorTemp = lightStatus.color_temp
def colorName = getCtName(colorTemp)
if (device.currentValue("colorTemperature") != colorTemp) {
sendEvent(name: "colorTemperature", value: colorTemp)
sendEvent(name: "colorName", value: colorName)
}
}
sendEvent(name: "switch", value: onOff, type: "digital")
}
if (emFunction) {
runIn(3, getPower)
} // 6.5.4
}
// ==================================================
// ==================================================
// ==================================================
// ==================================================
// ==================================================
// ~~~~~ start include (577) 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
// ===== Commands Common to all Bulbs/Lights ===== // library marker davegut.kasaLights, line 10
def on() { setLightOnOff(1, transition_Time) } // library marker davegut.kasaLights, line 11
def off() { setLightOnOff(0, transition_Time) } // library marker davegut.kasaLights, line 13
def setLevel(level, transTime = transition_Time) { // library marker davegut.kasaLights, line 15
setLightLevel(level, transTime) // library marker davegut.kasaLights, line 16
} // library marker davegut.kasaLights, line 17
def startLevelChange(direction) { // library marker davegut.kasaLights, line 19
if (direction == "up") { levelUp() } // library marker davegut.kasaLights, line 20
else { levelDown() } // library marker davegut.kasaLights, line 21
} // library marker davegut.kasaLights, line 22
def stopLevelChange() { // library marker davegut.kasaLights, line 24
unschedule(levelUp) // library marker davegut.kasaLights, line 25
unschedule(levelDown) // library marker davegut.kasaLights, line 26
} // library marker davegut.kasaLights, line 27
def levelUp() { // library marker davegut.kasaLights, line 29
def curLevel = device.currentValue("level").toInteger() // library marker davegut.kasaLights, line 30
if (curLevel == 100) { return } // library marker davegut.kasaLights, line 31
def newLevel = curLevel + 4 // library marker davegut.kasaLights, line 32
if (newLevel > 100) { newLevel = 100 } // library marker davegut.kasaLights, line 33
setLevel(newLevel, 0) // library marker davegut.kasaLights, line 34
runIn(1, levelUp) // library marker davegut.kasaLights, line 35
} // library marker davegut.kasaLights, line 36
def levelDown() { // library marker davegut.kasaLights, line 38
def curLevel = device.currentValue("level").toInteger() // library marker davegut.kasaLights, line 39
if (curLevel == 0 || device.currentValue("switch") == "off") { return } // library marker davegut.kasaLights, line 40
def newLevel = curLevel - 4 // library marker davegut.kasaLights, line 41
if (newLevel < 0) { off() } // library marker davegut.kasaLights, line 42
else { // library marker davegut.kasaLights, line 43
setLevel(newLevel, 0) // library marker davegut.kasaLights, line 44
runIn(1, levelDown) // library marker davegut.kasaLights, line 45
} // library marker davegut.kasaLights, line 46
} // library marker davegut.kasaLights, line 47
// ===== API Prep and Call Methods ===== // library marker davegut.kasaLights, line 49
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
} // 6.5.4 // 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 = 0 // library marker davegut.kasaLights, line 71
logWarn("checkLevel: level entry error. 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: level entry error. 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 (577) davegut.kasaLights ~~~~~
// ~~~~~ start include (578) 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
// ===== Commands === // library marker davegut.kasaColorLights, line 10
def setCircadian() { // library marker davegut.kasaColorLights, line 11
sendCmd("""{"${service()}":{"${method()}":{"mode":"circadian"}}}""") // library marker davegut.kasaColorLights, line 12
} // library marker davegut.kasaColorLights, line 13
def setHue(hue) { setColor([hue: hue]) } // library marker davegut.kasaColorLights, line 15
def setSaturation(saturation) { setColor([saturation: saturation]) } // library marker davegut.kasaColorLights, line 17
def setColor(Map color, transTime = transition_Time) { // library marker davegut.kasaColorLights, line 19
if (color == null) { // library marker davegut.kasaColorLights, line 20
LogWarn("setColor: Color map is null. Command not executed.") // library marker davegut.kasaColorLights, line 21
} else { // library marker davegut.kasaColorLights, line 22
def level = device.currentValue("level") // library marker davegut.kasaColorLights, line 23
if (color.level) { level = color.level } // library marker davegut.kasaColorLights, line 24
def hue = device.currentValue("hue") // library marker davegut.kasaColorLights, line 25
if (color.hue || color.hue == 0) { hue = color.hue.toInteger() } // library marker davegut.kasaColorLights, line 26
def saturation = device.currentValue("saturation") // library marker davegut.kasaColorLights, line 27
if (color.saturation || color.saturation == 0) { saturation = color.saturation } // library marker davegut.kasaColorLights, line 28
hue = Math.round(0.49 + hue * 3.6).toInteger() // library marker davegut.kasaColorLights, line 29
if (hue < 0 || hue > 360 || saturation < 0 || saturation > 100 || level < 0 || level > 100) { // library marker davegut.kasaColorLights, line 30
logWarn("setColor: Entered hue, saturation, or level out of range! (H:${hue}, S:${saturation}, L:${level}") // library marker davegut.kasaColorLights, line 31
} else { // library marker davegut.kasaColorLights, line 32
setLightColor(level, 0, hue, saturation, transTime) // library marker davegut.kasaColorLights, line 33
} // library marker davegut.kasaColorLights, line 34
} // library marker davegut.kasaColorLights, line 35
} // library marker davegut.kasaColorLights, line 36
def setRGB(rgb) { // library marker davegut.kasaColorLights, line 38
logDebug("setRGB: ${rgb}") // library marker davegut.kasaColorLights, line 39
def rgbArray = rgb.split('\\,') // library marker davegut.kasaColorLights, line 40
def hsvData = hubitat.helper.ColorUtils.rgbToHSV([rgbArray[0].toInteger(), rgbArray[1].toInteger(), rgbArray[2].toInteger()]) // library marker davegut.kasaColorLights, line 41
def hue = (0.5 + hsvData[0]).toInteger() // library marker davegut.kasaColorLights, line 42
def saturation = (0.5 + hsvData[1]).toInteger() // library marker davegut.kasaColorLights, line 43
def level = (0.5 + hsvData[2]).toInteger() // library marker davegut.kasaColorLights, line 44
def Map hslData = [ // library marker davegut.kasaColorLights, line 45
hue: hue, // library marker davegut.kasaColorLights, line 46
saturation: saturation, // library marker davegut.kasaColorLights, line 47
level: level // library marker davegut.kasaColorLights, line 48
] // library marker davegut.kasaColorLights, line 49
setColor(hslData) // library marker davegut.kasaColorLights, line 50
} // library marker davegut.kasaColorLights, line 51
// ===== API Prep and Call Methods ===== // library marker davegut.kasaColorLights, line 53
def setLightColor(level, colorTemp, hue, saturation, transTime = 0) { // library marker davegut.kasaColorLights, line 54
level = checkLevel(level) // library marker davegut.kasaColorLights, line 55
if (level == 0) { // library marker davegut.kasaColorLights, line 56
setLightOnOff(0, transTime) // library marker davegut.kasaColorLights, line 57
} else { // library marker davegut.kasaColorLights, line 58
transTime = checkTransTime(transTime) // library marker davegut.kasaColorLights, line 59
sendCmd("""{"${service()}":{"${method()}":{"ignore_default":1,"on_off":1,""" + // library marker davegut.kasaColorLights, line 60
""""brightness":${level},"color_temp":${colorTemp},""" + // library marker davegut.kasaColorLights, line 61
""""hue":${hue},"saturation":${saturation},"transition_period":${transTime}}}}""") // library marker davegut.kasaColorLights, line 62
} // library marker davegut.kasaColorLights, line 63
} // library marker davegut.kasaColorLights, line 64
def bulbPresetCreate(psName) { // library marker davegut.kasaColorLights, line 66
if (!state.bulbPresets) { state.bulbPresets = [:] } // library marker davegut.kasaColorLights, line 67
psName = psName.trim().toLowerCase() // library marker davegut.kasaColorLights, line 68
logDebug("bulbPresetCreate: ${psName}") // library marker davegut.kasaColorLights, line 69
def psData = [:] // library marker davegut.kasaColorLights, line 70
psData["hue"] = device.currentValue("hue") // library marker davegut.kasaColorLights, line 71
psData["saturation"] = device.currentValue("saturation") // library marker davegut.kasaColorLights, line 72
psData["level"] = device.currentValue("level") // library marker davegut.kasaColorLights, line 73
def colorTemp = device.currentValue("colorTemperature") // library marker davegut.kasaColorLights, line 74
if (colorTemp == null) { colorTemp = 0 } // library marker davegut.kasaColorLights, line 75
psData["colTemp"] = colorTemp // library marker davegut.kasaColorLights, line 76
state.bulbPresets << ["${psName}": psData] // library marker davegut.kasaColorLights, line 77
} // library marker davegut.kasaColorLights, line 78
def bulbPresetDelete(psName) { // library marker davegut.kasaColorLights, line 80
psName = psName.trim() // library marker davegut.kasaColorLights, line 81
logDebug("bulbPresetDelete: ${psName}") // library marker davegut.kasaColorLights, line 82
def presets = state.bulbPresets // library marker davegut.kasaColorLights, line 83
if (presets.toString().contains(psName)) { // library marker davegut.kasaColorLights, line 84
presets.remove(psName) // library marker davegut.kasaColorLights, line 85
} else { // library marker davegut.kasaColorLights, line 86
logWarn("bulbPresetDelete: ${psName} is not a valid name.") // library marker davegut.kasaColorLights, line 87
} // library marker davegut.kasaColorLights, line 88
} // library marker davegut.kasaColorLights, line 89
def syncBulbPresets() { // library marker davegut.kasaColorLights, line 91
device.updateSetting("syncBulbs", [type:"bool", value: false]) // library marker davegut.kasaColorLights, line 92
parent.syncBulbPresets(state.bulbPresets) // library marker davegut.kasaColorLights, line 93
return "Syncing" // library marker davegut.kasaColorLights, line 94
} // library marker davegut.kasaColorLights, line 95
def updatePresets(bulbPresets) { // library marker davegut.kasaColorLights, line 97
logInfo("updatePresets: ${bulbPresets}") // library marker davegut.kasaColorLights, line 98
state.bulbPresets = bulbPresets // library marker davegut.kasaColorLights, line 99
} // library marker davegut.kasaColorLights, line 100
def bulbPresetSet(psName, transTime = transition_Time) { // library marker davegut.kasaColorLights, line 102
psName = psName.trim() // library marker davegut.kasaColorLights, line 103
if (state.bulbPresets."${psName}") { // library marker davegut.kasaColorLights, line 104
def psData = state.bulbPresets."${psName}" // library marker davegut.kasaColorLights, line 105
def hue = Math.round(0.49 + psData.hue.toInteger() * 3.6).toInteger() // library marker davegut.kasaColorLights, line 106
setLightColor(psData.level, psData.colTemp, hue, psData.saturation, transTime) // library marker davegut.kasaColorLights, line 107
} else { // library marker davegut.kasaColorLights, line 108
logWarn("bulbPresetSet: ${psName} is not a valid name.") // library marker davegut.kasaColorLights, line 109
} // library marker davegut.kasaColorLights, line 110
} // library marker davegut.kasaColorLights, line 111
// ================================================== // library marker davegut.kasaColorLights, line 113
def getColorName(hue){ // library marker davegut.kasaColorLights, line 114
def colorName // library marker davegut.kasaColorLights, line 115
switch (hue){ // library marker davegut.kasaColorLights, line 116
case 0..15: colorName = "Red"; break // library marker davegut.kasaColorLights, line 117
case 16..45: colorName = "Orange"; break // library marker davegut.kasaColorLights, line 118
case 46..75: colorName = "Yellow"; break // library marker davegut.kasaColorLights, line 119
case 76..105: colorName = "Chartreuse"; break // library marker davegut.kasaColorLights, line 120
case 106..135: colorName = "Green"; break // library marker davegut.kasaColorLights, line 121
case 136..165: colorName = "Spring"; break // library marker davegut.kasaColorLights, line 122
case 166..195: colorName = "Cyan"; break // library marker davegut.kasaColorLights, line 123
case 196..225: colorName = "Azure"; break // library marker davegut.kasaColorLights, line 124
case 226..255: colorName = "Blue"; break // library marker davegut.kasaColorLights, line 125
case 256..285: colorName = "Violet"; break // library marker davegut.kasaColorLights, line 126
case 286..315: colorName = "Magenta"; break // library marker davegut.kasaColorLights, line 127
case 316..345: colorName = "Rose"; break // library marker davegut.kasaColorLights, line 128
case 346..360: colorName = "Red"; break // library marker davegut.kasaColorLights, line 129
default: // library marker davegut.kasaColorLights, line 130
logWarn("setRgbData: Unknown.") // library marker davegut.kasaColorLights, line 131
colorName = "Unknown" // library marker davegut.kasaColorLights, line 132
} // library marker davegut.kasaColorLights, line 133
return colorName // library marker davegut.kasaColorLights, line 134
} // library marker davegut.kasaColorLights, line 135
def getCtName(colorTemp){ // library marker davegut.kasaColorLights, line 137
def colorName // library marker davegut.kasaColorLights, line 138
switch (colorTemp){ // library marker davegut.kasaColorLights, line 139
case 0..2000: colorName = "Sodium"; break // library marker davegut.kasaColorLights, line 140
case 2001..2100: colorName = "Starlight"; break // library marker davegut.kasaColorLights, line 141
case 2101..2400: colorName = "Sunrise"; break // library marker davegut.kasaColorLights, line 142
case 2401..2800: colorName = "Incandescent"; break // library marker davegut.kasaColorLights, line 143
case 2801..3300: colorName = "Soft White"; break // library marker davegut.kasaColorLights, line 144
case 3301..3500: colorName = "Warm White"; break // library marker davegut.kasaColorLights, line 145
case 3501..4150: colorName = "Moonlight"; break // library marker davegut.kasaColorLights, line 146
case 4151..5000: colorName = "Horizon"; break // library marker davegut.kasaColorLights, line 147
case 5001..5500: colorName = "Daylight"; break // library marker davegut.kasaColorLights, line 148
case 5501..6000: colorName = "Electronic"; break // library marker davegut.kasaColorLights, line 149
case 6001..6500: colorName = "Skylight"; break // library marker davegut.kasaColorLights, line 150
default: // library marker davegut.kasaColorLights, line 151
colorName = "Polar" // library marker davegut.kasaColorLights, line 152
} // library marker davegut.kasaColorLights, line 153
return colorName // library marker davegut.kasaColorLights, line 154
} // library marker davegut.kasaColorLights, line 155
def getCtHslValue(kelvin) { // library marker davegut.kasaColorLights, line 157
kelvin = (100 * Math.round(kelvin / 100)).toInteger() // library marker davegut.kasaColorLights, line 158
switch(kelvin) { // library marker davegut.kasaColorLights, line 159
case 1000: rgb= [255, 56, 0]; break // library marker davegut.kasaColorLights, line 160
case 1100: rgb= [255, 71, 0]; break // library marker davegut.kasaColorLights, line 161
case 1200: rgb= [255, 83, 0]; break // library marker davegut.kasaColorLights, line 162
case 1300: rgb= [255, 93, 0]; break // library marker davegut.kasaColorLights, line 163
case 1400: rgb= [255, 101, 0]; break // library marker davegut.kasaColorLights, line 164
case 1500: rgb= [255, 109, 0]; break // library marker davegut.kasaColorLights, line 165
case 1600: rgb= [255, 115, 0]; break // library marker davegut.kasaColorLights, line 166
case 1700: rgb= [255, 121, 0]; break // library marker davegut.kasaColorLights, line 167
case 1800: rgb= [255, 126, 0]; break // library marker davegut.kasaColorLights, line 168
case 1900: rgb= [255, 131, 0]; break // library marker davegut.kasaColorLights, line 169
case 2000: rgb= [255, 138, 18]; break // library marker davegut.kasaColorLights, line 170
case 2100: rgb= [255, 142, 33]; break // library marker davegut.kasaColorLights, line 171
case 2200: rgb= [255, 147, 44]; break // library marker davegut.kasaColorLights, line 172
case 2300: rgb= [255, 152, 54]; break // library marker davegut.kasaColorLights, line 173
case 2400: rgb= [255, 157, 63]; break // library marker davegut.kasaColorLights, line 174
case 2500: rgb= [255, 161, 72]; break // library marker davegut.kasaColorLights, line 175
case 2600: rgb= [255, 165, 79]; break // library marker davegut.kasaColorLights, line 176
case 2700: rgb= [255, 169, 87]; break // library marker davegut.kasaColorLights, line 177
case 2800: rgb= [255, 173, 94]; break // library marker davegut.kasaColorLights, line 178
case 2900: rgb= [255, 177, 101]; break // library marker davegut.kasaColorLights, line 179
case 3000: rgb= [255, 180, 107]; break // library marker davegut.kasaColorLights, line 180
case 3100: rgb= [255, 184, 114]; break // library marker davegut.kasaColorLights, line 181
case 3200: rgb= [255, 187, 120]; break // library marker davegut.kasaColorLights, line 182
case 3300: rgb= [255, 190, 126]; break // library marker davegut.kasaColorLights, line 183
case 3400: rgb= [255, 193, 132]; break // library marker davegut.kasaColorLights, line 184
case 3500: rgb= [255, 196, 137]; break // library marker davegut.kasaColorLights, line 185
case 3600: rgb= [255, 199, 143]; break // library marker davegut.kasaColorLights, line 186
case 3700: rgb= [255, 201, 148]; break // library marker davegut.kasaColorLights, line 187
case 3800: rgb= [255, 204, 153]; break // library marker davegut.kasaColorLights, line 188
case 3900: rgb= [255, 206, 159]; break // library marker davegut.kasaColorLights, line 189
case 4000: rgb= [100, 209, 200]; break // library marker davegut.kasaColorLights, line 190
case 4100: rgb= [255, 211, 168]; break // library marker davegut.kasaColorLights, line 191
case 4200: rgb= [255, 213, 173]; break // library marker davegut.kasaColorLights, line 192
case 4300: rgb= [255, 215, 177]; break // library marker davegut.kasaColorLights, line 193
case 4400: rgb= [255, 217, 182]; break // library marker davegut.kasaColorLights, line 194
case 4500: rgb= [255, 219, 186]; break // library marker davegut.kasaColorLights, line 195
case 4600: rgb= [255, 221, 190]; break // library marker davegut.kasaColorLights, line 196
case 4700: rgb= [255, 223, 194]; break // library marker davegut.kasaColorLights, line 197
case 4800: rgb= [255, 225, 198]; break // library marker davegut.kasaColorLights, line 198
case 4900: rgb= [255, 227, 202]; break // library marker davegut.kasaColorLights, line 199
case 5000: rgb= [255, 228, 206]; break // library marker davegut.kasaColorLights, line 200
case 5100: rgb= [255, 230, 210]; break // library marker davegut.kasaColorLights, line 201
case 5200: rgb= [255, 232, 213]; break // library marker davegut.kasaColorLights, line 202
case 5300: rgb= [255, 233, 217]; break // library marker davegut.kasaColorLights, line 203
case 5400: rgb= [255, 235, 220]; break // library marker davegut.kasaColorLights, line 204
case 5500: rgb= [255, 236, 224]; break // library marker davegut.kasaColorLights, line 205
case 5600: rgb= [255, 238, 227]; break // library marker davegut.kasaColorLights, line 206
case 5700: rgb= [255, 239, 230]; break // library marker davegut.kasaColorLights, line 207
case 5800: rgb= [255, 240, 233]; break // library marker davegut.kasaColorLights, line 208
case 5900: rgb= [255, 242, 236]; break // library marker davegut.kasaColorLights, line 209
case 6000: rgb= [255, 243, 239]; break // library marker davegut.kasaColorLights, line 210
case 6100: rgb= [255, 244, 242]; break // library marker davegut.kasaColorLights, line 211
case 6200: rgb= [255, 245, 245]; break // library marker davegut.kasaColorLights, line 212
case 6300: rgb= [255, 246, 247]; break // library marker davegut.kasaColorLights, line 213
case 6400: rgb= [255, 248, 251]; break // library marker davegut.kasaColorLights, line 214
case 6500: rgb= [255, 249, 253]; break // library marker davegut.kasaColorLights, line 215
case 6600: rgb= [254, 249, 255]; break // library marker davegut.kasaColorLights, line 216
case 6700: rgb= [252, 247, 255]; break // library marker davegut.kasaColorLights, line 217
case 6800: rgb= [249, 246, 255]; break // library marker davegut.kasaColorLights, line 218
case 6900: rgb= [247, 245, 255]; break // library marker davegut.kasaColorLights, line 219
case 7000: rgb= [245, 243, 255]; break // library marker davegut.kasaColorLights, line 220
case 7100: rgb= [243, 242, 255]; break // library marker davegut.kasaColorLights, line 221
case 7200: rgb= [240, 241, 255]; break // library marker davegut.kasaColorLights, line 222
case 7300: rgb= [239, 240, 255]; break // library marker davegut.kasaColorLights, line 223
case 7400: rgb= [237, 239, 255]; break // library marker davegut.kasaColorLights, line 224
case 7500: rgb= [235, 238, 255]; break // library marker davegut.kasaColorLights, line 225
case 7600: rgb= [233, 237, 255]; break // library marker davegut.kasaColorLights, line 226
case 7700: rgb= [231, 236, 255]; break // library marker davegut.kasaColorLights, line 227
case 7800: rgb= [230, 235, 255]; break // library marker davegut.kasaColorLights, line 228
case 7900: rgb= [228, 234, 255]; break // library marker davegut.kasaColorLights, line 229
case 8000: rgb= [227, 233, 255]; break // library marker davegut.kasaColorLights, line 230
case 8100: rgb= [225, 232, 255]; break // library marker davegut.kasaColorLights, line 231
case 8200: rgb= [224, 231, 255]; break // library marker davegut.kasaColorLights, line 232
case 8300: rgb= [222, 230, 255]; break // library marker davegut.kasaColorLights, line 233
case 8400: rgb= [221, 230, 255]; break // library marker davegut.kasaColorLights, line 234
case 8500: rgb= [220, 229, 255]; break // library marker davegut.kasaColorLights, line 235
case 8600: rgb= [218, 229, 255]; break // library marker davegut.kasaColorLights, line 236
case 8700: rgb= [217, 227, 255]; break // library marker davegut.kasaColorLights, line 237
case 8800: rgb= [216, 227, 255]; break // library marker davegut.kasaColorLights, line 238
case 8900: rgb= [215, 226, 255]; break // library marker davegut.kasaColorLights, line 239
case 9000: rgb= [214, 225, 255]; break // library marker davegut.kasaColorLights, line 240
case 9100: rgb= [212, 225, 255]; break // library marker davegut.kasaColorLights, line 241
case 9200: rgb= [211, 224, 255]; break // library marker davegut.kasaColorLights, line 242
case 9300: rgb= [210, 223, 255]; break // library marker davegut.kasaColorLights, line 243
case 9400: rgb= [209, 223, 255]; break // library marker davegut.kasaColorLights, line 244
case 9500: rgb= [208, 222, 255]; break // library marker davegut.kasaColorLights, line 245
case 9600: rgb= [207, 221, 255]; break // library marker davegut.kasaColorLights, line 246
case 9700: rgb= [207, 221, 255]; break // library marker davegut.kasaColorLights, line 247
case 9800: rgb= [206, 220, 255]; break // library marker davegut.kasaColorLights, line 248
case 9900: rgb= [205, 220, 255]; break // library marker davegut.kasaColorLights, line 249
case 10000: rgb= [207, 218, 255]; break // library marker davegut.kasaColorLights, line 250
case 10100: rgb= [207, 218, 255]; break // library marker davegut.kasaColorLights, line 251
case 10200: rgb= [206, 217, 255]; break // library marker davegut.kasaColorLights, line 252
case 10300: rgb= [205, 217, 255]; break // library marker davegut.kasaColorLights, line 253
case 10400: rgb= [204, 216, 255]; break // library marker davegut.kasaColorLights, line 254
case 10500: rgb= [204, 216, 255]; break // library marker davegut.kasaColorLights, line 255
case 10600: rgb= [203, 215, 255]; break // library marker davegut.kasaColorLights, line 256
case 10700: rgb= [202, 215, 255]; break // library marker davegut.kasaColorLights, line 257
case 10800: rgb= [202, 214, 255]; break // library marker davegut.kasaColorLights, line 258
case 10900: rgb= [201, 214, 255]; break // library marker davegut.kasaColorLights, line 259
case 11000: rgb= [200, 213, 255]; break // library marker davegut.kasaColorLights, line 260
case 11100: rgb= [200, 213, 255]; break // library marker davegut.kasaColorLights, line 261
case 11200: rgb= [199, 212, 255]; break // library marker davegut.kasaColorLights, line 262
case 11300: rgb= [198, 212, 255]; break // library marker davegut.kasaColorLights, line 263
case 11400: rgb= [198, 212, 255]; break // library marker davegut.kasaColorLights, line 264
case 11500: rgb= [197, 211, 255]; break // library marker davegut.kasaColorLights, line 265
case 11600: rgb= [197, 211, 255]; break // library marker davegut.kasaColorLights, line 266
case 11700: rgb= [197, 210, 255]; break // library marker davegut.kasaColorLights, line 267
case 11800: rgb= [196, 210, 255]; break // library marker davegut.kasaColorLights, line 268
case 11900: rgb= [195, 210, 255]; break // library marker davegut.kasaColorLights, line 269
case 12000: rgb= [195, 209, 255]; break // library marker davegut.kasaColorLights, line 270
default: // library marker davegut.kasaColorLights, line 271
logWarn("setRgbData: Unknown.") // library marker davegut.kasaColorLights, line 272
colorName = "Unknown" // library marker davegut.kasaColorLights, line 273
} // library marker davegut.kasaColorLights, line 274
def hsvData = hubitat.helper.ColorUtils.rgbToHSV([rgb[0].toInteger(), rgb[1].toInteger(), rgb[2].toInteger()]) // library marker davegut.kasaColorLights, line 275
def hue = (0.5 + hsvData[0]).toInteger() // library marker davegut.kasaColorLights, line 276
def saturation = (0.5 + hsvData[1]).toInteger() // library marker davegut.kasaColorLights, line 277
def level = (0.5 + hsvData[2]).toInteger() // library marker davegut.kasaColorLights, line 278
def hslData = [ // library marker davegut.kasaColorLights, line 279
hue: hue, // library marker davegut.kasaColorLights, line 280
saturation: saturation, // library marker davegut.kasaColorLights, line 281
level: level // library marker davegut.kasaColorLights, line 282
] // library marker davegut.kasaColorLights, line 283
return hslData // library marker davegut.kasaColorLights, line 284
} // library marker davegut.kasaColorLights, line 285
// ~~~~~ end include (578) davegut.kasaColorLights ~~~~~
// ~~~~~ start include (545) 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
// ====== Common Install / Update Elements ===== // library marker davegut.kasaCommon, line 10
def installCommon() { // library marker davegut.kasaCommon, line 11
pauseExecution(3000) // library marker davegut.kasaCommon, line 12
def instStatus = [:] // library marker davegut.kasaCommon, line 13
if (getDataValue("deviceIP") == "CLOUD") { // library marker davegut.kasaCommon, line 14
sendEvent(name: "connection", value: "CLOUD") // library marker davegut.kasaCommon, line 15
device.updateSetting("useCloud", [type:"bool", value: true]) // library marker davegut.kasaCommon, line 16
instStatus << [useCloud: true, connection: "CLOUD"] // library marker davegut.kasaCommon, line 17
} else { // library marker davegut.kasaCommon, line 18
sendEvent(name: "connection", value: "LAN") // library marker davegut.kasaCommon, line 19
device.updateSetting("useCloud", [type:"bool", value: false]) // library marker davegut.kasaCommon, line 20
instStatus << [useCloud: false, connection: "LAN"] // library marker davegut.kasaCommon, line 21
} // library marker davegut.kasaCommon, line 22
sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommon, line 23
state.errorCount = 0 // library marker davegut.kasaCommon, line 24
state.pollInterval = "30 minutes" // library marker davegut.kasaCommon, line 25
instStatus << [driverVersion: driverVer()] // library marker davegut.kasaCommon, line 26
runIn(2, updated) // library marker davegut.kasaCommon, line 27
return instStatus // library marker davegut.kasaCommon, line 28
} // library marker davegut.kasaCommon, line 29
def updateCommon() { // library marker davegut.kasaCommon, line 31
unschedule() // 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
updStatus << [bind: bindUnbind()] // library marker davegut.kasaCommon, line 38
if (nameSync != "none") { // library marker davegut.kasaCommon, line 39
updStatus << [nameSync: syncName()] // library marker davegut.kasaCommon, line 40
} // library marker davegut.kasaCommon, line 41
if (debug) { runIn(1800, debugOff) } // library marker davegut.kasaCommon, line 42
updStatus << [debug: debug] // library marker davegut.kasaCommon, line 43
state.errorCount = 0 // library marker davegut.kasaCommon, line 44
sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommon, line 45
updStatus << [pollInterval: setPollInterval()] // library marker davegut.kasaCommon, line 46
refresh() // library marker davegut.kasaCommon, line 47
configure() // library marker davegut.kasaCommon, line 48
pauseExecution(3000) // library marker davegut.kasaCommon, line 49
return updStatus // library marker davegut.kasaCommon, line 50
} // library marker davegut.kasaCommon, line 51
def configure() { // library marker davegut.kasaCommon, line 53
def config = parent.updateConfigurations() // library marker davegut.kasaCommon, line 54
logInfo("configure: ${config}") // library marker davegut.kasaCommon, line 55
} // library marker davegut.kasaCommon, line 56
def childConfigure(updateData) { // library marker davegut.kasaCommon, line 58
def message = "configure: Configuring ${device.getLabel()}." // library marker davegut.kasaCommon, line 59
message += "\n\t\t\t *\tUpdated IP for all devices." // library marker davegut.kasaCommon, line 60
if(getDataValue("driverVersion") != driverVer()){ // library marker davegut.kasaCommon, line 61
updateDataValue("driverVersion", driverVer()) // library marker davegut.kasaCommon, line 62
if (state.pollNote) { state.remove("pollNote") } // library marker davegut.kasaCommon, line 63
if (state.pollWarning) { state.remove("pollWarning") } // library marker davegut.kasaCommon, line 64
if (!descriptionText || descriptionText == null) { // library marker davegut.kasaCommon, line 65
device.updateSetting("descriptionText", [type:"bool", value: true]) // library marker davegut.kasaCommon, line 66
} // library marker davegut.kasaCommon, line 67
if (!state.pollInterval) { state.pollInterval = "30 minutes" } // library marker davegut.kasaCommon, line 68
if (emFunction) { // library marker davegut.kasaCommon, line 69
// Kick start new version getEnergyThisMonth which adds state.getEnergy // library marker davegut.kasaCommon, line 70
schedule("10 0 0 * * ?", getEnergyThisMonth) // library marker davegut.kasaCommon, line 71
schedule("15 2 0 1 * ?", getEnergyLastMonth) // library marker davegut.kasaCommon, line 72
state.getEnergy = "This Month" // library marker davegut.kasaCommon, line 73
} // library marker davegut.kasaCommon, line 74
deviceConfigure() // library marker davegut.kasaCommon, line 75
} // library marker davegut.kasaCommon, line 76
logDebug("childConfigure: ${updateData}") // library marker davegut.kasaCommon, line 77
if (driverVer().trim() != updateData.appVersion) { // library marker davegut.kasaCommon, line 78
state.DRIVER_MISMATCH = "Driver version (${driverVer()}) not the same as App version (${updateData.appVersion})" // library marker davegut.kasaCommon, line 79
message += "\n\t\t\t *\tDriver/App Versions: Don't match! Update!" // library marker davegut.kasaCommon, line 80
logWarn("configure: Current driver does not match with App Version. Update to assure proper operation.") // library marker davegut.kasaCommon, line 81
} else { // library marker davegut.kasaCommon, line 82
state.remove("DRIVER_MISMATCH") // library marker davegut.kasaCommon, line 83
message += "\n\t\t\t *\tDriver/App Versions: OK, same for each." // library marker davegut.kasaCommon, line 84
} // library marker davegut.kasaCommon, line 85
if (updateData.updateAvailable) { // library marker davegut.kasaCommon, line 86
state.releaseNotes = "${updateData.releaseNotes}" // library marker davegut.kasaCommon, line 87
if (updateData.releaseNotes.contains("CRITICAL")) { // library marker davegut.kasaCommon, line 88
state.UPDATE_AVAILABLE = "A CRITICAL UPDATE TO APP AND DRIVER ARE AVAILABLE to version ${updateData.currVersion}." // library marker davegut.kasaCommon, line 89
message += "\n\t\t\t *\tDriver/App Updates: CRITICAL UPDATES AVAILABLE." // library marker davegut.kasaCommon, line 90
logWarn("A CRITICAL Applications and Drivers update is available for the Kasa Integration") // library marker davegut.kasaCommon, line 91
} else { // library marker davegut.kasaCommon, line 92
state.UPDATE_AVAILABLE = "App and driver updates are available to version ${updateData.currVersion}. Consider updating." // library marker davegut.kasaCommon, line 93
message += "\n\t\t\t *\tDriver/App Updates: Available." // library marker davegut.kasaCommon, line 94
} // library marker davegut.kasaCommon, line 95
} else { // library marker davegut.kasaCommon, line 96
message += "\n\t\t\t *\tDriver/App Updates: No updates available." // library marker davegut.kasaCommon, line 97
state.remove("UPDATE_AVAILABLE") // library marker davegut.kasaCommon, line 98
state.remove("releaseNotes") // library marker davegut.kasaCommon, line 99
} // library marker davegut.kasaCommon, line 100
logInfo(message) // library marker davegut.kasaCommon, line 101
} // library marker davegut.kasaCommon, line 102
// ===== Poll/Refresh ===== // library marker davegut.kasaCommon, line 104
def refresh() { poll() } // library marker davegut.kasaCommon, line 105
def poll() { getSysinfo() } // library marker davegut.kasaCommon, line 107
// ===== Preference Methods ===== // library marker davegut.kasaCommon, line 109
def setPollInterval(interval = state.pollInterval) { // library marker davegut.kasaCommon, line 110
if (interval == "default" || interval == "off" || interval == null) { // library marker davegut.kasaCommon, line 111
interval = "30 minutes" // library marker davegut.kasaCommon, line 112
} else if (useCloud && interval.contains("sec")) { // library marker davegut.kasaCommon, line 113
interval = "1 minute" // library marker davegut.kasaCommon, line 114
} // library marker davegut.kasaCommon, line 115
state.pollInterval = interval // library marker davegut.kasaCommon, line 116
def pollInterval = interval.substring(0,2).toInteger() // library marker davegut.kasaCommon, line 117
if (interval.contains("sec")) { // library marker davegut.kasaCommon, line 118
def start = Math.round((pollInterval-1) * Math.random()).toInteger() // library marker davegut.kasaCommon, line 119
schedule("${start}/${pollInterval} * * * * ?", "poll") // library marker davegut.kasaCommon, line 120
logWarn("setPollInterval: Polling intervals of less than one minute " + // library marker davegut.kasaCommon, line 121
"can take high resources and may impact hub performance.") // library marker davegut.kasaCommon, line 122
} else { // library marker davegut.kasaCommon, line 123
def start = Math.round(59 * Math.random()).toInteger() // library marker davegut.kasaCommon, line 124
schedule("${start} */${pollInterval} * * * ?", "poll") // library marker davegut.kasaCommon, line 125
} // library marker davegut.kasaCommon, line 126
logDebug("setPollInterval: interval = ${interval}.") // library marker davegut.kasaCommon, line 127
return interval // library marker davegut.kasaCommon, line 128
} // library marker davegut.kasaCommon, line 129
def rebootDevice() { // library marker davegut.kasaCommon, line 131
device.updateSetting("rebootDev", [type:"bool", value: false]) // library marker davegut.kasaCommon, line 132
reboot() // library marker davegut.kasaCommon, line 133
pauseExecution(10000) // library marker davegut.kasaCommon, line 134
return "REBOOTING DEVICE" // library marker davegut.kasaCommon, line 135
} // library marker davegut.kasaCommon, line 136
def bindUnbind() { // library marker davegut.kasaCommon, line 138
def message // library marker davegut.kasaCommon, line 139
if (bind == null || // library marker davegut.kasaCommon, line 140
getDataValue("deviceIP") == "CLOUD" || // library marker davegut.kasaCommon, line 141
type() == "Light Strip") { // library marker davegut.kasaCommon, line 142
message = "Getting current bind state" // library marker davegut.kasaCommon, line 143
getBind() // library marker davegut.kasaCommon, line 144
} else if (bind == true) { // library marker davegut.kasaCommon, line 145
if (!parent.kasaToken || parent.userName == null || parent.userPassword == null) { // library marker davegut.kasaCommon, line 146
message = "Username/pwd not set." // library marker davegut.kasaCommon, line 147
getBind() // library marker davegut.kasaCommon, line 148
} else { // library marker davegut.kasaCommon, line 149
message = "Binding device to the Kasa Cloud." // library marker davegut.kasaCommon, line 150
setBind(parent.userName, parent.userPassword) // library marker davegut.kasaCommon, line 151
} // library marker davegut.kasaCommon, line 152
} else if (bind == false) { // library marker davegut.kasaCommon, line 153
message = "Unbinding device from the Kasa Cloud." // library marker davegut.kasaCommon, line 154
setUnbind() // library marker davegut.kasaCommon, line 155
} // library marker davegut.kasaCommon, line 156
pauseExecution(5000) // library marker davegut.kasaCommon, line 157
return message // library marker davegut.kasaCommon, line 158
} // library marker davegut.kasaCommon, line 159
def setBindUnbind(cmdResp) { // library marker davegut.kasaCommon, line 161
def bindState = true // library marker davegut.kasaCommon, line 162
if (cmdResp.get_info) { // library marker davegut.kasaCommon, line 163
if (cmdResp.get_info.binded == 0) { bindState = false } // library marker davegut.kasaCommon, line 164
logInfo("setBindUnbind: Bind status set to ${bindState}") // library marker davegut.kasaCommon, line 165
setCommsType(bindState) // library marker davegut.kasaCommon, line 166
} else if (cmdResp.bind.err_code == 0){ // library marker davegut.kasaCommon, line 167
getBind() // library marker davegut.kasaCommon, line 168
} else { // library marker davegut.kasaCommon, line 169
logWarn("setBindUnbind: Unhandled response: ${cmdResp}") // library marker davegut.kasaCommon, line 170
} // library marker davegut.kasaCommon, line 171
} // library marker davegut.kasaCommon, line 172
def setCommsType(bindState) { // library marker davegut.kasaCommon, line 174
def commsType = "LAN" // library marker davegut.kasaCommon, line 175
def cloudCtrl = false // library marker davegut.kasaCommon, line 176
if (getDataValue("deviceIP") == "CLOUD") { // library marker davegut.kasaCommon, line 177
commsType = "CLOUD" // library marker davegut.kasaCommon, line 178
cloudCtrl = true // library marker davegut.kasaCommon, line 179
} else if (bindState == false && useCloud == true) { // library marker davegut.kasaCommon, line 180
logWarn("setCommsType: Can not use cloud. Device is not bound to Kasa cloud.") // library marker davegut.kasaCommon, line 181
} else if (bindState == true && useCloud == true && parent.kasaToken) { // library marker davegut.kasaCommon, line 182
commsType = "CLOUD" // library marker davegut.kasaCommon, line 183
cloudCtrl = true // library marker davegut.kasaCommon, line 184
} else if (altLan == true) { // library marker davegut.kasaCommon, line 185
commsType = "AltLAN" // library marker davegut.kasaCommon, line 186
state.response = "" // library marker davegut.kasaCommon, line 187
} // library marker davegut.kasaCommon, line 188
def commsSettings = [bind: bindState, useCloud: cloudCtrl, commsType: commsType] // library marker davegut.kasaCommon, line 189
device.updateSetting("bind", [type:"bool", value: bindState]) // library marker davegut.kasaCommon, line 190
device.updateSetting("useCloud", [type:"bool", value: cloudCtrl]) // library marker davegut.kasaCommon, line 191
sendEvent(name: "connection", value: "${commsType}") // library marker davegut.kasaCommon, line 192
logInfo("setCommsType: ${commsSettings}") // library marker davegut.kasaCommon, line 193
if (getDataValue("plugNo") != null) { // library marker davegut.kasaCommon, line 194
def coordData = [:] // library marker davegut.kasaCommon, line 195
coordData << [bind: bindState] // library marker davegut.kasaCommon, line 196
coordData << [useCloud: cloudCtrl] // library marker davegut.kasaCommon, line 197
coordData << [connection: commsType] // library marker davegut.kasaCommon, line 198
parent.coordinate("commsData", coordData, getDataValue("deviceId"), getDataValue("plugNo")) // library marker davegut.kasaCommon, line 199
} // library marker davegut.kasaCommon, line 200
pauseExecution(1000) // library marker davegut.kasaCommon, line 201
} // library marker davegut.kasaCommon, line 202
def syncName() { // library marker davegut.kasaCommon, line 204
def message // library marker davegut.kasaCommon, line 205
if (nameSync == "Hubitat") { // library marker davegut.kasaCommon, line 206
message = "Hubitat Label Sync" // library marker davegut.kasaCommon, line 207
setDeviceAlias(device.getLabel()) // library marker davegut.kasaCommon, line 208
} else if (nameSync == "device") { // library marker davegut.kasaCommon, line 209
message = "Device Alias Sync" // library marker davegut.kasaCommon, line 210
} else { // library marker davegut.kasaCommon, line 211
message = "Not Syncing" // library marker davegut.kasaCommon, line 212
} // library marker davegut.kasaCommon, line 213
return message // library marker davegut.kasaCommon, line 214
} // library marker davegut.kasaCommon, line 215
def updateName(response) { // library marker davegut.kasaCommon, line 217
device.updateSetting("nameSync",[type:"enum", value:"none"]) // library marker davegut.kasaCommon, line 218
def name = device.getLabel() // library marker davegut.kasaCommon, line 219
if (response.alias) { // library marker davegut.kasaCommon, line 220
name = response.alias // library marker davegut.kasaCommon, line 221
device.setLabel(name) // library marker davegut.kasaCommon, line 222
} else if (response.err_code != 0) { // library marker davegut.kasaCommon, line 223
def msg = "updateName: Name Sync from Hubitat to Device returned an error." // library marker davegut.kasaCommon, line 224
msg+= "Note: some devices do not support syncing name from the hub.\n\r" // library marker davegut.kasaCommon, line 225
logWarn(msg) // library marker davegut.kasaCommon, line 226
return // library marker davegut.kasaCommon, line 227
} // library marker davegut.kasaCommon, line 228
logInfo("updateName: Hubitat and Kasa device name synchronized to ${name}") // library marker davegut.kasaCommon, line 229
} // library marker davegut.kasaCommon, line 230
// ===== Kasa API Commands ===== // library marker davegut.kasaCommon, line 232
def getSysinfo() { // library marker davegut.kasaCommon, line 233
sendCmd("""{"system":{"get_sysinfo":{}}}""") // library marker davegut.kasaCommon, line 234
} // library marker davegut.kasaCommon, line 235
def reboot() { // library marker davegut.kasaCommon, line 237
def method = "system" // library marker davegut.kasaCommon, line 238
if (type().contains("Bulb") || type().contains("Light")) { // library marker davegut.kasaCommon, line 239
method = "smartlife.iot.common.system" // library marker davegut.kasaCommon, line 240
} // library marker davegut.kasaCommon, line 241
sendCmd("""{"${method}":{"reboot":{"delay":1}}}""") // library marker davegut.kasaCommon, line 242
} // library marker davegut.kasaCommon, line 243
def bindService() { // library marker davegut.kasaCommon, line 245
def service = "cnCloud" // library marker davegut.kasaCommon, line 246
if (type().contains("Bulb") || type().contains("Light")) { // library marker davegut.kasaCommon, line 247
service = "smartlife.iot.common.cloud" // library marker davegut.kasaCommon, line 248
} // library marker davegut.kasaCommon, line 249
return service // library marker davegut.kasaCommon, line 250
} // library marker davegut.kasaCommon, line 251
def getBind() { // library marker davegut.kasaCommon, line 253
sendLanCmd("""{"${bindService()}":{"get_info":{}}}""") // library marker davegut.kasaCommon, line 254
} // library marker davegut.kasaCommon, line 255
def setBind(userName, password) { // library marker davegut.kasaCommon, line 257
sendLanCmd("""{"${bindService()}":{"bind":{"username":"${userName}",""" + // library marker davegut.kasaCommon, line 258
""""password":"${password}"}},""" + // library marker davegut.kasaCommon, line 259
""""${bindService()}":{"get_info":{}}}""") // library marker davegut.kasaCommon, line 260
} // library marker davegut.kasaCommon, line 261
def setUnbind() { // library marker davegut.kasaCommon, line 263
sendLanCmd("""{"${bindService()}":{"unbind":""},""" + // library marker davegut.kasaCommon, line 264
""""${bindService()}":{"get_info":{}}}""") // library marker davegut.kasaCommon, line 265
} // library marker davegut.kasaCommon, line 266
def setDeviceAlias(newAlias) { // library marker davegut.kasaCommon, line 268
if (getDataValue("plugNo") != null) { // library marker davegut.kasaCommon, line 269
sendCmd("""{"context":{"child_ids":["${getDataValue("plugId")}"]},""" + // library marker davegut.kasaCommon, line 270
""""system":{"set_dev_alias":{"alias":"${device.getLabel()}"}}}""") // library marker davegut.kasaCommon, line 271
} else { // library marker davegut.kasaCommon, line 272
sendCmd("""{"system":{"set_dev_alias":{"alias":"${device.getLabel()}"}}}""") // library marker davegut.kasaCommon, line 273
} // library marker davegut.kasaCommon, line 274
} // library marker davegut.kasaCommon, line 275
// ~~~~~ end include (545) davegut.kasaCommon ~~~~~
// ~~~~~ start include (546) 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
def getPort() { // library marker davegut.kasaCommunications, line 12
def port = 9999 // library marker davegut.kasaCommunications, line 13
if (getDataValue("devicePort")) { // library marker davegut.kasaCommunications, line 14
port = getDataValue("devicePort") // library marker davegut.kasaCommunications, line 15
} // library marker davegut.kasaCommunications, line 16
return port // library marker davegut.kasaCommunications, line 17
} // library marker davegut.kasaCommunications, line 18
def sendCmd(command) { // library marker davegut.kasaCommunications, line 20
if (!command.contains("password")) { // library marker davegut.kasaCommunications, line 21
state.lastCommand = command // library marker davegut.kasaCommunications, line 22
} // library marker davegut.kasaCommunications, line 23
def connection = device.currentValue("connection") // library marker davegut.kasaCommunications, line 24
if (connection == "LAN") { // library marker davegut.kasaCommunications, line 25
sendLanCmd(command) // library marker davegut.kasaCommunications, line 26
} else if (connection == "CLOUD"){ // library marker davegut.kasaCommunications, line 27
sendKasaCmd(command) // library marker davegut.kasaCommunications, line 28
} else if (connection == "AltLAN") { // library marker davegut.kasaCommunications, line 29
sendTcpCmd(command) // library marker davegut.kasaCommunications, line 30
} else { // library marker davegut.kasaCommunications, line 31
logWarn("sendCmd: attribute connection is not set.") // library marker davegut.kasaCommunications, line 32
} // library marker davegut.kasaCommunications, line 33
} // library marker davegut.kasaCommunications, line 34
def sendLanCmd(command, commsTo = 3) { // library marker davegut.kasaCommunications, line 36
logDebug("sendLanCmd: [ip: ${getDataValue("deviceIP")}, commsTo: ${commsTo}, 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: commsTo, // library marker davegut.kasaCommunications, line 45
callback: parseUdp]) // library marker davegut.kasaCommunications, line 46
try { // library marker davegut.kasaCommunications, line 47
sendHubCommand(myHubAction) // library marker davegut.kasaCommunications, line 48
} catch (e) { // library marker davegut.kasaCommunications, line 49
logWarn("sendLanCmd: LAN Error = ${e}.\n\rNo retry on this error.") // library marker davegut.kasaCommunications, line 50
} // library marker davegut.kasaCommunications, line 51
} // library marker davegut.kasaCommunications, line 52
def parseUdp(message) { // library marker davegut.kasaCommunications, line 54
def resp = parseLanMessage(message) // library marker davegut.kasaCommunications, line 55
if (resp.type == "LAN_TYPE_UDPCLIENT") { // library marker davegut.kasaCommunications, line 56
def clearResp = inputXOR(resp.payload) // library marker davegut.kasaCommunications, line 57
if (clearResp.length() > 1022) { // library marker davegut.kasaCommunications, line 58
if (clearResp.contains("preferred")) { // library marker davegut.kasaCommunications, line 59
clearResp = clearResp.substring(0,clearResp.indexOf("preferred")-2) + "}}}" // library marker davegut.kasaCommunications, line 60
} else { // library marker davegut.kasaCommunications, line 61
def msg = "parseUdp: Response is too long for Hubitat UDP implementation." // library marker davegut.kasaCommunications, line 62
msg += "\n\tDevice attributes have not been updated." // library marker davegut.kasaCommunications, line 63
if(device.getName().contains("Multi")) { // library marker davegut.kasaCommunications, line 64
msg += "\n\tHS300:\tCheck your device names. The total Kasa App names of all " // library marker davegut.kasaCommunications, line 65
msg += "\n\t\t\tdevice names can't exceed 96 charactrs (16 per device).\n\r" // library marker davegut.kasaCommunications, line 66
} // library marker davegut.kasaCommunications, line 67
logWarn(msg) // 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
resetCommsError() // library marker davegut.kasaCommunications, line 75
} else { // library marker davegut.kasaCommunications, line 76
logDebug("parse: LAN Error = ${resp.type}") // library marker davegut.kasaCommunications, line 77
handleCommsError() // library marker davegut.kasaCommunications, line 78
} // library marker davegut.kasaCommunications, line 79
} // 6/5/4 // 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 113
def jsonSlurper = new groovy.json.JsonSlurper() // library marker davegut.kasaCommunications, line 114
def response = jsonSlurper.parseText(resp.data) // library marker davegut.kasaCommunications, line 115
if (resp.status == 200 && response.error_code == 0) { // library marker davegut.kasaCommunications, line 116
// distResp(jsonSlurper.parseText(response.result.responseData)) // library marker davegut.kasaCommunications, line 117
def cmdResp = new JsonSlurper().parseText(response.result.responseData) // library marker davegut.kasaCommunications, line 118
logDebug("cloudParse: ${cmdResp}") // library marker davegut.kasaCommunications, line 119
distResp(cmdResp) // library marker davegut.kasaCommunications, line 120
resetCommsError() // library marker davegut.kasaCommunications, line 121
} else { // library marker davegut.kasaCommunications, line 122
def msg = "sendKasaCmd:\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
handleCommsError() // library marker davegut.kasaCommunications, line 127
} // library marker davegut.kasaCommunications, line 128
} // 6.5.4 // library marker davegut.kasaCommunications, line 129
private sendTcpCmd(command) { // library marker davegut.kasaCommunications, line 131
logDebug("sendTcpCmd: ${command}") // library marker davegut.kasaCommunications, line 132
try { // library marker davegut.kasaCommunications, line 133
interfaces.rawSocket.connect("${getDataValue("deviceIP")}", // library marker davegut.kasaCommunications, line 134
getPort().toInteger(), byteInterface: true) // library marker davegut.kasaCommunications, line 135
} catch (error) { // library marker davegut.kasaCommunications, line 136
logDebug("SendTcpCmd: Unable to connect to device at ${getDataValue("deviceIP")}:${getDataValue("devicePort")}. " + // library marker davegut.kasaCommunications, line 137
"Error = ${error}") // library marker davegut.kasaCommunications, line 138
} // library marker davegut.kasaCommunications, line 139
state.lastCommand = command // library marker davegut.kasaCommunications, line 140
interfaces.rawSocket.sendMessage(outputXorTcp(command)) // library marker davegut.kasaCommunications, line 141
runIn(2, close) // library marker davegut.kasaCommunications, line 142
} // library marker davegut.kasaCommunications, line 143
def close() { interfaces.rawSocket.close() } // library marker davegut.kasaCommunications, line 145
def socketStatus(message) { // library marker davegut.kasaCommunications, line 147
if (message != "receive error: Stream closed.") { // library marker davegut.kasaCommunications, line 148
logDebug("socketStatus: Socket Established") // library marker davegut.kasaCommunications, line 149
} else { // library marker davegut.kasaCommunications, line 150
logWarn("socketStatus = ${message}") // library marker davegut.kasaCommunications, line 151
} // library marker davegut.kasaCommunications, line 152
} // library marker davegut.kasaCommunications, line 153
def parse(message) { // library marker davegut.kasaCommunications, line 155
def response = state.response.concat(message) // library marker davegut.kasaCommunications, line 156
state.response = response // library marker davegut.kasaCommunications, line 157
runInMillis(50, extractTcpResp, [data: response]) // library marker davegut.kasaCommunications, line 158
} // library marker davegut.kasaCommunications, line 159
def extractTcpResp(response) { // library marker davegut.kasaCommunications, line 161
state.response = "" // library marker davegut.kasaCommunications, line 162
if (response.length() == null) { // library marker davegut.kasaCommunications, line 163
logDebug("extractTcpResp: null return rejected.") // library marker davegut.kasaCommunications, line 164
return // library marker davegut.kasaCommunications, line 165
} // library marker davegut.kasaCommunications, line 166
logDebug("extractTcpResp: ${response}") // library marker davegut.kasaCommunications, line 167
try { // library marker davegut.kasaCommunications, line 168
// distResp(parseJson(inputXorTcp(response))) // library marker davegut.kasaCommunications, line 169
def cmdResp = parseJson(inputXorTcp(response)) // library marker davegut.kasaCommunications, line 170
logDebug("cloudParse: ${cmdResp}") // library marker davegut.kasaCommunications, line 171
distResp(cmdResp) // library marker davegut.kasaCommunications, line 172
resetCommsError() // library marker davegut.kasaCommunications, line 173
} catch (e) { // library marker davegut.kasaCommunications, line 174
logDebug("extractTcpResponse: comms error = ${e}") // library marker davegut.kasaCommunications, line 175
handleCommsError() // library marker davegut.kasaCommunications, line 176
} // library marker davegut.kasaCommunications, line 177
} // 6.5.4 // library marker davegut.kasaCommunications, line 178
def handleCommsError() { // library marker davegut.kasaCommunications, line 180
def count = state.errorCount + 1 // library marker davegut.kasaCommunications, line 181
state.errorCount = count // library marker davegut.kasaCommunications, line 182
def retry = true // library marker davegut.kasaCommunications, line 183
def status = [count: count, command: state.lastCommand] // library marker davegut.kasaCommunications, line 184
if (count == 3) { // library marker davegut.kasaCommunications, line 185
def attemptFix = parent.fixConnection() // library marker davegut.kasaCommunications, line 186
status << [attemptFixResult: [attemptFix]] // library marker davegut.kasaCommunications, line 187
} else if (count >= 4) { // library marker davegut.kasaCommunications, line 188
retry = false // library marker davegut.kasaCommunications, line 189
} // library marker davegut.kasaCommunications, line 190
if (retry == true) { // library marker davegut.kasaCommunications, line 191
def commsTo = 5 // library marker davegut.kasaCommunications, line 192
sendLanCmd(state.lastCommand, commsTo) // library marker davegut.kasaCommunications, line 193
if (count > 1) { // library marker davegut.kasaCommunications, line 194
logDebug("handleCommsError: [count: ${count}, timeout: ${commsTo}]") // library marker davegut.kasaCommunications, line 195
} // library marker davegut.kasaCommunications, line 196
} else { // library marker davegut.kasaCommunications, line 197
setCommsError() // library marker davegut.kasaCommunications, line 198
} // library marker davegut.kasaCommunications, line 199
status << [retry: retry] // library marker davegut.kasaCommunications, line 200
if (status.count > 2) { // library marker davegut.kasaCommunications, line 201
logWarn("handleCommsError: ${status}") // library marker davegut.kasaCommunications, line 202
} else { // library marker davegut.kasaCommunications, line 203
logDebug("handleCommsError: ${status}") // library marker davegut.kasaCommunications, line 204
} // library marker davegut.kasaCommunications, line 205
} // library marker davegut.kasaCommunications, line 206
def setCommsError() { // library marker davegut.kasaCommunications, line 208
if (device.currentValue("commsError") == "false") { // library marker davegut.kasaCommunications, line 209
def message = "Can't connect to your device at ${getDataValue("deviceIP")}:${getPort()}. " // library marker davegut.kasaCommunications, line 210
message += "Refer to troubleshooting guide commsError section." // library marker davegut.kasaCommunications, line 211
sendEvent(name: "commsError", value: "true") // library marker davegut.kasaCommunications, line 212
state.COMMS_ERROR = message // library marker davegut.kasaCommunications, line 213
logWarn("setCommsError: ${message}") // library marker davegut.kasaCommunications, line 214
runIn(15, limitPollInterval) // library marker davegut.kasaCommunications, line 215
} // library marker davegut.kasaCommunications, line 216
} // library marker davegut.kasaCommunications, line 217
def limitPollInterval() { // library marker davegut.kasaCommunications, line 219
state.nonErrorPollInterval = state.pollInterval // library marker davegut.kasaCommunications, line 220
setPollInterval("30 minutes") // library marker davegut.kasaCommunications, line 221
} // library marker davegut.kasaCommunications, line 222
def resetCommsError() { // library marker davegut.kasaCommunications, line 224
state.errorCount = 0 // library marker davegut.kasaCommunications, line 225
if (device.currentValue("commsError") == "true") { // library marker davegut.kasaCommunications, line 226
sendEvent(name: "commsError", value: "false") // library marker davegut.kasaCommunications, line 227
setPollInterval(state.nonErrorPollInterval) // library marker davegut.kasaCommunications, line 228
state.remove("nonErrorPollInterval") // library marker davegut.kasaCommunications, line 229
state.remove("COMMS_ERROR") // library marker davegut.kasaCommunications, line 230
logInfo("resetCommsError: Comms error cleared!") // library marker davegut.kasaCommunications, line 231
} // library marker davegut.kasaCommunications, line 232
} // library marker davegut.kasaCommunications, line 233
private outputXOR(command) { // library marker davegut.kasaCommunications, line 235
def str = "" // library marker davegut.kasaCommunications, line 236
def encrCmd = "" // library marker davegut.kasaCommunications, line 237
def key = 0xAB // library marker davegut.kasaCommunications, line 238
for (int i = 0; i < command.length(); i++) { // library marker davegut.kasaCommunications, line 239
str = (command.charAt(i) as byte) ^ key // library marker davegut.kasaCommunications, line 240
key = str // library marker davegut.kasaCommunications, line 241
encrCmd += Integer.toHexString(str) // library marker davegut.kasaCommunications, line 242
} // library marker davegut.kasaCommunications, line 243
return encrCmd // library marker davegut.kasaCommunications, line 244
} // library marker davegut.kasaCommunications, line 245
private inputXOR(encrResponse) { // library marker davegut.kasaCommunications, line 247
String[] strBytes = encrResponse.split("(?<=\\G.{2})") // library marker davegut.kasaCommunications, line 248
def cmdResponse = "" // library marker davegut.kasaCommunications, line 249
def key = 0xAB // library marker davegut.kasaCommunications, line 250
def nextKey // library marker davegut.kasaCommunications, line 251
byte[] XORtemp // library marker davegut.kasaCommunications, line 252
for(int i = 0; i < strBytes.length; i++) { // library marker davegut.kasaCommunications, line 253
nextKey = (byte)Integer.parseInt(strBytes[i], 16) // could be negative // library marker davegut.kasaCommunications, line 254
XORtemp = nextKey ^ key // library marker davegut.kasaCommunications, line 255
key = nextKey // library marker davegut.kasaCommunications, line 256
cmdResponse += new String(XORtemp) // library marker davegut.kasaCommunications, line 257
} // library marker davegut.kasaCommunications, line 258
return cmdResponse // library marker davegut.kasaCommunications, line 259
} // library marker davegut.kasaCommunications, line 260
private outputXorTcp(command) { // library marker davegut.kasaCommunications, line 262
def str = "" // library marker davegut.kasaCommunications, line 263
def encrCmd = "000000" + Integer.toHexString(command.length()) // library marker davegut.kasaCommunications, line 264
def key = 0xAB // library marker davegut.kasaCommunications, line 265
for (int i = 0; i < command.length(); i++) { // library marker davegut.kasaCommunications, line 266
str = (command.charAt(i) as byte) ^ key // library marker davegut.kasaCommunications, line 267
key = str // library marker davegut.kasaCommunications, line 268
encrCmd += Integer.toHexString(str) // library marker davegut.kasaCommunications, line 269
} // library marker davegut.kasaCommunications, line 270
return encrCmd // library marker davegut.kasaCommunications, line 271
} // library marker davegut.kasaCommunications, line 272
private inputXorTcp(resp) { // library marker davegut.kasaCommunications, line 274
String[] strBytes = resp.substring(8).split("(?<=\\G.{2})") // library marker davegut.kasaCommunications, line 275
def cmdResponse = "" // library marker davegut.kasaCommunications, line 276
def key = 0xAB // library marker davegut.kasaCommunications, line 277
def nextKey // library marker davegut.kasaCommunications, line 278
byte[] XORtemp // library marker davegut.kasaCommunications, line 279
for(int i = 0; i < strBytes.length; i++) { // library marker davegut.kasaCommunications, line 280
nextKey = (byte)Integer.parseInt(strBytes[i], 16) // could be negative // library marker davegut.kasaCommunications, line 281
XORtemp = nextKey ^ key // library marker davegut.kasaCommunications, line 282
key = nextKey // library marker davegut.kasaCommunications, line 283
cmdResponse += new String(XORtemp) // library marker davegut.kasaCommunications, line 284
} // library marker davegut.kasaCommunications, line 285
return cmdResponse // library marker davegut.kasaCommunications, line 286
} // library marker davegut.kasaCommunications, line 287
def logTrace(msg){ // library marker davegut.kasaCommunications, line 289
log.trace "[${device.getLabel()}: ${driverVer()}]: ${msg}" // library marker davegut.kasaCommunications, line 290
} // library marker davegut.kasaCommunications, line 291
def logInfo(msg) { // library marker davegut.kasaCommunications, line 293
if(descriptionText == true) { // library marker davegut.kasaCommunications, line 294
log.info "[${device.getLabel()}: ${driverVer()}]: ${msg}" // library marker davegut.kasaCommunications, line 295
} // library marker davegut.kasaCommunications, line 296
} // library marker davegut.kasaCommunications, line 297
def logDebug(msg){ // library marker davegut.kasaCommunications, line 299
if(debug == true) { // library marker davegut.kasaCommunications, line 300
log.debug "[${device.getLabel()}: ${driverVer()}]: ${msg}" // library marker davegut.kasaCommunications, line 301
} // library marker davegut.kasaCommunications, line 302
} // library marker davegut.kasaCommunications, line 303
def debugOff() { // library marker davegut.kasaCommunications, line 305
device.updateSetting("debug", [type:"bool", value: false]) // library marker davegut.kasaCommunications, line 306
logInfo("debugLogOff: Debug logging is off.") // library marker davegut.kasaCommunications, line 307
} // library marker davegut.kasaCommunications, line 308
def logWarn(msg) { // library marker davegut.kasaCommunications, line 310
log.warn "[${device.getLabel()}: ${driverVer()}]: ${msg}" // library marker davegut.kasaCommunications, line 311
} // library marker davegut.kasaCommunications, line 312
// ~~~~~ end include (546) davegut.kasaCommunications ~~~~~
// ~~~~~ start include (547) 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
runEvery30Minutes(getEnergyToday) // library marker davegut.kasaEnergyMonitor, line 12
schedule("10 0 0 * * ?", getEnergyThisMonth) // library marker davegut.kasaEnergyMonitor, line 13
schedule("15 2 0 1 * ?", getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 14
state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 15
return "Continuing EM Function" // library marker davegut.kasaEnergyMonitor, line 16
} else if (emFunction) { // library marker davegut.kasaEnergyMonitor, line 17
sendEvent(name: "power", value: 0, unit: "W") // library marker davegut.kasaEnergyMonitor, line 18
sendEvent(name: "energy", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 19
sendEvent(name: "currMonthTotal", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 20
sendEvent(name: "currMonthAvg", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 21
sendEvent(name: "lastMonthTotal", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 22
sendEvent(name: "lastMonthAvg", value: 0, unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 23
state.response = "" // library marker davegut.kasaEnergyMonitor, line 24
runEvery30Minutes(getEnergyToday) // library marker davegut.kasaEnergyMonitor, line 25
schedule("10 0 0 * * ?", getEnergyThisMonth) // library marker davegut.kasaEnergyMonitor, line 26
schedule("15 2 0 1 * ?", getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 27
state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 28
// Run order / delay is critical for successful operation. // library marker davegut.kasaEnergyMonitor, line 29
getEnergyThisMonth() // library marker davegut.kasaEnergyMonitor, line 30
runIn(10, getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 31
return "Initialized" // library marker davegut.kasaEnergyMonitor, line 32
} else if (device.currentValue("power") != null) { // library marker davegut.kasaEnergyMonitor, line 33
// for power != null, EM had to be enabled at one time. Set values to 0. // library marker davegut.kasaEnergyMonitor, line 34
sendEvent(name: "power", value: 0) // library marker davegut.kasaEnergyMonitor, line 35
sendEvent(name: "energy", value: 0) // library marker davegut.kasaEnergyMonitor, line 36
sendEvent(name: "currMonthTotal", value: 0) // library marker davegut.kasaEnergyMonitor, line 37
sendEvent(name: "currMonthAvg", value: 0) // library marker davegut.kasaEnergyMonitor, line 38
sendEvent(name: "lastMonthTotal", value: 0) // library marker davegut.kasaEnergyMonitor, line 39
sendEvent(name: "lastMonthAvg", value: 0) // library marker davegut.kasaEnergyMonitor, line 40
state.remove("getEnergy") // library marker davegut.kasaEnergyMonitor, line 41
return "Disabled" // library marker davegut.kasaEnergyMonitor, line 42
} else { // library marker davegut.kasaEnergyMonitor, line 43
return "Not initialized" // library marker davegut.kasaEnergyMonitor, line 44
} // library marker davegut.kasaEnergyMonitor, line 45
} // library marker davegut.kasaEnergyMonitor, line 46
def getDate() { // library marker davegut.kasaEnergyMonitor, line 48
def currDate = new Date() // library marker davegut.kasaEnergyMonitor, line 49
int year = currDate.format("yyyy").toInteger() // library marker davegut.kasaEnergyMonitor, line 50
int month = currDate.format("M").toInteger() // library marker davegut.kasaEnergyMonitor, line 51
int day = currDate.format("d").toInteger() // library marker davegut.kasaEnergyMonitor, line 52
return [year: year, month: month, day: day] // library marker davegut.kasaEnergyMonitor, line 53
} // library marker davegut.kasaEnergyMonitor, line 54
def distEmeter(emeterResp) { // library marker davegut.kasaEnergyMonitor, line 56
def date = getDate() // library marker davegut.kasaEnergyMonitor, line 57
logDebug("distEmeter: ${emeterResp}, ${date}, ${state.getEnergy}") // library marker davegut.kasaEnergyMonitor, line 58
def lastYear = date.year - 1 // library marker davegut.kasaEnergyMonitor, line 59
if (emeterResp.get_realtime) { // library marker davegut.kasaEnergyMonitor, line 60
setPower(emeterResp.get_realtime) // library marker davegut.kasaEnergyMonitor, line 61
} else if (emeterResp.get_monthstat) { // library marker davegut.kasaEnergyMonitor, line 62
def monthList = emeterResp.get_monthstat.month_list // library marker davegut.kasaEnergyMonitor, line 63
if (state.getEnergy == "Today") { // library marker davegut.kasaEnergyMonitor, line 64
setEnergyToday(monthList, date) // library marker davegut.kasaEnergyMonitor, line 65
} else if (state.getEnergy == "This Month") { // library marker davegut.kasaEnergyMonitor, line 66
setThisMonth(monthList, date) // library marker davegut.kasaEnergyMonitor, line 67
} else if (state.getEnergy == "Last Month") { // library marker davegut.kasaEnergyMonitor, line 68
setLastMonth(monthList, date) // library marker davegut.kasaEnergyMonitor, line 69
} else if (monthList == []) { // library marker davegut.kasaEnergyMonitor, line 70
logDebug("distEmeter: monthList Empty. No data for year.") // library marker davegut.kasaEnergyMonitor, line 71
} // library marker davegut.kasaEnergyMonitor, line 72
} else { // library marker davegut.kasaEnergyMonitor, line 73
logWarn("distEmeter: Unhandled response = ${emeterResp}") // library marker davegut.kasaEnergyMonitor, line 74
} // library marker davegut.kasaEnergyMonitor, line 75
} // library marker davegut.kasaEnergyMonitor, line 76
def getPower() { // library marker davegut.kasaEnergyMonitor, line 78
if (device.currentValue("switch") == "on") { // library marker davegut.kasaEnergyMonitor, line 79
getRealtime() // library marker davegut.kasaEnergyMonitor, line 80
} else if (device.currentValue("power") != 0) { // library marker davegut.kasaEnergyMonitor, line 81
sendEvent(name: "power", value: 0, descriptionText: "Watts", unit: "W", type: "digital") // library marker davegut.kasaEnergyMonitor, line 82
} // library marker davegut.kasaEnergyMonitor, line 83
} // library marker davegut.kasaEnergyMonitor, line 84
def setPower(response) { // library marker davegut.kasaEnergyMonitor, line 86
logDebug("setPower: ${response}") // library marker davegut.kasaEnergyMonitor, line 87
def status = [:] // library marker davegut.kasaEnergyMonitor, line 88
def power = response.power // library marker davegut.kasaEnergyMonitor, line 89
if (power == null) { power = response.power_mw / 1000 } // library marker davegut.kasaEnergyMonitor, line 90
power = (power + 0.5).toInteger() // library marker davegut.kasaEnergyMonitor, line 91
def curPwr = device.currentValue("power") // library marker davegut.kasaEnergyMonitor, line 92
def pwrChange = false // library marker davegut.kasaEnergyMonitor, line 93
if (curPwr != power) { // library marker davegut.kasaEnergyMonitor, line 94
if (curPwr == null || (curPwr == 0 && power > 0)) { // library marker davegut.kasaEnergyMonitor, line 95
pwrChange = true // library marker davegut.kasaEnergyMonitor, line 96
} else { // library marker davegut.kasaEnergyMonitor, line 97
def changeRatio = Math.abs((power - curPwr) / curPwr) // library marker davegut.kasaEnergyMonitor, line 98
if (changeRatio > 0.03) { // library marker davegut.kasaEnergyMonitor, line 99
pwrChange = true // library marker davegut.kasaEnergyMonitor, line 100
} // library marker davegut.kasaEnergyMonitor, line 101
} // library marker davegut.kasaEnergyMonitor, line 102
} // library marker davegut.kasaEnergyMonitor, line 103
if (pwrChange == true) { // library marker davegut.kasaEnergyMonitor, line 104
sendEvent(name: "power", value: power, descriptionText: "Watts", unit: "W", type: "digital") // library marker davegut.kasaEnergyMonitor, line 105
status << [power: power] // library marker davegut.kasaEnergyMonitor, line 106
} // library marker davegut.kasaEnergyMonitor, line 107
if (status != [:]) { logInfo("setPower: ${status}") } // library marker davegut.kasaEnergyMonitor, line 108
} // library marker davegut.kasaEnergyMonitor, line 109
def getEnergyToday() { // library marker davegut.kasaEnergyMonitor, line 111
state.getEnergy = "Today" // library marker davegut.kasaEnergyMonitor, line 112
def year = getDate().year // library marker davegut.kasaEnergyMonitor, line 113
logDebug("getEnergyToday: ${year}") // library marker davegut.kasaEnergyMonitor, line 114
runIn(5, getMonthstat, [data: year]) // library marker davegut.kasaEnergyMonitor, line 115
} // library marker davegut.kasaEnergyMonitor, line 116
def setEnergyToday(monthList, date) { // library marker davegut.kasaEnergyMonitor, line 118
logDebug("setEnergyToday: ${date}, ${monthList}") // library marker davegut.kasaEnergyMonitor, line 119
def data = monthList.find { it.month == date.month && it.year == date.year} // library marker davegut.kasaEnergyMonitor, line 120
def status = [:] // library marker davegut.kasaEnergyMonitor, line 121
def energy = 0 // library marker davegut.kasaEnergyMonitor, line 122
if (data == null) { // library marker davegut.kasaEnergyMonitor, line 123
status << [msgError: "Return Data Null"] // library marker davegut.kasaEnergyMonitor, line 124
} else { // library marker davegut.kasaEnergyMonitor, line 125
energy = data.energy // library marker davegut.kasaEnergyMonitor, line 126
if (energy == null) { energy = data.energy_wh/1000 } // library marker davegut.kasaEnergyMonitor, line 127
energy = Math.round(100*energy)/100 - device.currentValue("currMonthTotal") // library marker davegut.kasaEnergyMonitor, line 128
} // library marker davegut.kasaEnergyMonitor, line 129
if (device.currentValue("energy") != energy) { // library marker davegut.kasaEnergyMonitor, line 130
sendEvent(name: "energy", value: energy, descriptionText: "KiloWatt Hours", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 131
status << [energy: energy] // library marker davegut.kasaEnergyMonitor, line 132
} // library marker davegut.kasaEnergyMonitor, line 133
if (status != [:]) { logInfo("setEnergyToday: ${status}") } // library marker davegut.kasaEnergyMonitor, line 134
if (!state.getEnergy) { // library marker davegut.kasaEnergyMonitor, line 135
schedule("10 0 0 * * ?", getEnergyThisMonth) // library marker davegut.kasaEnergyMonitor, line 136
schedule("15 2 0 1 * ?", getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 137
state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 138
getEnergyThisMonth() // library marker davegut.kasaEnergyMonitor, line 139
runIn(10, getEnergyLastMonth) // library marker davegut.kasaEnergyMonitor, line 140
} // library marker davegut.kasaEnergyMonitor, line 141
} // library marker davegut.kasaEnergyMonitor, line 142
def getEnergyThisMonth() { // library marker davegut.kasaEnergyMonitor, line 144
state.getEnergy = "This Month" // library marker davegut.kasaEnergyMonitor, line 145
def year = getDate().year // library marker davegut.kasaEnergyMonitor, line 146
logDebug("getEnergyThisMonth: ${year}") // library marker davegut.kasaEnergyMonitor, line 147
runIn(5, getMonthstat, [data: year]) // library marker davegut.kasaEnergyMonitor, line 148
} // library marker davegut.kasaEnergyMonitor, line 149
def setThisMonth(monthList, date) { // library marker davegut.kasaEnergyMonitor, line 151
logDebug("setThisMonth: ${date} // ${monthList}") // library marker davegut.kasaEnergyMonitor, line 152
def data = monthList.find { it.month == date.month && it.year == date.year} // library marker davegut.kasaEnergyMonitor, line 153
def status = [:] // library marker davegut.kasaEnergyMonitor, line 154
def totEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 155
def avgEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 156
if (data == null) { // library marker davegut.kasaEnergyMonitor, line 157
status << [msgError: "Return Data Null"] // library marker davegut.kasaEnergyMonitor, line 158
} else { // library marker davegut.kasaEnergyMonitor, line 159
status << [msgError: "OK"] // library marker davegut.kasaEnergyMonitor, line 160
totEnergy = data.energy // library marker davegut.kasaEnergyMonitor, line 161
if (totEnergy == null) { totEnergy = data.energy_wh/1000 } // library marker davegut.kasaEnergyMonitor, line 162
if (date.day == 1) { // library marker davegut.kasaEnergyMonitor, line 163
avgEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 164
} else { // library marker davegut.kasaEnergyMonitor, line 165
avgEnergy = totEnergy /(date.day - 1) // library marker davegut.kasaEnergyMonitor, line 166
} // library marker davegut.kasaEnergyMonitor, line 167
} // library marker davegut.kasaEnergyMonitor, line 168
totEnergy = Math.round(100*totEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 169
avgEnergy = Math.round(100*avgEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 170
sendEvent(name: "currMonthTotal", value: totEnergy, // library marker davegut.kasaEnergyMonitor, line 171
descriptionText: "KiloWatt Hours", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 172
status << [currMonthTotal: totEnergy] // library marker davegut.kasaEnergyMonitor, line 173
sendEvent(name: "currMonthAvg", value: avgEnergy, // library marker davegut.kasaEnergyMonitor, line 174
descriptionText: "KiloWatt Hours per Day", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 175
status << [currMonthAvg: avgEnergy] // library marker davegut.kasaEnergyMonitor, line 176
// Update energy today in sync with energyThisMonth // library marker davegut.kasaEnergyMonitor, line 177
getEnergyToday() // library marker davegut.kasaEnergyMonitor, line 178
logInfo("setThisMonth: ${status}") // library marker davegut.kasaEnergyMonitor, line 179
} // library marker davegut.kasaEnergyMonitor, line 180
def getEnergyLastMonth() { // library marker davegut.kasaEnergyMonitor, line 182
state.getEnergy = "Last Month" // library marker davegut.kasaEnergyMonitor, line 183
def date = getDate() // library marker davegut.kasaEnergyMonitor, line 184
def year = date.year // library marker davegut.kasaEnergyMonitor, line 185
if (date.month == 1) { // library marker davegut.kasaEnergyMonitor, line 186
year = year - 1 // library marker davegut.kasaEnergyMonitor, line 187
} // library marker davegut.kasaEnergyMonitor, line 188
logDebug("getEnergyLastMonth: ${year}") // library marker davegut.kasaEnergyMonitor, line 189
runIn(5, getMonthstat, [data: year]) // library marker davegut.kasaEnergyMonitor, line 190
} // library marker davegut.kasaEnergyMonitor, line 191
def setLastMonth(monthList, date) { // library marker davegut.kasaEnergyMonitor, line 193
logDebug("setLastMonth: ${date} // ${monthList}") // library marker davegut.kasaEnergyMonitor, line 194
def lastMonthYear = date.year // library marker davegut.kasaEnergyMonitor, line 195
def lastMonth = date.month - 1 // library marker davegut.kasaEnergyMonitor, line 196
if (date.month == 1) { // library marker davegut.kasaEnergyMonitor, line 197
lastMonthYear -+ 1 // library marker davegut.kasaEnergyMonitor, line 198
lastMonth = 12 // library marker davegut.kasaEnergyMonitor, line 199
} // library marker davegut.kasaEnergyMonitor, line 200
def data = monthList.find { it.month == lastMonth } // library marker davegut.kasaEnergyMonitor, line 201
def status = [:] // library marker davegut.kasaEnergyMonitor, line 202
def totEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 203
def avgEnergy = 0 // library marker davegut.kasaEnergyMonitor, line 204
if (data == null) { // library marker davegut.kasaEnergyMonitor, line 205
status << [msgError: "Return Data Null"] // library marker davegut.kasaEnergyMonitor, line 206
} else { // library marker davegut.kasaEnergyMonitor, line 207
status << [msgError: "OK"] // library marker davegut.kasaEnergyMonitor, line 208
def monthLength // library marker davegut.kasaEnergyMonitor, line 209
switch(lastMonth) { // library marker davegut.kasaEnergyMonitor, line 210
case 4: // library marker davegut.kasaEnergyMonitor, line 211
case 6: // library marker davegut.kasaEnergyMonitor, line 212
case 9: // library marker davegut.kasaEnergyMonitor, line 213
case 11: // library marker davegut.kasaEnergyMonitor, line 214
monthLength = 30 // library marker davegut.kasaEnergyMonitor, line 215
break // library marker davegut.kasaEnergyMonitor, line 216
case 2: // library marker davegut.kasaEnergyMonitor, line 217
monthLength = 28 // library marker davegut.kasaEnergyMonitor, line 218
if (lastMonthYear == 2020 || lastMonthYear == 2024 || lastMonthYear == 2028) { // library marker davegut.kasaEnergyMonitor, line 219
monthLength = 29 // library marker davegut.kasaEnergyMonitor, line 220
} // library marker davegut.kasaEnergyMonitor, line 221
break // library marker davegut.kasaEnergyMonitor, line 222
default: // library marker davegut.kasaEnergyMonitor, line 223
monthLength = 31 // library marker davegut.kasaEnergyMonitor, line 224
} // library marker davegut.kasaEnergyMonitor, line 225
totEnergy = data.energy // library marker davegut.kasaEnergyMonitor, line 226
if (totEnergy == null) { totEnergy = data.energy_wh/1000 } // library marker davegut.kasaEnergyMonitor, line 227
avgEnergy = totEnergy / monthLength // library marker davegut.kasaEnergyMonitor, line 228
} // library marker davegut.kasaEnergyMonitor, line 229
totEnergy = Math.round(100*totEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 230
avgEnergy = Math.round(100*avgEnergy)/100 // library marker davegut.kasaEnergyMonitor, line 231
sendEvent(name: "lastMonthTotal", value: totEnergy, // library marker davegut.kasaEnergyMonitor, line 232
descriptionText: "KiloWatt Hours", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 233
status << [lastMonthTotal: totEnergy] // library marker davegut.kasaEnergyMonitor, line 234
sendEvent(name: "lastMonthAvg", value: avgEnergy, // library marker davegut.kasaEnergyMonitor, line 235
descriptionText: "KiloWatt Hoursper Day", unit: "KWH") // library marker davegut.kasaEnergyMonitor, line 236
status << [lastMonthAvg: avgEnergy] // library marker davegut.kasaEnergyMonitor, line 237
logInfo("setLastMonth: ${status}") // library marker davegut.kasaEnergyMonitor, line 238
} // library marker davegut.kasaEnergyMonitor, line 239
// ===== API Commands: Energy Monitor ===== // library marker davegut.kasaEnergyMonitor, line 241
def getRealtime() { // library marker davegut.kasaEnergyMonitor, line 242
if (getDataValue("plugNo") != null) { // library marker davegut.kasaEnergyMonitor, line 243
sendCmd("""{"context":{"child_ids":["${getDataValue("plugId")}"]},""" + // library marker davegut.kasaEnergyMonitor, line 244
""""emeter":{"get_realtime":{}}}""") // library marker davegut.kasaEnergyMonitor, line 245
} else if (type().contains("Bulb") || type().contains("Light")) { // library marker davegut.kasaEnergyMonitor, line 246
sendCmd("""{"smartlife.iot.common.emeter":{"get_realtime":{}}}""") // library marker davegut.kasaEnergyMonitor, line 247
} else { // library marker davegut.kasaEnergyMonitor, line 248
sendCmd("""{"emeter":{"get_realtime":{}}}""") // library marker davegut.kasaEnergyMonitor, line 249
} // library marker davegut.kasaEnergyMonitor, line 250
} // library marker davegut.kasaEnergyMonitor, line 251
def getMonthstat(year) { // library marker davegut.kasaEnergyMonitor, line 253
if (getDataValue("plugNo") != null) { // library marker davegut.kasaEnergyMonitor, line 254
sendCmd("""{"context":{"child_ids":["${getDataValue("plugId")}"]},""" + // library marker davegut.kasaEnergyMonitor, line 255
""""emeter":{"get_monthstat":{"year": ${year}}}}""") // library marker davegut.kasaEnergyMonitor, line 256
} else if (type().contains("Bulb") || type().contains("Light")) { // library marker davegut.kasaEnergyMonitor, line 257
sendCmd("""{"smartlife.iot.common.emeter":{"get_monthstat":{"year": ${year}}}}""") // library marker davegut.kasaEnergyMonitor, line 258
} else { // library marker davegut.kasaEnergyMonitor, line 259
sendCmd("""{"emeter":{"get_monthstat":{"year": ${year}}}}""") // library marker davegut.kasaEnergyMonitor, line 260
} // library marker davegut.kasaEnergyMonitor, line 261
} // library marker davegut.kasaEnergyMonitor, line 262
// ~~~~~ end include (547) davegut.kasaEnergyMonitor ~~~~~