mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-19 05:10:51 +00:00
Compare commits
16 Commits
MSA-1451-1
...
PROD_2016.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a22f71bc29 | ||
|
|
8eeb29a8a7 | ||
|
|
3d84bca3d7 | ||
|
|
46f47128bd | ||
|
|
9c8398b7a0 | ||
|
|
cdf5d21e8f | ||
|
|
d5b8db99a2 | ||
|
|
6ad4f0990c | ||
|
|
b1c318ef36 | ||
|
|
8eb6001f9f | ||
|
|
d90e15ee31 | ||
|
|
cfe25607ac | ||
|
|
f251042954 | ||
|
|
33df9b1ff1 | ||
|
|
c8bda222cb | ||
|
|
9d65150bf7 |
@@ -28,8 +28,8 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
valueTile("doNotRemove", "v", decoration: "flat", height: 2, width: 6, inactiveLabel: false) {
|
valueTile("doNotRemove", "v", decoration: "flat", height: 2, width: 6, inactiveLabel: false) {
|
||||||
state "default", label:'Do not remove'
|
state "default", label:'If removed, Hue lights will not work properly'
|
||||||
}
|
}
|
||||||
valueTile("idNumber", "device.idNumber", decoration: "flat", height: 2, width: 6, inactiveLabel: false) {
|
valueTile("idNumber", "device.idNumber", decoration: "flat", height: 2, width: 6, inactiveLabel: false) {
|
||||||
state "default", label:'ID: ${currentValue}'
|
state "default", label:'ID: ${currentValue}'
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ metadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main (["rich-control"])
|
main (["rich-control"])
|
||||||
details(["rich-control", "idNumber", "networkAddress", "doNotRemove"])
|
details(["rich-control", "doNotRemove", "idNumber", "networkAddress"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,8 +147,8 @@ private Map parseIasMessage(String description) {
|
|||||||
ZoneStatus zs = zigbee.parseZoneStatus(description)
|
ZoneStatus zs = zigbee.parseZoneStatus(description)
|
||||||
Map resultMap = [:]
|
Map resultMap = [:]
|
||||||
|
|
||||||
result.name = 'motion'
|
resultMap.name = 'motion'
|
||||||
result.value = zs.isAlarm2Set() ? 'active' : 'inactive'
|
resultMap.value = zs.isAlarm2Set() ? 'active' : 'inactive'
|
||||||
log.debug(zs.isAlarm2Set() ? 'motion' : 'no motion')
|
log.debug(zs.isAlarm2Set() ? 'motion' : 'no motion')
|
||||||
|
|
||||||
return resultMap
|
return resultMap
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false, data: [protocol: "zigbee"])
|
sendEvent(name: "checkInterval", value: 14400, displayed: false, data: [protocol: "zigbee"])
|
||||||
|
|
||||||
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
||||||
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false, data: [protocol: "zigbee"])
|
sendEvent(name: "checkInterval", value: 14400, displayed: false, data: [protocol: "zigbee"])
|
||||||
|
|
||||||
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
||||||
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false, data: [protocol: "zigbee"])
|
sendEvent(name: "checkInterval", value: 14400, displayed: false, data: [protocol: "zigbee"])
|
||||||
|
|
||||||
log.debug "Configuring Reporting"
|
log.debug "Configuring Reporting"
|
||||||
|
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false, data: [protocol: "zigbee"])
|
sendEvent(name: "checkInterval", value: 14400, displayed: false, data: [protocol: "zigbee"])
|
||||||
|
|
||||||
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
||||||
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ def refresh()
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false, data: [protocol: "zigbee"])
|
sendEvent(name: "checkInterval", value: 14400, displayed: false, data: [protocol: "zigbee"])
|
||||||
|
|
||||||
log.debug "Configuring Reporting and Bindings."
|
log.debug "Configuring Reporting and Bindings."
|
||||||
def configCmds = [
|
def configCmds = [
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ metadata {
|
|||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Color Temperature"
|
capability "Color Temperature"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
|
capability "Health Check"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Switch Level"
|
capability "Switch Level"
|
||||||
@@ -72,6 +73,12 @@ def parse(String description) {
|
|||||||
log.debug "description is $description"
|
log.debug "description is $description"
|
||||||
def event = zigbee.getEvent(description)
|
def event = zigbee.getEvent(description)
|
||||||
if (event) {
|
if (event) {
|
||||||
|
// Temporary fix for the case when Device is OFFLINE and is connected again
|
||||||
|
if (state.lastActivity == null){
|
||||||
|
state.lastActivity = now()
|
||||||
|
sendEvent(name: "deviceWatch-lastActivity", value: state.lastActivity, description: "Last Activity is on ${new Date((long)state.lastActivity)}", displayed: false, isStateChange: true)
|
||||||
|
}
|
||||||
|
state.lastActivity = now()
|
||||||
if (event.name=="level" && event.value==0) {}
|
if (event.name=="level" && event.value==0) {}
|
||||||
else {
|
else {
|
||||||
if (event.name=="colorTemperature") {
|
if (event.name=="colorTemperature") {
|
||||||
@@ -98,12 +105,29 @@ def setLevel(value) {
|
|||||||
zigbee.setLevel(value)
|
zigbee.setLevel(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PING is used by Device-Watch in attempt to reach the Device
|
||||||
|
* */
|
||||||
|
def ping() {
|
||||||
|
|
||||||
|
if (state.lastActivity < (now() - (1000 * device.currentValue("checkInterval"))) ){
|
||||||
|
log.info "ping, alive=no, lastActivity=${state.lastActivity}"
|
||||||
|
state.lastActivity = null
|
||||||
|
return zigbee.onOffRefresh()
|
||||||
|
} else {
|
||||||
|
log.info "ping, alive=yes, lastActivity=${state.lastActivity}"
|
||||||
|
sendEvent(name: "deviceWatch-lastActivity", value: state.lastActivity, description: "Last Activity is on ${new Date((long)state.lastActivity)}", displayed: false, isStateChange: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Configuring Reporting and Bindings."
|
log.debug "Configuring Reporting and Bindings."
|
||||||
|
// Enrolls device to Device-Watch with 3 x Reporting interval 30min
|
||||||
|
sendEvent(name: "checkInterval", value: 1800, displayed: false, data: [protocol: "zigbee"])
|
||||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,14 +133,23 @@ def bulbDiscovery() {
|
|||||||
state.inBulbDiscovery = true
|
state.inBulbDiscovery = true
|
||||||
def bridge = null
|
def bridge = null
|
||||||
if (selectedHue) {
|
if (selectedHue) {
|
||||||
bridge = getChildDevice(selectedHue)
|
bridge = getChildDevice(selectedHue)
|
||||||
subscribe(bridge, "bulbList", bulbListData)
|
subscribe(bridge, "bulbList", bulbListData)
|
||||||
}
|
}
|
||||||
state.bridgeRefreshCount = 0
|
state.bridgeRefreshCount = 0
|
||||||
def bulboptions = bulbsDiscovered() ?: [:]
|
def allLightsFound = bulbsDiscovered() ?: [:]
|
||||||
def numFound = bulboptions.size() ?: 0
|
|
||||||
if (numFound == 0)
|
// List lights currently not added to the user (editable)
|
||||||
app.updateSetting("selectedBulbs", "")
|
def newLights = allLightsFound.findAll {getChildDevice(it.key) == null} ?: [:]
|
||||||
|
newLights = newLights.sort {it.value.toLowerCase()}
|
||||||
|
|
||||||
|
// List lights already added to the user (not editable)
|
||||||
|
def existingLights = allLightsFound.findAll {getChildDevice(it.key) != null} ?: [:]
|
||||||
|
existingLights = existingLights.sort {it.value.toLowerCase()}
|
||||||
|
|
||||||
|
def numFound = newLights.size() ?: 0
|
||||||
|
if (numFound == 0)
|
||||||
|
app.updateSetting("selectedBulbs", "")
|
||||||
|
|
||||||
if((bulbRefreshCount % 5) == 0) {
|
if((bulbRefreshCount % 5) == 0) {
|
||||||
discoverHueBulbs()
|
discoverHueBulbs()
|
||||||
@@ -148,14 +157,25 @@ def bulbDiscovery() {
|
|||||||
def selectedBridge = state.bridges.find { key, value -> value?.serialNumber?.equalsIgnoreCase(selectedHue) }
|
def selectedBridge = state.bridges.find { key, value -> value?.serialNumber?.equalsIgnoreCase(selectedHue) }
|
||||||
def title = selectedBridge?.value?.name ?: "Find bridges"
|
def title = selectedBridge?.value?.name ?: "Find bridges"
|
||||||
|
|
||||||
|
// List of all lights previously added shown to user
|
||||||
|
def existingLightsDescription = ""
|
||||||
|
if (existingLights) {
|
||||||
|
existingLights.each {
|
||||||
|
if (existingLightsDescription.isEmpty()) {
|
||||||
|
existingLightsDescription += it.value
|
||||||
|
} else {
|
||||||
|
existingLightsDescription += ", ${it.value}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dynamicPage(name:"bulbDiscovery", title:"Light Discovery Started!", nextPage:"", refreshInterval:refreshInterval, install:true, uninstall: true) {
|
return dynamicPage(name:"bulbDiscovery", title:"Light Discovery Started!", nextPage:"", refreshInterval:refreshInterval, install:true, uninstall: true) {
|
||||||
section("Please wait while we discover your Hue Lights. Discovery can take five minutes or more, so sit back and relax! Select your device below once discovered.") {
|
section("Please wait while we discover your Hue Lights. Discovery can take five minutes or more, so sit back and relax! Select your device below once discovered.") {
|
||||||
input "selectedBulbs", "enum", required:false, title:"Select Hue Lights (${numFound} found)", multiple:true, options:bulboptions
|
input "selectedBulbs", "enum", required:false, title:"Select Hue Lights to add (${numFound} found)", multiple:true, options:newLights
|
||||||
|
paragraph title: "Previously added Hue Lights (${existingLights.size()} added)", existingLightsDescription
|
||||||
}
|
}
|
||||||
section {
|
section {
|
||||||
href "bridgeDiscovery", title: title, description: "", state: selectedHue ? "complete" : "incomplete", params: [override: true]
|
href "bridgeDiscovery", title: title, description: "", state: selectedHue ? "complete" : "incomplete", params: [override: true]
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,8 +310,11 @@ def manualRefresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def uninstalled(){
|
def uninstalled(){
|
||||||
|
// Remove bridgedevice connection to allow uninstall of smartapp even though bridge is listed
|
||||||
|
// as user of smartapp
|
||||||
|
app.updateSetting("bridgeDevice", null)
|
||||||
state.bridges = [:]
|
state.bridges = [:]
|
||||||
state.username = null
|
state.username = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles events to add new bulbs
|
// Handles events to add new bulbs
|
||||||
@@ -415,23 +438,32 @@ def addBridge() {
|
|||||||
// Hue uses last 6 digits of MAC address as ID number, this number is shown on the bottom of the bridge
|
// Hue uses last 6 digits of MAC address as ID number, this number is shown on the bottom of the bridge
|
||||||
def idNumber = getBridgeIdNumber(selectedHue)
|
def idNumber = getBridgeIdNumber(selectedHue)
|
||||||
d = addChildDevice("smartthings", "Hue Bridge", selectedHue, vbridge.value.hub, ["label": "Hue Bridge ($idNumber)"])
|
d = addChildDevice("smartthings", "Hue Bridge", selectedHue, vbridge.value.hub, ["label": "Hue Bridge ($idNumber)"])
|
||||||
d?.completedSetup = true
|
if (d) {
|
||||||
log.debug "created ${d.displayName} with id ${d.deviceNetworkId}"
|
// Associate smartapp to bridge so user will be warned if trying to delete bridge
|
||||||
def childDevice = getChildDevice(d.deviceNetworkId)
|
app.updateSetting("bridgeDevice", [type: "device.hueBridge", value: d.id])
|
||||||
updateBridgeStatus(childDevice)
|
|
||||||
childDevice.sendEvent(name: "idNumber", value: idNumber)
|
d.completedSetup = true
|
||||||
if (vbridge.value.ip && vbridge.value.port) {
|
log.debug "created ${d.displayName} with id ${d.deviceNetworkId}"
|
||||||
if (vbridge.value.ip.contains(".")) {
|
def childDevice = getChildDevice(d.deviceNetworkId)
|
||||||
childDevice.sendEvent(name: "networkAddress", value: vbridge.value.ip + ":" + vbridge.value.port)
|
updateBridgeStatus(childDevice)
|
||||||
childDevice.updateDataValue("networkAddress", vbridge.value.ip + ":" + vbridge.value.port)
|
childDevice.sendEvent(name: "idNumber", value: idNumber)
|
||||||
} else {
|
|
||||||
childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port))
|
|
||||||
childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port))
|
if (vbridge.value.ip && vbridge.value.port) {
|
||||||
}
|
if (vbridge.value.ip.contains(".")) {
|
||||||
|
childDevice.sendEvent(name: "networkAddress", value: vbridge.value.ip + ":" + vbridge.value.port)
|
||||||
|
childDevice.updateDataValue("networkAddress", vbridge.value.ip + ":" + vbridge.value.port)
|
||||||
|
} else {
|
||||||
|
childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port))
|
||||||
|
childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
|
||||||
|
childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
|
log.error "Failed to create Hue Bridge device"
|
||||||
childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug "found ${d.displayName} with id $selectedHue already exists"
|
log.debug "found ${d.displayName} with id $selectedHue already exists"
|
||||||
@@ -1043,6 +1075,7 @@ def setColor(childDevice, huesettings) {
|
|||||||
else
|
else
|
||||||
value.sat = Math.min(Math.round(childDevice.device?.currentValue("saturation") * 254 / 100), 254)
|
value.sat = Math.min(Math.round(childDevice.device?.currentValue("saturation") * 254 / 100), 254)
|
||||||
|
|
||||||
|
/* Disabled for now due to bad behavior via Lightning Wizard
|
||||||
if (!value.xy) {
|
if (!value.xy) {
|
||||||
// Below will translate values to hex->XY to take into account the color support of the different hue types
|
// Below will translate values to hex->XY to take into account the color support of the different hue types
|
||||||
def hex = colorUtil.hslToHex((int) huesettings.hue, (int) huesettings.saturation)
|
def hex = colorUtil.hslToHex((int) huesettings.hue, (int) huesettings.saturation)
|
||||||
@@ -1050,6 +1083,7 @@ def setColor(childDevice, huesettings) {
|
|||||||
// Once groups, or scenes are introduced it might be a good idea to use unique models again
|
// Once groups, or scenes are introduced it might be a good idea to use unique models again
|
||||||
value.xy = calculateXY(hex)
|
value.xy = calculateXY(hex)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Default behavior is to turn light on
|
// Default behavior is to turn light on
|
||||||
value.on = true
|
value.on = true
|
||||||
|
|||||||
Reference in New Issue
Block a user