2 * ZWN-SC7 Enerwave 7 Button Scene Controller
4 * Author: Matt Frank based on VRCS Button Controller by Brian Dahlem, based on SmartThings Button Controller
5 * Date Created: 2014-12-18
6 * Last Updated: 2015-02-13
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the License at:
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
14 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
15 * for the specific language governing permissions and limitations under the License.
20 // Automatically generated. Make future change here.
21 definition (name: "ZWN-SC7 Enerwave 7 Button Scene Controller", namespace: "mattjfrank", author: "Matt Frank") {
24 capability "Configuration"
25 capability "Indicator"
28 attribute "currentButton", "STRING"
29 attribute "numButtons", "STRING"
31 fingerprint deviceId: "0x0202", inClusters:"0x21, 0x2D, 0x85, 0x86, 0x72"
32 fingerprint deviceId: "0x0202", inClusters:"0x2D, 0x85, 0x86, 0x72"
36 status "button 1 pushed": "command: 2B01, payload: 01 FF"
37 status "button 2 pushed": "command: 2B01, payload: 02 FF"
38 status "button 3 pushed": "command: 2B01, payload: 03 FF"
39 status "button 4 pushed": "command: 2B01, payload: 04 FF"
40 status "button 5 pushed": "command: 2B01, payload: 05 FF"
41 status "button 6 pushed": "command: 2B01, payload: 06 FF"
42 status "button 7 pushed": "command: 2B01, payload: 07 FF"
43 status "button released": "command: 2C02, payload: 00"
47 standardTile("button", "device.button", width: 2, height: 2) {
48 state "default", label: " ", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
49 state "button 1", label: "1", icon: "st.Weather.weather14", backgroundColor: "#79b821"
50 state "button 2", label: "2", icon: "st.Weather.weather14", backgroundColor: "#79b821"
51 state "button 3", label: "3", icon: "st.Weather.weather14", backgroundColor: "#79b821"
52 state "button 4", label: "4", icon: "st.Weather.weather14", backgroundColor: "#79b821"
53 state "button 5", label: "5", icon: "st.Weather.weather14", backgroundColor: "#79b821"
54 state "button 6", label: "6", icon: "st.Weather.weather14", backgroundColor: "#79b821"
55 state "button 7", label: "7", icon: "st.Weather.weather14", backgroundColor: "#79b821"
58 // Configure button. Syncronize the device capabilities that the UI provides
59 standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
60 state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
64 details (["button", "configure"])
68 // parse events into attributes
69 def parse(String description) {
70 log.debug "Parsing '${description}'"
73 def cmd = zwave.parse(description)
75 result = zwaveEvent(cmd)
81 // Handle a button being pressed
82 def buttonEvent(button) {
83 button = button as Integer
86 updateState("currentButton", "$button")
89 // update the device state, recording the button press
90 result << createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
92 // turn off the button LED
93 result << response(zwave.sceneActuatorConfV1.sceneActuatorConfReport(dimmingDuration: 255, level: 255, sceneId: 0))
96 // update the device state, recording the button press
97 result << createEvent(name: "button", value: "default", descriptionText: "$device.displayName button was released", isStateChange: true)
99 result << response(zwave.sceneActuatorConfV1.sceneActuatorConfReport(dimmingDuration: 255, level: 255, sceneId: 0))
105 // A zwave command for a button press was received
106 def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) {
108 // The controller likes to repeat the command... ignore repeats
109 if (state.lastScene == cmd.sceneId && (state.repeatCount < 4) && (now() - state.repeatStart < 1000)) {
110 log.debug "Button ${cmd.sceneId} repeat ${state.repeatCount}x ${now()}"
111 state.repeatCount = state.repeatCount + 1
115 // If the button was really pressed, store the new scene and handle the button press
116 state.lastScene = cmd.sceneId
118 state.repeatCount = 0
119 state.repeatStart = now()
121 buttonEvent(cmd.sceneId)
125 // A scene command was received -- it's probably scene 0, so treat it like a button release
126 def zwaveEvent(physicalgraph.zwave.commands.sceneactuatorconfv1.SceneActuatorConfGet cmd) {
127 buttonEvent(cmd.sceneId)
130 // The controller sent a scene activation report. Log it, but it really shouldn't happen.
131 def zwaveEvent(physicalgraph.zwave.commands.sceneactuatorconfv1.SceneActuatorConfReport cmd) {
132 log.debug "Scene activation report"
133 log.debug "Scene ${cmd.sceneId} set to ${cmd.level}"
139 // Configuration Reports are replys to configuration value requests... If we knew what configuration parameters
140 // to request this could be very helpful.
141 def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
145 // The VRC supports hail commands, but I haven't seen them.
146 def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) {
147 createEvent([name: "hail", value: "hail", descriptionText: "Switch button was pressed", displayed: false])
150 // Update manufacturer information when it is reported
151 def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
152 if (state.manufacturer != cmd.manufacturerName) {
153 updateDataValue("manufacturer", cmd.manufacturerName)
159 // Association Groupings Reports tell us how many groupings the device supports. This equates to the number of
160 // buttons/scenes in the VRCS
161 def zwaveEvent(physicalgraph.zwave.commands.associationv2.AssociationGroupingsReport cmd) {
164 log.debug "${getDataByName("numButtons")} buttons stored"
165 if (getDataByName("numButtons") != "$cmd.supportedGroupings") {
166 updateState("numButtons", "$cmd.supportedGroupings")
167 log.debug "${cmd.supportedGroupings} groups available"
168 response << createEvent(name: "numButtons", value: cmd.supportedGroupings, displayed: false)
170 response << associateHub()
173 response << createEvent(name: "numButtons", value: cmd.supportedGroupings, displayed: false)
180 // Handles all Z-Wave commands we don't know we are interested in
181 def zwaveEvent(physicalgraph.zwave.Command cmd) {
187 // Create a list of the configuration commands to send to the device
188 def configurationCmds() {
189 // Always check the manufacturer and the number of groupings allowed
191 zwave.manufacturerSpecificV1.manufacturerSpecificGet().format(),
192 zwave.associationV1.associationGroupingsGet().format(),
193 zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:1, sceneId:1).format(),
194 zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:2, sceneId:2).format(),
195 zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:3, sceneId:3).format(),
196 zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:4, sceneId:4).format(),
197 zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:5, sceneId:5).format(),
198 zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:6, sceneId:6).format(),
199 zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:7, sceneId:7).format()
202 commands << associateHub()
204 delayBetween(commands)
207 // Configure the device
209 def cmd=configurationCmds()
210 log.debug("Sending configuration: ${cmd}")
216 // Associate the hub with the buttons on the device, so we will get status updates
220 // Loop through all the buttons on the controller
221 for (def buttonNum = 1; buttonNum <= integer(getDataByName("numButtons")); buttonNum++) {
223 // Associate the hub with the button so we will get status updates
224 commands << zwave.associationV1.associationSet(groupingIdentifier: buttonNum, nodeId: zwaveHubNodeId).format()
232 // Store mode and settings
233 def updateState(String name, String value) {
235 device.updateDataValue(name, value)
239 // Given the name of a setting/attribute, lookup the setting's value
240 def getDataByName(String name) {
241 state[name] ?: device.getDataValue(name)
246 // convert a double to an integer
247 def integer(double v) {
251 // convert a hex string to integer
252 def integerhex(String v) {
257 return Integer.parseInt(v, 16)
260 // convert a hex string to integer
261 def integer(String v) {
266 return Integer.parseInt(v)