mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-18 13:20:53 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08ed9170d4 | ||
|
|
9c9fba0939 | ||
|
|
725f9ebec7 | ||
|
|
e217805d98 | ||
|
|
ff39270ba4 | ||
|
|
9d016839c8 |
@@ -0,0 +1,195 @@
|
|||||||
|
/**
|
||||||
|
* Climax PSM-29ZBSR - Zigbee - Power Outlet Switch and Energy Meter
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Thanks to SmartThings and its community!
|
||||||
|
*
|
||||||
|
* Product Page: http://www.climax.com.tw/psm29zb-zb.php
|
||||||
|
* Developer manual https://fccid.io/document.php?id=2553357
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
metadata {
|
||||||
|
definition (name: "Climax Power Outlet", namespace: "bortuzar", author: "bortuzar") {
|
||||||
|
|
||||||
|
capability "Actuator"
|
||||||
|
capability "Configuration"
|
||||||
|
capability "Refresh"
|
||||||
|
capability "Sensor"
|
||||||
|
capability "Switch"
|
||||||
|
capability "Power Meter"
|
||||||
|
|
||||||
|
fingerprint endpointId: "0x0A", profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0702", outClusters: "0000"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||||
|
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
|
||||||
|
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||||
|
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.switch", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||||
|
}
|
||||||
|
valueTile("power", "device.power", inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "power", label: '${currentValue} W'
|
||||||
|
}
|
||||||
|
|
||||||
|
//standardTile("configure", "device.power", inactiveLabel: false, decoration: "flat") {
|
||||||
|
// state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
main(["switch", "power"])
|
||||||
|
details(["switch", "power", "refresh"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parse incoming device messages to generate events
|
||||||
|
def parse(String description) {
|
||||||
|
|
||||||
|
log.debug "Parse Method Called"
|
||||||
|
log.trace description
|
||||||
|
|
||||||
|
if (description?.startsWith("catchall:")) {
|
||||||
|
def msg = zigbee.parse(description)
|
||||||
|
log.trace "data: $msg.data"
|
||||||
|
|
||||||
|
} else if (description?.startsWith("read attr -")) {
|
||||||
|
def descMap = parseDescriptionAsMap(description)
|
||||||
|
log.debug "Desc Map:"
|
||||||
|
log.debug descMap
|
||||||
|
|
||||||
|
if (descMap.cluster == "0006" && descMap.attrId == "0000") {
|
||||||
|
name = "switch"
|
||||||
|
value = descMap.value.endsWith("01") ? "on" : "off"
|
||||||
|
def result = createEvent(name: name, value: value)
|
||||||
|
log.debug "Parse returned ${result?.descriptionText}"
|
||||||
|
return result
|
||||||
|
} else if(descMap.cluster =="0702" && descMap.attrId == "0400") {
|
||||||
|
|
||||||
|
def value = convertHexToInt(descMap.value[-4..-1])/10
|
||||||
|
// Reading the last 4 characters of the string...Maybe 4 are needed. Needs further test.
|
||||||
|
// Dividing by 10 as the Divisor is 10000 and unit is kW for the device. AttrId: 0302 and 0300. Simplifying to 10
|
||||||
|
log.debug value
|
||||||
|
def name = "power"
|
||||||
|
def result = createEvent(name: name, value: value)
|
||||||
|
log.debug "Parse returned ${result?.descriptionText}"
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
def name = description?.startsWith("on/off: ") ? "switch" : null
|
||||||
|
def value = name == "switch" ? (description?.endsWith(" 1") ? "on" : "off") : null
|
||||||
|
def result = createEvent(name: name, value: value)
|
||||||
|
log.debug "Parse returned ${result?.descriptionText}"
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def on() {
|
||||||
|
log.debug "On Method called"
|
||||||
|
sendEvent(name: "switch", value: "on")
|
||||||
|
"st cmd 0x${device.deviceNetworkId} 1 6 1 {}"
|
||||||
|
}
|
||||||
|
|
||||||
|
def off() {
|
||||||
|
log.debug "Off Method called"
|
||||||
|
sendEvent(name: "switch", value: "off")
|
||||||
|
"st cmd 0x${device.deviceNetworkId} 1 6 0 {}"
|
||||||
|
}
|
||||||
|
|
||||||
|
def refresh() {
|
||||||
|
log.debug "Refresh Method called";
|
||||||
|
//read attribute 1024Decimal, translates to 400Hex.
|
||||||
|
[
|
||||||
|
"st rattr 0x${device.deviceNetworkId} 1 6 0", "delay 500",
|
||||||
|
"st rattr 0x${device.deviceNetworkId} 1 0x0702 1024", , "delay 500"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def configure() {
|
||||||
|
|
||||||
|
log.debug "Configure Method called"
|
||||||
|
|
||||||
|
String zigbeeId = swapEndianHex(device.hub.zigbeeId)
|
||||||
|
|
||||||
|
def configCmds = [
|
||||||
|
|
||||||
|
//Switch Reporting
|
||||||
|
"zcl global send-me-a-report 6 0 0x10 0 3600 {01}", "delay 500",
|
||||||
|
"send 0x${device.deviceNetworkId} 1 1", "delay 1000",
|
||||||
|
|
||||||
|
//bing to cluster 0x006. Switch On-Off
|
||||||
|
"zdo bind 0x${device.deviceNetworkId} 1 1 6 {${device.zigbeeId}} {}", "delay 1000",
|
||||||
|
|
||||||
|
//bind to cluster 0x702. Power Consumption
|
||||||
|
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0702 {${device.zigbeeId}} {}", "delay 500",
|
||||||
|
|
||||||
|
]
|
||||||
|
return configCmds + refresh() // send refresh cmds as part of config
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parseDescriptionAsMap(description) {
|
||||||
|
(description - "read attr - ").split(",").inject([:]) { map, param ->
|
||||||
|
def nameAndValue = param.split(":")
|
||||||
|
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private hex(value, width=2) {
|
||||||
|
def s = new BigInteger(Math.round(value).toString()).toString(16)
|
||||||
|
while (s.size() < width) {
|
||||||
|
s = "0" + s
|
||||||
|
}
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer convertHexToInt(hex) {
|
||||||
|
Integer.parseInt(hex,16)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String swapEndianHex(String hex) {
|
||||||
|
reverseArray(hex.decodeHex()).encodeHex()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private byte[] reverseArray(byte[] array) {
|
||||||
|
int i = 0;
|
||||||
|
int j = array.length - 1;
|
||||||
|
byte tmp;
|
||||||
|
while (j > i) {
|
||||||
|
tmp = array[j];
|
||||||
|
array[j] = array[i];
|
||||||
|
array[i] = tmp;
|
||||||
|
j--;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return array
|
||||||
|
}
|
||||||
@@ -55,141 +55,136 @@ metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
standardTile("indicator", "device.indicatorStatus", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
|
standardTile("indicator", "device.indicatorStatus", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
|
||||||
state "when off", action:"indicator.indicatorWhenOn", icon:"st.indicators.lit-when-off"
|
state "when off", action:"indicator.indicatorWhenOn", icon:"st.indicators.lit-when-off"
|
||||||
state "when on", action:"indicator.indicatorNever", icon:"st.indicators.lit-when-on"
|
state "when on", action:"indicator.indicatorNever", icon:"st.indicators.lit-when-on"
|
||||||
state "never", action:"indicator.indicatorWhenOff", icon:"st.indicators.never-lit"
|
state "never", action:"indicator.indicatorWhenOff", icon:"st.indicators.never-lit"
|
||||||
}
|
}
|
||||||
standardTile("refresh", "device.switch", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
|
|
||||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
|
||||||
|
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||||
|
}
|
||||||
|
|
||||||
|
valueTile("level", "device.level", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||||
|
state "level", label:'${currentValue} %', unit:"%", backgroundColor:"#ffffff"
|
||||||
}
|
}
|
||||||
|
|
||||||
main(["switch"])
|
main(["switch"])
|
||||||
details(["switch", "refresh", "indicator"])
|
details(["switch", "level", "indicator", "refresh"])
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse(String description) {
|
def parse(String description) {
|
||||||
def item1 = [
|
def result = null
|
||||||
canBeCurrentState: false,
|
if (description != "updated") {
|
||||||
linkText: getLinkText(device),
|
log.debug "parse() >> zwave.parse($description)"
|
||||||
isStateChange: false,
|
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
|
||||||
displayed: false,
|
if (cmd) {
|
||||||
descriptionText: description,
|
result = zwaveEvent(cmd)
|
||||||
value: description
|
}
|
||||||
]
|
|
||||||
def result
|
|
||||||
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
|
|
||||||
if (cmd) {
|
|
||||||
result = createEvent(cmd, item1)
|
|
||||||
}
|
}
|
||||||
else {
|
if (result?.name == 'hail' && hubFirmwareLessThan("000.011.00602")) {
|
||||||
item1.displayed = displayed(description, item1.isStateChange)
|
result = [result, response(zwave.basicV1.basicGet())]
|
||||||
result = [item1]
|
log.debug "Was hailed: requesting state update"
|
||||||
|
} else {
|
||||||
|
log.debug "Parse returned ${result?.descriptionText}"
|
||||||
}
|
}
|
||||||
log.debug "Parse returned ${result?.descriptionText}"
|
return result
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def createEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, Map item1) {
|
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
|
||||||
def result = doCreateEvent(cmd, item1)
|
dimmerEvents(cmd)
|
||||||
for (int i = 0; i < result.size(); i++) {
|
}
|
||||||
result[i].type = "physical"
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
|
||||||
|
dimmerEvents(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd) {
|
||||||
|
dimmerEvents(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd) {
|
||||||
|
dimmerEvents(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
private dimmerEvents(physicalgraph.zwave.Command cmd) {
|
||||||
|
def value = (cmd.value ? "on" : "off")
|
||||||
|
def result = [createEvent(name: "switch", value: value)]
|
||||||
|
if (cmd.value && cmd.value <= 100) {
|
||||||
|
result << createEvent(name: "level", value: cmd.value, unit: "%")
|
||||||
}
|
}
|
||||||
result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
def createEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd, Map item1) {
|
|
||||||
def result = doCreateEvent(cmd, item1)
|
|
||||||
for (int i = 0; i < result.size(); i++) {
|
|
||||||
result[i].type = "physical"
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStartLevelChange cmd, Map item1) {
|
|
||||||
[]
|
|
||||||
}
|
|
||||||
|
|
||||||
def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd, Map item1) {
|
|
||||||
[response(zwave.basicV1.basicGet())]
|
|
||||||
}
|
|
||||||
|
|
||||||
def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd, Map item1) {
|
|
||||||
def result = doCreateEvent(cmd, item1)
|
|
||||||
for (int i = 0; i < result.size(); i++) {
|
|
||||||
result[i].type = "physical"
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd, Map item1) {
|
|
||||||
def result = doCreateEvent(cmd, item1)
|
|
||||||
result[0].descriptionText = "${item1.linkText} is ${item1.value}"
|
|
||||||
result[0].handlerName = cmd.value ? "statusOn" : "statusOff"
|
|
||||||
for (int i = 0; i < result.size(); i++) {
|
|
||||||
result[i].type = "digital"
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
def doCreateEvent(physicalgraph.zwave.Command cmd, Map item1) {
|
|
||||||
def result = [item1]
|
|
||||||
|
|
||||||
item1.name = "switch"
|
|
||||||
item1.value = cmd.value ? "on" : "off"
|
|
||||||
item1.handlerName = item1.value
|
|
||||||
item1.descriptionText = "${item1.linkText} was turned ${item1.value}"
|
|
||||||
item1.canBeCurrentState = true
|
|
||||||
item1.isStateChange = isStateChange(device, item1.name, item1.value)
|
|
||||||
item1.displayed = item1.isStateChange
|
|
||||||
|
|
||||||
if (cmd.value >= 5) {
|
|
||||||
def item2 = new LinkedHashMap(item1)
|
|
||||||
item2.name = "level"
|
|
||||||
item2.value = cmd.value as String
|
|
||||||
item2.unit = "%"
|
|
||||||
item2.descriptionText = "${item1.linkText} dimmed ${item2.value} %"
|
|
||||||
item2.canBeCurrentState = true
|
|
||||||
item2.isStateChange = isStateChange(device, item2.name, item2.value)
|
|
||||||
item2.displayed = false
|
|
||||||
result << item2
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
|
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
|
||||||
|
log.debug "ConfigurationReport $cmd"
|
||||||
def value = "when off"
|
def value = "when off"
|
||||||
if (cmd.configurationValue[0] == 1) {value = "when on"}
|
if (cmd.configurationValue[0] == 1) {value = "when on"}
|
||||||
if (cmd.configurationValue[0] == 2) {value = "never"}
|
if (cmd.configurationValue[0] == 2) {value = "never"}
|
||||||
[name: "indicatorStatus", value: value, display: false]
|
createEvent([name: "indicatorStatus", value: value])
|
||||||
}
|
}
|
||||||
|
|
||||||
def createEvent(physicalgraph.zwave.Command cmd, Map map) {
|
def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) {
|
||||||
// Handles any Z-Wave commands we aren't interested in
|
createEvent([name: "hail", value: "hail", descriptionText: "Switch button was pressed", displayed: false])
|
||||||
log.debug "UNHANDLED COMMAND $cmd"
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||||
|
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
||||||
|
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
||||||
|
log.debug "productId: ${cmd.productId}"
|
||||||
|
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||||
|
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
||||||
|
updateDataValue("MSR", msr)
|
||||||
|
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd) {
|
||||||
|
[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
|
||||||
|
}
|
||||||
|
|
||||||
|
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||||
|
// Handles all Z-Wave commands we aren't interested in
|
||||||
|
[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
def on() {
|
def on() {
|
||||||
log.info "on"
|
delayBetween([
|
||||||
delayBetween([zwave.basicV1.basicSet(value: 0xFF).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
|
zwave.basicV1.basicSet(value: 0xFF).format(),
|
||||||
|
zwave.switchMultilevelV1.switchMultilevelGet().format()
|
||||||
|
],5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
def off() {
|
def off() {
|
||||||
delayBetween ([zwave.basicV1.basicSet(value: 0x00).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
|
delayBetween([
|
||||||
|
zwave.basicV1.basicSet(value: 0x00).format(),
|
||||||
|
zwave.switchMultilevelV1.switchMultilevelGet().format()
|
||||||
|
],5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
def setLevel(value) {
|
def setLevel(value) {
|
||||||
|
log.debug "setLevel >> value: $value"
|
||||||
def valueaux = value as Integer
|
def valueaux = value as Integer
|
||||||
def level = Math.min(valueaux, 99)
|
def level = Math.max(Math.min(valueaux, 99), 0)
|
||||||
|
if (level > 0) {
|
||||||
|
sendEvent(name: "switch", value: "on")
|
||||||
|
} else {
|
||||||
|
sendEvent(name: "switch", value: "off")
|
||||||
|
}
|
||||||
|
sendEvent(name: "level", value: level, unit: "%")
|
||||||
delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
|
delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
def setLevel(value, duration) {
|
def setLevel(value, duration) {
|
||||||
|
log.debug "setLevel >> value: $value, duration: $duration"
|
||||||
def valueaux = value as Integer
|
def valueaux = value as Integer
|
||||||
def level = Math.min(valueaux, 99)
|
def level = Math.max(Math.min(valueaux, 99), 0)
|
||||||
def dimmingDuration = duration < 128 ? duration : 128 + Math.round(duration / 60)
|
def dimmingDuration = duration < 128 ? duration : 128 + Math.round(duration / 60)
|
||||||
zwave.switchMultilevelV2.switchMultilevelSet(value: level, dimmingDuration: dimmingDuration).format()
|
def getStatusDelay = duration < 128 ? (duration*1000)+2000 : (Math.round(duration / 60)*60*1000)+2000
|
||||||
|
delayBetween ([zwave.switchMultilevelV2.switchMultilevelSet(value: level, dimmingDuration: dimmingDuration).format(),
|
||||||
|
zwave.switchMultilevelV1.switchMultilevelGet().format()], getStatusDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
def poll() {
|
def poll() {
|
||||||
@@ -197,21 +192,27 @@ def poll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def refresh() {
|
def refresh() {
|
||||||
zwave.switchMultilevelV1.switchMultilevelGet().format()
|
log.debug "refresh() is called"
|
||||||
|
def commands = []
|
||||||
|
commands << zwave.switchMultilevelV1.switchMultilevelGet().format()
|
||||||
|
if (getDataValue("MSR") == null) {
|
||||||
|
commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
|
||||||
|
}
|
||||||
|
delayBetween(commands,100)
|
||||||
}
|
}
|
||||||
|
|
||||||
def indicatorWhenOn() {
|
def indicatorWhenOn() {
|
||||||
sendEvent(name: "indicatorStatus", value: "when on", display: false)
|
sendEvent(name: "indicatorStatus", value: "when on")
|
||||||
zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()
|
zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()
|
||||||
}
|
}
|
||||||
|
|
||||||
def indicatorWhenOff() {
|
def indicatorWhenOff() {
|
||||||
sendEvent(name: "indicatorStatus", value: "when off", display: false)
|
sendEvent(name: "indicatorStatus", value: "when off")
|
||||||
zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
|
zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
|
||||||
}
|
}
|
||||||
|
|
||||||
def indicatorNever() {
|
def indicatorNever() {
|
||||||
sendEvent(name: "indicatorStatus", value: "never", display: false)
|
sendEvent(name: "indicatorStatus", value: "never")
|
||||||
zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()
|
zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* ZigBee White Color Temperature Bulb
|
||||||
|
*
|
||||||
|
* Author: SmartThings
|
||||||
|
* Date: 2015-09-22
|
||||||
|
*/
|
||||||
|
|
||||||
|
metadata {
|
||||||
|
definition (name: "ZigBee White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings") {
|
||||||
|
|
||||||
|
capability "Actuator"
|
||||||
|
capability "Color Temperature"
|
||||||
|
capability "Configuration"
|
||||||
|
capability "Refresh"
|
||||||
|
capability "Sensor"
|
||||||
|
capability "Switch"
|
||||||
|
capability "Switch Level"
|
||||||
|
|
||||||
|
attribute "colorName", "string"
|
||||||
|
command "setGenericName"
|
||||||
|
|
||||||
|
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0300,0B04", outClusters: "0019"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.switch", 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 finalResult = zigbee.getKnownDescription(description)
|
||||||
|
if (finalResult) {
|
||||||
|
log.info finalResult
|
||||||
|
if (finalResult.type == "update") {
|
||||||
|
log.info "$device updates: ${finalResult.value}"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sendEvent(name: finalResult.type, value: finalResult.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
||||||
|
log.debug zigbee.parseDescriptionAsMap(description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def off() {
|
||||||
|
zigbee.off()
|
||||||
|
}
|
||||||
|
|
||||||
|
def on() {
|
||||||
|
zigbee.on()
|
||||||
|
}
|
||||||
|
|
||||||
|
def setLevel(value) {
|
||||||
|
zigbee.setLevel(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
def refresh() {
|
||||||
|
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
||||||
|
def setGenericName(value){
|
||||||
|
if (value != null) {
|
||||||
|
def genericName = "White"
|
||||||
|
if (value < 3300) {
|
||||||
|
genericName = "Soft White"
|
||||||
|
} else if (value < 4150) {
|
||||||
|
genericName = "Moonlight"
|
||||||
|
} else if (value <= 5000) {
|
||||||
|
genericName = "Cool White"
|
||||||
|
} else if (value >= 5000) {
|
||||||
|
genericName = "Daylight"
|
||||||
|
}
|
||||||
|
sendEvent(name: "colorName", value: genericName)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
* Switch Too
|
|
||||||
*
|
|
||||||
* Copyright 2015 Bob Florian
|
|
||||||
*
|
|
||||||
* 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: "Switch Too", author: "Bob Florian") {
|
|
||||||
capability "Switch"
|
|
||||||
}
|
|
||||||
|
|
||||||
simulator {
|
|
||||||
// TODO: define status and reply messages here
|
|
||||||
}
|
|
||||||
|
|
||||||
tiles {
|
|
||||||
// TODO: define your main and details tiles here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse events into attributes
|
|
||||||
def parse(String description) {
|
|
||||||
log.debug "Parsing '${description}'"
|
|
||||||
// TODO: handle 'switch' attribute
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle commands
|
|
||||||
def on() {
|
|
||||||
log.debug "Executing 'on'"
|
|
||||||
// TODO: handle 'on' command
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
log.debug "Executing 'off'"
|
|
||||||
// TODO: handle 'off' command
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user