[RELEASE] Cooper Eaton Aspire RFWC5 Keypad driver for Hubitat

https://github.com/joelwetzel/Hubitat-Cooper-Aspire-Scene-Controller

Cooper Eaton Aspire RFWC5 RFWC5D Keypad driver for Hubitat

This is a Hubitat driver for the Cooper Eaton Aspire RFWC5 and RFWC5D 5-button keypads. These are in-wall z-wave scene controllers, but this driver allows them to be used as keypads for a variety of purposes.

Supported Devices

Physical Device Behavior

The physical keypad has 5 main buttons with indicators. Pressing a button causes its indicator to toggle, and a z-wave message is sent to the hub, which can then determine what all the indicator states are.

There is also a 6th button. If held for a few seconds, all the lights will flash and then every button will turn off. This also sends a z-wave message to the hub, indicating that all buttons are off.

(The keypad is also capable of being associated to other z-wave devices. However, I do not find this useful, since then the hub is unaware of what is happening. So my driver disables that, and all messages go through the hub.)

Behavior Virtualization

This is where the magic happens. To a passer-by, the keypad looks and behaves like 5 toggle switches. They are toggled by pressing the buttons, and the lights indicate if each of the switches is on. So we can use child virtual devices in the Hubitat hub to make it look like 5 switches to other apps and automations. It becomes easy to use Rule Machine, Switch Bindings, or other automation apps to drive behavior based on keypad presses.

In fact, because the hub can also control the indicator states, we can give the keypad even more complex behaviors than just "5 switches", and expose those behaviors as child virtual devices that match common capabilities.

Currently, this driver has 3 modes:

  1. Configure Children as Virtual Switches (This creates 5 virtual switches as child devices.)
  2. Configure Children as Virtual Fan Controller (This creates a virtual fan controller and one virtual switch as child devices. Then the keypad can be used to control a Hampton Bay Zigbee Fan Controller with Light, or control a GE Fan Controller and a GE Light Switch, or other smart devices that implement the "Fan Control" and "Switch" capabilities.)
  3. Configure Children as Virtual Button (This creates a Virtual Button - with 5 buttons - as the child device.)

General Installation

The following steps should be followed, no matter which mode you are going to use.

The best way to install this code is by using Hubitat Package Manager. If you use HPM, you can skip down to step 6 after installing the package.

  1. On the Hubitat hub, go to the "Drivers Code" page
  2. Click "+New Driver"
  3. Copy in the code from RFWC5-Keypad.groovy
  4. Click "Save"
  5. Repeat these first 4 steps for the files RFWC5-VirtualSwitch.groovy and RFWC5D-VirtualFanControllery.groovy. When you are done, you should have a total of 3 new drivers in your "Drivers Code" page.
  6. Wire up your RFWC5 keypad in the wall.
  7. Perform a factory reset on the keypad. Do this by pressing and holding buttons 1, 3, and 5 for 5 seconds at the same time. Release the buttons. Then press and release the ALL OFF button. If successful, all 5 LEDs should blink.
  8. Join the keypad to your z-wave network. On the "Devices" page of Hubitat, click the Discover button, then press the ALL OFF button on the keypad.
  9. On the device page in Hubitat, change the device's Type to "Cooper RFWC5 Keypad" and click "Save Device".
  10. Refresh the page.
  11. Click the "Save Preferences" button and then click the "Configure" command button. This will send a bunch of configuration commands to the keypad. It will take several minutes. You can watch the progress by going to Hubitat's "Logs" page.
  12. When it is finished, you can do some minimal testing. Press buttons on the keypad. On the device page in Hubitat, in the "Current States" section, you should see the value of "Indicators" update to show which lights are turned on. If this works, proceed to one of the next scenarios.

Configuration Scenario 1 - Virtual Switches Bound to Other Lights and Switches

This is my main use case. I have three smart lamps in my living room, and they didn't have switches on the wall. I could control them through an app, or through Alexa, but visitors to the house didn't know what to do with them. By installing an RFWC5D in the living room wall, there is now a simple and discoverable physical control for them.

  1. Open the Hubitat device page for the keypad.
  2. Click the command "Configure Child Devices As Virtual Switches" It will take 3-5 seconds, and then you should see that the value of VirtualDeviceMode is "virtualSwitches".
  3. Refresh the page.
  4. Now if you scroll down, you should see 5 component devices. They are virtual switches, and the driver will keep them exactly in sync with the lights on the keypad. (It is a bi-directional sync too, which will be important in a moment.)
  5. Now, we want to make those virtual switches control some real devices. You could do this with Rule Machine, but my Switch Bindings app was made specially for doing this in a fast, simple, and reliable way. If you haven't already, install the Switch Bindings app from here: https://github.com/joelwetzel/Hubitat-Switch-Bindings
  6. In Switch Bindings, create up to 5 bindings. In each one, bind one virtual switch from the keypad to the real smart device you want it to control. In my case, I bound each of the first three virtual switches to one of my smart lamps.

Result: You should now be able to press the buttons on the keypad to toggle your bound switches/lamps on and off. Also, because Switch Bindings app is bi-directional, and the virtual switches are bi-directionally synced with the keypad indicators, if you use another means (such as Alexa or scheduled Scenes) to turn the lights on and off, the keypad indicators will stay in sync with what the devices are doing. All the binding is fully bi-directional.

Configuration Scenario 2 - Virtual Fan Controller and One Virtual Light Switch

This is useful for 2 sub-scenarios:

  1. With the release of the Hampton Bay Zigbee Fan Controller (https://www.homedepot.com/p/Hampton-Bay-Universal-Wink-Enabled-White-Ceiling-Fan-Premier-Remote-Control-99432/206591100), there is now a smart device that control both a fan, as well as the light in the fan. However, it just has its own remote. What if you want to control it from a decora-style wall control?
  2. People have also done something similar by hiding a GE Fan Controller and GE Light Switch (or equivalent micro devices, such as the ones by AEOTEC) up in the fan shroud.

In either of these cases, you end up with two smart devices in Hubitat that we want to control: A Fan Controller, and a Switch. In Scenario 2, we are going to expose the functionality of the RFWC5 Keypad as a virtual fan controller and virtual switch, that can then be bound to the actual fan controller and switch.

  1. Open the Hubitat device page for the keypad.
  2. Click the command "Configure Child Devices as Virtual Fan Controller" It will take 3-5 seconds, and then you should see that the value of VirtualDeviceMode is "virtualSwitches".
  3. Refresh the page.
  4. Now if you scroll down, you should see 2 component devices. One is a virtual fan controller, and one is a virtual switch.
  5. Now, we want to make those virtual switches control the real devices. You could do this with Rule Machine, but my Switch Bindings app was made specially for doing this in a fast, simple, and reliable way. If you haven't already, install the Switch Bindings app from here: https://github.com/joelwetzel/Hubitat-Switch-Bindings
  6. In Switch Bindings, create 2 bindings. Bind the Virtual Fan Controller to the real fan controller. Bind the Virtual Switch to the real light switch for the fan.

Result: The bottom button (button 5) on the keypad behaves as a switch for the fan light. The next button up is Fan off. Then buttons 3, 2, and 1 are Low, Medium, and High respectively. You'll notice that only one of the fan lights will be on at a time. Also, this binding is also bi-directional. If you use Alexa or a scheduled routine to alter the fan light or the fan speed, these changes will be reflected in the keypad's indicator lights.

Configuration Scenario 3 - Virtual Buttons

Rather than exposing the keypad as 5 switches, this exposes it as 5 buttons. The default state of the keypad will be to have all the lights turned off. If you press buttons, the lights come on for just a second, and then turn off again, but virtual button presses happen in Hubitat.

  1. Open the Hubitat device page for the keypad.
  2. Click the command "Configure Child Devices as Virtual Button" It will take 3-5 seconds, and then you should see that the value of VirtualDeviceMode is "virtualButton".
  3. Refresh the page.
  4. Now if you scroll down, you should see 1 component device - a Virtual Button. (Hubitat allows more than one button inside a single "Virtual Button")
  5. Now I recommend using the built-in Button Controllers app in Hubitat. You tell it to watch the Virtual Button, and then assign actions for when buttons 1-5 are pressed. (Such as toggling lights or activating scenes.)

Acknowledgments

Many thanks to Scott Ainsworth for figuring out the z-wave configuration steps for the keypads. I borrowed the configuration code from his original driver for SmartThings: https://github.com/saains/SmartThingsPublic/blob/master/devicetypes/saains/cooper-aspire-scene-controller-rfwc5-rfwc5d.src/cooper-aspire-scene-controller-rfwc5-rfwc5d.groovy

4 Likes

I made a short video showing it in use. I'm using the keypad to control lights in my living room that don't have their own switches. The video shows how fast everything responds.

Thank you! Exactly what I was looking for!

Just published an update to Github. It improves both response speed, and reliability.

Wanted to give you a heads up on an error that's been showing up in my logs during a z wave repair.

[dev:225](http://172.16.0.103/logs#dev225)2019-04-02 21:10:45.716 [error](http://172.16.0.103/device/edit/225)groovy.lang.MissingMethodException: No signature of method: user_driver_joelwetzel_Cooper_RFWC5_Keypad_321.parse() is applicable for argument types: (hubitat.zwave.commands.associationv2.AssociationReport) values: [AssociationReport(groupingIdentifier:1, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])] Possible solutions: parse(java.lang.String), use([Ljava.lang.Object;), wait(), run(), run(), grep() (parse)"

Ok, I was able to replicate the error and then fix it. There's an updated version of RFWC5-Keypad.groovy on Github. Thanks for the bug report!

My pleasure, all thanks to you for keeping this up to date!

Still really like the functionality of this. But recently had to reinstall my RFWC5 and ran into some trouble. I run into some errors when configuring the controller.

dev:5502019-05-24 22:44:22.296 errorgroovy.lang.MissingMethodException: No signature of method: user_driver_joelwetzel_Cooper_RFWC5_Keypad_513.parse() is applicable for argument types: (hubitat.zwave.commands.scenecontrollerconfv1.SceneControllerConfReport) values: [SceneControllerConfReport(dimmingDuration:0, groupId:5, sceneId:255)]
Possible solutions: parse(java.lang.String), use([Ljava.lang.Object;), wait(), run(), run(), grep() (parse)
dev:5502019-05-24 22:44:18.725 debugUNPARSED CMD: AssociationReport(groupingIdentifier:5, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])
dev:5502019-05-24 22:43:57.792 errorgroovy.lang.MissingMethodException: No signature of method: user_driver_joelwetzel_Cooper_RFWC5_Keypad_513.parse() is applicable for argument types: (hubitat.zwave.commands.scenecontrollerconfv1.SceneControllerConfReport) values: [SceneControllerConfReport(dimmingDuration:0, groupId:4, sceneId:254)]
Possible solutions: parse(java.lang.String), use([Ljava.lang.Object;), wait(), run(), run(), grep() (parse)
dev:5502019-05-24 22:43:54.221 debugUNPARSED CMD: AssociationReport(groupingIdentifier:4, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])
dev:5502019-05-24 22:43:33.263 errorgroovy.lang.MissingMethodException: No signature of method: user_driver_joelwetzel_Cooper_RFWC5_Keypad_513.parse() is applicable for argument types: (hubitat.zwave.commands.scenecontrollerconfv1.SceneControllerConfReport) values: [SceneControllerConfReport(dimmingDuration:0, groupId:3, sceneId:253)]
Possible solutions: parse(java.lang.String), use([Ljava.lang.Object;), wait(), run(), run(), grep() (parse)
dev:5502019-05-24 22:43:29.705 debugUNPARSED CMD: AssociationReport(groupingIdentifier:3, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])
dev:5502019-05-24 22:43:08.739 errorgroovy.lang.MissingMethodException: No signature of method: user_driver_joelwetzel_Cooper_RFWC5_Keypad_513.parse() is applicable for argument types: (hubitat.zwave.commands.scenecontrollerconfv1.SceneControllerConfReport) values: [SceneControllerConfReport(dimmingDuration:0, groupId:2, sceneId:252)]
Possible solutions: parse(java.lang.String), use([Ljava.lang.Object;), wait(), run(), run(), grep() (parse)
dev:5502019-05-24 22:43:05.183 debugUNPARSED CMD: AssociationReport(groupingIdentifier:2, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])
dev:5502019-05-24 22:42:44.235 errorgroovy.lang.MissingMethodException: No signature of method: user_driver_joelwetzel_Cooper_RFWC5_Keypad_513.parse() is applicable for argument types: (hubitat.zwave.commands.scenecontrollerconfv1.SceneControllerConfReport) values: [SceneControllerConfReport(dimmingDuration:0, groupId:1, sceneId:251)]
Possible solutions: parse(java.lang.String), use([Ljava.lang.Object;), wait(), run(), run(), grep() (parse)
dev:5502019-05-24 22:42:40.705 debugUNPARSED CMD: AssociationReport(groupingIdentifier:1, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])
dev:5502019-05-24 22:42:23.121 infoPlease Wait this can take a few minutes...
dev:5502019-05-24 22:42:23.118 info[850401, 850101, 7004010132, 2D0101FB00, 85010101, 850201, 2D0201, 850402, 850102, 7004020132, 2D0102FC00, 85010201, 850202, 2D0202, 850403, 850103, 7004030132, 2D0103FD00, 85010301, 850203, 2D0203, 850404, 850104, 7004040132, 2D0104FE00, 85010401, 850204, 2D0204, 850405, 850105, 7004050132, 2D0105FF00, 85010501, 850205, 2D0205]
dev:5502019-05-24 22:42:23.115 infoassociating group for button:5: 1
dev:5502019-05-24 22:42:23.113 infosetting scene commands for button:5 scene:255 dimmingduration:0
dev:5502019-05-24 22:42:23.110 infosetting configuration commands for button:5 Level:[50]
dev:5502019-05-24 22:42:23.107 infoassociating group for button:5: []
dev:5502019-05-24 22:42:23.104 infoassociating group for button:4: 1
dev:5502019-05-24 22:42:23.097 infosetting scene commands for button:4 scene:254 dimmingduration:0
dev:5502019-05-24 22:42:23.093 infosetting configuration commands for button:4 Level:[50]
dev:5502019-05-24 22:42:23.090 infoassociating group for button:4: []
dev:5502019-05-24 22:42:23.087 infoassociating group for button:3: 1
dev:5502019-05-24 22:42:23.085 infosetting scene commands for button:3 scene:253 dimmingduration:0
dev:5502019-05-24 22:42:23.082 infosetting configuration commands for button:3 Level:[50]
dev:5502019-05-24 22:42:23.079 infoassociating group for button:3: []
dev:5502019-05-24 22:42:23.074 infoassociating group for button:2: 1
dev:5502019-05-24 22:42:23.068 infosetting scene commands for button:2 scene:252 dimmingduration:0
dev:5502019-05-24 22:42:23.065 infosetting configuration commands for button:2 Level:[50]
dev:5502019-05-24 22:42:23.062 infoassociating group for button:2: []
dev:5502019-05-24 22:42:23.059 infoassociating group for button:1: 1
dev:5502019-05-24 22:42:23.057 infosetting scene commands for button:1 scene:251 dimmingduration:0
dev:5502019-05-24 22:42:23.054 infosetting configuration commands for button:1 Level:[50]
dev:5502019-05-24 22:42:23.051 infoassociating group for button:1: []
dev:5502019-05-24 22:42:23.041 infoKitchen Scene Controller.configure() - setting the Z-Wave configuration on the physical keypad device.
--- Live Log Started, waiting for events ---

(One of these days I'll have to pick up some Groovy and contribute!)

Ok, I just posted an update to RFWC5-Keypad.groovy on Github. Can you test and let me know if that fixes the issue?

That did the trick! Thank you!

Current bug anyone using my driver should be aware of. I have some lines of code that call getChildDevices(). In previous versions of the Hubitat firmware, this returned them in the order they were created. That seems to have changed recently. It's causing some bugs with my driver. I'm working on a solution.

I recommend grabbing the latest code for RFWC5-Keypad.groovy from my Github to fix a bug with the lights that popped up.

This is an instance of Hyrum's Law. Hubitat documentation never promised that getChildDevices() would return them in the order they were created, but for the past 6 months at least, that had been true. And my code had come to rely on it. When it changed with a recent firmware update, my code broke.

The fix was for me to define a getChildDevicesInCreationOrder() method.

nuts. just wired one of these up, but can't get the thing to pair.

too far from hub, tried closer location, good to go. annoying that devices can be picky like that.

Thanks for the driver! Configured my as 5 buttons instead of switches.

Have you looked into the possibility of capturing button events for the 6th button - the 'off' switch?

I assume you have and it's just not possible given the way the device works, but thought I'd ask before investigating myself.

Glad you like it! Yes, unfortunately the 6th button doesn't register as a separate event. It just sends off events for all 5 of the other buttons.

Using this driver as a button controller, I was seeing a delay of ~1.5 seconds from the hub receiving the zwave event to raising the button event and processing it.
I was able to modify the driver [probably in a hacky way] to get it down to ~0.05 sec delay.
If there's others using it as a button controller and experiencing the delay, let me know. I might be able to clean this up to the point I wouldn't be embarrassed sharing it.

Debug Info

Before:
dev:972019-10-20 01:22:11.951 pm debug Cooper 5 button.syncVirtualStateToIndicators(00000)
dev:982019-10-20 01:22:11.920 pm info Cooper 5 button (Virtual Button) button 3 was pushed
dev:972019-10-20 01:22:10.860 pm debug PARSED IndicatorReport(value:4) to: [['name':'Indicators', 'value':00100, 'descriptionText':Indicators: 00100, 'linkText':Indicators: 00100]]
dev:972019-10-20 01:22:10.748 pm debug PARSED IndicatorReport(value:4) to: [['name':'Indicators', 'value':00100, 'descriptionText':Indicators: 00100, 'linkText':Indicators: 00100]]
dev:972019-10-20 01:22:10.646 pm debug PARSED SceneActivationSet(dimmingDuration:0, sceneId:253) to: []
dev:972019-10-20 01:22:10.642 pm debug PARSED SceneActivationSet(dimmingDuration:0, sceneId:253) to: []

After:
dev:972019-10-20 01:24:39.898 pm debug Cooper 5 button.syncVirtualStateToIndicators(00000)
dev:972019-10-20 01:24:38.776 pm debug PARSED IndicatorReport(value:4) to: [['name':'Indicators', 'value':00100, 'descriptionText':Indicators: 00100, 'linkText':Indicators: 00100]]
dev:972019-10-20 01:24:38.722 pm debug CMD: IndicatorReport(value:4)
dev:972019-10-20 01:24:38.707 pm trace parse - description: zw device: 08, command: 8703, payload: 04 , isMulticast: false
dev:972019-10-20 01:24:38.656 pm debug PARSED SceneActivationSet(dimmingDuration:0, sceneId:253) to: []
dev:982019-10-20 01:24:38.640 pm info Cooper 5 button (Virtual Button) button 3 was pushed
dev:972019-10-20 01:24:38.621 pm trace Event-SceneActivationSet SceneActivationSet(dimmingDuration:0, sceneId:253)
dev:972019-10-20 01:24:38.617 pm trace Ignore Duplicate Scene Activation
dev:972019-10-20 01:24:38.606 pm debug CMD: SceneActivationSet(dimmingDuration:0, sceneId:253)
dev:972019-10-20 01:24:38.590 pm debug CMD: SceneActivationSet(dimmingDuration:0, sceneId:253)

That's quite an improvement! Can you send me your code? I'll do the cleanup for you and integrate it into the main codebase.

Trying to get these things up and running. Added first of 3 of these to my system tonight and the logs show these errors:
dev:5582019-10-23 07:40:16.014 pm debugUNPARSED CMD: SceneControllerConfReport(dimmingDuration:0, groupId:5, sceneId:255)

dev:5582019-10-23 07:40:12.612 pm debugUNPARSED CMD: AssociationReport(groupingIdentifier:5, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])

dev:5582019-10-23 07:40:12.504 pm debugUNPARSED CMD: AssociationReport(groupingIdentifier:5, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])

dev:5582019-10-23 07:39:51.427 pm debugUNPARSED CMD: SceneControllerConfReport(dimmingDuration:0, groupId:4, sceneId:254)

dev:5582019-10-23 07:39:47.935 pm debugUNPARSED CMD: AssociationReport(groupingIdentifier:4, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])

dev:5582019-10-23 07:39:26.801 pm debugUNPARSED CMD: SceneControllerConfReport(dimmingDuration:0, groupId:3, sceneId:253)

dev:5582019-10-23 07:39:23.394 pm debugUNPARSED CMD: AssociationReport(groupingIdentifier:3, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])

dev:5582019-10-23 07:39:23.387 pm debugUNPARSED CMD: AssociationReport(groupingIdentifier:3, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])

dev:5582019-10-23 07:39:02.210 pm debugUNPARSED CMD: SceneControllerConfReport(dimmingDuration:0, groupId:2, sceneId:252)

dev:5582019-10-23 07:38:58.682 pm debugUNPARSED CMD: AssociationReport(groupingIdentifier:2, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])

dev:5582019-10-23 07:38:37.667 pm debugUNPARSED CMD: SceneControllerConfReport(dimmingDuration:0, groupId:1, sceneId:251)

dev:5582019-10-23 07:38:34.318 pm debugUNPARSED CMD: AssociationReport(groupingIdentifier:1, maxNodesSupported:232, reportsToFollow:0, nodeId:[1])

I'm not sure what to make of it

Also, it seems that in the most recent update of Hubitat, Button Controllers app has been removed and they now say to use RM.

So, i configured the device as per your instructions, then configured child device as virtual button

The device is then available in RM for programming as a button device, but, so far it just doesn't work very well. Observations:

  1. Double tapping doesn't seem to work at all from the device. If you send the command from the hubitat devices screen, it will work. Not sure if double tapping worked in the past when you were using the Button controllers app.
  2. Not very reliable. When I push a button, it sometimes registers, shows up in the log, and the command executes, but many times (probably more than 50% of the time) it does not show in the log or execute.