Request for Edge Driver for ZWN-SC7 Enerwave 7 Button Scene Controller
- currentButton: 7
- manufacturer: Wenzhou MTLC Electric Appliances Co.,Ltd.
- networkSecurityLevel: ZWAVE_LEGACY_NON_SECURE
- numButtons: 7
zw:L type:0202 mfr:011A prod:0801 model:0B03 ver:1.05 zwv:3.42 lib:02 cc:2D,85,86,72
Matt Franks Groovy Driver Below
/**
- ZWN-SC7 Enerwave 7 Button Scene Controller
- Author: Matt Frank based on VRCS Button Controller by Brian Dahlem, based on SmartThings Button Controller
- Date Created: 2014-12-18
- Updated: 2017-05-10 update DT to support pushed as @ady624
- Last Update: 2021-01-26 update by Tim Grimley to work in new Smartthings app
- 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.
- 2016-09-30 Modified to allow for correct event value âpushedâ and added numberOfButtons as per ST documentation
*/
import groovy.transform.Field
import groovy.json.JsonOutput
metadata {
// Automatically generated. Make future change here.
definition (name: âZWNSC7 Enerwave Scene Masterâ, namespace: âmwav3â, author: âTim Grimleyâ) {
capability âActuatorâ
capability âButtonâ
capability âConfigurationâ
capability âIndicatorâ
capability âSensorâ
attribute "currentButton", "STRING"
attribute "numButtons", "STRING"
attribute "numberOfButtons", "NUMBER"
fingerprint deviceId: "0x0202", inClusters:"0x21, 0x2D, 0x85, 0x86, 0x72"
fingerprint deviceId: "0x0202", inClusters:"0x2D, 0x85, 0x86, 0x72"
preferences {
input "forceupdate", "bool", title: "Force Settings Update/Refresh?", description: "Toggle to force settings update", required: false
}
}
simulator {
status âbutton 1 pushedâ: âcommand: 2B01, payload: 01 FFâ
status âbutton 2 pushedâ: âcommand: 2B01, payload: 02 FFâ
status âbutton 3 pushedâ: âcommand: 2B01, payload: 03 FFâ
status âbutton 4 pushedâ: âcommand: 2B01, payload: 04 FFâ
status âbutton 5 pushedâ: âcommand: 2B01, payload: 05 FFâ
status âbutton 6 pushedâ: âcommand: 2B01, payload: 06 FFâ
status âbutton 7 pushedâ: âcommand: 2B01, payload: 07 FFâ
status âbutton releasedâ: âcommand: 2C02, payload: 00â
}
tiles {
standardTile(âbuttonâ, âdevice.buttonâ, width: 2, height: 2) {
state âdefaultâ, label: " ", icon: âst.unknown.zwave.remote-controllerâ, backgroundColor: â#ffffffâ
state âbutton 1â, label: â1â, icon: âst.Weather.weather14â, backgroundColor: â#79b821â
state âbutton 2â, label: â2â, icon: âst.Weather.weather14â, backgroundColor: â#79b821â
state âbutton 3â, label: â3â, icon: âst.Weather.weather14â, backgroundColor: â#79b821â
state âbutton 4â, label: â4â, icon: âst.Weather.weather14â, backgroundColor: â#79b821â
state âbutton 5â, label: â5â, icon: âst.Weather.weather14â, backgroundColor: â#79b821â
state âbutton 6â, label: â6â, icon: âst.Weather.weather14â, backgroundColor: â#79b821â
state âbutton 7â, label: â7â, icon: âst.Weather.weather14â, backgroundColor: â#79b821â
}
// Configure button. Syncronize the device capabilities that the UI provides
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
}
main "button"
details (["button", "configure"])
}
}
// parse events into attributes
def parse(String description) {
log.debug âParsing â${description}ââ
def result = null
def cmd = zwave.parse(description)
if (cmd) {
result = zwaveEvent(cmd)
}
return result
}
// Handle a button being pressed
def buttonEvent(button) {
button = button as Integer
def result =
updateState("currentButton", "$button")
if (button > 0) {
// update the device state, recording the button press
result << createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
// turn off the button LED
result << response(zwave.sceneActuatorConfV1.sceneActuatorConfReport(dimmingDuration: 255, level: 255, sceneId: 0))
}
else {
// update the device state, recording the button press
result << createEvent(name: âbuttonâ, value: âdefaultâ, descriptionText: â$device.displayName button was releasedâ, isStateChange: true)
result << response(zwave.sceneActuatorConfV1.sceneActuatorConfReport(dimmingDuration: 255, level: 255, sceneId: 0))
}
result
}
// A zwave command for a button press was received
def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) {
// The controller likes to repeat the command⊠ignore repeats
if (state.lastScene == cmd.sceneId && (state.repeatCount < 4) && (now() - state.repeatStart < 2000)) {
log.debug âButton ${cmd.sceneId} repeat ${state.repeatCount}x ${now()}â
state.repeatCount = state.repeatCount + 1
createEvent([:])
}
else {
// If the button was really pressed, store the new scene and handle the button press
state.lastScene = cmd.sceneId
state.lastLevel = 0
state.repeatCount = 0
state.repeatStart = now()
buttonEvent(cmd.sceneId)
}
}
// A scene command was received â itâs probably scene 0, so treat it like a button release
def zwaveEvent(physicalgraph.zwave.commands.sceneactuatorconfv1.SceneActuatorConfGet cmd) {
buttonEvent(cmd.sceneId)
}
// The controller sent a scene activation report. Log it, but it really shouldnât happen.
def zwaveEvent(physicalgraph.zwave.commands.sceneactuatorconfv1.SceneActuatorConfReport cmd) {
log.debug âScene activation reportâ
log.debug âScene ${cmd.sceneId} set to ${cmd.level}â
createEvent([:])
}
// Configuration Reports are replys to configuration value requests⊠If we knew what configuration parameters
// to request this could be very helpful.
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
createEvent([:])
}
// The VRC supports hail commands, but I havenât seen them.
def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) {
createEvent([name: âhailâ, value: âhailâ, descriptionText: âSwitch button was pressedâ, displayed: false])
}
// Update manufacturer information when it is reported
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
if (state.manufacturer != cmd.manufacturerName) {
updateDataValue(âmanufacturerâ, cmd.manufacturerName)
}
createEvent([:])
}
// Association Groupings Reports tell us how many groupings the device supports. This equates to the number of
// buttons/scenes in the VRCS
def zwaveEvent(physicalgraph.zwave.commands.associationv2.AssociationGroupingsReport cmd) {
def response =
log.debug "${getDataByName("numButtons")} buttons stored"
if ((getDataByName(ânumButtonsâ) != â$cmd.supportedGroupingsâ) || (getDataByName(ânumberOfButtonsâ) != (int) cmd.supportedGroupings)) {
updateState(ânumButtonsâ, â$cmd.supportedGroupingsâ)
updateState(ânumberOfButtonsâ, (int) cmd.supportedGroupings)
log.debug â${cmd.supportedGroupings} groups availableâ
response << createEvent(name: ânumButtonsâ, value: cmd.supportedGroupings, displayed: false)
response << createEvent(name: ânumberOfButtonsâ, value: cmd.supportedGroupings, displayed: false)
response << associateHub()
}
else {
response << createEvent(name: ânumButtonsâ, value: cmd.supportedGroupings, displayed: false)
response << createEvent(name: ânumberOfButtonsâ, value: cmd.supportedGroupings, displayed: false)
}
return response
}
// Handles all Z-Wave commands we donât know we are interested in
def zwaveEvent(physicalgraph.zwave.Command cmd) {
createEvent([:])
}
// handle commands
// Create a list of the configuration commands to send to the device
def configurationCmds() {
// Always check the manufacturer and the number of groupings allowed
def commands = [
zwave.manufacturerSpecificV1.manufacturerSpecificGet().format(),
zwave.associationV1.associationGroupingsGet().format(),
zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:1, sceneId:1).format(),
zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:2, sceneId:2).format(),
zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:3, sceneId:3).format(),
zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:4, sceneId:4).format(),
zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:5, sceneId:5).format(),
zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:6, sceneId:6).format(),
zwave.sceneControllerConfV1.sceneControllerConfSet(groupId:7, sceneId:7).format()
]
commands << associateHub()
delayBetween(commands)
}
// Configure the device
def configure() {
def cmd=configurationCmds()
log.debug(âSending configuration: ${cmd}â)
return cmd
}
def initialize() {
sendEvent(name: ânumberOfButtonsâ, value: 7, displayed: false)
sendEvent(name: âsupportedButtonValuesâ, value:JsonOutput.toJson([âpushedâ]), displayed:false)
configure()
}
//Update Settings
def updated() {
sendEvent(name: "supportedButtonValues", value:JsonOutput.toJson(["pushed"]), displayed:false)
sendEvent(name: "numberOfButtons", value: 7, displayed: false)
configure()
}
//
// Associate the hub with the buttons on the device, so we will get status updates
def associateHub() {
def commands =
// Loop through all the buttons on the controller
for (def buttonNum = 1; buttonNum <= integer(getDataByName("numButtons")); buttonNum++) {
// Associate the hub with the button so we will get status updates
commands << zwave.associationV1.associationSet(groupingIdentifier: buttonNum, nodeId: zwaveHubNodeId).format()
}
return commands
}
// Update State
// Store mode and settings
def updateState(String name, String value) {
state[name] = value
device.updateDataValue(name, value)
}
// Get Data By Name
// Given the name of a setting/attribute, lookup the settingâs value
def getDataByName(String name) {
state[name] ?: device.getDataValue(name)
}
//Stupid conversions
// convert a double to an integer
def integer(double v) {
return v.toInteger()
}
// convert a hex string to integer
def integerhex(String v) {
if (v == null) {
return 0
}
return Integer.parseInt(v, 16)
}
// convert a hex string to integer
def integer(String v) {
if (v == null) {
return 0
}
return Integer.parseInt(v)
}