mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-14 13:11:52 +00:00
Compare commits
3 Commits
MSA-1240-1
...
MSA-1250-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce069d1c75 | ||
|
|
467c6ff055 | ||
|
|
5beacf0ef2 |
@@ -13,17 +13,19 @@
|
||||
* for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
//@Deprecated: Moved to ZLL Dimmer Bulb
|
||||
metadata {
|
||||
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||
|
||||
capability "Actuator"
|
||||
capability "Configuration"
|
||||
capability "Polling"
|
||||
capability "Refresh"
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
|
||||
fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0000,0019"
|
||||
//fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0000,0019"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
@@ -88,6 +90,10 @@ def refresh() {
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig()
|
||||
}
|
||||
|
||||
def poll() {
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
log.debug "Configuring Reporting and Bindings."
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Test Arrival Sensor", namespace: "smartthings", author: "Mr.kim") {
|
||||
capability "Tone"
|
||||
capability "Actuator"
|
||||
capability "Signal Strength"
|
||||
capability "Presence Sensor"
|
||||
capability "Sensor"
|
||||
capability "Battery"
|
||||
|
||||
fingerprint profileId: "FC01", deviceId: "019A"
|
||||
fingerprint profileId: "FC01", deviceId: "0131", inClusters: "0000,0003", outClusters: "0003"
|
||||
fingerprint profileId: "FC01", deviceId: "0131", inClusters: "0000", outClusters: "0006"
|
||||
}
|
||||
|
||||
simulator {
|
||||
status "present": "presence: 1"
|
||||
status "not present": "presence: 0"
|
||||
status "battery": "battery: 27, batteryDivisor: 0A, rssi: 100, lqi: 64"
|
||||
}
|
||||
|
||||
preferences {
|
||||
section {
|
||||
image(name: 'educationalcontent', multiple: true, images: [
|
||||
"http://cdn.device-gse.smartthings.com/Arrival/Arrival1.jpg",
|
||||
"http://cdn.device-gse.smartthings.com/Arrival/Arrival2.jpg"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
tiles {
|
||||
standardTile("presence", "device.presence", width: 2, height: 2, canChangeBackground: true) {
|
||||
state "present", labelIcon:"st.presence.tile.present", backgroundColor:"#53a7c0"
|
||||
state "not present", labelIcon:"st.presence.tile.not-present", backgroundColor:"#ebeef2"
|
||||
}
|
||||
standardTile("beep", "device.beep", decoration: "flat") {
|
||||
state "beep", label:'', action:"tone.beep", icon:"st.secondary.beep", backgroundColor:"#ffffff"
|
||||
}
|
||||
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false) {
|
||||
state "battery", label:'${currentValue}% battery', unit:""/*, backgroundColors:[
|
||||
[value: 5, color: "#BC2323"],
|
||||
[value: 10, color: "#D04E00"],
|
||||
[value: 15, color: "#F1D801"],
|
||||
[value: 16, color: "#FFFFFF"]
|
||||
]*/
|
||||
}
|
||||
/*
|
||||
valueTile("lqi", "device.lqi", decoration: "flat", inactiveLabel: false) {
|
||||
state "lqi", label:'${currentValue}% signal', unit:""
|
||||
}
|
||||
*/
|
||||
|
||||
main "presence"
|
||||
details(["presence", "beep", "battery"/*, "lqi"*/])
|
||||
}
|
||||
}
|
||||
|
||||
def beep() {
|
||||
/*
|
||||
You can make the speaker turn on for 0.5-second beeps by sending some CLI commands:
|
||||
|
||||
Command: send raw, wait 7, send raw, wait 7, send raw
|
||||
Future: new packet type "st.beep"
|
||||
|
||||
raw 0xFC05 {15 0A 11 00 00 15 01}
|
||||
send 0x2F7F 2 2
|
||||
|
||||
where "0xABCD" is the node ID of the Smart Tag, everything else above is a constant. Except
|
||||
the "15 01" at the end of the first raw command, that sets the speaker's period (reciprocal
|
||||
of frequency). You can play with this value up or down to experiment with loudness as the
|
||||
loudness will be strongly dependent upon frequency and the enclosure that it's in. Note that
|
||||
"15 01" represents the hex number 0x0115 so a lower frequency is "16 01" (longer period) and
|
||||
a higher frequency is "14 01" (shorter period). Note that since the tag only checks its parent
|
||||
for messages every 5 seconds (while at rest) or every 3 seconds (while in motion) it will take
|
||||
up to this long from the time you send the message to the time you hear a sound.
|
||||
*/
|
||||
|
||||
[
|
||||
"raw 0xFC05 {15 0A 11 00 00 15 01}",
|
||||
"delay 7000",
|
||||
"raw 0xFC05 {15 0A 11 00 00 15 01}",
|
||||
"delay 7000",
|
||||
"raw 0xFC05 {15 0A 11 00 00 15 01}",
|
||||
"delay 7000",
|
||||
"raw 0xFC05 {15 0A 11 00 00 15 01}",
|
||||
"delay 7000",
|
||||
"raw 0xFC05 {15 0A 11 00 00 15 01}"
|
||||
]
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def results
|
||||
if (isBatteryMessage(description)) {
|
||||
results = parseBatteryMessage(description)
|
||||
}
|
||||
else {
|
||||
results = parsePresenceMessage(description)
|
||||
}
|
||||
|
||||
log.debug "Parse returned $results.descriptionText"
|
||||
results
|
||||
}
|
||||
|
||||
private Map parsePresenceMessage(String description) {
|
||||
def name = parseName(description)
|
||||
def value = parseValue(description)
|
||||
def linkText = getLinkText(device)
|
||||
def descriptionText = parseDescriptionText(linkText, value, description)
|
||||
def handlerName = getState(value)
|
||||
def isStateChange = isStateChange(device, name, value)
|
||||
|
||||
def results = [
|
||||
name: name,
|
||||
value: value,
|
||||
unit: null,
|
||||
linkText: linkText,
|
||||
descriptionText: descriptionText,
|
||||
handlerName: handlerName,
|
||||
isStateChange: isStateChange,
|
||||
displayed: displayed(description, isStateChange)
|
||||
]
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
private String parseName(String description) {
|
||||
if (description?.startsWith("presence: ")) {
|
||||
return "presence"
|
||||
}
|
||||
null
|
||||
}
|
||||
|
||||
private String parseValue(String description) {
|
||||
if (description?.startsWith("presence: "))
|
||||
{
|
||||
if (description?.endsWith("1"))
|
||||
{
|
||||
return "present"
|
||||
}
|
||||
else if (description?.endsWith("0"))
|
||||
{
|
||||
return "not present"
|
||||
}
|
||||
}
|
||||
|
||||
description
|
||||
}
|
||||
|
||||
private parseDescriptionText(String linkText, String value, String description) {
|
||||
switch(value) {
|
||||
case "present": return "$linkText has arrived"
|
||||
case "not present": return "$linkText has left"
|
||||
default: return value
|
||||
}
|
||||
}
|
||||
|
||||
private getState(String value) {
|
||||
def state = value
|
||||
if (value == "present") {
|
||||
state = "arrived"
|
||||
}
|
||||
else if (value == "not present") {
|
||||
state = "left"
|
||||
}
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
private Boolean isBatteryMessage(String description) {
|
||||
// "raw:36EF1C, dni:36EF, battery:1B, rssi:, lqi:"
|
||||
description ==~ /.*battery:.*rssi:.*lqi:.*/
|
||||
}
|
||||
|
||||
private List parseBatteryMessage(String description) {
|
||||
def results = []
|
||||
def parts = description.split(',')
|
||||
parts.each { part ->
|
||||
part = part.trim()
|
||||
if (part.startsWith('battery:')) {
|
||||
def batteryResult = getBatteryResult(part, description)
|
||||
if (batteryResult) {
|
||||
results << batteryResult
|
||||
}
|
||||
}
|
||||
else if (part.startsWith('rssi:')) {
|
||||
def rssiResult = getRssiResult(part, description)
|
||||
if (rssiResult) {
|
||||
results << rssiResult
|
||||
}
|
||||
}
|
||||
else if (part.startsWith('lqi:')) {
|
||||
def lqiResult = getLqiResult(part, description)
|
||||
if (lqiResult) {
|
||||
results << lqiResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
private getBatteryResult(part, description) {
|
||||
def batteryDivisor = description.split(",").find {it.split(":")[0].trim() == "batteryDivisor"} ? description.split(",").find {it.split(":")[0].trim() == "batteryDivisor"}.split(":")[1].trim() : null
|
||||
def name = "battery"
|
||||
def value = zigbee.parseSmartThingsBatteryValue(part, batteryDivisor)
|
||||
def unit = "%"
|
||||
def linkText = getLinkText(device)
|
||||
def descriptionText = "$linkText battery was ${value}${unit}"
|
||||
def isStateChange = isStateChange(device, name, value)
|
||||
|
||||
[
|
||||
name: name,
|
||||
value: value,
|
||||
unit: unit,
|
||||
linkText: linkText,
|
||||
descriptionText: descriptionText,
|
||||
handlerName: name,
|
||||
isStateChange: isStateChange,
|
||||
//displayed: displayed(description, isStateChange)
|
||||
displayed: false
|
||||
]
|
||||
}
|
||||
|
||||
private getRssiResult(part, description) {
|
||||
def name = "rssi"
|
||||
def parts = part.split(":")
|
||||
if (parts.size() != 2) return null
|
||||
|
||||
def valueString = parts[1].trim()
|
||||
def valueInt = Integer.parseInt(valueString, 16)
|
||||
def value = (valueInt - 128).toString()
|
||||
def linkText = getLinkText(device)
|
||||
def descriptionText = "$linkText was $value dBm"
|
||||
def isStateChange = isStateChange(device, name, value)
|
||||
|
||||
[
|
||||
name: name,
|
||||
value: value,
|
||||
unit: "dBm",
|
||||
linkText: linkText,
|
||||
descriptionText: descriptionText,
|
||||
handlerName: null,
|
||||
isStateChange: isStateChange,
|
||||
//displayed: displayed(description, isStateChange)
|
||||
displayed: false
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Use LQI (Link Quality Indicator) as a measure of signal strength. The values
|
||||
* are 0 to 255 (0x00 to 0xFF) and higher values represent higher signal
|
||||
* strength. Return as a percentage of 255.
|
||||
*
|
||||
* Note: To make the signal strength indicator more accurate, we could combine
|
||||
* LQI with RSSI.
|
||||
*/
|
||||
private getLqiResult(part, description) {
|
||||
def name = "lqi"
|
||||
def parts = part.split(":")
|
||||
if (parts.size() != 2) return null
|
||||
|
||||
def valueString = parts[1].trim()
|
||||
def valueInt = Integer.parseInt(valueString, 16)
|
||||
def percentageOf = 255
|
||||
def value = Math.round((valueInt / percentageOf * 100)).toString()
|
||||
def unit = "%"
|
||||
def linkText = getLinkText(device)
|
||||
def descriptionText = "$linkText Signal (LQI) was ${value}${unit}"
|
||||
def isStateChange = isStateChange(device, name, value)
|
||||
|
||||
[
|
||||
name: name,
|
||||
value: value,
|
||||
unit: unit,
|
||||
linkText: linkText,
|
||||
descriptionText: descriptionText,
|
||||
handlerName: null,
|
||||
isStateChange: isStateChange,
|
||||
//displayed: displayed(description, isStateChange)
|
||||
displayed: false
|
||||
]
|
||||
}
|
||||
@@ -11,6 +11,9 @@
|
||||
* for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
//@Deprecated - Moved to zll-rgbw-bulb
|
||||
|
||||
/* Philips Hue (via Zigbee)
|
||||
|
||||
Capabilities:
|
||||
@@ -22,10 +25,10 @@ Capabilities:
|
||||
Sensor
|
||||
Switch
|
||||
Switch Level
|
||||
|
||||
|
||||
Custom Commands:
|
||||
setAdjustedColor
|
||||
|
||||
|
||||
*/
|
||||
|
||||
metadata {
|
||||
@@ -41,7 +44,7 @@ metadata {
|
||||
|
||||
command "setAdjustedColor"
|
||||
|
||||
fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019"
|
||||
//fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
|
||||
@@ -33,6 +33,7 @@ metadata {
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0300,0B04,FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY A19 RGBW", deviceJoinName: "OSRAM LIGHTIFY LED A19 RGBW"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0300,0B04,FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY BR RGBW", deviceJoinName: "OSRAM LIGHTIFY LED BR30 RGBW"
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0300,0B04,FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY RT RGBW", deviceJoinName: "OSRAM LIGHTIFY LED RT 5/6 RGBW"
|
||||
fingerprint profileId: "C05E", deviceId: "0220", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019", manufacturer: "LDS", model: "ZLL-ColorTemperature", deviceJoinName: "LDS ZLL-ColorTemperature"
|
||||
}
|
||||
|
||||
// UI tile definitions
|
||||
@@ -141,4 +142,4 @@ def setHue(value) {
|
||||
def setSaturation(value) {
|
||||
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") //payload-> sat value, transition time
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Copyright 2016 SmartThings
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||
|
||||
capability "Actuator"
|
||||
capability "Configuration"
|
||||
capability "Polling"
|
||||
capability "Refresh"
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019"
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019", manufacturer: "CREE", model: "Connected A-19 60W Equivalent", deviceJoinName: "Cree Connected Bulb"
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light"
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
simulator {
|
||||
// status messages
|
||||
status "on": "on/off: 1"
|
||||
status "off": "on/off: 0"
|
||||
|
||||
// reply messages
|
||||
reply "zcl on-off on": "on/off: 1"
|
||||
reply "zcl on-off off": "on/off: 0"
|
||||
}
|
||||
|
||||
// UI tile definitions
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||
attributeState "level", action:"switch level.setLevel"
|
||||
}
|
||||
}
|
||||
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(["switch", "refresh"])
|
||||
}
|
||||
}
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "description is $description"
|
||||
|
||||
def resultMap = zigbee.getEvent(description)
|
||||
if (resultMap) {
|
||||
sendEvent(resultMap)
|
||||
}
|
||||
else {
|
||||
log.debug "DID NOT PARSE MESSAGE for description : $description"
|
||||
log.debug zigbee.parseDescriptionAsMap(description)
|
||||
}
|
||||
}
|
||||
|
||||
def off() {
|
||||
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
|
||||
}
|
||||
|
||||
def on() {
|
||||
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
|
||||
}
|
||||
|
||||
def setLevel(value) {
|
||||
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh()
|
||||
}
|
||||
|
||||
def poll() {
|
||||
refresh()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
log.debug "Configuring Reporting and Bindings."
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
||||
}
|
||||
150
devicetypes/smartthings/zll-rgbw-bulb.src/zll-rgbw-bulb.groovy
Normal file
150
devicetypes/smartthings/zll-rgbw-bulb.src/zll-rgbw-bulb.groovy
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Copyright 2016 SmartThings
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||
|
||||
capability "Actuator"
|
||||
capability "Color Control"
|
||||
capability "Color Temperature"
|
||||
capability "Configuration"
|
||||
capability "Polling"
|
||||
capability "Refresh"
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019"
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019"
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 RGBW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 RGBW"
|
||||
}
|
||||
|
||||
// UI tile definitions
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", 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"
|
||||
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"
|
||||
}
|
||||
tileAttribute ("device.color", key: "COLOR_CONTROL") {
|
||||
attributeState "color", action:"color control.setColor"
|
||||
}
|
||||
}
|
||||
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..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("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
|
||||
main(["switch"])
|
||||
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
|
||||
}
|
||||
}
|
||||
|
||||
//Globals
|
||||
private getATTRIBUTE_HUE() { 0x0000 }
|
||||
private getATTRIBUTE_SATURATION() { 0x0001 }
|
||||
private getHUE_COMMAND() { 0x00 }
|
||||
private getSATURATION_COMMAND() { 0x03 }
|
||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
||||
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "description is $description"
|
||||
|
||||
def finalResult = zigbee.getEvent(description)
|
||||
if (finalResult) {
|
||||
log.debug finalResult
|
||||
sendEvent(finalResult)
|
||||
}
|
||||
else {
|
||||
def zigbeeMap = zigbee.parseDescriptionAsMap(description)
|
||||
log.trace "zigbeeMap : $zigbeeMap"
|
||||
|
||||
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
|
||||
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
|
||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 360)
|
||||
sendEvent(name: "hue", value: hueValue, displayed:false)
|
||||
}
|
||||
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
|
||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
||||
sendEvent(name: "saturation", value: saturationValue, displayed:false)
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.info "DID NOT PARSE MESSAGE for description : $description"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def on() {
|
||||
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
|
||||
}
|
||||
|
||||
def off() {
|
||||
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
refreshAttributes() + configureAttributes()
|
||||
}
|
||||
|
||||
def poll() {
|
||||
refreshAttributes()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
log.debug "Configuring Reporting and Bindings."
|
||||
configureAttributes() + refreshAttributes()
|
||||
}
|
||||
|
||||
def configureAttributes() {
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, 0x20, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, 0x20, 1, 3600, 0x01)
|
||||
}
|
||||
|
||||
def refreshAttributes() {
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.readAttribute(0x0300, 0x00) + zigbee.readAttribute(0x0300, ATTRIBUTE_HUE) + zigbee.readAttribute(0x0300, ATTRIBUTE_SATURATION)
|
||||
}
|
||||
|
||||
def setColorTemperature(value) {
|
||||
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
|
||||
}
|
||||
|
||||
def setLevel(value) {
|
||||
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
|
||||
}
|
||||
|
||||
def setColor(value){
|
||||
log.trace "setColor($value)"
|
||||
zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes()
|
||||
}
|
||||
|
||||
def setHue(value) {
|
||||
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
|
||||
}
|
||||
|
||||
def setSaturation(value) {
|
||||
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") //payload-> sat value, transition time
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Copyright 2016 SmartThings
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||
|
||||
capability "Actuator"
|
||||
capability "Color Temperature"
|
||||
capability "Configuration"
|
||||
capability "Polling"
|
||||
capability "Refresh"
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
|
||||
attribute "colorName", "string"
|
||||
command "setGenericName"
|
||||
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, 0B04, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 TW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 Tunable White"
|
||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"PAR16 50 TW", deviceJoinName: "OSRAM LIGHTIFY LED PAR16 50 Tunable White"
|
||||
}
|
||||
|
||||
// UI tile definitions
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||
attributeState "level", action:"switch level.setLevel"
|
||||
}
|
||||
tileAttribute ("colorName", key: "SECONDARY_CONTROL") {
|
||||
attributeState "colorName", label:'${currentValue}'
|
||||
}
|
||||
}
|
||||
|
||||
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
|
||||
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..6500)") {
|
||||
state "colorTemperature", action:"color temperature.setColorTemperature"
|
||||
}
|
||||
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "colorTemperature", label: '${currentValue} K'
|
||||
}
|
||||
|
||||
main(["switch"])
|
||||
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
|
||||
}
|
||||
}
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "description is $description"
|
||||
def event = zigbee.getEvent(description)
|
||||
if (event) {
|
||||
sendEvent(event)
|
||||
}
|
||||
else {
|
||||
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
||||
log.debug zigbee.parseDescriptionAsMap(description)
|
||||
}
|
||||
}
|
||||
|
||||
def off() {
|
||||
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
|
||||
}
|
||||
|
||||
def on() {
|
||||
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
|
||||
}
|
||||
|
||||
def setLevel(value) {
|
||||
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh()
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
||||
}
|
||||
|
||||
def poll() {
|
||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
log.debug "Configuring Reporting and Bindings."
|
||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
||||
}
|
||||
|
||||
def setColorTemperature(value) {
|
||||
setGenericName(value)
|
||||
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
|
||||
}
|
||||
|
||||
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
||||
def setGenericName(value){
|
||||
if (value != null) {
|
||||
def genericName = ""
|
||||
if (value < 3300) {
|
||||
genericName = "Soft White"
|
||||
} else if (value < 4150) {
|
||||
genericName = "Moonlight"
|
||||
} else if (value <= 5000) {
|
||||
genericName = "Cool White"
|
||||
} else {
|
||||
genericName = "Daylight"
|
||||
}
|
||||
sendEvent(name: "colorName", value: genericName)
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Turn It On For 5 Minutes
|
||||
* Turn on a switch when a contact sensor opens and then turn it back off 5 minutes later.
|
||||
*
|
||||
* Author: SmartThings
|
||||
*/
|
||||
definition(
|
||||
name: "Turn It On For 1 Minutes",
|
||||
namespace: "smartthings",
|
||||
author: "mr.kim",
|
||||
description: "When a SmartSense Multi is opened, a switch will be turned on, and then turned off after 5 minutes.",
|
||||
category: "Safety & Security",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_contact-outlet.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_contact-outlet@2x.png"
|
||||
)
|
||||
|
||||
preferences {
|
||||
section("When it opens..."){
|
||||
input "contact1", "capability.contactSensor"
|
||||
}
|
||||
section("Turn on a switch for 5 minutes..."){
|
||||
input "switch1", "capability.switch"
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
log.debug "Installed with settings: ${settings}"
|
||||
subscribe(contact1, "contact.open", contactOpenHandler)
|
||||
}
|
||||
|
||||
def updated(settings) {
|
||||
log.debug "Updated with settings: ${settings}"
|
||||
unsubscribe()
|
||||
subscribe(contact1, "contact.open", contactOpenHandler)
|
||||
}
|
||||
|
||||
def contactOpenHandler(evt) {
|
||||
switch1.on()
|
||||
def fiveMinuteDelay = 60 * 1
|
||||
runIn(fiveMinuteDelay, turnOffSwitch)
|
||||
}
|
||||
|
||||
def turnOffSwitch() {
|
||||
switch1.off()
|
||||
}
|
||||
Reference in New Issue
Block a user