mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-04-12 14:23:07 +01:00
Merge pull request #239 from juano2310/WEMO_FFinal4
DVCSMP-1189: Wemo refactor final
This commit is contained in:
@@ -25,6 +25,8 @@ metadata {
|
|||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
|
||||||
|
attribute "currentIP", "string"
|
||||||
|
|
||||||
command "subscribe"
|
command "subscribe"
|
||||||
command "resubscribe"
|
command "resubscribe"
|
||||||
command "unsubscribe"
|
command "unsubscribe"
|
||||||
@@ -34,21 +36,36 @@ metadata {
|
|||||||
// simulator metadata
|
// simulator metadata
|
||||||
simulator {}
|
simulator {}
|
||||||
|
|
||||||
// UI tile definitions
|
// UI tile definitions
|
||||||
tiles {
|
tiles(scale: 2) {
|
||||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
multiAttributeTile(name:"rich-control", type: "switch", canChangeIcon: true){
|
||||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||||
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
state "turningOn", label:'${name}', icon:"st.switches.switch.on", backgroundColor:"#79b821"
|
attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
state "turningOff", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ffffff"
|
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
}
|
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
attributeState "offline", label:'${name}', icon:"st.Home.home30", backgroundColor:"#ff0000"
|
||||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
}
|
||||||
}
|
tileAttribute ("currentIP", key: "SECONDARY_CONTROL") {
|
||||||
|
attributeState "currentIP", label: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
main "switch"
|
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||||
details (["switch", "refresh"])
|
state "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
}
|
state "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
|
state "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
|
state "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
|
state "offline", label:'${name}', icon:"st.Home.home30", backgroundColor:"#ff0000"
|
||||||
|
}
|
||||||
|
|
||||||
|
standardTile("refresh", "device.switch", inactiveLabel: false, height: 2, width: 2, decoration: "flat") {
|
||||||
|
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||||
|
}
|
||||||
|
|
||||||
|
main(["switch"])
|
||||||
|
details(["rich-control", "refresh"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse events into attributes
|
// parse events into attributes
|
||||||
@@ -68,6 +85,7 @@ def parse(String description) {
|
|||||||
def result = []
|
def result = []
|
||||||
def bodyString = msg.body
|
def bodyString = msg.body
|
||||||
if (bodyString) {
|
if (bodyString) {
|
||||||
|
unschedule("setOffline")
|
||||||
def body = new XmlSlurper().parseText(bodyString)
|
def body = new XmlSlurper().parseText(bodyString)
|
||||||
|
|
||||||
if (body?.property?.TimeSyncRequest?.text()) {
|
if (body?.property?.TimeSyncRequest?.text()) {
|
||||||
@@ -78,13 +96,14 @@ def parse(String description) {
|
|||||||
} else if (body?.property?.BinaryState?.text()) {
|
} else if (body?.property?.BinaryState?.text()) {
|
||||||
def value = body?.property?.BinaryState?.text().toInteger() == 1 ? "on" : "off"
|
def value = body?.property?.BinaryState?.text().toInteger() == 1 ? "on" : "off"
|
||||||
log.trace "Notify: BinaryState = ${value}"
|
log.trace "Notify: BinaryState = ${value}"
|
||||||
result << createEvent(name: "switch", value: value)
|
result << createEvent(name: "switch", value: value, descriptionText: "Switch is ${value}")
|
||||||
} else if (body?.property?.TimeZoneNotification?.text()) {
|
} else if (body?.property?.TimeZoneNotification?.text()) {
|
||||||
log.debug "Notify: TimeZoneNotification = ${body?.property?.TimeZoneNotification?.text()}"
|
log.debug "Notify: TimeZoneNotification = ${body?.property?.TimeZoneNotification?.text()}"
|
||||||
} else if (body?.Body?.GetBinaryStateResponse?.BinaryState?.text()) {
|
} else if (body?.Body?.GetBinaryStateResponse?.BinaryState?.text()) {
|
||||||
def value = body?.Body?.GetBinaryStateResponse?.BinaryState?.text().toInteger() == 1 ? "on" : "off"
|
def value = body?.Body?.GetBinaryStateResponse?.BinaryState?.text().toInteger() == 1 ? "on" : "off"
|
||||||
log.trace "GetBinaryResponse: BinaryState = ${value}"
|
log.trace "GetBinaryResponse: BinaryState = ${value}"
|
||||||
result << createEvent(name: "switch", value: value)
|
def dispaux = device.currentValue("switch") != value
|
||||||
|
result << createEvent(name: "switch", value: value, descriptionText: "Switch is ${value}", displayed: dispaux)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,14 +120,6 @@ private getCallBackAddress() {
|
|||||||
device.hub.getDataValue("localIP") + ":" + device.hub.getDataValue("localSrvPortTCP")
|
device.hub.getDataValue("localIP") + ":" + device.hub.getDataValue("localSrvPortTCP")
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer convertHexToInt(hex) {
|
|
||||||
Integer.parseInt(hex,16)
|
|
||||||
}
|
|
||||||
|
|
||||||
private String convertHexToIP(hex) {
|
|
||||||
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
|
||||||
}
|
|
||||||
|
|
||||||
private getHostAddress() {
|
private getHostAddress() {
|
||||||
def ip = getDataValue("ip")
|
def ip = getDataValue("ip")
|
||||||
def port = getDataValue("port")
|
def port = getDataValue("port")
|
||||||
@@ -195,6 +206,8 @@ def subscribe(ip, port) {
|
|||||||
if (ip && ip != existingIp) {
|
if (ip && ip != existingIp) {
|
||||||
log.debug "Updating ip from $existingIp to $ip"
|
log.debug "Updating ip from $existingIp to $ip"
|
||||||
updateDataValue("ip", ip)
|
updateDataValue("ip", ip)
|
||||||
|
def ipvalue = convertHexToIP(getDataValue("ip"))
|
||||||
|
sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP changed to ${ipvalue}")
|
||||||
}
|
}
|
||||||
if (port && port != existingPort) {
|
if (port && port != existingPort) {
|
||||||
log.debug "Updating port from $existingPort to $port"
|
log.debug "Updating port from $existingPort to $port"
|
||||||
@@ -259,6 +272,8 @@ User-Agent: CyberGarage-HTTP/1.0
|
|||||||
|
|
||||||
def poll() {
|
def poll() {
|
||||||
log.debug "Executing 'poll'"
|
log.debug "Executing 'poll'"
|
||||||
|
if (device.currentValue("currentIP") != "Offline")
|
||||||
|
runIn(10, setOffline)
|
||||||
new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
||||||
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
|
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
|
||||||
Content-Length: 277
|
Content-Length: 277
|
||||||
@@ -274,3 +289,15 @@ User-Agent: CyberGarage-HTTP/1.0
|
|||||||
</s:Body>
|
</s:Body>
|
||||||
</s:Envelope>""", physicalgraph.device.Protocol.LAN)
|
</s:Envelope>""", physicalgraph.device.Protocol.LAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def setOffline() {
|
||||||
|
sendEvent(name: "switch", value: "offline", descriptionText: "The device is offline")
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer convertHexToInt(hex) {
|
||||||
|
Integer.parseInt(hex,16)
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertHexToIP(hex) {
|
||||||
|
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
|
||||||
|
attribute "currentIP", "string"
|
||||||
|
|
||||||
command "subscribe"
|
command "subscribe"
|
||||||
command "resubscribe"
|
command "resubscribe"
|
||||||
command "unsubscribe"
|
command "unsubscribe"
|
||||||
@@ -31,17 +33,30 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UI tile definitions
|
// UI tile definitions
|
||||||
tiles {
|
tiles(scale: 2) {
|
||||||
|
multiAttributeTile(name:"rich-control", type: "motion", canChangeIcon: true){
|
||||||
|
tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
|
||||||
|
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
|
||||||
|
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
|
||||||
|
attributeState "offline", label:'${name}', icon:"st.motion.motion.active", backgroundColor:"#ff0000"
|
||||||
|
}
|
||||||
|
tileAttribute ("currentIP", key: "SECONDARY_CONTROL") {
|
||||||
|
attributeState "currentIP", label: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
standardTile("motion", "device.motion", width: 2, height: 2) {
|
standardTile("motion", "device.motion", width: 2, height: 2) {
|
||||||
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
|
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
|
||||||
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
|
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
|
||||||
}
|
state("offline", label:'${name}', icon:"st.motion.motion.inactive", backgroundColor:"#ff0000")
|
||||||
standardTile("refresh", "device.motion", inactiveLabel: false, decoration: "flat") {
|
|
||||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
standardTile("refresh", "device.switch", inactiveLabel: false, height: 2, width: 2, decoration: "flat") {
|
||||||
|
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||||
|
}
|
||||||
|
|
||||||
main "motion"
|
main "motion"
|
||||||
details (["motion", "refresh"])
|
details (["rich-control", "refresh"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +77,7 @@ def parse(String description) {
|
|||||||
def result = []
|
def result = []
|
||||||
def bodyString = msg.body
|
def bodyString = msg.body
|
||||||
if (bodyString) {
|
if (bodyString) {
|
||||||
|
unschedule("setOffline")
|
||||||
def body = new XmlSlurper().parseText(bodyString)
|
def body = new XmlSlurper().parseText(bodyString)
|
||||||
|
|
||||||
if (body?.property?.TimeSyncRequest?.text()) {
|
if (body?.property?.TimeSyncRequest?.text()) {
|
||||||
@@ -72,7 +88,7 @@ def parse(String description) {
|
|||||||
} else if (body?.property?.BinaryState?.text()) {
|
} else if (body?.property?.BinaryState?.text()) {
|
||||||
def value = body?.property?.BinaryState?.text().toInteger() == 1 ? "active" : "inactive"
|
def value = body?.property?.BinaryState?.text().toInteger() == 1 ? "active" : "inactive"
|
||||||
log.debug "Notify - BinaryState = ${value}"
|
log.debug "Notify - BinaryState = ${value}"
|
||||||
result << createEvent(name: "motion", value: value)
|
result << createEvent(name: "motion", value: value, descriptionText: "Motion is ${value}")
|
||||||
} else if (body?.property?.TimeZoneNotification?.text()) {
|
} else if (body?.property?.TimeZoneNotification?.text()) {
|
||||||
log.debug "Notify: TimeZoneNotification = ${body?.property?.TimeZoneNotification?.text()}"
|
log.debug "Notify: TimeZoneNotification = ${body?.property?.TimeZoneNotification?.text()}"
|
||||||
}
|
}
|
||||||
@@ -91,14 +107,6 @@ private getCallBackAddress() {
|
|||||||
device.hub.getDataValue("localIP") + ":" + device.hub.getDataValue("localSrvPortTCP")
|
device.hub.getDataValue("localIP") + ":" + device.hub.getDataValue("localSrvPortTCP")
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer convertHexToInt(hex) {
|
|
||||||
Integer.parseInt(hex,16)
|
|
||||||
}
|
|
||||||
|
|
||||||
private String convertHexToIP(hex) {
|
|
||||||
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
|
||||||
}
|
|
||||||
|
|
||||||
private getHostAddress() {
|
private getHostAddress() {
|
||||||
def ip = getDataValue("ip")
|
def ip = getDataValue("ip")
|
||||||
def port = getDataValue("port")
|
def port = getDataValue("port")
|
||||||
@@ -125,6 +133,8 @@ def refresh() {
|
|||||||
////////////////////////////
|
////////////////////////////
|
||||||
def getStatus() {
|
def getStatus() {
|
||||||
log.debug "Executing WeMo Motion 'getStatus'"
|
log.debug "Executing WeMo Motion 'getStatus'"
|
||||||
|
if (device.currentValue("currentIP") != "Offline")
|
||||||
|
runIn(10, setOffline)
|
||||||
new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
||||||
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
|
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
|
||||||
Content-Length: 277
|
Content-Length: 277
|
||||||
@@ -165,7 +175,9 @@ def subscribe(ip, port) {
|
|||||||
def existingPort = getDataValue("port")
|
def existingPort = getDataValue("port")
|
||||||
if (ip && ip != existingIp) {
|
if (ip && ip != existingIp) {
|
||||||
log.debug "Updating ip from $existingIp to $ip"
|
log.debug "Updating ip from $existingIp to $ip"
|
||||||
updateDataValue("ip", ip)
|
updateDataValue("ip", ip)
|
||||||
|
def ipvalue = convertHexToIP(getDataValue("ip"))
|
||||||
|
sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP changed to ${ipvalue}")
|
||||||
}
|
}
|
||||||
if (port && port != existingPort) {
|
if (port && port != existingPort) {
|
||||||
log.debug "Updating port from $existingPort to $port"
|
log.debug "Updating port from $existingPort to $port"
|
||||||
@@ -226,3 +238,15 @@ User-Agent: CyberGarage-HTTP/1.0
|
|||||||
</s:Envelope>
|
</s:Envelope>
|
||||||
""", physicalgraph.device.Protocol.LAN)
|
""", physicalgraph.device.Protocol.LAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def setOffline() {
|
||||||
|
sendEvent(name: "motion", value: "offline", descriptionText: "The device is offline")
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer convertHexToInt(hex) {
|
||||||
|
Integer.parseInt(hex,16)
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertHexToIP(hex) {
|
||||||
|
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,120 +10,142 @@
|
|||||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
* 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.
|
* for the specific language governing permissions and limitations under the License.
|
||||||
*
|
*
|
||||||
* Wemo Switch
|
* Wemo Switch
|
||||||
*
|
*
|
||||||
* Author: superuser
|
* Author: Juan Risso (SmartThings)
|
||||||
* Date: 2013-10-11
|
* Date: 2015-10-11
|
||||||
*/
|
*/
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Wemo Switch", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Wemo Switch", namespace: "smartthings", author: "SmartThings") {
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Polling"
|
capability "Polling"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
|
|
||||||
command "subscribe"
|
attribute "currentIP", "string"
|
||||||
command "resubscribe"
|
|
||||||
command "unsubscribe"
|
|
||||||
}
|
|
||||||
|
|
||||||
// simulator metadata
|
command "subscribe"
|
||||||
simulator {}
|
command "resubscribe"
|
||||||
|
command "unsubscribe"
|
||||||
|
}
|
||||||
|
|
||||||
// UI tile definitions
|
// simulator metadata
|
||||||
tiles {
|
simulator {}
|
||||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
|
||||||
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821"
|
|
||||||
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff"
|
|
||||||
}
|
|
||||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
|
|
||||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "switch"
|
// UI tile definitions
|
||||||
details (["switch", "refresh"])
|
tiles(scale: 2) {
|
||||||
}
|
multiAttributeTile(name:"rich-control", type: "switch", canChangeIcon: true){
|
||||||
|
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||||
|
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
|
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
|
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
|
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
|
attributeState "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ff0000"
|
||||||
|
}
|
||||||
|
tileAttribute ("currentIP", key: "SECONDARY_CONTROL") {
|
||||||
|
attributeState "currentIP", label: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||||
|
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
|
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
|
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.off", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
|
state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.on", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
|
state "offline", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ff0000"
|
||||||
|
}
|
||||||
|
|
||||||
|
standardTile("refresh", "device.switch", inactiveLabel: false, height: 2, width: 2, decoration: "flat") {
|
||||||
|
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||||
|
}
|
||||||
|
|
||||||
|
main(["switch"])
|
||||||
|
details(["rich-control", "refresh"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse events into attributes
|
// parse events into attributes
|
||||||
def parse(String description) {
|
def parse(String description) {
|
||||||
log.debug "Parsing '${description}'"
|
log.debug "Parsing '${description}'"
|
||||||
|
|
||||||
def msg = parseLanMessage(description)
|
def msg = parseLanMessage(description)
|
||||||
def headerString = msg.header
|
def headerString = msg.header
|
||||||
|
|
||||||
if (headerString?.contains("SID: uuid:")) {
|
if (headerString?.contains("SID: uuid:")) {
|
||||||
def sid = (headerString =~ /SID: uuid:.*/) ? ( headerString =~ /SID: uuid:.*/)[0] : "0"
|
def sid = (headerString =~ /SID: uuid:.*/) ? ( headerString =~ /SID: uuid:.*/)[0] : "0"
|
||||||
sid -= "SID: uuid:".trim()
|
sid -= "SID: uuid:".trim()
|
||||||
|
|
||||||
updateDataValue("subscriptionId", sid)
|
updateDataValue("subscriptionId", sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
def result = []
|
def result = []
|
||||||
def bodyString = msg.body
|
def bodyString = msg.body
|
||||||
if (bodyString) {
|
if (bodyString) {
|
||||||
def body = new XmlSlurper().parseText(bodyString)
|
unschedule("setOffline")
|
||||||
|
def body = new XmlSlurper().parseText(bodyString)
|
||||||
if (body?.property?.TimeSyncRequest?.text()) {
|
if (body?.property?.TimeSyncRequest?.text()) {
|
||||||
log.trace "Got TimeSyncRequest"
|
log.trace "Got TimeSyncRequest"
|
||||||
result << timeSyncResponse()
|
result << timeSyncResponse()
|
||||||
} else if (body?.Body?.SetBinaryStateResponse?.BinaryState?.text()) {
|
} else if (body?.Body?.SetBinaryStateResponse?.BinaryState?.text()) {
|
||||||
log.trace "Got SetBinaryStateResponse = ${body?.Body?.SetBinaryStateResponse?.BinaryState?.text()}"
|
log.trace "Got SetBinaryStateResponse = ${body?.Body?.SetBinaryStateResponse?.BinaryState?.text()}"
|
||||||
} else if (body?.property?.BinaryState?.text()) {
|
} else if (body?.property?.BinaryState?.text()) {
|
||||||
def value = body?.property?.BinaryState?.text().toInteger() == 1 ? "on" : "off"
|
def value = body?.property?.BinaryState?.text().substring(0, 1).toInteger() == 0 ? "off" : "on"
|
||||||
log.trace "Notify: BinaryState = ${value}"
|
log.trace "Notify: BinaryState = ${value}, ${body.property.BinaryState}"
|
||||||
result << createEvent(name: "switch", value: value)
|
def dispaux = device.currentValue("switch") != value
|
||||||
} else if (body?.property?.TimeZoneNotification?.text()) {
|
result << createEvent(name: "switch", value: value, descriptionText: "Switch is ${value}", displayed: dispaux)
|
||||||
log.debug "Notify: TimeZoneNotification = ${body?.property?.TimeZoneNotification?.text()}"
|
} else if (body?.property?.TimeZoneNotification?.text()) {
|
||||||
} else if (body?.Body?.GetBinaryStateResponse?.BinaryState?.text()) {
|
log.debug "Notify: TimeZoneNotification = ${body?.property?.TimeZoneNotification?.text()}"
|
||||||
def value = body?.Body?.GetBinaryStateResponse?.BinaryState?.text().toInteger() == 1 ? "on" : "off"
|
} else if (body?.Body?.GetBinaryStateResponse?.BinaryState?.text()) {
|
||||||
log.trace "GetBinaryResponse: BinaryState = ${value}"
|
def value = body?.Body?.GetBinaryStateResponse?.BinaryState?.text().substring(0, 1).toInteger() == 0 ? "off" : "on"
|
||||||
result << createEvent(name: "switch", value: value)
|
log.trace "GetBinaryResponse: BinaryState = ${value}, ${body.property.BinaryState}"
|
||||||
}
|
log.info "Connection: ${device.currentValue("connection")}"
|
||||||
}
|
if (device.currentValue("currentIP") == "Offline") {
|
||||||
|
def ipvalue = convertHexToIP(getDataValue("ip"))
|
||||||
result
|
sendEvent(name: "IP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
|
}
|
||||||
|
def dispaux2 = device.currentValue("switch") != value
|
||||||
|
result << createEvent(name: "switch", value: value, descriptionText: "Switch is ${value}", displayed: dispaux2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
private getTime() {
|
private getTime() {
|
||||||
// This is essentially System.currentTimeMillis()/1000, but System is disallowed by the sandbox.
|
// This is essentially System.currentTimeMillis()/1000, but System is disallowed by the sandbox.
|
||||||
((new GregorianCalendar().time.time / 1000l).toInteger()).toString()
|
((new GregorianCalendar().time.time / 1000l).toInteger()).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCallBackAddress() {
|
private getCallBackAddress() {
|
||||||
device.hub.getDataValue("localIP") + ":" + device.hub.getDataValue("localSrvPortTCP")
|
device.hub.getDataValue("localIP") + ":" + device.hub.getDataValue("localSrvPortTCP")
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer convertHexToInt(hex) {
|
private Integer convertHexToInt(hex) {
|
||||||
Integer.parseInt(hex,16)
|
Integer.parseInt(hex,16)
|
||||||
}
|
}
|
||||||
|
|
||||||
private String convertHexToIP(hex) {
|
private String convertHexToIP(hex) {
|
||||||
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
||||||
}
|
}
|
||||||
|
|
||||||
private getHostAddress() {
|
private getHostAddress() {
|
||||||
def ip = getDataValue("ip")
|
def ip = getDataValue("ip")
|
||||||
def port = getDataValue("port")
|
def port = getDataValue("port")
|
||||||
|
if (!ip || !port) {
|
||||||
if (!ip || !port) {
|
def parts = device.deviceNetworkId.split(":")
|
||||||
def parts = device.deviceNetworkId.split(":")
|
if (parts.length == 2) {
|
||||||
if (parts.length == 2) {
|
ip = parts[0]
|
||||||
ip = parts[0]
|
port = parts[1]
|
||||||
port = parts[1]
|
} else {
|
||||||
} else {
|
log.warn "Can't figure out ip and port for device: ${device.id}"
|
||||||
log.warn "Can't figure out ip and port for device: ${device.id}"
|
}
|
||||||
}
|
}
|
||||||
}
|
log.debug "Using ip: ${ip} and port: ${port} for device: ${device.id}"
|
||||||
log.debug "Using ip: ${ip} and port: ${port} for device: ${device.id}"
|
return convertHexToIP(ip) + ":" + convertHexToInt(port)
|
||||||
return convertHexToIP(ip) + ":" + convertHexToInt(port)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def on() {
|
def on() {
|
||||||
log.debug "Executing 'on'"
|
log.debug "Executing 'on'"
|
||||||
sendEvent(name: "switch", value: "on")
|
|
||||||
def turnOn = new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
def turnOn = new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
||||||
SOAPAction: "urn:Belkin:service:basicevent:1#SetBinaryState"
|
SOAPAction: "urn:Belkin:service:basicevent:1#SetBinaryState"
|
||||||
Host: ${getHostAddress()}
|
Host: ${getHostAddress()}
|
||||||
@@ -133,17 +155,16 @@ Content-Length: 333
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
<SOAP-ENV:Body>
|
<SOAP-ENV:Body>
|
||||||
<m:SetBinaryState xmlns:m="urn:Belkin:service:basicevent:1">
|
<m:SetBinaryState xmlns:m="urn:Belkin:service:basicevent:1">
|
||||||
<BinaryState>1</BinaryState>
|
<BinaryState>1</BinaryState>
|
||||||
</m:SetBinaryState>
|
</m:SetBinaryState>
|
||||||
</SOAP-ENV:Body>
|
</SOAP-ENV:Body>
|
||||||
</SOAP-ENV:Envelope>""", physicalgraph.device.Protocol.LAN)
|
</SOAP-ENV:Envelope>""", physicalgraph.device.Protocol.LAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
def off() {
|
def off() {
|
||||||
log.debug "Executing 'off'"
|
log.debug "Executing 'off'"
|
||||||
sendEvent(name: "switch", value: "off")
|
def turnOff = new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
||||||
def turnOff = new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
|
||||||
SOAPAction: "urn:Belkin:service:basicevent:1#SetBinaryState"
|
SOAPAction: "urn:Belkin:service:basicevent:1#SetBinaryState"
|
||||||
Host: ${getHostAddress()}
|
Host: ${getHostAddress()}
|
||||||
Content-Type: text/xml
|
Content-Type: text/xml
|
||||||
@@ -152,36 +173,13 @@ Content-Length: 333
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
<SOAP-ENV:Body>
|
<SOAP-ENV:Body>
|
||||||
<m:SetBinaryState xmlns:m="urn:Belkin:service:basicevent:1">
|
<m:SetBinaryState xmlns:m="urn:Belkin:service:basicevent:1">
|
||||||
<BinaryState>0</BinaryState>
|
<BinaryState>0</BinaryState>
|
||||||
</m:SetBinaryState>
|
</m:SetBinaryState>
|
||||||
</SOAP-ENV:Body>
|
</SOAP-ENV:Body>
|
||||||
</SOAP-ENV:Envelope>""", physicalgraph.device.Protocol.LAN)
|
</SOAP-ENV:Envelope>""", physicalgraph.device.Protocol.LAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*def refresh() {
|
|
||||||
log.debug "Executing 'refresh'"
|
|
||||||
new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
|
||||||
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
|
|
||||||
Content-Length: 277
|
|
||||||
Content-Type: text/xml; charset="utf-8"
|
|
||||||
HOST: ${getHostAddress()}
|
|
||||||
User-Agent: CyberGarage-HTTP/1.0
|
|
||||||
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
|
||||||
<s:Body>
|
|
||||||
<u:GetBinaryState xmlns:u="urn:Belkin:service:basicevent:1">
|
|
||||||
</u:GetBinaryState>
|
|
||||||
</s:Body>
|
|
||||||
</s:Envelope>""", physicalgraph.device.Protocol.LAN)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
def refresh() {
|
|
||||||
log.debug "Executing WeMo Switch 'subscribe', then 'timeSyncResponse', then 'poll'"
|
|
||||||
[subscribe(), timeSyncResponse(), poll()]
|
|
||||||
}
|
|
||||||
|
|
||||||
def subscribe(hostAddress) {
|
def subscribe(hostAddress) {
|
||||||
log.debug "Executing 'subscribe()'"
|
log.debug "Executing 'subscribe()'"
|
||||||
def address = getCallBackAddress()
|
def address = getCallBackAddress()
|
||||||
@@ -200,27 +198,30 @@ def subscribe() {
|
|||||||
subscribe(getHostAddress())
|
subscribe(getHostAddress())
|
||||||
}
|
}
|
||||||
|
|
||||||
def subscribe(ip, port) {
|
def refresh() {
|
||||||
def existingIp = getDataValue("ip")
|
log.debug "Executing WeMo Switch 'subscribe', then 'timeSyncResponse', then 'poll'"
|
||||||
def existingPort = getDataValue("port")
|
[subscribe(), timeSyncResponse(), poll()]
|
||||||
if (ip && ip != existingIp) {
|
}
|
||||||
log.debug "Updating ip from $existingIp to $ip"
|
|
||||||
updateDataValue("ip", ip)
|
|
||||||
}
|
|
||||||
if (port && port != existingPort) {
|
|
||||||
log.debug "Updating port from $existingPort to $port"
|
|
||||||
updateDataValue("port", port)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
def subscribe(ip, port) {
|
||||||
|
def existingIp = getDataValue("ip")
|
||||||
|
def existingPort = getDataValue("port")
|
||||||
|
if (ip && ip != existingIp) {
|
||||||
|
log.debug "Updating ip from $existingIp to $ip"
|
||||||
|
updateDataValue("ip", ip)
|
||||||
|
def ipvalue = convertHexToIP(getDataValue("ip"))
|
||||||
|
sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP changed to ${ipvalue}")
|
||||||
|
}
|
||||||
|
if (port && port != existingPort) {
|
||||||
|
log.debug "Updating port from $existingPort to $port"
|
||||||
|
updateDataValue("port", port)
|
||||||
|
}
|
||||||
subscribe("${ip}:${port}")
|
subscribe("${ip}:${port}")
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////
|
|
||||||
def resubscribe() {
|
def resubscribe() {
|
||||||
log.debug "Executing 'resubscribe()'"
|
log.debug "Executing 'resubscribe()'"
|
||||||
|
def sid = getDeviceDataByName("subscriptionId")
|
||||||
def sid = getDeviceDataByName("subscriptionId")
|
|
||||||
|
|
||||||
new physicalgraph.device.HubAction("""SUBSCRIBE /upnp/event/basicevent1 HTTP/1.1
|
new physicalgraph.device.HubAction("""SUBSCRIBE /upnp/event/basicevent1 HTTP/1.1
|
||||||
HOST: ${getHostAddress()}
|
HOST: ${getHostAddress()}
|
||||||
SID: uuid:${sid}
|
SID: uuid:${sid}
|
||||||
@@ -228,12 +229,11 @@ TIMEOUT: Second-5400
|
|||||||
|
|
||||||
|
|
||||||
""", physicalgraph.device.Protocol.LAN)
|
""", physicalgraph.device.Protocol.LAN)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////
|
|
||||||
def unsubscribe() {
|
def unsubscribe() {
|
||||||
def sid = getDeviceDataByName("subscriptionId")
|
def sid = getDeviceDataByName("subscriptionId")
|
||||||
new physicalgraph.device.HubAction("""UNSUBSCRIBE publisher path HTTP/1.1
|
new physicalgraph.device.HubAction("""UNSUBSCRIBE publisher path HTTP/1.1
|
||||||
HOST: ${getHostAddress()}
|
HOST: ${getHostAddress()}
|
||||||
SID: uuid:${sid}
|
SID: uuid:${sid}
|
||||||
@@ -242,7 +242,7 @@ SID: uuid:${sid}
|
|||||||
""", physicalgraph.device.Protocol.LAN)
|
""", physicalgraph.device.Protocol.LAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////
|
|
||||||
//TODO: Use UTC Timezone
|
//TODO: Use UTC Timezone
|
||||||
def timeSyncResponse() {
|
def timeSyncResponse() {
|
||||||
log.debug "Executing 'timeSyncResponse()'"
|
log.debug "Executing 'timeSyncResponse()'"
|
||||||
@@ -267,9 +267,15 @@ User-Agent: CyberGarage-HTTP/1.0
|
|||||||
""", physicalgraph.device.Protocol.LAN)
|
""", physicalgraph.device.Protocol.LAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def setOffline() {
|
||||||
|
//sendEvent(name: "currentIP", value: "Offline", displayed: false)
|
||||||
|
sendEvent(name: "switch", value: "offline", descriptionText: "The device is offline")
|
||||||
|
}
|
||||||
|
|
||||||
def poll() {
|
def poll() {
|
||||||
log.debug "Executing 'poll'"
|
log.debug "Executing 'poll'"
|
||||||
|
if (device.currentValue("currentIP") != "Offline")
|
||||||
|
runIn(10, setOffline)
|
||||||
new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
|
||||||
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
|
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
|
||||||
Content-Length: 277
|
Content-Length: 277
|
||||||
|
|||||||
@@ -61,10 +61,7 @@ def firstPage()
|
|||||||
|
|
||||||
log.debug "REFRESH COUNT :: ${refreshCount}"
|
log.debug "REFRESH COUNT :: ${refreshCount}"
|
||||||
|
|
||||||
if(!state.subscribe) {
|
subscribe(location, null, locationHandler, [filterEvents:false])
|
||||||
subscribe(location, null, locationHandler, [filterEvents:false])
|
|
||||||
state.subscribe = true
|
|
||||||
}
|
|
||||||
|
|
||||||
//ssdp request every 25 seconds
|
//ssdp request every 25 seconds
|
||||||
if((refreshCount % 5) == 0) {
|
if((refreshCount % 5) == 0) {
|
||||||
@@ -168,21 +165,30 @@ def getWemoLightSwitches()
|
|||||||
def installed() {
|
def installed() {
|
||||||
log.debug "Installed with settings: ${settings}"
|
log.debug "Installed with settings: ${settings}"
|
||||||
initialize()
|
initialize()
|
||||||
|
|
||||||
runIn(5, "subscribeToDevices") //initial subscriptions delayed by 5 seconds
|
|
||||||
runIn(10, "refreshDevices") //refresh devices, delayed by 10 seconds
|
|
||||||
runIn(900, "doDeviceSync" , [overwrite: false]) //setup ip:port syncing every 15 minutes
|
|
||||||
|
|
||||||
// SUBSCRIBE responses come back with TIMEOUT-1801 (30 minutes), so we refresh things a bit before they expire (29 minutes)
|
|
||||||
runIn(1740, "refresh", [overwrite: false])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def updated() {
|
def updated() {
|
||||||
log.debug "Updated with settings: ${settings}"
|
log.debug "Updated with settings: ${settings}"
|
||||||
initialize()
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
runIn(5, "subscribeToDevices") //subscribe again to new/old devices wait 5 seconds
|
def initialize() {
|
||||||
runIn(10, "refreshDevices") //refresh devices again, delayed by 10 seconds
|
unsubscribe()
|
||||||
|
unschedule()
|
||||||
|
subscribe(location, null, locationHandler, [filterEvents:false])
|
||||||
|
|
||||||
|
if (selectedSwitches)
|
||||||
|
addSwitches()
|
||||||
|
|
||||||
|
if (selectedMotions)
|
||||||
|
addMotions()
|
||||||
|
|
||||||
|
if (selectedLightSwitches)
|
||||||
|
addLightSwitches()
|
||||||
|
|
||||||
|
runIn(5, "subscribeToDevices") //initial subscriptions delayed by 5 seconds
|
||||||
|
runIn(10, "refreshDevices") //refresh devices, delayed by 10 seconds
|
||||||
|
runEvery5Minutes("refresh")
|
||||||
}
|
}
|
||||||
|
|
||||||
def resubscribe() {
|
def resubscribe() {
|
||||||
@@ -192,8 +198,7 @@ def resubscribe() {
|
|||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
log.debug "refresh() called"
|
log.debug "refresh() called"
|
||||||
//reschedule the refreshes
|
doDeviceSync()
|
||||||
runIn(1740, "refresh", [overwrite: false])
|
|
||||||
refreshDevices()
|
refreshDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +241,8 @@ def addSwitches() {
|
|||||||
"port": selectedSwitch.value.port
|
"port": selectedSwitch.value.port
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
def ipvalue = convertHexToIP(selectedSwitch.value.ip)
|
||||||
|
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"
|
||||||
@@ -266,8 +272,9 @@ def addMotions() {
|
|||||||
"port": selectedMotion.value.port
|
"port": selectedMotion.value.port
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
def ipvalue = convertHexToIP(selectedMotion.value.ip)
|
||||||
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
|
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"
|
||||||
}
|
}
|
||||||
@@ -296,7 +303,8 @@ def addLightSwitches() {
|
|||||||
"port": selectedLightSwitch.value.port
|
"port": selectedLightSwitch.value.port
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
def ipvalue = convertHexToIP(selectedLightSwitch.value.ip)
|
||||||
|
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"
|
||||||
@@ -304,27 +312,6 @@ def addLightSwitches() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize() {
|
|
||||||
// remove location subscription afterwards
|
|
||||||
unsubscribe()
|
|
||||||
state.subscribe = false
|
|
||||||
|
|
||||||
if (selectedSwitches)
|
|
||||||
{
|
|
||||||
addSwitches()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedMotions)
|
|
||||||
{
|
|
||||||
addMotions()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedLightSwitches)
|
|
||||||
{
|
|
||||||
addLightSwitches()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def locationHandler(evt) {
|
def locationHandler(evt) {
|
||||||
def description = evt.description
|
def description = evt.description
|
||||||
def hub = evt?.hubId
|
def hub = evt?.hubId
|
||||||
@@ -333,53 +320,32 @@ def locationHandler(evt) {
|
|||||||
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
|
|
||||||
{ // just update the values
|
|
||||||
|
|
||||||
log.debug "Device was already found in state..."
|
log.debug "Device was already found in state..."
|
||||||
|
|
||||||
def d = switches."${parsedEvent.ssdpUSN.toString()}"
|
def d = switches."${parsedEvent.ssdpUSN.toString()}"
|
||||||
boolean deviceChangedValues = false
|
boolean deviceChangedValues = false
|
||||||
|
log.debug "$d.ip <==> $parsedEvent.ip"
|
||||||
if(d.ip != parsedEvent.ip || d.port != parsedEvent.port) {
|
if(d.ip != parsedEvent.ip || d.port != parsedEvent.port) {
|
||||||
d.ip = parsedEvent.ip
|
d.ip = parsedEvent.ip
|
||||||
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)
|
||||||
|
child.subscribe(parsedEvent.ip, parsedEvent.port)
|
||||||
|
child.poll()
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
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..."
|
||||||
|
|
||||||
def d = motions."${parsedEvent.ssdpUSN.toString()}"
|
def d = motions."${parsedEvent.ssdpUSN.toString()}"
|
||||||
@@ -412,10 +378,7 @@ def locationHandler(evt) {
|
|||||||
if (!(lightSwitches."${parsedEvent.ssdpUSN.toString()}"))
|
if (!(lightSwitches."${parsedEvent.ssdpUSN.toString()}"))
|
||||||
{ //if it doesn't already exist
|
{ //if it doesn't already exist
|
||||||
lightSwitches << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
lightSwitches << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{ // just update the values
|
|
||||||
|
|
||||||
log.debug "Device was already found in state..."
|
log.debug "Device was already found in state..."
|
||||||
|
|
||||||
def d = lightSwitches."${parsedEvent.ssdpUSN.toString()}"
|
def d = lightSwitches."${parsedEvent.ssdpUSN.toString()}"
|
||||||
@@ -426,21 +389,11 @@ 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)
|
||||||
|
log.debug "updating ip and port, and resubscribing, for device with mac ${parsedEvent.mac}"
|
||||||
|
child.subscribe(parsedEvent.ip, parsedEvent.port)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (parsedEvent.headers && parsedEvent.body) {
|
else if (parsedEvent.headers && parsedEvent.body) {
|
||||||
String headerString = new String(parsedEvent.headers.decodeBase64())?.toLowerCase()
|
String headerString = new String(parsedEvent.headers.decodeBase64())?.toLowerCase()
|
||||||
@@ -580,73 +533,30 @@ private def parseDiscoveryMessage(String description) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device
|
device
|
||||||
}
|
}
|
||||||
|
|
||||||
def doDeviceSync(){
|
def doDeviceSync(){
|
||||||
log.debug "Doing Device Sync!"
|
log.debug "Doing Device Sync!"
|
||||||
runIn(900, "doDeviceSync" , [overwrite: false]) //schedule to run again in 15 minutes
|
|
||||||
|
|
||||||
if(!state.subscribe) {
|
|
||||||
subscribe(location, null, locationHandler, [filterEvents:false])
|
|
||||||
state.subscribe = true
|
|
||||||
}
|
|
||||||
|
|
||||||
discoverAllWemoTypes()
|
discoverAllWemoTypes()
|
||||||
}
|
}
|
||||||
|
|
||||||
def pollChildren() {
|
private String convertHexToIP(hex) {
|
||||||
def devices = getAllChildDevices()
|
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
||||||
devices.each { d ->
|
|
||||||
//only poll switches?
|
|
||||||
d.poll()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def delayPoll() {
|
private Integer convertHexToInt(hex) {
|
||||||
log.debug "Executing 'delayPoll'"
|
Integer.parseInt(hex,16)
|
||||||
|
|
||||||
runIn(5, "pollChildren")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*def poll() {
|
private Boolean canInstallLabs() {
|
||||||
log.debug "Executing 'poll'"
|
|
||||||
runIn(600, "poll", [overwrite: false]) //schedule to run again in 10 minutes
|
|
||||||
|
|
||||||
def lastPoll = getLastPollTime()
|
|
||||||
def currentTime = now()
|
|
||||||
def lastPollDiff = currentTime - lastPoll
|
|
||||||
log.debug "lastPoll: $lastPoll, currentTime: $currentTime, lastPollDiff: $lastPollDiff"
|
|
||||||
setLastPollTime(currentTime)
|
|
||||||
|
|
||||||
doDeviceSync()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def setLastPollTime(currentTime) {
|
|
||||||
state.lastpoll = currentTime
|
|
||||||
}
|
|
||||||
|
|
||||||
def getLastPollTime() {
|
|
||||||
state.lastpoll ?: now()
|
|
||||||
}
|
|
||||||
|
|
||||||
def now() {
|
|
||||||
new Date().getTime()
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private Boolean canInstallLabs()
|
|
||||||
{
|
|
||||||
return hasAllHubsOver("000.011.00603")
|
return hasAllHubsOver("000.011.00603")
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean hasAllHubsOver(String desiredFirmware)
|
private Boolean hasAllHubsOver(String desiredFirmware) {
|
||||||
{
|
|
||||||
return realHubFirmwareVersions.every { fw -> fw >= desiredFirmware }
|
return realHubFirmwareVersions.every { fw -> fw >= desiredFirmware }
|
||||||
}
|
}
|
||||||
|
|
||||||
private List getRealHubFirmwareVersions()
|
private List getRealHubFirmwareVersions() {
|
||||||
{
|
|
||||||
return location.hubs*.firmwareVersionString.findAll { it }
|
return location.hubs*.firmwareVersionString.findAll { it }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user