mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-20 13:20:53 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb3d2d001d | ||
|
|
a4ebe87f4e | ||
|
|
f84e21d83a | ||
|
|
85175eb298 | ||
|
|
c75568bcf1 | ||
|
|
edc98e4840 | ||
|
|
fb2c2cb2a7 | ||
|
|
62aeb0533d | ||
|
|
fb6cbcc35e | ||
|
|
097584944e | ||
|
|
01fae3dcd4 | ||
|
|
6c125fe80f | ||
|
|
5728f08770 | ||
|
|
f073df0a57 | ||
|
|
9263107f0e | ||
|
|
6c5b93da87 |
@@ -45,7 +45,16 @@ metadata {
|
|||||||
valueTile("temperature", "device.temperature", width: 2, height: 2) {
|
valueTile("temperature", "device.temperature", width: 2, height: 2) {
|
||||||
state("temperature", label:'${currentValue}°', unit:"F",
|
state("temperature", label:'${currentValue}°', unit:"F",
|
||||||
backgroundColors:[
|
backgroundColors:[
|
||||||
[value: 31, color: "#153591"],
|
// Celsius
|
||||||
|
[value: 0, color: "#153591"],
|
||||||
|
[value: 7, color: "#1e9cbb"],
|
||||||
|
[value: 15, color: "#90d2a7"],
|
||||||
|
[value: 23, color: "#44b621"],
|
||||||
|
[value: 28, color: "#f1d801"],
|
||||||
|
[value: 35, color: "#d04e00"],
|
||||||
|
[value: 37, color: "#bc2323"],
|
||||||
|
// Fahrenheit
|
||||||
|
[value: 40, color: "#153591"],
|
||||||
[value: 44, color: "#1e9cbb"],
|
[value: 44, color: "#1e9cbb"],
|
||||||
[value: 59, color: "#90d2a7"],
|
[value: 59, color: "#90d2a7"],
|
||||||
[value: 74, color: "#44b621"],
|
[value: 74, color: "#44b621"],
|
||||||
@@ -103,7 +112,7 @@ metadata {
|
|||||||
state "humidity", label:'${currentValue}%'
|
state "humidity", label:'${currentValue}%'
|
||||||
}
|
}
|
||||||
main "temperature"
|
main "temperature"
|
||||||
details(["temperature", "upButtonControl", "thermostatSetpoint", "currentStatus", "downButtonControl", "mode", "fanMode","resumeProgram", "humidity", "refresh"])
|
details(["temperature", "upButtonControl", "thermostatSetpoint", "currentStatus", "downButtonControl", "mode", "fanMode","humidity", "resumeProgram", "refresh"])
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences {
|
preferences {
|
||||||
@@ -204,11 +213,11 @@ private getThermostatDescriptionText(name, value, linkText) {
|
|||||||
|
|
||||||
void setHeatingSetpoint(setpoint) {
|
void setHeatingSetpoint(setpoint) {
|
||||||
log.debug "***heating setpoint $setpoint"
|
log.debug "***heating setpoint $setpoint"
|
||||||
def heatingSetpoint = setpoint.toDouble()
|
def heatingSetpoint = setpoint
|
||||||
def coolingSetpoint = device.currentValue("coolingSetpoint").toDouble()
|
def coolingSetpoint = device.currentValue("coolingSetpoint")
|
||||||
def deviceId = device.deviceNetworkId.split(/\./).last()
|
def deviceId = device.deviceNetworkId.split(/\./).last()
|
||||||
def maxHeatingSetpoint = device.currentValue("maxHeatingSetpoint").toDouble()
|
def maxHeatingSetpoint = device.currentValue("maxHeatingSetpoint")
|
||||||
def minHeatingSetpoint = device.currentValue("minHeatingSetpoint").toDouble()
|
def minHeatingSetpoint = device.currentValue("minHeatingSetpoint")
|
||||||
|
|
||||||
//enforce limits of heatingSetpoint
|
//enforce limits of heatingSetpoint
|
||||||
if (heatingSetpoint > maxHeatingSetpoint) {
|
if (heatingSetpoint > maxHeatingSetpoint) {
|
||||||
@@ -241,11 +250,11 @@ void setHeatingSetpoint(setpoint) {
|
|||||||
|
|
||||||
void setCoolingSetpoint(setpoint) {
|
void setCoolingSetpoint(setpoint) {
|
||||||
log.debug "***cooling setpoint $setpoint"
|
log.debug "***cooling setpoint $setpoint"
|
||||||
def heatingSetpoint = device.currentValue("heatingSetpoint").toDouble()
|
def heatingSetpoint = device.currentValue("heatingSetpoint")
|
||||||
def coolingSetpoint = setpoint.toDouble()
|
def coolingSetpoint = setpoint
|
||||||
def deviceId = device.deviceNetworkId.split(/\./).last()
|
def deviceId = device.deviceNetworkId.split(/\./).last()
|
||||||
def maxCoolingSetpoint = device.currentValue("maxCoolingSetpoint").toDouble()
|
def maxCoolingSetpoint = device.currentValue("maxCoolingSetpoint")
|
||||||
def minCoolingSetpoint = device.currentValue("minCoolingSetpoint").toDouble()
|
def minCoolingSetpoint = device.currentValue("minCoolingSetpoint")
|
||||||
|
|
||||||
|
|
||||||
if (coolingSetpoint > maxCoolingSetpoint) {
|
if (coolingSetpoint > maxCoolingSetpoint) {
|
||||||
@@ -421,6 +430,10 @@ def heat() {
|
|||||||
generateStatusEvent()
|
generateStatusEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def emergencyHeat() {
|
||||||
|
auxHeatOnly()
|
||||||
|
}
|
||||||
|
|
||||||
def auxHeatOnly() {
|
def auxHeatOnly() {
|
||||||
log.debug "auxHeatOnly"
|
log.debug "auxHeatOnly"
|
||||||
def deviceId = device.deviceNetworkId.split(/\./).last()
|
def deviceId = device.deviceNetworkId.split(/\./).last()
|
||||||
@@ -505,9 +518,6 @@ def fanAuto() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generateSetpointEvent() {
|
def generateSetpointEvent() {
|
||||||
|
|
||||||
log.debug "Generate SetPoint Event"
|
log.debug "Generate SetPoint Event"
|
||||||
@@ -536,6 +546,7 @@ def generateSetpointEvent() {
|
|||||||
coolingSetpoint = roundC(coolingSetpoint)
|
coolingSetpoint = roundC(coolingSetpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sendEvent("name":"maxHeatingSetpoint", "value":maxHeatingSetpoint, "unit":location.temperatureScale)
|
sendEvent("name":"maxHeatingSetpoint", "value":maxHeatingSetpoint, "unit":location.temperatureScale)
|
||||||
sendEvent("name":"maxCoolingSetpoint", "value":maxCoolingSetpoint, "unit":location.temperatureScale)
|
sendEvent("name":"maxCoolingSetpoint", "value":maxCoolingSetpoint, "unit":location.temperatureScale)
|
||||||
sendEvent("name":"minHeatingSetpoint", "value":minHeatingSetpoint, "unit":location.temperatureScale)
|
sendEvent("name":"minHeatingSetpoint", "value":minHeatingSetpoint, "unit":location.temperatureScale)
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ metadata {
|
|||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305"
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325"
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326"
|
||||||
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326-L", deviceJoinName: "Iris Motion Sensor"
|
||||||
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "motionv4", deviceJoinName: "Motion Sensor"
|
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "motionv4", deviceJoinName: "Motion Sensor"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,18 @@
|
|||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "SmartSense Open/Closed Sensor", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "SmartSense Open/Closed Sensor", namespace: "smartthings", author: "SmartThings") {
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Contact Sensor"
|
capability "Contact Sensor"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
|
|
||||||
command "enrollResponse"
|
command "enrollResponse"
|
||||||
|
|
||||||
|
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300-S"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300-S"
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3300"
|
||||||
|
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3320-L", deviceJoinName: "Iris Contact Sensor"
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ metadata {
|
|||||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702"
|
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702"
|
||||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "0003, 000A, 0019", manufacturer: "Jasco Products", model: "45853", deviceJoinName: "GE ZigBee Plug-In Switch"
|
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "0003, 000A, 0019", manufacturer: "Jasco Products", model: "45853", deviceJoinName: "GE ZigBee Plug-In Switch"
|
||||||
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "000A, 0019", manufacturer: "Jasco Products", model: "45856", deviceJoinName: "GE ZigBee In-Wall Switch"
|
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702, 0B05", outClusters: "000A, 0019", manufacturer: "Jasco Products", model: "45856", deviceJoinName: "GE ZigBee In-Wall Switch"
|
||||||
|
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 000F, 0B04", outClusters: "0019", manufacturer: "SmartThings", model: "outletv4", deviceJoinName: "Outlet"
|
||||||
}
|
}
|
||||||
|
|
||||||
tiles(scale: 2) {
|
tiles(scale: 2) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -257,21 +257,16 @@ def getEcobeeThermostats() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug "http status: ${resp.status}"
|
log.debug "http status: ${resp.status}"
|
||||||
//refresh the auth token
|
|
||||||
if (resp.data.status.code == 14) {
|
|
||||||
log.debug "Storing the failed action to try later"
|
|
||||||
atomicState.action = "getEcobeeThermostats"
|
|
||||||
log.debug "Refreshing your auth_token!"
|
|
||||||
refreshAuthToken()
|
|
||||||
} else {
|
|
||||||
log.error "Authentication error, invalid authentication method, lack of credentials, etc."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch (groovyx.net.http.HttpResponseException e) {
|
||||||
log.debug "___exception getEcobeeThermostats(): " + e
|
log.trace "Exception polling children: " + e.response.data.status
|
||||||
refreshAuthToken()
|
if (e.response.data.status.code == 14) {
|
||||||
}
|
atomicState.action = "getEcobeeThermostats"
|
||||||
|
log.debug "Refreshing your auth_token!"
|
||||||
|
refreshAuthToken()
|
||||||
|
}
|
||||||
|
}
|
||||||
atomicState.thermostats = stats
|
atomicState.thermostats = stats
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
@@ -450,23 +445,15 @@ def pollChildren(child = null) {
|
|||||||
}
|
}
|
||||||
result = true
|
result = true
|
||||||
log.debug "updated ${atomicState.thermostats?.size()} stats: ${atomicState.thermostats}"
|
log.debug "updated ${atomicState.thermostats?.size()} stats: ${atomicState.thermostats}"
|
||||||
} else {
|
|
||||||
log.error "polling children & got http status ${resp.status}"
|
|
||||||
|
|
||||||
//refresh the auth token
|
|
||||||
if (resp.data.status.code == 14) {
|
|
||||||
atomicState.action = "pollChildren"
|
|
||||||
log.debug "Refreshing your auth_token!"
|
|
||||||
refreshAuthToken()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.error "Authentication error, invalid authentication method, lack of credentials, etc."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch (groovyx.net.http.HttpResponseException e) {
|
||||||
log.debug "___exception polling children: " + e
|
log.trace "Exception polling children: " + e.response.data.status
|
||||||
refreshAuthToken()
|
if (e.response.data.status.code == 14) {
|
||||||
|
atomicState.action = "pollChildren"
|
||||||
|
log.debug "Refreshing your auth_token!"
|
||||||
|
refreshAuthToken()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -642,16 +629,14 @@ private refreshAuthToken() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
atomicState.action = ""
|
atomicState.action = ""
|
||||||
} else {
|
|
||||||
log.debug "refresh failed ${resp.status} : ${resp.status.code}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (groovyx.net.http.HttpResponseException e) {
|
} catch (groovyx.net.http.HttpResponseException e) {
|
||||||
log.error "refreshAuthToken() >> Error: e.statusCode ${e.statusCode}"
|
log.error "refreshAuthToken() >> Error: e.statusCode ${e.statusCode}"
|
||||||
def reAttemptPeriod = 300 // in sec
|
def reAttemptPeriod = 300 // in sec
|
||||||
if (e.statusCode != 401) { //this issue might comes from exceed 20sec app execution, connectivity issue etc.
|
if (e.statusCode != 401) { // this issue might comes from exceed 20sec app execution, connectivity issue etc.
|
||||||
runIn(reAttemptPeriod, "refreshAuthToken")
|
runIn(reAttemptPeriod, "refreshAuthToken")
|
||||||
} else if (e.statusCode == 401) { //refresh token is expired
|
} else if (e.statusCode == 401) { // unauthorized
|
||||||
atomicState.reAttempt = atomicState.reAttempt + 1
|
atomicState.reAttempt = atomicState.reAttempt + 1
|
||||||
log.warn "reAttempt refreshAuthToken to try = ${atomicState.reAttempt}"
|
log.warn "reAttempt refreshAuthToken to try = ${atomicState.reAttempt}"
|
||||||
if (atomicState.reAttempt <= 3) {
|
if (atomicState.reAttempt <= 3) {
|
||||||
@@ -724,29 +709,21 @@ def sendJson(child = null, String jsonBody) {
|
|||||||
log.debug "Error return code = ${resp.data.status.code}"
|
log.debug "Error return code = ${resp.data.status.code}"
|
||||||
debugEvent("Error return code = ${resp.data.status.code}")
|
debugEvent("Error return code = ${resp.data.status.code}")
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.error "sent Json & got http status ${resp.status} - ${resp.status.code}"
|
|
||||||
debugEvent ("sent Json & got http status ${resp.status} - ${resp.status.code}")
|
|
||||||
|
|
||||||
//refresh the auth token
|
|
||||||
if (resp.status.code == 14) {
|
|
||||||
log.debug "Refreshing your auth_token!"
|
|
||||||
debugEvent ("Refreshing OAUTH Token")
|
|
||||||
refreshAuthToken()
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
debugEvent ("Authentication error, invalid authentication method, lack of credentials, etc.")
|
|
||||||
log.error "Authentication error, invalid authentication method, lack of credentials, etc."
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch (groovyx.net.http.HttpResponseException e) {
|
||||||
log.debug "Exception Sending Json: " + e
|
log.trace "Exception Sending Json: " + e.response.data.status
|
||||||
debugEvent ("Exception Sending JSON: " + e)
|
debugEvent ("sent Json & got http status ${e.statusCode} - ${e.response.data.status.code}")
|
||||||
refreshAuthToken()
|
if (e.response.data.status.code == 14) {
|
||||||
return false
|
atomicState.action = "pollChildren"
|
||||||
}
|
log.debug "Refreshing your auth_token!"
|
||||||
|
refreshAuthToken()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugEvent("Authentication error, invalid authentication method, lack of credentials, etc.")
|
||||||
|
log.error "Authentication error, invalid authentication method, lack of credentials, etc."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (returnStatus == 0)
|
if (returnStatus == 0)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -16,14 +16,14 @@
|
|||||||
* Date: 2013-09-06
|
* Date: 2013-09-06
|
||||||
*/
|
*/
|
||||||
definition(
|
definition(
|
||||||
name: "Wemo (Connect)",
|
name: "Wemo (Connect)",
|
||||||
namespace: "smartthings",
|
namespace: "smartthings",
|
||||||
author: "SmartThings",
|
author: "SmartThings",
|
||||||
description: "Allows you to integrate your WeMo Switch and Wemo Motion sensor with SmartThings.",
|
description: "Allows you to integrate your WeMo Switch and Wemo Motion sensor with SmartThings.",
|
||||||
category: "SmartThings Labs",
|
category: "SmartThings Labs",
|
||||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/wemo.png",
|
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/wemo.png",
|
||||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/wemo@2x.png",
|
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/wemo@2x.png",
|
||||||
singleInstance: true
|
singleInstance: true
|
||||||
)
|
)
|
||||||
|
|
||||||
preferences {
|
preferences {
|
||||||
@@ -39,7 +39,7 @@ private getFriendlyName(String deviceNetworkId) {
|
|||||||
sendHubCommand(new physicalgraph.device.HubAction("""GET /setup.xml HTTP/1.1
|
sendHubCommand(new physicalgraph.device.HubAction("""GET /setup.xml HTTP/1.1
|
||||||
HOST: ${deviceNetworkId}
|
HOST: ${deviceNetworkId}
|
||||||
|
|
||||||
""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))
|
""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}", [callback: "setupHandler"]))
|
||||||
}
|
}
|
||||||
|
|
||||||
private verifyDevices() {
|
private verifyDevices() {
|
||||||
@@ -52,6 +52,13 @@ private verifyDevices() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ssdpSubscribe() {
|
||||||
|
subscribe(location, "ssdpTerm.urn:Belkin:device:insight:1", ssdpSwitchHandler)
|
||||||
|
subscribe(location, "ssdpTerm.urn:Belkin:device:controllee:1", ssdpSwitchHandler)
|
||||||
|
subscribe(location, "ssdpTerm.urn:Belkin:device:sensor:1", ssdpMotionHandler)
|
||||||
|
subscribe(location, "ssdpTerm.urn:Belkin:device:lightswitch:1", ssdpLightSwitchHandler)
|
||||||
|
}
|
||||||
|
|
||||||
def firstPage()
|
def firstPage()
|
||||||
{
|
{
|
||||||
if(canInstallLabs())
|
if(canInstallLabs())
|
||||||
@@ -62,7 +69,7 @@ def firstPage()
|
|||||||
|
|
||||||
log.debug "REFRESH COUNT :: ${refreshCount}"
|
log.debug "REFRESH COUNT :: ${refreshCount}"
|
||||||
|
|
||||||
subscribe(location, null, locationHandler, [filterEvents:false])
|
ssdpSubscribe()
|
||||||
|
|
||||||
//ssdp request every 25 seconds
|
//ssdp request every 25 seconds
|
||||||
if((refreshCount % 5) == 0) {
|
if((refreshCount % 5) == 0) {
|
||||||
@@ -105,9 +112,7 @@ def devicesDiscovered() {
|
|||||||
def motions = getWemoMotions()
|
def motions = getWemoMotions()
|
||||||
def lightSwitches = getWemoLightSwitches()
|
def lightSwitches = getWemoLightSwitches()
|
||||||
def devices = switches + motions + lightSwitches
|
def devices = switches + motions + lightSwitches
|
||||||
def list = []
|
devices?.collect{ [app.id, it.ssdpUSN].join('.') }
|
||||||
|
|
||||||
list = devices?.collect{ [app.id, it.ssdpUSN].join('.') }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def switchesDiscovered() {
|
def switchesDiscovered() {
|
||||||
@@ -175,8 +180,9 @@ def updated() {
|
|||||||
|
|
||||||
def initialize() {
|
def initialize() {
|
||||||
unsubscribe()
|
unsubscribe()
|
||||||
unschedule()
|
unschedule()
|
||||||
subscribe(location, null, locationHandler, [filterEvents:false])
|
|
||||||
|
ssdpSubscribe()
|
||||||
|
|
||||||
if (selectedSwitches)
|
if (selectedSwitches)
|
||||||
addSwitches()
|
addSwitches()
|
||||||
@@ -189,7 +195,7 @@ def initialize() {
|
|||||||
|
|
||||||
runIn(5, "subscribeToDevices") //initial subscriptions delayed by 5 seconds
|
runIn(5, "subscribeToDevices") //initial subscriptions delayed by 5 seconds
|
||||||
runIn(10, "refreshDevices") //refresh devices, delayed by 10 seconds
|
runIn(10, "refreshDevices") //refresh devices, delayed by 10 seconds
|
||||||
runEvery5Minutes("refresh")
|
runEvery5Minutes("refresh")
|
||||||
}
|
}
|
||||||
|
|
||||||
def resubscribe() {
|
def resubscribe() {
|
||||||
@@ -199,7 +205,7 @@ def resubscribe() {
|
|||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
log.debug "refresh() called"
|
log.debug "refresh() called"
|
||||||
doDeviceSync()
|
doDeviceSync()
|
||||||
refreshDevices()
|
refreshDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,14 +241,14 @@ def addSwitches() {
|
|||||||
if (!d) {
|
if (!d) {
|
||||||
log.debug "Creating WeMo Switch with dni: ${selectedSwitch.value.mac}"
|
log.debug "Creating WeMo Switch with dni: ${selectedSwitch.value.mac}"
|
||||||
d = addChildDevice("smartthings", "Wemo Switch", selectedSwitch.value.mac, selectedSwitch?.value.hub, [
|
d = addChildDevice("smartthings", "Wemo Switch", selectedSwitch.value.mac, selectedSwitch?.value.hub, [
|
||||||
"label": selectedSwitch?.value?.name ?: "Wemo Switch",
|
"label": selectedSwitch?.value?.name ?: "Wemo Switch",
|
||||||
"data": [
|
"data": [
|
||||||
"mac": selectedSwitch.value.mac,
|
"mac": selectedSwitch.value.mac,
|
||||||
"ip": selectedSwitch.value.ip,
|
"ip": selectedSwitch.value.ip,
|
||||||
"port": selectedSwitch.value.port
|
"port": selectedSwitch.value.port
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
def ipvalue = convertHexToIP(selectedSwitch.value.ip)
|
def ipvalue = convertHexToIP(selectedSwitch.value.ip)
|
||||||
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
||||||
} else {
|
} else {
|
||||||
@@ -273,9 +279,9 @@ def addMotions() {
|
|||||||
"port": selectedMotion.value.port
|
"port": selectedMotion.value.port
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
def ipvalue = convertHexToIP(selectedMotion.value.ip)
|
def ipvalue = convertHexToIP(selectedMotion.value.ip)
|
||||||
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
||||||
} else {
|
} else {
|
||||||
log.debug "found ${d.displayName} with id $dni already exists"
|
log.debug "found ${d.displayName} with id $dni already exists"
|
||||||
}
|
}
|
||||||
@@ -304,26 +310,147 @@ def addLightSwitches() {
|
|||||||
"port": selectedLightSwitch.value.port
|
"port": selectedLightSwitch.value.port
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
def ipvalue = convertHexToIP(selectedLightSwitch.value.ip)
|
def ipvalue = convertHexToIP(selectedLightSwitch.value.ip)
|
||||||
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
log.debug "created ${d.displayName} with id $dni"
|
log.debug "created ${d.displayName} with id $dni"
|
||||||
} else {
|
} else {
|
||||||
log.debug "found ${d.displayName} with id $dni already exists"
|
log.debug "found ${d.displayName} with id $dni already exists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def ssdpSwitchHandler(evt) {
|
||||||
|
def description = evt.description
|
||||||
|
def hub = evt?.hubId
|
||||||
|
def parsedEvent = parseDiscoveryMessage(description)
|
||||||
|
parsedEvent << ["hub":hub]
|
||||||
|
log.debug parsedEvent
|
||||||
|
|
||||||
|
def switches = getWemoSwitches()
|
||||||
|
if (!(switches."${parsedEvent.ssdpUSN.toString()}")) {
|
||||||
|
//if it doesn't already exist
|
||||||
|
switches << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
||||||
|
} else {
|
||||||
|
log.debug "Device was already found in state..."
|
||||||
|
def d = switches."${parsedEvent.ssdpUSN.toString()}"
|
||||||
|
boolean deviceChangedValues = false
|
||||||
|
log.debug "$d.ip <==> $parsedEvent.ip"
|
||||||
|
if(d.ip != parsedEvent.ip || d.port != parsedEvent.port) {
|
||||||
|
d.ip = parsedEvent.ip
|
||||||
|
d.port = parsedEvent.port
|
||||||
|
deviceChangedValues = true
|
||||||
|
log.debug "Device's port or ip changed..."
|
||||||
|
def child = getChildDevice(parsedEvent.mac)
|
||||||
|
child.subscribe(parsedEvent.ip, parsedEvent.port)
|
||||||
|
child.poll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def ssdpMotionHandler(evt) {
|
||||||
|
log.info("ssdpMotionHandler")
|
||||||
|
def description = evt.description
|
||||||
|
def hub = evt?.hubId
|
||||||
|
def parsedEvent = parseDiscoveryMessage(description)
|
||||||
|
parsedEvent << ["hub":hub]
|
||||||
|
log.debug parsedEvent
|
||||||
|
|
||||||
|
def motions = getWemoMotions()
|
||||||
|
if (!(motions."${parsedEvent.ssdpUSN.toString()}")) {
|
||||||
|
//if it doesn't already exist
|
||||||
|
motions << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
||||||
|
} else { // just update the values
|
||||||
|
log.debug "Device was already found in state..."
|
||||||
|
|
||||||
|
def d = motions."${parsedEvent.ssdpUSN.toString()}"
|
||||||
|
boolean deviceChangedValues = false
|
||||||
|
|
||||||
|
if(d.ip != parsedEvent.ip || d.port != parsedEvent.port) {
|
||||||
|
d.ip = parsedEvent.ip
|
||||||
|
d.port = parsedEvent.port
|
||||||
|
deviceChangedValues = true
|
||||||
|
log.debug "Device's port or ip changed..."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceChangedValues) {
|
||||||
|
def children = getChildDevices()
|
||||||
|
log.debug "Found children ${children}"
|
||||||
|
children.each {
|
||||||
|
if (it.getDeviceDataByName("mac") == parsedEvent.mac) {
|
||||||
|
log.debug "updating ip and port, and resubscribing, for device ${it} with mac ${parsedEvent.mac}"
|
||||||
|
it.subscribe(parsedEvent.ip, parsedEvent.port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def ssdpLightSwitchHandler(evt) {
|
||||||
|
log.info("ssdpLightSwitchHandler")
|
||||||
|
def description = evt.description
|
||||||
|
def hub = evt?.hubId
|
||||||
|
def parsedEvent = parseDiscoveryMessage(description)
|
||||||
|
parsedEvent << ["hub":hub]
|
||||||
|
log.debug parsedEvent
|
||||||
|
|
||||||
|
def lightSwitches = getWemoLightSwitches()
|
||||||
|
|
||||||
|
if (!(lightSwitches."${parsedEvent.ssdpUSN.toString()}")) {
|
||||||
|
//if it doesn't already exist
|
||||||
|
lightSwitches << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
||||||
|
} else {
|
||||||
|
log.debug "Device was already found in state..."
|
||||||
|
|
||||||
|
def d = lightSwitches."${parsedEvent.ssdpUSN.toString()}"
|
||||||
|
boolean deviceChangedValues = false
|
||||||
|
|
||||||
|
if(d.ip != parsedEvent.ip || d.port != parsedEvent.port) {
|
||||||
|
d.ip = parsedEvent.ip
|
||||||
|
d.port = parsedEvent.port
|
||||||
|
deviceChangedValues = true
|
||||||
|
log.debug "Device's port or ip changed..."
|
||||||
|
def child = getChildDevice(parsedEvent.mac)
|
||||||
|
log.debug "updating ip and port, and resubscribing, for device with mac ${parsedEvent.mac}"
|
||||||
|
child.subscribe(parsedEvent.ip, parsedEvent.port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupHandler(hubResponse) {
|
||||||
|
String contentType = hubResponse?.headers['Content-Type']
|
||||||
|
if (contentType != null && contentType == 'text/xml') {
|
||||||
|
def body = hubResponse.xml
|
||||||
|
def wemoDevices = []
|
||||||
|
String deviceType = body?.device?.deviceType?.text() ?: ""
|
||||||
|
if (deviceType.startsWith("urn:Belkin:device:controllee:1") || deviceType.startsWith("urn:Belkin:device:insight:1")) {
|
||||||
|
wemoDevices = getWemoSwitches()
|
||||||
|
} else if (deviceType.startsWith("urn:Belkin:device:sensor")) {
|
||||||
|
wemoDevices = getWemoMotions()
|
||||||
|
} else if (deviceType.startsWith("urn:Belkin:device:lightswitch")) {
|
||||||
|
wemoDevices = getWemoLightSwitches()
|
||||||
|
}
|
||||||
|
|
||||||
|
def wemoDevice = wemoDevices.find {it?.key?.contains(body?.device?.UDN?.text())}
|
||||||
|
if (wemoDevice) {
|
||||||
|
wemoDevice.value << [name:body?.device?.friendlyName?.text(), verified: true]
|
||||||
|
} else {
|
||||||
|
log.error "/setup.xml returned a wemo device that didn't exist"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
def locationHandler(evt) {
|
def locationHandler(evt) {
|
||||||
def description = evt.description
|
def description = evt.description
|
||||||
def hub = evt?.hubId
|
def hub = evt?.hubId
|
||||||
def parsedEvent = parseDiscoveryMessage(description)
|
def parsedEvent = parseDiscoveryMessage(description)
|
||||||
parsedEvent << ["hub":hub]
|
parsedEvent << ["hub":hub]
|
||||||
log.debug parsedEvent
|
log.debug parsedEvent
|
||||||
|
|
||||||
if (parsedEvent?.ssdpTerm?.contains("Belkin:device:controllee") || parsedEvent?.ssdpTerm?.contains("Belkin:device:insight")) {
|
if (parsedEvent?.ssdpTerm?.contains("Belkin:device:controllee") || parsedEvent?.ssdpTerm?.contains("Belkin:device:insight")) {
|
||||||
def switches = getWemoSwitches()
|
def switches = getWemoSwitches()
|
||||||
if (!(switches."${parsedEvent.ssdpUSN.toString()}")) {
|
if (!(switches."${parsedEvent.ssdpUSN.toString()}")) {
|
||||||
//if it doesn't already exist
|
//if it doesn't already exist
|
||||||
switches << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
switches << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
||||||
} else {
|
} else {
|
||||||
log.debug "Device was already found in state..."
|
log.debug "Device was already found in state..."
|
||||||
@@ -335,16 +462,16 @@ def locationHandler(evt) {
|
|||||||
d.port = parsedEvent.port
|
d.port = parsedEvent.port
|
||||||
deviceChangedValues = true
|
deviceChangedValues = true
|
||||||
log.debug "Device's port or ip changed..."
|
log.debug "Device's port or ip changed..."
|
||||||
def child = getChildDevice(parsedEvent.mac)
|
def child = getChildDevice(parsedEvent.mac)
|
||||||
child.subscribe(parsedEvent.ip, parsedEvent.port)
|
child.subscribe(parsedEvent.ip, parsedEvent.port)
|
||||||
child.poll()
|
child.poll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (parsedEvent?.ssdpTerm?.contains("Belkin:device:sensor")) {
|
else if (parsedEvent?.ssdpTerm?.contains("Belkin:device:sensor")) {
|
||||||
def motions = getWemoMotions()
|
def motions = getWemoMotions()
|
||||||
if (!(motions."${parsedEvent.ssdpUSN.toString()}")) {
|
if (!(motions."${parsedEvent.ssdpUSN.toString()}")) {
|
||||||
//if it doesn't already exist
|
//if it doesn't already exist
|
||||||
motions << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
motions << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
||||||
} else { // just update the values
|
} else { // just update the values
|
||||||
log.debug "Device was already found in state..."
|
log.debug "Device was already found in state..."
|
||||||
@@ -459,6 +586,7 @@ def locationHandler(evt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
private def parseXmlBody(def body) {
|
private def parseXmlBody(def body) {
|
||||||
def decodedBytes = body.decodeBase64()
|
def decodedBytes = body.decodeBase64()
|
||||||
def bodyString
|
def bodyString
|
||||||
|
|||||||
Reference in New Issue
Block a user