Compare commits

..

8 Commits

Author SHA1 Message Date
Vinay Rao
62a965d90b Merge pull request #599 from SmartThingsCommunity/staging
Rolling up changes to production from staging 2016-03-10 Release
2016-03-10 16:26:26 -08:00
Vinay Rao
fb9f1dee47 Merge pull request #626 from munds/hue-hotfix
Hue hotfix for color temperature and overall stability
2016-03-10 15:04:01 -08:00
Amol Mundayoor
3a433d3865 Hue hotfix for color temperature and overall stability 2016-03-10 14:21:49 -08:00
Vinay Rao
8f25ff4434 Merge pull request #570 from SmartThingsCommunity/master
Rolling up changes to staging from master
2016-03-01 12:01:26 -08:00
Vinay Rao
515b268374 Merge pull request #549 from SmartThingsCommunity/staging
Rolling up changes to production from staging 2016-02-25 Release
2016-02-26 10:51:42 -08:00
Vinay Rao
9b87d39fe8 Merge pull request #546 from SmartThingsCommunity/master
Rolling up changes from master to staging
2016-02-23 10:50:20 -08:00
Vinay Rao
a103d437c2 Merge pull request #523 from SmartThingsCommunity/staging
Deploy to production 2/18
2016-02-18 09:28:02 -08:00
Vinay Rao
bdd88deb99 Merge pull request #504 from SmartThingsCommunity/staging
Merging changes from staging to production
2016-02-11 22:40:38 -08:00
18 changed files with 154 additions and 349 deletions

View File

@@ -1,240 +0,0 @@
/**
* Copyright 2016 Stuart Buchanan
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
* Aeon Water Sensor (DSB45-ZWEU/DSB45-ZWUS)
*
* Author: Stuart Buchanan, Based on original work by Tosa with thanks
* Date: 2016-03-07
*/
metadata {
definition (name: "Aeon Water Sensor", namespace: "fuzzysb", author: "Stuart Buchanan") {
capability "Water Sensor"
capability "Battery"
capability "Configuration"
fingerprint deviceId: "0x2001", inClusters: "0x30,0x80,0x84,0x71,0x70,0x85,0x86,0x72"
}
simulator {
status "dry": "command: 2001, payload: 00"
status "wet": "command: 2001, payload: FF"
}
tiles {
standardTile("water", "device.water", width: 2, height: 2) {
state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
}
valueTile("battery", "device.battery", inactiveLabel: false, canChangeBackground: true) {
state "battery", label:'${currentValue}% Battery', unit:"",
backgroundColors:[
[value: 19, color: "#BC2323"],
[value: 20, color: "#D04E00"],
[value: 30, color: "#D04E00"],
[value: 40, color: "#DAC400"],
[value: 41, color: "#79b821"]
]
}
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
}
main "water"
details(["water", "battery", "configure"])
}
}
def parse(String description) {
def result = null
if (description.startsWith("Err 106")) {
if (state.sec) {
log.debug description
} else {
result = createEvent(
descriptionText: "This sensor failed to complete the network security key exchange. If you are unable to control it via SmartThings, you must remove it from your network and add it again.",
eventType: "ALERT",
name: "secureInclusion",
value: "failed",
isStateChange: true,
)
}
} else if (description != "updated") {
def cmd = zwave.parse(description, [0x20: 1, 0x25: 1, 0x30: 1, 0x31: 5, 0x80: 1, 0x84: 1, 0x71: 3, 0x9C: 1])
if (cmd) {
result = zwaveEvent(cmd)
}
}
log.debug "parsed '$description' to $result"
return result
}
def updated() {
def cmds = []
if (!state.MSR) {
cmds = [
zwave.manufacturerSpecificV2.manufacturerSpecificGet().format(),
"delay 1200",
zwave.wakeUpV1.wakeUpNoMoreInformation().format()
]
} else if (!state.lastbat) {
cmds = []
} else {
cmds = [zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
}
response(cmds)
}
def configure() {
delayBetween([
zwave.manufacturerSpecificV2.manufacturerSpecificGet().format(),
batteryGetCommand()
], 6000)
}
def sensorValueEvent(value) {
if (value) {
createEvent(name: "water", value: "wet", descriptionText: "$device.displayName is wet")
} else {
createEvent(name: "water", value: "dry", descriptionText: "$device.displayName is dry")
}
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cmd)
{
sensorValueEvent(cmd.sensorValue)
}
def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
{
sensorValueEvent(cmd.sensorState)
}
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd)
{
def result = []
if (cmd.notificationType == 0x06 && cmd.event == 0x16) {
result << sensorValueEvent(1)
} else if (cmd.notificationType == 0x06 && cmd.event == 0x17) {
result << sensorValueEvent(0)
} else if (cmd.notificationType == 0x07) {
if (cmd.v1AlarmType == 0x07) { // special case for nonstandard messages from Monoprice door/window sensors
result << sensorValueEvent(cmd.v1AlarmLevel)
} else if (cmd.event == 0x01 || cmd.event == 0x02) {
result << sensorValueEvent(1)
} else if (cmd.event == 0x03) {
result << createEvent(descriptionText: "$device.displayName covering was removed", isStateChange: true)
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds:4*3600, nodeid:zwaveHubNodeId))
if(!state.MSR) result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
} else if (cmd.event == 0x05 || cmd.event == 0x06) {
result << createEvent(descriptionText: "$device.displayName detected glass breakage", isStateChange: true)
} else if (cmd.event == 0x07) {
if(!state.MSR) result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
result << createEvent(name: "motion", value: "active", descriptionText:"$device.displayName detected motion")
}
} else if (cmd.notificationType) {
def text = "Notification $cmd.notificationType: event ${([cmd.event] + cmd.eventParameter).join(", ")}"
result << createEvent(name: "notification$cmd.notificationType", value: "$cmd.event", descriptionText: text, displayed: false)
} else {
def value = cmd.v1AlarmLevel == 255 ? "active" : cmd.v1AlarmLevel ?: "inactive"
result << createEvent(name: "alarm $cmd.v1AlarmType", value: value, displayed: false)
}
result
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
def event = createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)
def cmds = []
if (!state.MSR) {
cmds << zwave.wakeUpV1.wakeUpIntervalSet(seconds:4*3600, nodeid:zwaveHubNodeId).format()
cmds << zwave.manufacturerSpecificV2.manufacturerSpecificGet().format()
cmds << "delay 1200"
}
if (!state.lastbat || now() - state.lastbat > 53*60*60*1000) {
cmds << batteryGetCommand()
} else {
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
}
[event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "${device.displayName} has a low battery"
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
}
state.lastbat = now()
[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
def result = []
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
log.debug "msr: $msr"
updateDataValue("MSR", msr)
result << createEvent(descriptionText: "$device.displayName MSR: $msr", isStateChange: false)
if (msr == "011A-0601-0901") { // Enerwave motion doesn't always get the associationSet that the hub sends on join
result << response(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId))
} else if (!device.currentState("battery")) {
if (msr == "0086-0102-0059") {
result << response(zwave.securityV1.securityMessageEncapsulation().encapsulate(zwave.batteryV1.batteryGet()).format())
} else {
result << response(batteryGetCommand())
}
}
result
}
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x85: 2, 0x70: 1])
// log.debug "encapsulated: $encapsulatedCommand"
if (encapsulatedCommand) {
state.sec = 1
zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
createEvent(descriptionText: "$device.displayName: $cmd", displayed: false)
}
def batteryGetCommand() {
def cmd = zwave.batteryV1.batteryGet()
if (state.sec) {
cmd = zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd)
}
cmd.format()
}

View File

@@ -48,8 +48,8 @@ metadata {
}
standardTile("motion", "device.motion") {
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {

View File

@@ -1,4 +1,3 @@
/**
* Hue Bulb
*
@@ -11,13 +10,14 @@ metadata {
capability "Switch Level"
capability "Actuator"
capability "Color Control"
capability "Color Temperature"
capability "Switch"
capability "Refresh"
capability "Sensor"
command "setAdjustedColor"
command "reset"
command "refresh"
command "reset"
command "refresh"
}
simulator {
@@ -25,7 +25,7 @@ metadata {
}
tiles (scale: 2){
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
multiAttributeTile(name:"rich-control", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
@@ -33,23 +33,58 @@ metadata {
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
}
tileAttribute ("device.level", key: "SECONDARY_CONTROL") {
attributeState "level", label: 'Level ${currentValue}%'
}
tileAttribute ("device.color", key: "COLOR_CONTROL") {
attributeState "color", action:"setAdjustedColor"
}
}
standardTile("reset", "device.reset", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2000..6500)") {
state "colorTemperature", action:"color temperature.setColorTemperature"
}
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "colorTemperature", label: '${currentValue} K'
}
standardTile("reset", "device.reset", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:"Reset Color", action:"reset", icon:"st.lights.philips.hue-single"
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("refresh", "device.switch", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
}
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") {
state "level", action:"switch level.setLevel"
}
valueTile("level", "device.level", inactiveLabel: false, decoration: "flat") {
state "level", label: 'Level ${currentValue}%'
}
controlTile("saturationSliderControl", "device.saturation", "slider", height: 1, width: 2, inactiveLabel: false) {
state "saturation", action:"color control.setSaturation"
}
valueTile("saturation", "device.saturation", inactiveLabel: false, decoration: "flat") {
state "saturation", label: 'Sat ${currentValue} '
}
controlTile("hueSliderControl", "device.hue", "slider", height: 1, width: 2, inactiveLabel: false) {
state "hue", action:"color control.setHue"
}
valueTile("hue", "device.hue", inactiveLabel: false, decoration: "flat") {
state "hue", label: 'Hue ${currentValue} '
}
main(["switch"])
details(["switch", "levelSliderControl", "rgbSelector", "refresh", "reset"])
main(["switch"])
details(["rich-control", "colorTempSliderControl", "colorTemp", "reset", "refresh"])
}
}
// parse events into attributes
@@ -119,19 +154,27 @@ void setColor(value) {
void reset() {
log.debug "Executing 'reset'"
def value = [level:100, hex:"#90C638", saturation:56, hue:23]
setAdjustedColor(value)
def value = [level:100, hex:"#90C638", saturation:56, hue:23]
setAdjustedColor(value)
parent.poll()
}
void setAdjustedColor(value) {
if (value) {
log.trace "setAdjustedColor: ${value}"
def adjusted = value + [:]
adjusted.hue = adjustOutgoingHue(value.hue)
// Needed because color picker always sends 100
adjusted.level = null
setColor(adjusted)
log.trace "setAdjustedColor: ${value}"
def adjusted = value + [:]
adjusted.hue = adjustOutgoingHue(value.hue)
// Needed because color picker always sends 100
adjusted.level = null
setColor(adjusted)
}
}
void setColorTemperature(value) {
if (value) {
log.trace "setColorTemperature: ${value}k"
parent.setColorTemperature(this, value)
sendEvent(name: "colorTemperature", value: value)
}
}

View File

@@ -13,47 +13,47 @@ metadata {
capability "Refresh"
capability "Sensor"
command "refresh"
command "refresh"
}
simulator {
// TODO: define status and reply messages here
}
tiles(scale: 2) {
multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
tiles(scale: 2) {
multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
}
tileAttribute ("device.level", key: "SECONDARY_CONTROL") {
attributeState "level", label: 'Level ${currentValue}%'
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
}
tileAttribute ("device.level", key: "SECONDARY_CONTROL") {
attributeState "level", label: 'Level ${currentValue}%'
}
}
}
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
}
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") {
state "level", action:"switch level.setLevel"
}
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") {
state "level", action:"switch level.setLevel"
}
standardTile("refresh", "device.switch", inactiveLabel: false, height: 2, width: 2, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main(["switch"])
details(["rich-control", "refresh"])
}
main(["switch"])
details(["rich-control", "refresh"])
}
}
// parse events into attributes

View File

@@ -14,8 +14,6 @@
*
*/
//DEPRECATED - Using the smartsense-motion-sensor.groovy DTH for this device. Users need to be moved before deleting this DTH
metadata {
definition (name: "SmartSense Motion/Temp Sensor", namespace: "smartthings", author: "SmartThings") {
capability "Motion Sensor"
@@ -27,6 +25,10 @@ metadata {
command "enrollResponse"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305-S"
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: "3326"
}
simulator {
@@ -231,7 +233,7 @@ private Map getBatteryResult(rawValue) {
def volts = rawValue / 10
def descriptionText
if (rawValue == 0 || rawValue == 255) {}
if (rawValue == 0) {}
else {
if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."

View File

@@ -13,7 +13,6 @@
* for the specific language governing permissions and limitations under the License.
*
*/
//DEPRECATED - Using the smartsense-multi-sensor.groovy DTH for this device. Users need to be moved before deleting this DTH
metadata {
definition (name: "SmartSense Open/Closed Accelerometer Sensor", namespace: "smartthings", author: "SmartThings") {
@@ -24,7 +23,8 @@
capability "Refresh"
capability "Temperature Measurement"
command "enrollResponse"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321"
}
simulator {
@@ -225,8 +225,7 @@ def getTemperature(value) {
def volts = rawValue / 10
def descriptionText
if (rawValue == 0 || rawValue == 255) {}
else if (volts > 3.5) {
if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else {

View File

@@ -220,8 +220,7 @@ private Map getBatteryResult(rawValue) {
def volts = rawValue / 10
def descriptionText
if (rawValue == 0 || rawValue == 255) {}
else if (volts > 3.5) {
if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else {

View File

@@ -196,8 +196,7 @@ private Map getBatteryResult(rawValue) {
def volts = rawValue / 10
def descriptionText
if (rawValue == 0 || rawValue == 255) {}
else if (volts > 3.5) {
if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else {

View File

@@ -44,7 +44,7 @@ metadata {
attributeState "power", label:'${currentValue} W'
}
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "switch"

View File

@@ -39,7 +39,7 @@ metadata {
attributeState "level", action:"switch level.setLevel"
}
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "switch"

View File

@@ -63,7 +63,7 @@ metadata {
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
controlTile("rgbSelector", "device.color", "color", height: 3, width: 3, inactiveLabel: false) {

View File

@@ -52,7 +52,7 @@
valueTile("battery", "device.battery", inactiveLabel:false, decoration:"flat", width:2, height:2) {
state "battery", label:'${currentValue}% battery', unit:""
}
standardTile("refresh", "device.refresh", inactiveLabel:false, decoration:"flat", width:2, height:2) {
standardTile("refresh", "device.lock", inactiveLabel:false, decoration:"flat", width:2, height:2) {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}

View File

@@ -57,7 +57,7 @@ metadata {
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "colorTemperature", label: '${currentValue} K'
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}

View File

@@ -40,7 +40,7 @@ metadata {
attributeState "power", label:'${currentValue} W'
}
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "switch"

View File

@@ -42,7 +42,7 @@ metadata {
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "switch"

View File

@@ -54,7 +54,7 @@ metadata {
}
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}

View File

@@ -545,15 +545,10 @@ def updateSensorData() {
def occupancy = ""
it.capability.each {
if (it.type == "temperature") {
if (it.value == "unknown") {
temperature = "--"
if (location.temperatureScale == "F") {
temperature = Math.round(it.value.toDouble() / 10)
} else {
if (location.temperatureScale == "F") {
temperature = Math.round(it.value.toDouble() / 10)
} else {
temperature = convertFtoC(it.value.toDouble() / 10)
}
temperature = convertFtoC(it.value.toDouble() / 10)
}
} else if (it.type == "occupancy") {

View File

@@ -15,7 +15,7 @@
* for the specific language governing permissions and limitations under the License.
*
*/
definition(
name: "Hue (Connect)",
namespace: "smartthings",
@@ -24,7 +24,7 @@ definition(
category: "SmartThings Labs",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/hue.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png",
singleInstance: true
//singleInstance: true
)
preferences {
@@ -58,7 +58,7 @@ def bridgeDiscovery(params=[:])
state.bridges = [:]
state.bridgeRefreshCount = 0
app.updateSetting("selectedHue", "")
}
}
subscribe(location, null, locationHandler, [filterEvents:false])
@@ -130,8 +130,8 @@ def bulbDiscovery() {
def bulboptions = bulbsDiscovered() ?: [:]
def numFound = bulboptions.size() ?: 0
if (numFound == 0)
app.updateSetting("selectedBulbs", "")
app.updateSetting("selectedBulbs", "")
if((bulbRefreshCount % 5) == 0) {
discoverHueBulbs()
}
@@ -140,7 +140,7 @@ def bulbDiscovery() {
section("Please wait while we discover your Hue Bulbs. 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 Bulbs (${numFound} found)", multiple:true, options:bulboptions
}
section {
section {
def title = getBridgeIP() ? "Hue bridge (${getBridgeIP()})" : "Find bridges"
href "bridgeDiscovery", title: title, description: "", state: selectedHue ? "complete" : "incomplete", params: [override: true]
@@ -246,13 +246,13 @@ def installed() {
def updated() {
log.trace "Updated with settings: ${settings}"
unsubscribe()
unschedule()
unsubscribe()
unschedule()
initialize()
}
def initialize() {
log.debug "Initializing"
log.debug "Initializing"
unsubscribe(bridge)
state.inBulbDiscovery = false
state.bridgeRefreshCount = 0
@@ -281,18 +281,18 @@ def uninstalled(){
def bulbListHandler(hub, data = "") {
def msg = "Bulbs list not processed. Only while in settings menu."
def bulbs = [:]
if (state.inBulbDiscovery) {
if (state.inBulbDiscovery) {
def logg = ""
log.trace "Adding bulbs to state..."
state.bridgeProcessedLightList = true
def object = new groovy.json.JsonSlurper().parseText(data)
def object = new groovy.json.JsonSlurper().parseText(data)
object.each { k,v ->
if (v instanceof Map)
if (v instanceof Map)
bulbs[k] = [id: k, name: v.name, type: v.type, hub:hub]
}
}
}
def bridge = null
if (selectedHue)
if (selectedHue)
bridge = getChildDevice(selectedHue)
bridge.sendEvent(name: "bulbList", value: hub, data: bulbs, isStateChange: true, displayed: false)
msg = "${bulbs.size()} bulbs found. ${bulbs}"
@@ -318,7 +318,7 @@ def addBulbs() {
} else {
log.debug "$dni in not longer paired to the Hue Bridge or ID changed"
}
} else {
} else {
//backwards compatable
newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni }
d = addChildDevice("smartthings", "Hue Bulb", dni, newHueBulb?.hub, ["label":newHueBulb?.name])
@@ -344,7 +344,7 @@ def addBridge() {
def d = getChildDevice(selectedHue)
if(!d) {
// compatibility with old devices
def newbridge = true
def newbridge = true
childDevices.each {
if (it.getDeviceDataByName("mac")) {
def newDNI = "${it.getDeviceDataByName("mac")}"
@@ -354,10 +354,10 @@ def addBridge() {
it.setDeviceNetworkId("${newDNI}")
if (oldDNI == selectedHue)
app.updateSetting("selectedHue", newDNI)
newbridge = false
newbridge = false
}
}
}
}
}
if (newbridge) {
d = addChildDevice("smartthings", "Hue Bridge", selectedHue, vbridge.value.hub)
log.debug "created ${d.displayName} with id ${d.deviceNetworkId}"
@@ -368,13 +368,13 @@ def addBridge() {
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.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 {
log.debug "found ${d.displayName} with id $selectedHue already exists"
@@ -436,7 +436,7 @@ def locationHandler(evt) {
dstate.name = "Philips hue ($ip)"
d.sendEvent(name:"networkAddress", value: host)
d.updateDataValue("networkAddress", host)
}
}
}
}
}
@@ -504,11 +504,11 @@ def isValidSource(macAddress) {
/////////////////////////////////////
def parse(childDevice, description) {
def parsedEvent = parseLanMessage(description)
def parsedEvent = parseLanMessage(description)
if (parsedEvent.headers && parsedEvent.body) {
def headerString = parsedEvent.headers.toString()
def bodyString = parsedEvent.body.toString()
if (headerString?.contains("json")) {
if (headerString?.contains("json")) {
def body
try {
body = new groovy.json.JsonSlurper().parseText(bodyString)
@@ -516,11 +516,11 @@ def parse(childDevice, description) {
log.warn "Parsing Body failed - trying again..."
poll()
}
if (body instanceof java.util.HashMap) {
if (body instanceof java.util.HashMap) {
//poll response
def bulbs = getChildDevices()
for (bulb in body) {
def d = bulbs.find{it.deviceNetworkId == "${app.id}/${bulb.key}"}
def d = bulbs.find{it.deviceNetworkId == "${app.id}/${bulb.key}"}
if (d) {
if (bulb.value.state?.reachable) {
sendEvent(d.deviceNetworkId, [name: "switch", value: bulb.value?.state?.on ? "on" : "off"])
@@ -535,18 +535,18 @@ def parse(childDevice, description) {
}
} else {
sendEvent(d.deviceNetworkId, [name: "switch", value: "off"])
sendEvent(d.deviceNetworkId, [name: "level", value: 100])
sendEvent(d.deviceNetworkId, [name: "level", value: 100])
if (bulb.value.state.sat) {
def hue = 23
def sat = 56
def hex = colorUtil.hslToHex(23, 56)
sendEvent(d.deviceNetworkId, [name: "color", value: hex])
sendEvent(d.deviceNetworkId, [name: "hue", value: hue])
sendEvent(d.deviceNetworkId, [name: "saturation", value: sat])
}
sendEvent(d.deviceNetworkId, [name: "saturation", value: sat])
}
}
}
}
}
}
else
{ //put response
@@ -595,7 +595,7 @@ def parse(childDevice, description) {
}
}
}
}
} else {
log.debug "parse - got something other than headers,body..."
return []
@@ -616,7 +616,7 @@ def off(childDevice) {
def setLevel(childDevice, percent) {
log.debug "Executing 'setLevel'"
def level
def level
if (percent == 1) level = 1 else level = Math.min(Math.round(percent * 255 / 100), 255)
put("lights/${getId(childDevice)}/state", [bri: level, on: percent > 0])
}
@@ -633,6 +633,14 @@ def setHue(childDevice, percent) {
put("lights/${getId(childDevice)}/state", [hue: level])
}
def setColorTemperature(childDevice, huesettings) {
log.debug "Executing 'setColorTemperature($huesettings)'"
def ct = Math.round(Math.abs((huesettings / 12.96829971181556) - 654))
def value = [ct: ct, on: true]
log.trace "sending command $value"
put("lights/${getId(childDevice)}/state", value)
}
def setColor(childDevice, huesettings) {
log.debug "Executing 'setColor($huesettings)'"
def hue = Math.min(Math.round(huesettings.hue * 65535 / 100), 65535)
@@ -689,7 +697,7 @@ HOST: ${host}
}
private put(path, body) {
def host = getBridgeIP()
def host = getBridgeIP()
def uri = "/api/${state.username}/$path"
def bodyJSON = new groovy.json.JsonBuilder(body).toString()
def length = bodyJSON.getBytes().size().toString()
@@ -715,11 +723,11 @@ private getBridgeIP() {
host = d.getDeviceDataByName("networkAddress")
else
host = d.latestState('networkAddress').stringValue
}
}
if (host == null || host == "") {
def serialNumber = selectedHue
def bridge = getHueBridges().find { it?.value?.serialNumber?.equalsIgnoreCase(serialNumber) }?.value
if (!bridge) {
if (!bridge) {
bridge = getHueBridges().find { it?.value?.mac?.equalsIgnoreCase(serialNumber) }?.value
}
if (bridge?.ip && bridge?.port) {
@@ -729,9 +737,9 @@ private getBridgeIP() {
host = "${convertHexToIP(bridge?.ip)}:${convertHexToInt(bridge?.port)}"
} else if (bridge?.networkAddress && bridge?.deviceAddress)
host = "${convertHexToIP(bridge?.networkAddress)}:${convertHexToInt(bridge?.deviceAddress)}"
}
}
log.trace "Bridge: $selectedHue - Host: $host"
}
}
return host
}