For those of you like me that have hooked up hue lights so they are always on and use switches like the cooper or eaton etc switch with a dimmer control ie
This is the device driver/handler i use that also has been updated for the new smartthings mobile app so it correctly shows the switch state (on/off) in the dashboard view and also has all the features
(ie swtich , color control, dimmer) in the detail view.
I wire my bulbs on all the time so they dont get turned off but still want a switch to control them in the wall. I use color coord smart app to cordinate⌠In this way you can change the color in the app on the switch and all the synced hue lights also change.
Also the separate dimmer up/down on the switch works as well
.
/**
- 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.
- lgk a few changes
-
- switch level capability so level changes get passed through and received from other apps
- like dim with me. Now you can have this control a set of lights and dim based on this.
- also reduced delays as the ge switches delay enough.
- Finally, Added color control capability, rgb control tiles and associated functions,
- and a color control tile⌠I know the switch has nothing
- to do with color. But since you use this device type to control slave lamps using either smart lighting
- smart app or dim with me smartapp. Once this is in place you can use the color coordinator smartapp
- and make this device the master to control the slave bulbs.
- also works with other dimmers. Tested with GE (have delay) and Cooper (Instant). Can control hue lights with
- no load hooked up. Recommend using Color with me App.
*/
metadata {
definition (name: âAdvanced Zwave Dimmer Switch w Color Control V2â, namespace: âlgkappsâ, author: âkahn@lgk.comâ, mnmn: âSmartThingsCommunityâ, vid: â3c16e1df-31b3-326e-91f4-215267497679â )
{
capability âActuatorâ
capability âIndicatorâ
capability âSwitchâ
capability âPollingâ
capability âRefreshâ
capability âSensorâ
capability âSwitch Levelâ
capability âColor Controlâ
capability âHealth Checkâ
command "setColor"
command "setAdjustedColor"
fingerprint inClusters: "0x26"
}
simulator {
status "on": "command: 2003, payload: FF"
status "off": "command: 2003, payload: 00"
status "09%": "command: 2003, payload: 09"
status "10%": "command: 2003, payload: 0A"
status "33%": "command: 2003, payload: 21"
status "66%": "command: 2003, payload: 42"
status "99%": "command: 2003, payload: 63"
// reply messages
reply "2001FF,delay 5000,2602": "command: 2603, payload: FF"
reply "200100,delay 5000,2602": "command: 2603, payload: 00"
reply "200119,delay 5000,2602": "command: 2603, payload: 19"
reply "200132,delay 5000,2602": "command: 2603, payload: 32"
reply "20014B,delay 5000,2602": "command: 2603, payload: 4B"
reply "200163,delay 5000,2602": "command: 2603, payload: 63"
}
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.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
}
}
controlTile(ârgbSelectorâ, âdevice.colorâ, âcolorâ, height: 6, width: 4, inactiveLabel: false) {
state âcolorâ, action:âsetAdjustedColorâ
}
standardTile(âindicatorâ, âdevice.indicatorStatusâ, height: 2, width: 2, inactiveLabel: false, decoration: âflatâ) {
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 â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â, icon:âst.secondary.refreshâ
}
main(["switch"])
details(["switch", "rgbSelector","refresh", "indicator"])
}
}
def parse(String description) {
def item1 = [
canBeCurrentState: false,
linkText: getLinkText(device),
isStateChange: false,
displayed: false,
descriptionText: description,
value: description
]
log.debug "in parse desc = $description"
def result
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
if (cmd) {
result = createEvent(cmd, item1)
}
else {
item1.displayed = displayed(description, item1.isStateChange)
result = [item1]
}
log.debug "Parse returned ${result?.descriptionText}"
result
}
def createEvent(physicalgraph.zwave.commands.basicv1.BasicReport 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.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â
log.debug "result size = $result.size"
for (int i = 0; i < result.size(); i++) {
result[i].type = "digital"
}
result
}
def doCreateEvent(physicalgraph.zwave.Command cmd, Map item1) {
def result = [item1]
log.debug âin create event cmd = $cmdâ
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
def intlevel = item2.value as Integer
setLevel(item2.value)// sendEvent(name:"switch.setLevel",value:intlevel)
result << item2
}
result
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
def value = âwhen offâ
if (cmd.configurationValue[0] == 1) {value = âwhen onâ}
if (cmd.configurationValue[0] == 2) {value = âneverâ}
[name: âindicatorStatusâ, value: value, display: false]
}
def createEvent(physicalgraph.zwave.Command cmd, Map map) {
// Handles any Z-Wave commands we arenât interested in
log.debug âUNHANDLED COMMAND $cmdâ
}
def on() {
log.debug âin onâ
delayBetween([zwave.basicV1.basicSet(value: 0xFF).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 1000)
}
def off() {
log.debug âin offâ
delayBetween ([zwave.basicV1.basicSet(value: 0x00).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 3000)
}
def setLevel(value) {
def valueaux = value as Integer
def level = Math.max(Math.min(valueaux, 99), 0)
log.debug âin set level new level = $levelâ
if (level > 0) {
sendEvent(name: âswitchâ, value: âonâ)
} else {
sendEvent(name: âswitchâ, value: âoffâ)
}
//sendEvent(name:âswitch.setLevelâ,value:level)
delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 500)
}
def setLevelo(value) {
def valueaux = value as Integer
def level = Math.min(valueaux, 99)
log.debug "in set level new level = $level"
delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format(),
sendEvent(name:"switch.setLevel",value:level)], 500)
}
def setLevel(value, duration) {
log.debug âin set level w duration new level = $value duration = $durationâ
def valueaux = value as Integer
def level = Math.min(valueaux, 99)
log.debug âin set level w duration new level = $level duration = $durationâ
def dimmingDuration = duration < 128 ? duration : 128 + Math.round(duration / 60)
zwave.switchMultilevelV2.switchMultilevelSet(value: level, dimmingDuration: dimmingDuration).format()
sendEvent(name:âswitch.setLevelâ,value:level)
}
def poll() {
zwave.switchMultilevelV1.switchMultilevelGet().format()
initialize()
}
def refresh()
{ log.debug âin refreshâ
// invertSwitch()
zwave.switchMultilevelV1.switchMultilevelGet().format()
}
def indicatorWhenOn() {
sendEvent(name: âindicatorStatusâ, value: âwhen onâ, display: false)
zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()
}
def indicatorWhenOff() {
sendEvent(name: âindicatorStatusâ, value: âwhen offâ, display: false)
zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
}
def indicatorNever() {
sendEvent(name: âindicatorStatusâ, value: âneverâ, display: false)
zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()
}
def invertSwitch(invert=true) {
log.debug âin invertâ
if (invert) {
zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 4, size: 1).format()
}
else {
log.debug âturn off invertâ
zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 4, size: 1).format()
}
}
def setColor(value) {
log.debug âsetColor: ${value}, $thisâ
if (value.hue) { sendEvent(name: âhueâ, value: value.hue)}
if (value.saturation) { sendEvent(name: âsaturationâ, value: value.saturation)}
if (value.hex) { sendEvent(name: âcolorâ, value: value.hex)}
if (value.level) { sendEvent(name: âlevelâ, value: value.level)}
}
def setAdjustedColor(value) {
if (value) {
log.trace âsetAdjustedColor: ${value}â
def adjusted = value + [:]
adjusted.hue = adjustOutgoingHue(value.hue)
// Needed because color picker always sends 100
adjusted.level = null
setColor(adjusted)
}
}
def adjustOutgoingHue(percent) {
def adjusted = percent
if (percent > 31) {
if (percent < 63.0) {
adjusted = percent + (7 * (percent -30 ) / 32)
}
else if (percent < 73.0) {
adjusted = 69 + (5 * (percent - 62) / 10)
}
else {
adjusted = percent + (2 * (100 - percent) / 28)
}
}
log.info âpercent: $percent, adjusted: $adjustedâ
adjusted
}
def ping()
{
//command(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x01)) //poll the temperature to ping
}
def installed() {
log.trace âExecuting âinstalledââ
// use settings report time for check interval it is mintes
sendEvent(name: âcheckIntervalâ, value: 3600 , displayed: false, data: [protocol: âzwaveâ, hubHardwareId: device.hub.hardwareID])
initialize()
}
private initialize() {
log.trace âExecuting âinitializeââ
sendEvent(name: "DeviceWatch-DeviceStatus", value: "online")
sendEvent(name: "healthStatus", value: "online")
sendEvent(name: "DeviceWatch-Enroll", value: [protocol: "cloud", scheme:"untracked"].encodeAsJson(), displayed: false)
}