Homeseer WD200 LED Color and Ramp rate

I have 25 Homeseer WD200 switches. I migrated to HE from ST. On ST I was able to control the LED color and ramp rate within the device handler settings in the ST app. I could change these settings for each switch individually. Is this possible on HE as well? If so some guidance on exactly how would be appreciated.

If your talking about ramp rate, your talking about dimmers, not switches correct?

A lot of good info, including setting led color in this thread.

1 Like

David thank you for the quick response.Yes, they are dimmers. I read that thread before I posted this new thread. Even after reading that thread I could not figure out how to change the color or ramp rate. I'm enjoying HE its a bit more advanced than ST. I did use Webcore a fair amount for complex rules but it was easier for me to create them because I could look at how other people built pistons that were similar to what I wanted to do.

Could you post a screen shot of how your's are set up? Does each dimmer require a RM command? Or can I set these within the device settings page of each device?

Sure no prob. The way I am using them is to let me know at night if any perimeter doors or windows are open. I have the wall dimmer just have the white led lights that indicate dimming level when all doors and windows are closed. If a door or window is open, the LED's blink Red.

To set this up is two parts. first you need to create two custom commands, then create a rule.

To setup the custom commands:

  1. Click on Apps
  2. Click on Rule Machine
  3. Click "Create Custom Commands"
  4. create a custom command for the led indicator flashing red. after selecting your test device, choose setStatusLED() from the drop down list. It needs three parameters. All three parameters need to be of the string type or it wont work.

After you are done creating the custom command, now you need to create another one that clears the flashing red indicator lights.
Just repeat the steps above, but set the three parameter values to "0".

Then create a rule that applies the custom commands

2 Likes

I have not been able to find a way to set the default color for when the indicators are in dimmer level mode. Only when using the lights as a status indicator used in a rule like above. I believe the ability to set the default color would need to be added to the driver as a settable parameter like it was in the ST handler for it to work.

David you're awesome man, thank you! I will give it a try tonight after I get off work.

1 Like

I tested it last night and it worked! Thanks for the help with that, I wasn't ever going to get there on my own.

What is the difference between the 8 and the 0 in the first parameter?

There are 7 LEDs, and I remember the ST driver Darwin created, he added the 8 to = 'all'. 0 seems to behave the same, I tested (0,1,0) and got the same results as (8,1,0).

Concur. SetLED doesnt behave as expected...anyway for the code to be posted so we can take a look? Or perhaps there is a some other code out there we can use?

Ok, so I did a search and found Homeseer's own Smartthings' driver code. I modified it to work on HE. Here is what I have and am using now:

HomeSeer HS-WD200+ Hubitat Code

/**

  • HomeSeer HS-WD200+
  • Copyright 2018 HomeSeer
  • Modified from the work by DarwinsDen device handler for the WD100 version 1.03
  • 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.
  • Author: HomeSeer
  • Date: 12/2017
  • Changelog:
  • 1.0.dd.8 28-Jul-2018 Additional protection against floating point default preference values
  • 1.0.dd.6 27-Jul-2018 Added call to set led flash rate and added protection against floating point default preference values
  • 1.0.dd.5 26-Mar-2018 Corrected issues: 1) Turning off all LEDs did not return switch to Normal mode,
  •                    2) Turning off last lit LED would set Normal mode, but leave LED state as on (darwin@darwinsden.com)
    
  • 1.0.dd.4 28-Feb-2018 Updated all LED option to use LED=0 (8 will be depricated) and increased delay by 50ms (darwin@darwinsden.com)
  • 1.0.dd.3 19-Feb-2018 Corrected bit-wise blink off operator (darwin@darwinsden.com)
  • 1.0.dd.2 16-Feb 2018 Added button number labels to virtual buttons and reduced size (darwin@darwinsden.com)
  • 1.0.dd.1 15-Feb 2018 Added option to set all LED's simultaneously(darwin@darwinsden.com)
  • 1.0 Jan 2017 Initial Version
  • Button Mappings:
  • ACTION BUTTON# BUTTON ACTION
  • Double-Tap Up 1 pressed
  • Double-Tap Down 2 pressed
  • Triple-Tap Up 3 pressed
  • Triple-Tap Down 4 pressed
  • Hold Up 5 pressed
  • Hold Down 6 pressed
  • Single-Tap Up 7 pressed
  • Single-Tap Down 8 pressed
  • 4 taps up 9 pressed
  • 4 taps down 10 pressed
  • 5 taps up 11 pressed
  • 5 taps down 12 pressed

*/

metadata {
definition (name: "WD200+ Dimmer", namespace: "homeseer", author: "support@homeseer.com") {
capability "Switch Level"
capability "Actuator"
capability "Indicator"
capability "Switch"
capability "Polling"
capability "Refresh"
capability "Sensor"
/* capability "Button" */
capability "Configuration"

    command "tapUp2"
    command "tapDown2"
    command "tapUp3"
    command "tapDown3"
    command "tapUp4"
    command "tapDown4"
    command "tapUp5"
    command "tapDown5"
    command "holdUp"
    command "holdDown"
    command "setStatusLed"
    command "setSwitchModeNormal"
    command "setSwitchModeStatus"
    command "setDefaultColor"
    command "setBlinkDurationMilliseconds"
    
    fingerprint mfr: "000C", prod: "4447", model: "3036"

}

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"

}

preferences {      
   input "doubleTapToFullBright", "bool", title: "Double-Tap Up sets to full brightness",  defaultValue: false,  displayDuringSetup: true, required: false	       
   input "singleTapToFullBright", "bool", title: "Single-Tap Up sets to full brightness",  defaultValue: false,  displayDuringSetup: true, required: false	
   input "doubleTapDownToDim",    "bool", title: "Double-Tap Down sets to 25% level",      defaultValue: false,  displayDuringSetup: true, required: false	       
   input "reverseSwitch", "bool", title: "Reverse Switch",  defaultValue: false,  displayDuringSetup: true, required: false
   input "bottomled", "bool", title: "Bottom LED On if Load is Off",  defaultValue: false,  displayDuringSetup: true, required: false
   input ( "localcontrolramprate", "number", title: "Press Configuration button after changing preferences\n\nLocal Ramp Rate: Duration (0-90)(1=1 sec) [default: 3]", defaultValue: 3,range: "0..90", required: false)
   input ( "remotecontrolramprate", "number", title: "Remote Ramp Rate: duration (0-90)(1=1 sec) [default: 3]", defaultValue: 3, range: "0..90", required: false)       
   input ( "color", "enum", title: "Default LED Color", options: ["White", "Red", "Green", "Blue", "Magenta", "Yellow", "Cyan"], description: "Select Color", required: false)
}

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.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
}
tileAttribute("device.status", key: "SECONDARY_CONTROL") {
attributeState("default", label:'${currentValue}', unit:"")
}
}

  standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
  	state "default", label:'', action:"refresh.refresh", icon:"st.secondary.configure"
  }
    
    valueTile("firmwareVersion", "device.firmwareVersion", width:2, height: 2, decoration: "flat", inactiveLabel: false) {
  	state "default", label: '${currentValue}'
  }
    
  valueTile("level", "device.level", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
  	state "level", label:'${currentValue} %', unit:"%", backgroundColor:"#ffffff"
  }

    valueTile("tapUp2", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 1\nTap\n▲▲", backgroundColor: "#ffffff", action: "tapUp2"
  }     

    valueTile("tapDown2", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 2\nTap\n▼▼", backgroundColor: "#ffffff", action: "tapDown2"
  } 

    valueTile("tapUp3", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 3\nTap\n▲▲▲", backgroundColor: "#ffffff", action: "tapUp3"
  } 

    valueTile("tapDown3", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 4\nTap\n▼▼▼", backgroundColor: "#ffffff", action: "tapDown3"
  }
    valueTile("tapUp1", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 7\nTap\n▲", backgroundColor: "#ffffff", action: "tapUp1"
  }     

    valueTile("tapDown1", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 8\nTap\n▼", backgroundColor: "#ffffff", action: "tapDown1"
  } 

    valueTile("tapUp4", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 9\nTap\n▲▲▲▲", backgroundColor: "#ffffff", action: "tapUp4"
  } 
    
    valueTile("tapDown4", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 10\nTap\n▼▼▼▼", backgroundColor: "#ffffff", action: "tapDown4"
  } 
    
    valueTile("tapUp5", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 11\nTap\n▲▲▲▲▲", backgroundColor: "#ffffff", action: "tapUp5"
  } 

    valueTile("tapDown5", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 12\nTap\n▼▼▼▼▼", backgroundColor: "#ffffff", action: "tapDown5"
  } 

    valueTile("holdUp", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 5\nHold\n▲", backgroundColor: "#ffffff", action: "holdUp"
  } 

    valueTile("holdDown", "device.button", width: 1, height: 1, decoration: "flat") {
  	state "default", label: "Button 6\nHold\n▼", backgroundColor: "#ffffff", action: "holdDown"
    }
    
  main(["switch"])
    
  details(["switch","tapUp2","tapDown2","tapUp3","tapDown3","holdUp","holdDown","tapUp1","tapDown1","tapUp4","tapDown4","tapUp5","tapDown5","level","firmwareVersion","refresh"])

}
}

def parse(String description) {
def result = null
log.debug (description)
if (description != "updated") {
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
if (cmd) {
result = zwaveEvent(cmd)
}
}
if (!result){
log.debug "Parse returned ${result} for command ${cmd}"
}
else {
log.debug "Parse returned ${result}"
}
return result
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) {
dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet cmd) {
dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd) {
dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd) {
dimmerEvents(cmd)
}

private dimmerEvents(hubitat.zwave.Command cmd) {
def value = (cmd.value ? "on" : "off")
def result = [createEvent(name: "switch", value: value)]
state.lastLevel = cmd.value
if (cmd.value && cmd.value <= 100) {
result << createEvent(name: "level", value: cmd.value, unit: "%")
}
return result
}

def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
log.debug "ConfigurationReport $cmd"
def value = "when off"
if (cmd.configurationValue[0] == 1) {value = "when on"}
if (cmd.configurationValue[0] == 2) {value = "never"}
createEvent([name: "indicatorStatus", value: value])
}

def zwaveEvent(hubitat.zwave.commands.hailv1.Hail cmd) {
createEvent([name: "hail", value: "hail", descriptionText: "Switch button was pressed", displayed: false])
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
log.debug "manufacturerId: ${cmd.manufacturerId}"
log.debug "manufacturerName: ${cmd.manufacturerName}"
state.manufacturer=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)
setFirmwareVersion()
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.versionv1.VersionReport cmd) {
//updateDataValue("applicationVersion", "${cmd.applicationVersion}")
log.debug ("received Version Report")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
state.firmwareVersion=cmd.applicationVersion+'.'+cmd.applicationSubVersion
log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
setFirmwareVersion()
createEvent([descriptionText: "Firmware V"+state.firmwareVersion, isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.firmwareupdatemdv2.FirmwareMdReport cmd) {
log.debug ("received Firmware Report")
log.debug "checksum: ${cmd.checksum}"
log.debug "firmwareId: ${cmd.firmwareId}"
log.debug "manufacturerId: ${cmd.manufacturerId}"
[:]
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd) {
[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
}

def zwaveEvent(hubitat.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
[:]
}

def on() {
sendEvent(tapUp1Response("digital"))
delayBetween([
zwave.basicV1.basicSet(value: 0xFF).format(),
zwave.switchMultilevelV1.switchMultilevelGet().format()
],5000)
}

def off() {
sendEvent(tapDown1Response("digital"))
delayBetween([
zwave.basicV1.basicSet(value: 0x00).format(),
zwave.switchMultilevelV1.switchMultilevelGet().format()
],5000)
}

def setLevel (value) {
log.debug "setLevel >> value: $value"
def valueaux = value as Integer
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: "%")
def result =

result += response(zwave.basicV1.basicSet(value: level))
result += response("delay 5000")
result += response(zwave.switchMultilevelV1.switchMultilevelGet())
result += response("delay 5000")
result += response(zwave.switchMultilevelV1.switchMultilevelGet())

}

/*

  • Set dimmer to status mode, then set the color of the individual LED
  • led = 1-7
  • color = 0=0ff
  •      1=red
    
  •      2=green
    
  •      3=blue
    
  •      4=magenta
    
  •      5=yellow
    
  •      6=cyan
    
  •      7=white
    

*/

def setBlinkDurationMilliseconds (newBlinkDuration) {
def cmds=
if (0<newBlinkDuration && newBlinkDuration<25500){
log.debug "setting blink duration to: ${newBlinkDuration} ms"
state.blinkDuration = newBlinkDuration.toInteger()/100
log.debug "blink duration config parameter 30 is: ${state.blinkDuration}"
cmds << zwave.configurationV2.configurationSet(configurationValue: [state.blinkDuration.toInteger()], parameterNumber: 30, size: 1).format()
} else
{
log.debug "commanded blink duration ${newBlinkDuration} is outside range 0 .. 25500 ms"
}
return cmds
}

def setStatusLed (led,color,blink) {
def cmds=

if(state.statusled1==null) {    	
	state.statusled1=0
    state.statusled2=0
    state.statusled3=0
    state.statusled4=0
    state.statusled5=0
    state.statusled6=0
    state.statusled7=0
    state.blinkval=0
}

/* set led # and color */
switch(led) {
	case 1:
    	state.statusled1=color
        break
    case 2:
    	state.statusled2=color
        break
	case 3:
    	state.statusled3=color
        break
    case 4:
    	state.statusled4=color
        break
    case 5:
    	state.statusled5=color
        break
    case 6:
    	state.statusled6=color
        break
    case 7:
    	state.statusled7=color
        break
    case 0:
    case 8:
        // Special case - all LED's
    	state.statusled1=color
        state.statusled2=color
        state.statusled3=color
        state.statusled4=color
        state.statusled5=color
        state.statusled6=color
        state.statusled7=color
        break

}

if(state.statusled1==0 && state.statusled2==0 && state.statusled3==0 && state.statusled4==0 && state.statusled5==0 && state.statusled6==0 && state.statusled7==0)
{
	// no LEDS are set, put back to NORMAL mode
    cmds << zwave.configurationV2.configurationSet(configurationValue: [0], parameterNumber: 13, size: 1).format()         
}
else
{
   // at least one LED is set, put to status mode
   cmds << zwave.configurationV2.configurationSet(configurationValue: [1], parameterNumber: 13, size: 1).format()
}

if (led==8 | led==0) 
{
     for (def ledToChange = 1; ledToChange <= 7; ledToChange++)
     {
       // set color for all LEDs
       cmds << zwave.configurationV2.configurationSet(configurationValue: [color], parameterNumber: ledToChange+20, size: 1).format()
     }
}
else
{
       // set color for specified LED
       cmds << zwave.configurationV2.configurationSet(configurationValue: [color], parameterNumber: led+20, size: 1).format()
}   

// check if LED should be blinking
def blinkval = state.blinkval

if(blink)
{
        switch(led) {
        	case 1:
            	blinkval = blinkval | 0x1
                break
            case 2:
            	blinkval = blinkval | 0x2
                break
            case 3:
            	blinkval = blinkval | 0x4
                break
            case 4:
            	blinkval = blinkval | 0x8
                break
            case 5:
            	blinkval = blinkval | 0x10
                break
            case 6:
            	blinkval = blinkval | 0x20
                break
            case 7:
            	blinkval = blinkval | 0x40
                break
            case 0:
            case 8:
            	blinkval = 0x7F
                break
        }
    	cmds << zwave.configurationV2.configurationSet(configurationValue: [blinkval], parameterNumber: 31, size: 1).format()
        state.blinkval = blinkval
        // set blink frequency if not already set, 5=500ms
        if(state.blinkDuration == null | state.blinkDuration < 0 | state.blinkDuration > 255) {
           cmds << zwave.configurationV2.configurationSet(configurationValue: [5], parameterNumber: 30, size: 1).format()
        }
 }
 else
 {
    
    	switch(led) {
        	case 1:
            	blinkval = blinkval & 0xFE
                break
            case 2:
            	blinkval = blinkval & 0xFD
                break
            case 3:
            	blinkval = blinkval & 0xFB
                break
            case 4:
            	blinkval = blinkval & 0xF7
                break
            case 5:
            	blinkval = blinkval & 0xEF
                break
            case 6:
            	blinkval = blinkval & 0xDF
                break
            case 7:
            	blinkval = blinkval & 0xBF
                break
            case 0:  
            case 8:
            	blinkval = 0
                break         
        }
        cmds << zwave.configurationV2.configurationSet(configurationValue: [blinkval], parameterNumber: 31, size: 1).format()
        state.blinkval = blinkval
}     
  delayBetween(cmds, 150)

}

/*

  • Set Dimmer to Normal dimming mode (exit status mode)

*/
def setSwitchModeNormal() {
def cmds=
cmds << zwave.configurationV2.configurationSet(configurationValue: [0], parameterNumber: 13, size: 1).format()
delayBetween(cmds, 500)
}

/*

  • Set Dimmer to Status mode (exit normal mode)

*/
def setSwitchModeStatus() {
def cmds=
cmds << zwave.configurationV2.configurationSet(configurationValue: [1], parameterNumber: 13, size: 1).format()
delayBetween(cmds, 500)
}

/*

  • Set the color of the LEDS for normal dimming mode, shows the current dim level
    */
    def setDefaultColor(color) {
    def cmds=
    cmds << zwave.configurationV2.configurationSet(configurationValue: [color], parameterNumber: 14, size: 1).format()
    delayBetween(cmds, 500)
    }

def poll() {
zwave.switchMultilevelV1.switchMultilevelGet().format()
}

def refresh() {
log.debug "refresh() called"
configure()
}

def zwaveEvent(hubitat.zwave.commands.centralscenev1.CentralSceneNotification cmd) {
log.debug("sceneNumber: ${cmd.sceneNumber} keyAttributes: ${cmd.keyAttributes}")
def result =

switch (cmd.sceneNumber) {
  case 1:
      // Up
      switch (cmd.keyAttributes) {
          case 0:
               // Press Once
              result += createEvent(tapUp1Response("physical"))  
              result += createEvent([name: "switch", value: "on", type: "physical"])
   
              if (singleTapToFullBright)
              {
                 result += setLevel(99)
                 result += response("delay 5000")
                 result += response(zwave.switchMultilevelV1.switchMultilevelGet())
              } 
              break
          case 1:
              result=createEvent([name: "switch", value: "on", type: "physical"])
              break
          case 2:
              // Hold
              result += createEvent(holdUpResponse("physical"))  
              result += createEvent([name: "switch", value: "on", type: "physical"])    
              break
          case 3: 
              // 2 Times
              result +=createEvent(tapUp2Response("physical"))
              if (doubleTapToFullBright)
              {
                 result += setLevel(99)
                 result += response("delay 5000")
                 result += response(zwave.switchMultilevelV1.switchMultilevelGet())
              }                    
              break
          case 4:
              // 3 times
              result=createEvent(tapUp3Response("physical"))
              break
          case 5:
              // 4 times
              result=createEvent(tapUp4Response("physical"))
              break
          case 6:
              // 5 times
              result=createEvent(tapUp5Response("physical"))
              break
          default:
              log.debug ("unexpected up press keyAttribute: $cmd.keyAttributes")
      }
      break
      
  case 2:
      // Down
      switch (cmd.keyAttributes) {
          case 0:
              // Press Once
              result += createEvent(tapDown1Response("physical"))
              result += createEvent([name: "switch", value: "off", type: "physical"]) 
              break
          case 1:
              result=createEvent([name: "switch", value: "off", type: "physical"])
              break
          case 2:
              // Hold
              result += createEvent(holdDownResponse("physical"))
              result += createEvent([name: "switch", value: "off", type: "physical"]) 
              break
          case 3: 
              // 2 Times
              result+=createEvent(tapDown2Response("physical"))
              if (doubleTapDownToDim)
              {
                 result += setLevel(25)
                 result += response("delay 5000")
                 result += response(zwave.switchMultilevelV1.switchMultilevelGet())
              }  
              break
          case 4:
              // 3 Times
              result=createEvent(tapDown3Response("physical"))
              break
          case 5:
              // 4 Times
              result=createEvent(tapDown4Response("physical"))
              break
          case 6:
              // 5 Times
              result=createEvent(tapDown5Response("physical"))
              break
          default:
              log.debug ("unexpected down press keyAttribute: $cmd.keyAttributes")
       } 
       break
       
  default:
       // unexpected case
       log.debug ("unexpected scene: $cmd.sceneNumber")

}
return result
}

def tapUp1Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▲")
[name: "button", value: "pushed", data: [buttonNumber: "7"], descriptionText: "$device.displayName Tap-Up-1 (button 7) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapDown1Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▼")
[name: "button", value: "pushed", data: [buttonNumber: "8"], descriptionText: "$device.displayName Tap-Down-1 (button 8) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapUp2Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▲▲")
[name: "button", value: "pushed", data: [buttonNumber: "1"], descriptionText: "$device.displayName Tap-Up-2 (button 1) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapDown2Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▼▼")
[name: "button", value: "pushed", data: [buttonNumber: "2"], descriptionText: "$device.displayName Tap-Down-2 (button 2) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapUp3Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▲▲▲")
[name: "button", value: "pushed", data: [buttonNumber: "3"], descriptionText: "$device.displayName Tap-Up-3 (button 3) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapUp4Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▲▲▲▲")
[name: "button", value: "pushed", data: [buttonNumber: "9"], descriptionText: "$device.displayName Tap-Up-4 (button 9) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapUp5Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▲▲▲▲▲")
[name: "button", value: "pushed", data: [buttonNumber: "11"], descriptionText: "$device.displayName Tap-Up-5 (button 11) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapDown3Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▼▼▼")
[name: "button", value: "pushed", data: [buttonNumber: "4"], descriptionText: "$device.displayName Tap-Down-3 (button 4) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapDown4Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▼▼▼▼")
[name: "button", value: "pushed", data: [buttonNumber: "10"], descriptionText: "$device.displayName Tap-Down-3 (button 10) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapDown5Response(String buttonType) {
sendEvent(name: "status" , value: "Tap ▼▼▼▼▼")
[name: "button", value: "pushed", data: [buttonNumber: "12"], descriptionText: "$device.displayName Tap-Down-3 (button 12) pressed",
isStateChange: true, type: "$buttonType"]
}

def holdUpResponse(String buttonType) {
sendEvent(name: "status" , value: "Hold ▲")
[name: "button", value: "pushed", data: [buttonNumber: "5"], descriptionText: "$device.displayName Hold-Up (button 5) pressed",
isStateChange: true, type: "$buttonType"]
}

def holdDownResponse(String buttonType) {
sendEvent(name: "status" , value: "Hold ▼")
[name: "button", value: "pushed", data: [buttonNumber: "6"], descriptionText: "$device.displayName Hold-Down (button 6) pressed",
isStateChange: true, type: "$buttonType"]
}

def tapUp1() {
sendEvent(tapUp1Response("digital"))
}

def tapDown1() {
sendEvent(tapDown1Response("digital"))
}

def tapUp2() {
sendEvent(tapUp2Response("digital"))
}

def tapDown2() {
sendEvent(tapDown2Response("digital"))
}

def tapUp3() {
sendEvent(tapUp3Response("digital"))
}

def tapDown3() {
sendEvent(tapDown3Response("digital"))
}

def tapUp4() {
sendEvent(tapUp4Response("digital"))
}

def tapDown4() {
sendEvent(tapDown4Response("digital"))
}

def tapUp5() {
sendEvent(tapUp5Response("digital"))
}

def tapDown5() {
sendEvent(tapDown5Response("digital"))
}

def holdUp() {
sendEvent(holdUpResponse("digital"))
}

def holdDown() {
sendEvent(holdDownResponse("digital"))
}

def setFirmwareVersion() {
def versionInfo = ''
if (state.manufacturer)
{
versionInfo=state.manufacturer+' '
}
if (state.firmwareVersion)
{
versionInfo=versionInfo+"Firmware V"+state.firmwareVersion
}
else
{
versionInfo=versionInfo+"Firmware unknown"
}
sendEvent(name: "firmwareVersion", value: versionInfo, isStateChange: true, displayed: false)
}

def configure() {
log.debug ("configure() called")

sendEvent(name: "numberOfButtons", value: 12, displayed: false)
def commands =
commands << setDimRatePrefs()
commands << zwave.switchMultilevelV1.switchMultilevelGet().format()
commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
commands << zwave.versionV1.versionGet().format()
delayBetween(commands,500)
}

def setDimRatePrefs()
{
log.debug ("set prefs")
def cmds =

if (color)
{
switch (color) {
case "White":
cmds << zwave.configurationV2.configurationSet(configurationValue: [0], parameterNumber: 14, size: 1).format()
break
case "Red":
cmds << zwave.configurationV2.configurationSet(configurationValue: [1], parameterNumber: 14, size: 1).format()
break
case "Green":
cmds << zwave.configurationV2.configurationSet(configurationValue: [2], parameterNumber: 14, size: 1).format()
break
case "Blue":
cmds << zwave.configurationV2.configurationSet(configurationValue: [3], parameterNumber: 14, size: 1).format()
break
case "Magenta":
cmds << zwave.configurationV2.configurationSet(configurationValue: [4], parameterNumber: 14, size: 1).format()
break
case "Yellow":
cmds << zwave.configurationV2.configurationSet(configurationValue: [5], parameterNumber: 14, size: 1).format()
break
case "Cyan":
cmds << zwave.configurationV2.configurationSet(configurationValue: [6], parameterNumber: 14, size: 1).format()
break
}
}

if(localcontrolramprate != null) {
//log.debug localcontrolramprate
def localRamprate = Math.max(Math.min(localcontrolramprate.toInteger(), 90), 0)
cmds << zwave.configurationV2.configurationSet(configurationValue: [localRamprate.toInteger()], parameterNumber: 12, size: 1).format()
}

if(remotecontrolramprate != null) {
//log.debug remotecontrolramprate
def remoteRamprate = Math.max(Math.min(remotecontrolramprate.toInteger(), 90), 0)
cmds << zwave.configurationV2.configurationSet(configurationValue: [remoteRamprate.toInteger()], parameterNumber: 11, size: 1).format()
}

if (reverseSwitch)
{
cmds << zwave.configurationV2.configurationSet(configurationValue: [1], parameterNumber: 4, size: 1).format()
}
else
{
cmds << zwave.configurationV2.configurationSet(configurationValue: [0], parameterNumber: 4, size: 1).format()
}

if (bottomled)
{
cmds << zwave.configurationV2.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
}
else
{
cmds << zwave.configurationV2.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()
}

//Enable the following configuration gets to verify configuration in the logs
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 8).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()

return cmds
}

def updated()
{
def cmds=
cmds << setDimRatePrefs
delayBetween(cmds, 500)
}

1 Like

Hi @walksonair. Awesome work. Care to try one for the Homeseer WD100+ dimmers too?

Try this code out. My WD200 port is not perfect so don't expect much from this one:

HomeSeer HS-WD100+ Hubitat Code
/**
 *  HomeSeer HS-WD100+
 *
 *  Copyright 2016, 2017 DarwinsDen.com
 *
 *  For button mappings, device parameter information and images, questions or to provide feedback on this device handler, 
 *  please visit: 
 *
 *      darwinsden.com/homeseer100plus/
 *
 *  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.
 *
 *	Author: Darwin@DarwinsDen.com
 *	Date: 2016-04-10
 *
 *	Changelog:
 *
 *  1.05 (05/06/2018) - Request dim level on hold to improve dim level status. Removed call to set switch status off on hold release.
 *  1.04 (05/04/2018) - Remove call to set switch to off when held down
 *  1.03 (11/14/2017) - Turn off firmware event log, correct physical button setting for some presses, remove 100ms delay in instant status
 *  1.02 (06/25/2017) - Pulled in @stephack's changes to include button 7/8 events when triggered remotely
 *  1.01 (01/16/2017) - Corrected advertised number of buttons (8)
 *  1.00 (01/14/2017) - Added button 7 (single tap up) and button 8 (single tap down). Added double down to 25% dim level option. 
 *  0.17 (10/05/2016) - Added single-tap-up to full brightness option.
 *  0.16 (09/24/2016) - Added double-tap-up to full brightness option and support for firmware dim rate configuration parameters.
 *  0.15 (09/06/2016) - Added Firmware version info. Removed unused lit indicator button.
 *  0.14 (08/01/2016) - Corrected 60% dim rate limit test that was inadvertently pulled into repository
 *  0.13 (06/13/2016) - Added dim level ramp-up option for remote dim commands
 *  0.12 (06/03/2016) - Added press type indicator to display last tap/hold press status
 *  0.11 (05/28/2016) - Set numberOfButtons attribute for ease of use with CoRE and other SmartApps. Corrected physical/digital states.
 *	0.10 (04/10/2016) -	Initial 0.1 Beta.
 *
 *
 *   Button Mappings:
 *
 *   ACTION          BUTTON#    BUTTON ACTION
 *   Double-Tap Up     1        pressed
 *   Double-Tap Down   2        pressed
 *   Triple-Tap Up     3        pressed
 *   Triple-Tap Down   4        pressed
 *   Hold Up           5 	    pressed
 *   Hold Down         6 	    pressed
 *   Single-Tap Up     7        pressed
 *   Single-Tap Down   8        pressed
 *
 */
 
metadata {
	definition (name: "WD100+ Dimmer", namespace: "darwinsden", author: "darwin@darwinsden.com") {
		capability "Switch Level"
		capability "Actuator"
		capability "Indicator"
		capability "Switch"
		capability "Polling"
		capability "Refresh"
		capability "Sensor"
/*        capability "Button" */
        capability "Configuration"
        
        command "tapUp2"
        command "tapDown2"
        command "tapUp3"
        command "tapDown3"
        command "holdUp"
        command "holdDown"
        
        fingerprint deviceId: "0x1101", inClusters: "0x5E, 0x86, 0x72, 0x5A, 0x85, 0x59, 0x73, 0x26, 0x27, 0x70, 0x2C, 0x2B, 0x5B, 0x7A", outClusters: "0x5B"
}

	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"
	}

    preferences {      
       input "doubleTapToFullBright", "bool", title: "Double-Tap Up sets to full brightness",  defaultValue: false,  displayDuringSetup: true, required: false	       
       input "singleTapToFullBright", "bool", title: "Single-Tap Up sets to full brightness",  defaultValue: false,  displayDuringSetup: true, required: false	
       input "doubleTapDownToDim",    "bool", title: "Double-Tap Down sets to 25% level",      defaultValue: false,  displayDuringSetup: true, required: false	       
       input "reverseSwitch", "bool", title: "Reverse Switch",  defaultValue: false,  displayDuringSetup: true, required: false	       
        
       input ( "localStepDuration", "number", title: "Press Configuration button after entering ramp rate preferences\n\nLocal Ramp Rate: Duration of each level (1-22)(1=10ms) [default: 3]", defaultValue: 3,range: "1..22", required: false)
       input ( "localStepSize", "number", title: "Local Ramp Rate: Dim level % to change each duration (1-99) [default: 1]", defaultValue: 1, range: "1..99", required: false)
       input ( "remoteStepDuration", "number", title: "Remote Ramp Rate: Duration of each level (1-22)(1=10ms) [default: 3]", defaultValue: 3,range: "1..22", required: false)
       input ( "remoteStepSize", "number", title: "Remote Ramp Rate: Dim level % to change each duration (1-99) [default: 1]", defaultValue: 1, range: "1..99", required: false)
    }
    
	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.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
				attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
			}
			tileAttribute ("device.level", key: "SLIDER_CONTROL") {
				attributeState "level", action:"switch level.setLevel"
			}
            tileAttribute("device.status", key: "SECONDARY_CONTROL") {
                attributeState("default", label:'${currentValue}', unit:"")
            }
		}

		standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.configure"
		}
        
        valueTile("firmwareVersion", "device.firmwareVersion", width:2, height: 2, decoration: "flat", inactiveLabel: false) {
			state "default", label: '${currentValue}'
		}
        
		valueTile("level", "device.level", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
			state "level", label:'${currentValue} %', unit:"%", backgroundColor:"#ffffff"
		}

        standardTile("tapUp2", "device.button", width: 2, height: 2, decoration: "flat") {
			state "default", label: "Tap ▲▲", backgroundColor: "#ffffff", action: "tapUp2", icon: "st.Home.home30"
		}     
 
        standardTile("tapDown2", "device.button", width: 2, height: 2, decoration: "flat") {
			state "default", label: "Tap ▼▼", backgroundColor: "#ffffff", action: "tapDown2", icon: "st.Home.home30"
		} 

        standardTile("tapUp3", "device.button", width: 2, height: 2, decoration: "flat") {
			state "default", label: "Tap ▲▲▲", backgroundColor: "#ffffff", action: "tapUp3", icon: "st.Home.home30"
		} 

        standardTile("tapDown3", "device.button", width: 2, height: 2, decoration: "flat") {
			state "default", label: "Tap ▼▼▼", backgroundColor: "#ffffff", action: "tapDown3", icon: "st.Home.home30"
		} 

        standardTile("holdUp", "device.button", width: 2, height: 2, decoration: "flat") {
			state "default", label: "Hold ▲", backgroundColor: "#ffffff", action: "holdUp", icon: "st.Home.home30"
		} 

        standardTile("holdDown", "device.button", width: 2, height: 2, decoration: "flat") {
			state "default", label: "Hold ▼", backgroundColor: "#ffffff", action: "holdDown", icon: "st.Home.home30"
        }
        
		main(["switch"])
        
		details(["switch","tapUp2","tapUp3","holdUp","tapDown2","tapDown3","holdDown","level","firmwareVersion", "refresh"])
	}
}

def parse(String description) {
	def result = null
    log.debug (description)
    if (description != "updated") {
	    def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])	
        if (cmd) {
		    result = zwaveEvent(cmd)
	    }
    }
    if (!result){
        log.debug "Parse returned ${result} for command ${cmd}"
    }
    else {
		log.debug "Parse returned ${result}"
    }   
	return result
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) {
 	dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet cmd) {
	dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd) {
    dimmerEvents(cmd) 
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd) {
	dimmerEvents(cmd)
}

private dimmerEvents(hubitat.zwave.Command cmd) {
	def value = (cmd.value ? "on" : "off")
	def result = [createEvent(name: "switch", value: value)]
    state.lastLevel = cmd.value
	if (cmd.value && cmd.value <= 100) {
		result << createEvent(name: "level", value: cmd.value, unit: "%")   
	}
	return result
}

def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
	log.debug "ConfigurationReport $cmd"
	def value = "when off"
	if (cmd.configurationValue[0] == 1) {value = "when on"}
	if (cmd.configurationValue[0] == 2) {value = "never"}
	createEvent([name: "indicatorStatus", value: value])
}

def zwaveEvent(hubitat.zwave.commands.hailv1.Hail cmd) {
	createEvent([name: "hail", value: "hail", descriptionText: "Switch button was pressed", displayed: false])
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
	log.debug "manufacturerId:   ${cmd.manufacturerId}"
	log.debug "manufacturerName: ${cmd.manufacturerName}"
    state.manufacturer=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)	
    setFirmwareVersion()
    createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.versionv1.VersionReport cmd) {	
    //updateDataValue("applicationVersion", "${cmd.applicationVersion}")
    log.debug ("received Version Report")
    log.debug "applicationVersion:      ${cmd.applicationVersion}"
    log.debug "applicationSubVersion:   ${cmd.applicationSubVersion}"
    state.firmwareVersion=cmd.applicationVersion+'.'+cmd.applicationSubVersion
    log.debug "zWaveLibraryType:        ${cmd.zWaveLibraryType}"
    log.debug "zWaveProtocolVersion:    ${cmd.zWaveProtocolVersion}"
    log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
    setFirmwareVersion()
    createEvent([descriptionText: "Firmware V"+state.firmwareVersion, isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.firmwareupdatemdv2.FirmwareMdReport cmd) { 
    log.debug ("received Firmware Report")
    log.debug "checksum:       ${cmd.checksum}"
    log.debug "firmwareId:     ${cmd.firmwareId}"
    log.debug "manufacturerId: ${cmd.manufacturerId}"
    [:]
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd) {
	[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
}

def zwaveEvent(hubitat.zwave.Command cmd) {
	// Handles all Z-Wave commands we aren't interested in
	[:]
}

def on() {
	sendEvent(tapUp1Response("digital"))
	delayBetween([
			zwave.basicV1.basicSet(value: 0xFF).format(),
			zwave.switchMultilevelV1.switchMultilevelGet().format()
	],5000)
}

def off() {
	sendEvent(tapDown1Response("digital"))
	delayBetween([
			zwave.basicV1.basicSet(value: 0x00).format(),
			zwave.switchMultilevelV1.switchMultilevelGet().format()
	],5000)
}

def setLevel (value) {
	log.debug "setLevel >> value: $value"
	def valueaux = value as Integer
	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: "%")
    def result = []
 
    result += response(zwave.basicV1.basicSet(value: level))
    result += response("delay 5000")
    result += response(zwave.switchMultilevelV1.switchMultilevelGet())
    result += response("delay 5000")
    result += response(zwave.switchMultilevelV1.switchMultilevelGet())
}

def poll() {
	zwave.switchMultilevelV1.switchMultilevelGet().format()
}

def refresh() {
	log.debug "refresh() called"
    configure()
}

def zwaveEvent(hubitat.zwave.commands.centralscenev1.CentralSceneNotification cmd) {
    log.debug("sceneNumber: ${cmd.sceneNumber} keyAttributes: ${cmd.keyAttributes}")
    def result = []
    
    switch (cmd.sceneNumber) {
      case 1:
          // Up
          switch (cmd.keyAttributes) {
              case 0:
                   // Press Once
                  result += createEvent(tapUp1Response("physical"))  
                  result += createEvent([name: "switch", value: "on", type: "physical"])
       
                  if (singleTapToFullBright)
                  {
                     result += setLevel(99)
                     result += response("delay 5000")
                     result += response(zwave.switchMultilevelV1.switchMultilevelGet())
                  } 
                  break
              case 1:
                  //Hold release? (inconsistent) 
                  break
              case 2:
                  // Hold
                  result += createEvent(holdUpResponse("physical"))  
                  result += response(["delay 5000", zwave.switchMultilevelV1.switchMultilevelGet().format()])
                  break
              case 3: 
                  // 2 Times
                  result +=createEvent(tapUp2Response("physical"))
                  if (doubleTapToFullBright)
                  {
                     result += setLevel(99)
                     result += response("delay 5000")
                     result += response(zwave.switchMultilevelV1.switchMultilevelGet())
                  }                    
                  break
              case 4:
                  // 3 Three times
                  result=createEvent(tapUp3Response("physical"))
                  break
              default:
                  log.debug ("unexpected up press keyAttribute: $cmd.keyAttributes")
          }
          break
          
      case 2:
          // Down
          switch (cmd.keyAttributes) {
              case 0:
                  // Press Once
                  result += createEvent(tapDown1Response("physical"))
                  result += createEvent([name: "switch", value: "off", type: "physical"]) 
                  break
              case 1:
                  //Hold release? (inconsistent) 
                  break
              case 2:
                  // Hold
                  result += createEvent(holdDownResponse("physical"))
                  result += response(["delay 5000", zwave.switchMultilevelV1.switchMultilevelGet().format()])
                  break
              case 3: 
                  // 2 Times
                  result+=createEvent(tapDown2Response("physical"))
                  if (doubleTapDownToDim)
                  {
                     result += setLevel(25)
                     result += response("delay 5000")
                     result += response(zwave.switchMultilevelV1.switchMultilevelGet())
                  }  
                  break
              case 4:
                  // 3 Times
                  result=createEvent(tapDown3Response("physical"))
                  break
              default:
                  log.debug ("unexpected down press keyAttribute: $cmd.keyAttributes")
           } 
           break
           
      default:
           // unexpected case
           log.debug ("unexpected scene: $cmd.sceneNumber")
   }  
   return result
}

def tapUp1Response(String buttonType) {
    sendEvent(name: "status" , value: "Tap ▲")
	[name: "button", value: "pushed", data: [buttonNumber: "7"], descriptionText: "$device.displayName Tap-Up-1 (button 7) pressed", 
       isStateChange: true, type: "$buttonType"]
}

def tapDown1Response(String buttonType) {
    sendEvent(name: "status" , value: "Tap ▼")
	[name: "button", value: "pushed", data: [buttonNumber: "8"], descriptionText: "$device.displayName Tap-Down-1 (button 8) pressed", 
      isStateChange: true, type: "$buttonType"]
}

def tapUp2Response(String buttonType) {
    sendEvent(name: "status" , value: "Tap ▲▲")
	[name: "button", value: "pushed", data: [buttonNumber: "1"], descriptionText: "$device.displayName Tap-Up-2 (button 1) pressed", 
       isStateChange: true, type: "$buttonType"]
}

def tapDown2Response(String buttonType) {
    sendEvent(name: "status" , value: "Tap ▼▼")
	[name: "button", value: "pushed", data: [buttonNumber: "2"], descriptionText: "$device.displayName Tap-Down-2 (button 2) pressed", 
      isStateChange: true, type: "$buttonType"]
}

def tapUp3Response(String buttonType) {
    sendEvent(name: "status" , value: "Tap ▲▲▲")
	[name: "button", value: "pushed", data: [buttonNumber: "3"], descriptionText: "$device.displayName Tap-Up-3 (button 3) pressed", 
    isStateChange: true, type: "$buttonType"]
}

def tapDown3Response(String buttonType) {
    sendEvent(name: "status" , value: "Tap ▼▼▼")
	[name: "button", value: "pushed", data: [buttonNumber: "4"], descriptionText: "$device.displayName Tap-Down-3 (button 4) pressed", 
    isStateChange: true, type: "$buttonType"]
}

def holdUpResponse(String buttonType) {
    sendEvent(name: "status" , value: "Hold ▲")
	[name: "button", value: "pushed", data: [buttonNumber: "5"], descriptionText: "$device.displayName Hold-Up (button 5) pressed", 
    isStateChange: true, type: "$buttonType"]
}

def holdDownResponse(String buttonType) {
    sendEvent(name: "status" , value: "Hold ▼")
	[name: "button", value: "pushed", data: [buttonNumber: "6"], descriptionText: "$device.displayName Hold-Down (button 6) pressed", 
    isStateChange: true, type: "$buttonType"]
}

def tapUp2() {
	sendEvent(tapUp2Response("digital"))
}

def tapDown2() {
	sendEvent(tapDown2Response("digital"))
}

def tapUp3() {
	sendEvent(tapUp3Response("digital"))
}

def tapDown3() {
	sendEvent(tapDown3Response("digital"))
}

def holdUp() {
	sendEvent(holdUpResponse("digital"))
}

def holdDown() {
	sendEvent(holdDownResponse("digital"))
} 

def setFirmwareVersion() {
   def versionInfo = ''
   if (state.manufacturer)
   {
      versionInfo=state.manufacturer+' '
   }
   if (state.firmwareVersion)
   {
      versionInfo=versionInfo+"Firmware V"+state.firmwareVersion
   }
   else 
   {
     versionInfo=versionInfo+"Firmware unknown"
   }   
   sendEvent(name: "firmwareVersion",  value: versionInfo, isStateChange: true, displayed: false)
}

def configure() {
   log.debug ("configure() called")
 
   sendEvent(name: "numberOfButtons", value: 8, displayed: false)
   def commands = []
   commands << setDimRatePrefs()
   commands << zwave.switchMultilevelV1.switchMultilevelGet().format()
   commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
   commands << zwave.versionV1.versionGet().format()
   delayBetween(commands,500)
}

def setDimRatePrefs() 
{
   log.debug ("set prefs")
   def cmds = []

   if (remoteStepSize)
   {
      def remoteStepSize = Math.max(Math.min(remoteStepSize, 99), 1)
      cmds << zwave.configurationV2.configurationSet(configurationValue: [remoteStepSize], parameterNumber: 7, size: 1).format()
   }
   
   if (remoteStepDuration)
   {
       def remoteStepDuration = Math.max(Math.min(remoteStepDuration, 22), 2)
       cmds << zwave.configurationV2.configurationSet(configurationValue: [0, remoteStepDuration], parameterNumber: 8, size: 2).format()
   }
   
   
   if (localStepSize)
   {
      def localStepSize = Math.max(Math.min(localStepSize, 99), 1)
      cmds << zwave.configurationV2.configurationSet(configurationValue: [localStepSize], parameterNumber: 9, size: 1).format()
   }
   
   if (localStepDuration)
   {
      def localStepDuration = Math.max(Math.min(localStepDuration, 22), 2)
      cmds << zwave.configurationV2.configurationSet(configurationValue: [0,localStepDuration], parameterNumber: 10, size: 2).format()
   }
   
   if (reverseSwitch)
   {
       cmds << zwave.configurationV2.configurationSet(configurationValue: [1], parameterNumber: 4, size: 1).format()
   }
   else
   {
      cmds << zwave.configurationV2.configurationSet(configurationValue: [0], parameterNumber: 4, size: 1).format()
   }
   
   //Enable the following configuration gets to verify configuration in the logs
   //cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
   //cmds << zwave.configurationV1.configurationGet(parameterNumber: 8).format()
   //cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
   //cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
   
   return cmds
}
 
def updated()
{
 def cmds= []
 cmds << setDimRatePrefs
 delayBetween(cmds, 500)
}
2 Likes

This is exactly what I have been waiting for, great job! All my switches in my house are WD200's and I was only getting limited functionality from them. I can't wait to test this driver out when I get off work tonight. Thanks again for this driver!

This was perfect information! Is the code listed here the same that's in the device driver list or is it modified even more?

I was able to create a custom rule that after 9pm if either door is unlocked it flashes red. It took a while to get the whole if and or thing down but I finally had it working.

My next step is to try and get the top two to flash if its the front door and bottom two to flash for the back door. Eventually I will add the middle for the garage. Is there away to have two flash with one commend? I have been experimenting and it didnt work.. so I guess I will have to create multiple individual custom commands for the LEDS and then when the rule clears re-issue the 0 color command for the individual LED instead of 0,0,0.

I'll report back when I get lost in trying to do it :slight_smile:

Yes, you’re right. You need 2 custom commands but you only need 1 rule.

thanks! ended up making 2 rules - one for the front and one for the back.. so the bottom 2 flash red when the back is unlocked and the top 2 when the door is unlocked after 9pm.. and they are interdependent of one another - very cool!

Please share the rules and configuration. I have 5 variables I want to track and I keep getting lost.

1 Like

will do.. but before I do, I need to figure out what went wrong tonight.. the rule goes into effect at 8pm to 5am. at 8pm tonight the back door was unlocked and at 8pm the lights should have triggered.. they did not, I went to the front and unlocked it and it worked as expected. went to the back, locked it and then unlocked it and it worked.. It just didnt kick in at 8pm when it was already unlocked as the clocked turned 8. Am I missing something?

Live logs (Show Past Logs) and look at 8:00 to see what explanation there is. I see that Rule Logging for that Rule is not enabled. Tomorrow evening, 7:45, turn that on :slight_smile:

I unlocked the front door at 4:10 and changed the rule to start at 4:15. 4:15 rolled around and nothing showed up in the live log and the rule didnt run. So I went an locked the door - then unlocked it and the rule ran and the lights came on. I then locked the door and the lights went off. So it looks like it needs to be triggerd to run?

app:3942018-11-17 04:18:43.597 pm infofront door unlocked notice is now False

app:3942018-11-17 04:18:43.500 pm info --> Front Door Lock unlocked [false]

app:3942018-11-17 04:18:43.472 pm infofront door unlocked notice: Front Door Lock lock locked

dev:1992018-11-17 04:18:43.367 pm infoFront Door Lock was manually locked [physical][6:1]

dev:1992018-11-17 04:18:43.362 pm debugalarmv2.AlarmReport: AlarmReport(alarmLevel:1, alarmType:21, eventParameter:, numberOfEventParameters:0, zensorNetSourceNodeId:0, zwaveAlarmEvent:1, zwaveAlarmStatus:255, zwaveAlarmType:6)

dev:1992018-11-17 04:18:43.353 pm debugparse: zw device: 0F, command: 9881, payload: 00 71 05 15 01 00 FF 06 01 00

dev:1992018-11-17 04:18:30.327 pm infoFront Door Lock battery is 98%

dev:1992018-11-17 04:18:30.323 pm debugBatteryReport: BatteryReport(batteryLevel:98)

dev:1992018-11-17 04:18:30.307 pm debugparse: zw device: 0F, command: 9881, payload: 00 80 03 62

app:3942018-11-17 04:18:26.940 pm infofront door unlocked notice is now True

app:3942018-11-17 04:18:26.847 pm info --> Front Door Lock unlocked [true]

app:3942018-11-17 04:18:26.819 pm infofront door unlocked notice: Front Door Lock lock unlocked

dev:1992018-11-17 04:18:26.731 pm infoFront Door Lock was manually unlocked [physical][6:2]

dev:1992018-11-17 04:18:26.728 pm debugalarmv2.AlarmReport: AlarmReport(alarmLevel:1, alarmType:22, eventParameter:, numberOfEventParameters:0, zensorNetSourceNodeId:0, zwaveAlarmEvent:2, zwaveAlarmStatus:255, zwaveAlarmType:6)

dev:1992018-11-17 04:18:26.719 pm debugparse: zw device: 0F, command: 9881, payload: 00 71 05 16 01 00 FF 06 02 00

app:3942018-11-17 04:18:14.120 pm infofront door unlocked notice is now False

app:3942018-11-17 04:18:14.029 pm info --> Front Door Lock unlocked [false]

app:3942018-11-17 04:18:14.002 pm infofront door unlocked notice: Front Door Lock lock locked

dev:1992018-11-17 04:18:13.914 pm infoFront Door Lock was manually locked [physical][6:1]

dev:1992018-11-17 04:18:13.908 pm debugalarmv2.AlarmReport: AlarmReport(alarmLevel:1, alarmType:21, eventParameter:, numberOfEventParameters:0, zensorNetSourceNodeId:0, zwaveAlarmEvent:1, zwaveAlarmStatus:255, zwaveAlarmType:6)

dev:1992018-11-17 04:18:13.888 pm debugparse: zw device: 0F, command: 9881, payload