Compare commits

...

16 Commits

Author SHA1 Message Date
Vinay Rao
a22f71bc29 Merge pull request #1171 from SmartThingsCommunity/staging
Rolling up staging to prod for deploy
2016-08-30 12:57:12 -07:00
Vinay Rao
8eeb29a8a7 Merge pull request #1170 from SmartThingsCommunity/production
Rolling down prod hotfix to staging
2016-08-30 12:56:16 -07:00
Lars Finander
3d84bca3d7 Merge pull request #1168 from larsfinander/SSVD-2603_removing_hue_bridge_issue_staging
SSVD-2603 Prevent removing of Hue bridge
2016-08-30 12:54:17 -06:00
Lars Finander
46f47128bd Merge pull request #1169 from larsfinander/SSVD-2613_stop_removing_hue_lights_staging
SSVD-2613 UX for Hue when adding lights is confusing
2016-08-30 12:54:08 -06:00
Lars Finander
9c8398b7a0 SSVD-2613 UX for Hue when adding lights is confusing
-Split lights list in SmartApp into already added lights and new lights
-Also fixed WWST-39 Sort list of bulbs by name during discovery
2016-08-29 16:18:07 -06:00
Lars Finander
cdf5d21e8f SSVD-2603 Prevent removing of Hue bridge
-Moved warning messages to top of bridge DTH screen
-User is now presented with a warning message when removing
2016-08-29 15:35:58 -06:00
Vinay Rao
d5b8db99a2 Merge pull request #1160 from workingmonk/bug/battery_health_timeout
CHF-201 changing timeout for health check to 4 hours
2016-08-27 01:07:04 -07:00
Vinay Rao
6ad4f0990c CHF-201 changing timeout for health check to 4 hours for battery powered devices 2016-08-27 01:05:10 -07:00
Vinay Rao
b1c318ef36 Merge pull request #1156 from workingmonk/feature/osram_cct_health
CHF-239 health extension for osram cct bulbs
2016-08-26 13:39:15 -07:00
Vinay Rao
8eb6001f9f CHF-239 extension for osram cct bulbs 2016-08-26 13:20:51 -07:00
Vinay Rao
d90e15ee31 Merge pull request #1151 from larsfinander/PROB-1352_Hue_colors_rendering_incorrectly_production
PROB-1352 Hue colors rendering incorrectly
2016-08-24 13:13:45 -07:00
Lars Finander
cfe25607ac PROB-1352 Hue colors rendering incorrectly
-Disable color conversion algorithm for hue/sat
2016-08-24 13:56:06 -06:00
Vinay Rao
f251042954 Merge pull request #1149 from varzac/dprot-153-null-pointer
Fix event map name in NYCE Motion sensor
2016-08-24 12:10:40 -07:00
Zach Varberg
33df9b1ff1 Fix event map name in NYCE Motion sensor
There was a null pointer as a result of using the wrong map name

This resolves: https://smartthings.atlassian.net/browse/DPROT-153
2016-08-24 14:04:19 -05:00
Vinay Rao
c8bda222cb Merge pull request #1146 from SmartThingsCommunity/master
Rolling up master for next week's deploy
2016-08-23 15:12:15 -07:00
Vinay Rao
9d65150bf7 Merge pull request #1143 from SmartThingsCommunity/staging
Rolling up changes to production for deploy
2016-08-23 14:04:20 -07:00
9 changed files with 100 additions and 42 deletions

View File

@@ -28,8 +28,8 @@ metadata {
}
}
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) {
state "default", label:'ID: ${currentValue}'
}
@@ -38,7 +38,7 @@ metadata {
}
main (["rich-control"])
details(["rich-control", "idNumber", "networkAddress", "doNotRemove"])
details(["rich-control", "doNotRemove", "idNumber", "networkAddress"])
}
}

View File

@@ -147,8 +147,8 @@ private Map parseIasMessage(String description) {
ZoneStatus zs = zigbee.parseZoneStatus(description)
Map resultMap = [:]
result.name = 'motion'
result.value = zs.isAlarm2Set() ? 'active' : 'inactive'
resultMap.name = 'motion'
resultMap.value = zs.isAlarm2Set() ? 'active' : 'inactive'
log.debug(zs.isAlarm2Set() ? 'motion' : 'no motion')
return resultMap

View File

@@ -24,7 +24,7 @@ metadata {
capability "Temperature Measurement"
capability "Water Sensor"
capability "Health Check"
capability "Sensor"
capability "Sensor"
command "enrollResponse"
@@ -304,7 +304,7 @@ def refresh() {
}
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)
log.debug "Configuring Reporting, IAS CIE, and Bindings."

View File

@@ -24,7 +24,7 @@ metadata {
capability "Temperature Measurement"
capability "Refresh"
capability "Health Check"
capability "Sensor"
capability "Sensor"
command "enrollResponse"
@@ -315,7 +315,7 @@ def refresh() {
}
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)
log.debug "Configuring Reporting, IAS CIE, and Bindings."

View File

@@ -413,7 +413,7 @@ def refresh() {
}
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"

View File

@@ -267,7 +267,7 @@ def refresh() {
}
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)
log.debug "Configuring Reporting, IAS CIE, and Bindings."

View File

@@ -275,7 +275,7 @@ def refresh()
}
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."
def configCmds = [

View File

@@ -22,6 +22,7 @@ metadata {
capability "Actuator"
capability "Color Temperature"
capability "Configuration"
capability "Health Check"
capability "Refresh"
capability "Switch"
capability "Switch Level"
@@ -72,6 +73,12 @@ def parse(String description) {
log.debug "description is $description"
def event = zigbee.getEvent(description)
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) {}
else {
if (event.name=="colorTemperature") {
@@ -98,12 +105,29 @@ def 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() {
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
}
def configure() {
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()
}

View File

@@ -133,14 +133,23 @@ def bulbDiscovery() {
state.inBulbDiscovery = true
def bridge = null
if (selectedHue) {
bridge = getChildDevice(selectedHue)
subscribe(bridge, "bulbList", bulbListData)
bridge = getChildDevice(selectedHue)
subscribe(bridge, "bulbList", bulbListData)
}
state.bridgeRefreshCount = 0
def bulboptions = bulbsDiscovered() ?: [:]
def numFound = bulboptions.size() ?: 0
if (numFound == 0)
app.updateSetting("selectedBulbs", "")
state.bridgeRefreshCount = 0
def allLightsFound = bulbsDiscovered() ?: [:]
// List lights currently not added to the user (editable)
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) {
discoverHueBulbs()
@@ -148,14 +157,25 @@ def bulbDiscovery() {
def selectedBridge = state.bridges.find { key, value -> value?.serialNumber?.equalsIgnoreCase(selectedHue) }
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) {
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 {
href "bridgeDiscovery", title: title, description: "", state: selectedHue ? "complete" : "incomplete", params: [override: true]
}
}
}
@@ -290,8 +310,11 @@ def manualRefresh() {
}
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.username = null
state.username = null
}
// 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
def idNumber = getBridgeIdNumber(selectedHue)
d = addChildDevice("smartthings", "Hue Bridge", selectedHue, vbridge.value.hub, ["label": "Hue Bridge ($idNumber)"])
d?.completedSetup = true
log.debug "created ${d.displayName} with id ${d.deviceNetworkId}"
def childDevice = getChildDevice(d.deviceNetworkId)
updateBridgeStatus(childDevice)
childDevice.sendEvent(name: "idNumber", value: idNumber)
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))
}
if (d) {
// Associate smartapp to bridge so user will be warned if trying to delete bridge
app.updateSetting("bridgeDevice", [type: "device.hueBridge", value: d.id])
d.completedSetup = true
log.debug "created ${d.displayName} with id ${d.deviceNetworkId}"
def childDevice = getChildDevice(d.deviceNetworkId)
updateBridgeStatus(childDevice)
childDevice.sendEvent(name: "idNumber", value: idNumber)
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 {
childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
}
log.error "Failed to create Hue Bridge device"
}
}
} else {
log.debug "found ${d.displayName} with id $selectedHue already exists"
@@ -1017,12 +1049,12 @@ def setColor(childDevice, huesettings) {
log.debug "Executing 'setColor($huesettings)'"
updateInProgress()
def value = [:]
def hue = null
def sat = null
def xy = null
// For now ignore model to get a consistent color if same color is set across multiple devices
// def model = state.bulbs[getId(childDevice)]?.modelid
if (huesettings.hex != null) {
@@ -1038,11 +1070,12 @@ def setColor(childDevice, huesettings) {
else
value.hue = Math.min(Math.round(childDevice.device?.currentValue("hue") * 65535 / 100), 65535)
if (huesettings.saturation != null)
if (huesettings.saturation != null)
value.sat = Math.min(Math.round(huesettings.saturation * 254 / 100), 254)
else
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) {
// 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)
@@ -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
value.xy = calculateXY(hex)
}
*/
// Default behavior is to turn light on
value.on = true
@@ -1059,7 +1093,7 @@ def setColor(childDevice, huesettings) {
value.on = false
else if (huesettings.level == 1)
value.bri = 1
else
else
value.bri = Math.min(Math.round(huesettings.level * 254 / 100), 254)
}
value.alert = huesettings.alert ? huesettings.alert : "none"