mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-28 13:23:07 +00:00
Compare commits
1 Commits
MSA-1252-3
...
MSA-1240-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a338e4890 |
@@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
* Zw Multichannel
|
|
||||||
*
|
|
||||||
* 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: "Zw Multichannel", namespace: "capabilities", author: "SmartThings") {
|
|
||||||
capability "Zw Multichannel"
|
|
||||||
}
|
|
||||||
|
|
||||||
simulator {
|
|
||||||
status "ZWEvent":""
|
|
||||||
status "ZWInfo":""
|
|
||||||
}
|
|
||||||
|
|
||||||
tiles {
|
|
||||||
valueTile("zwEvent", "device.epEvent", label:"${name}", width:2, height:2) {}
|
|
||||||
valueTile("zwInfo", "device.epInfo", label:"${name}", width:2, height:2) {}
|
|
||||||
main("zwEvent")
|
|
||||||
details(["zwEvent","zwInfo"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse events into attributes
|
|
||||||
def parse(String description) {
|
|
||||||
def pair = description.split(":")
|
|
||||||
createEvent(name: pair[0].trim(), value: pair[1].trim())
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle commands
|
|
||||||
def enableEpEvents(data) {
|
|
||||||
'[enableEpEvents]${data}'
|
|
||||||
}
|
|
||||||
|
|
||||||
def epCmd(num, str) {
|
|
||||||
'[epCmd]${num}:${str}'
|
|
||||||
}
|
|
||||||
@@ -13,19 +13,17 @@
|
|||||||
* for the specific language governing permissions and limitations under the License.
|
* for the specific language governing permissions and limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//@Deprecated: Moved to ZLL Dimmer Bulb
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Polling"
|
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Switch Level"
|
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
|
// simulator metadata
|
||||||
@@ -90,10 +88,6 @@ def refresh() {
|
|||||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig()
|
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
def poll() {
|
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Configuring Reporting and Bindings."
|
log.debug "Configuring Reporting and Bindings."
|
||||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
/**
|
||||||
|
* 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,9 +11,6 @@
|
|||||||
* for the specific language governing permissions and limitations under the License.
|
* for the specific language governing permissions and limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//@Deprecated - Moved to zll-rgbw-bulb
|
|
||||||
|
|
||||||
/* Philips Hue (via Zigbee)
|
/* Philips Hue (via Zigbee)
|
||||||
|
|
||||||
Capabilities:
|
Capabilities:
|
||||||
@@ -25,10 +22,10 @@ Capabilities:
|
|||||||
Sensor
|
Sensor
|
||||||
Switch
|
Switch
|
||||||
Switch Level
|
Switch Level
|
||||||
|
|
||||||
Custom Commands:
|
Custom Commands:
|
||||||
setAdjustedColor
|
setAdjustedColor
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
@@ -44,7 +41,7 @@ metadata {
|
|||||||
|
|
||||||
command "setAdjustedColor"
|
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
|
// simulator metadata
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear - LIGHTIFY", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019", manufacturer: "Philips", model: "LWB006", deviceJoinName: "Philips Hue White"
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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