Compare commits
1 Commits
user167778
...
MSA-2605-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b9665eb59 |
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
TP-Link Plug and Switch Device Handler, 2018, Version 2
|
||||
Copyright 2018 Dave Gutheinz
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the
|
||||
License. You may obtain a copy of the License at:
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
either express or implied. See the License for the specific
|
||||
language governing permissions and limitations under the
|
||||
License.
|
||||
Discalimer: This Service Manager and the associated Device
|
||||
Handlers are in no way sanctioned or supported by TP-Link.
|
||||
All development is based upon open-source data on the
|
||||
TP-Link devices; primarily various users on GitHub.com.
|
||||
===== History =============================================
|
||||
2018-01-31 Update to Version 2
|
||||
a. Common file content for all bulb implementations,
|
||||
using separate files by model only.
|
||||
b. User file-internal selection of Energy Monitor
|
||||
function enabling.
|
||||
// ===== Hub or Cloud Installation =========================*/
|
||||
def installType = "Cloud"
|
||||
//def installType = "Hub"
|
||||
// ===========================================================
|
||||
|
||||
metadata {
|
||||
definition (name: "(${installType}) TP-Link Plug-Switch",
|
||||
namespace: "davegut",
|
||||
author: "Dave Gutheinz",
|
||||
deviceType: "Plug-Switch",
|
||||
energyMonitor: "Standard",
|
||||
installType: "${installType}") {
|
||||
capability "Switch"
|
||||
capability "refresh"
|
||||
capability "polling"
|
||||
capability "Sensor"
|
||||
capability "Actuator"
|
||||
}
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc",
|
||||
nextState:"waiting"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff",
|
||||
nextState:"waiting"
|
||||
attributeState "waiting", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#15EE10",
|
||||
nextState:"waiting"
|
||||
attributeState "commsError", label:'Comms Error', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#e86d13",
|
||||
nextState:"waiting"
|
||||
}
|
||||
tileAttribute ("deviceError", key: "SECONDARY_CONTROL") {
|
||||
attributeState "deviceError", label: '${currentValue}'
|
||||
}
|
||||
}
|
||||
|
||||
standardTile("refresh", "capability.refresh", width: 2, height: 1, decoration: "flat") {
|
||||
state "default", label:"Refresh", action:"refresh.refresh"
|
||||
}
|
||||
|
||||
main("switch")
|
||||
details("switch", "refresh")
|
||||
}
|
||||
|
||||
def rates = [:]
|
||||
rates << ["5" : "Refresh every 5 minutes"]
|
||||
rates << ["10" : "Refresh every 10 minutes"]
|
||||
rates << ["15" : "Refresh every 15 minutes"]
|
||||
rates << ["30" : "Refresh every 30 minutes"]
|
||||
|
||||
preferences {
|
||||
if (installType == "Hub") {
|
||||
input("deviceIP", "text", title: "Device IP", required: true, displayDuringSetup: true)
|
||||
input("gatewayIP", "text", title: "Gateway IP", required: true, displayDuringSetup: true)
|
||||
}
|
||||
input name: "refreshRate", type: "enum", title: "Refresh Rate", options: rates, description: "Select Refresh Rate", required: false
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Update when installed or setting changed =====
|
||||
def installed() {
|
||||
update()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
runIn(2, update)
|
||||
}
|
||||
|
||||
def update() {
|
||||
state.deviceType = metadata.definition.deviceType
|
||||
state.installType = metadata.definition.installType
|
||||
unschedule()
|
||||
switch(refreshRate) {
|
||||
case "5":
|
||||
runEvery5Minutes(refresh)
|
||||
log.info "Refresh Scheduled for every 5 minutes"
|
||||
break
|
||||
case "10":
|
||||
runEvery10Minutes(refresh)
|
||||
log.info "Refresh Scheduled for every 10 minutes"
|
||||
break
|
||||
case "15":
|
||||
runEvery15Minutes(refresh)
|
||||
log.info "Refresh Scheduled for every 15 minutes"
|
||||
break
|
||||
default:
|
||||
runEvery30Minutes(refresh)
|
||||
log.info "Refresh Scheduled for every 30 minutes"
|
||||
}
|
||||
runIn(5, refresh)
|
||||
}
|
||||
|
||||
void uninstalled() {
|
||||
if (state.installType == "Cloud") {
|
||||
def alias = device.label
|
||||
log.debug "Removing device ${alias} with DNI = ${device.deviceNetworkId}"
|
||||
parent.removeChildDevice(alias, device.deviceNetworkId)
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Basic Plug Control/Status =====
|
||||
def on() {
|
||||
sendCmdtoServer('{"system":{"set_relay_state":{"state": 1}}}', "deviceCommand", "commandResponse")
|
||||
}
|
||||
|
||||
def off() {
|
||||
sendCmdtoServer('{"system":{"set_relay_state":{"state": 0}}}', "deviceCommand", "commandResponse")
|
||||
}
|
||||
|
||||
def poll() {
|
||||
sendCmdtoServer('{"system":{"get_sysinfo":{}}}', "deviceCommand", "commandResponse")
|
||||
}
|
||||
|
||||
def refresh(){
|
||||
sendCmdtoServer('{"system":{"get_sysinfo":{}}}', "deviceCommand", "commandResponse")
|
||||
}
|
||||
|
||||
def commandResponse(cmdResponse){
|
||||
if (cmdResponse.system.set_relay_state == null) {
|
||||
def status = cmdResponse.system.get_sysinfo.relay_state
|
||||
if (status == 1) {
|
||||
status = "on"
|
||||
} else {
|
||||
status = "off"
|
||||
}
|
||||
log.info "${device.name} ${device.label}: Power: ${status}"
|
||||
sendEvent(name: "switch", value: status)
|
||||
} else {
|
||||
refresh()
|
||||
}
|
||||
}
|
||||
|
||||
// ----- SEND COMMAND TO CLOUD VIA SM -----
|
||||
private sendCmdtoServer(command, hubCommand, action) {
|
||||
if (state.installType == "Hub") {
|
||||
sendCmdtoHub(command, hubCommand, action)
|
||||
} else {
|
||||
sendCmdtoCloud(command, hubCommand, action)
|
||||
}
|
||||
}
|
||||
|
||||
private sendCmdtoCloud(command, hubCommand, action){
|
||||
def appServerUrl = getDataValue("appServerUrl")
|
||||
def deviceId = getDataValue("deviceId")
|
||||
def cmdResponse = parent.sendDeviceCmd(appServerUrl, deviceId, command)
|
||||
String cmdResp = cmdResponse.toString()
|
||||
if (cmdResp.substring(0,5) == "ERROR"){
|
||||
def errMsg = cmdResp.substring(7,cmdResp.length())
|
||||
log.error "${device.name} ${device.label}: ${errMsg}"
|
||||
sendEvent(name: "switch", value: "commsError", descriptionText: errMsg)
|
||||
sendEvent(name: "deviceError", value: errMsg)
|
||||
action = ""
|
||||
} else {
|
||||
sendEvent(name: "deviceError", value: "OK")
|
||||
}
|
||||
actionDirector(action, cmdResponse)
|
||||
}
|
||||
|
||||
private sendCmdtoHub(command, hubCommand, action){
|
||||
def headers = [:]
|
||||
headers.put("HOST", "$gatewayIP:8082") // Same as on Hub.
|
||||
headers.put("tplink-iot-ip", deviceIP)
|
||||
headers.put("tplink-command", command)
|
||||
headers.put("action", action)
|
||||
headers.put("command", hubCommand)
|
||||
sendHubCommand(new physicalgraph.device.HubAction([
|
||||
headers: headers],
|
||||
device.deviceNetworkId,
|
||||
[callback: hubResponseParse]
|
||||
))
|
||||
}
|
||||
|
||||
def hubResponseParse(response) {
|
||||
def action = response.headers["action"]
|
||||
def cmdResponse = parseJson(response.headers["cmd-response"])
|
||||
if (cmdResponse == "TcpTimeout") {
|
||||
log.error "$device.name $device.label: Communications Error"
|
||||
sendEvent(name: "switch", value: "offline", descriptionText: "ERROR at hubResponseParse TCP Timeout")
|
||||
sendEvent(name: "deviceError", value: "TCP Timeout in Hub")
|
||||
} else {
|
||||
actionDirector(action, cmdResponse)
|
||||
sendEvent(name: "deviceError", value: "OK")
|
||||
}
|
||||
}
|
||||
|
||||
def actionDirector(action, cmdResponse) {
|
||||
switch(action) {
|
||||
case "commandResponse":
|
||||
commandResponse(cmdResponse)
|
||||
break
|
||||
|
||||
default:
|
||||
log.debug "at default"
|
||||
}
|
||||
}
|
||||
|
||||
// ----- CHILD / PARENT INTERCHANGE TASKS -----
|
||||
def syncAppServerUrl(newAppServerUrl) {
|
||||
updateDataValue("appServerUrl", newAppServerUrl)
|
||||
log.info "Updated appServerUrl for ${device.name} ${device.label}"
|
||||
}
|
||||
Reference in New Issue
Block a user