We do not, we didn't actually have any staff using it.
Drivers are a little more work to migrate than apps, not much though. I'm sure we'll publish something shortly on the steps involved.
It works with Generic ZWave Switch to control one of the relays but not the other just as an FYI
Do you have the driver for ST? If so, itâs pretty easy to change it.
I do but unfortunately Iâm not a coder just a breaker.
if anyone wants to help
/**
- Enerwave RSM2
- Borrowed from Matt Frank via smartthings community forums. Minor edits by Joel Tamkin
- 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.
/
/*
-
Enerwave Dual Load ZWN-RSM2
*/
// for the UI
metadata {
definition (name: âEnerwave Dual Load ZWN-RSM2â, author: âmattâ) {
capability "Switch"
capability "Polling"
capability "Configuration"
capability âRefreshâattribute "switch1", "string" attribute "switch2", "string" command "on1" command "off1" command "on2" command "off2"
}
simulator {
// TODO: define status and reply messages here
}tiles {
standardTile("switch1", "device.switch1",canChangeIcon: true) { state "on", label: "switch1", action: "off1", icon: "st.switches.switch.on", backgroundColor: "#79b821" state "off", label: "switch1", action: "on1", icon: "st.switches.switch.off", backgroundColor: "#ffffff" } standardTile("switch2", "device.switch2",canChangeIcon: true) { state "on", label: "switch2", action: "off2", icon: "st.switches.switch.on", backgroundColor: "#79b821" state "off", label: "switch2", action: "on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff" } standardTile("refresh", "device.switch1", inactiveLabel: false, decoration: "flat") { state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" } standardTile("configure", "device.switch1", inactiveLabel: false, decoration: "flat") { state "default", label:"", action:"configure", icon:"st.secondary.configure" } main(["switch1", "switch2"]) details(["switch1","switch2","refresh","configure"])
}
}
// 0x25 0x32 0x27 0x70 0x85 0x72 0x86 0x60 0xEF 0x82
// 0x25: switch binary
// 0x32: meter
// 0x27: switch all
// 0x70: configuration
// 0x85: association
// 0x86: version
// 0x60: multi-channel
// 0xEF: mark
// 0x82: hail
// parse events into attributes
def parse(String description) {
log.debug âParsing desc => â${description}ââ
def result = null
def cmd = zwave.parse(description, [0x60:3, 0x25:1, 0x70:1, 0x72:1])
if (cmd) {
result = createEvent(zwaveEvent(cmd))
}
return result
}
//Reports
def zwaveEvent(physicalgraph.zwave.Command cmd) {
createEvent(descriptionText: â${device.displayName}: ${cmd}â)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
log.debug "BasicReport $cmd.value"
def map = [name: âswitch1â, type: âphysicalâ]
if (cmd.value == 0) {
map.value = âoffâ
}
else if (cmd.value == 255) {
map.value = âonâ
}
//refresh()
return map
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
//[name: âswitchâ, value: cmd.value ? âonâ : âoffâ, type: âdigitalâ]
log.debug âSwitchBinaryReport $cmd.valueâ
}
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
//log.debug âMultiChannelCmdEncap $cmdâ
def map = [ name: "switch$cmd.sourceEndPoint" ]
if (cmd.commandClass == 37){
if (cmd.parameter == [0]) {
map.value = "off"
}
if (cmd.parameter == [255]) {
map.value = "on"
}
log.debug "Processed zwave message: $map"
map
}
}
// handle commands
def refresh() {
delayBetween([
log.debug(ârefreshing s1â),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
log.debug(ârefreshing s2â),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
//zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format()
])
}
def poll() {
delayBetween([
zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
])
}
def configure() {
log.debug "Executing âconfigureâ"
delayBetween([
zwave.configurationV1.configurationSet(parameterNumber:4, configurationValue: [0]).format() // Report reguarly
])
}
def on1() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[255]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
def off1() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[0]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
def on2() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:1, parameter:[255]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
def off2() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:1, parameter:[0]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
/*
Enerwave Dual Load ZWN-RSM2
*/
// for the UI
metadata {
definition (name: "Enerwave Dual Load ZWN-RSM2", namespace: "hubitat", author: "matt") {
capability "Switch"
capability "Polling"
capability "Configuration"
capability "Refresh"
attribute "switch1", "string"
attribute "switch2", "string"
command "on1"
command "off1"
command "on2"
command "off2"
}
}
// 0x25 0x32 0x27 0x70 0x85 0x72 0x86 0x60 0xEF 0x82
// 0x25: switch binary
// 0x32: meter
// 0x27: switch all
// 0x70: configuration
// 0x85: association
// 0x86: version
// 0x60: multi-channel
// 0xEF: mark
// 0x82: hail
// parse events into attributes
def parse(String description) {
log.debug "Parsing desc => â${description}â"
def result = null
def cmd = zwave.parse(description, [0x60:3, 0x25:1, 0x70:1, 0x72:1])
if (cmd) {
result = createEvent(zwaveEvent(cmd))
}
return result
}
//Reports
def zwaveEvent(hubitat.zwave.Command cmd) {
createEvent(descriptionText: "${device.displayName}: ${cmd}")
}
def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) {
log.debug "BasicReport $cmd.value"
def map = [name: "switch1", type: "physical"]
if (cmd.value == 0) {
map.value = "off"
}
else if (cmd.value == 255) {
map.value = "on"
}
//refresh()
return map
}
def zwaveEvent(hubitat.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
//[name: "switch", value: cmd.value ? "on" : "off", type: "digital"]
log.debug "SwitchBinaryReport $cmd.value"
}
def zwaveEvent(hubitat.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
//log.debug "MultiChannelCmdEncap $cmd"
def map = [ name: "switch$cmd.sourceEndPoint" ]
if (cmd.commandClass == 37){
if (cmd.parameter == [0]) {
map.value = "off"
}
if (cmd.parameter == [255]) {
map.value = "on"
}
log.debug "Processed zwave message: $map"
map
}
}
// handle commands
def refresh() {
delayBetween([
log.debug("refreshing s1"),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
log.debug("refreshing s2"),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
//zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format()
])
}
def poll() {
delayBetween([
zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
])
}
def configure() {
log.debug "Executing âconfigureâ"
delayBetween([
zwave.configurationV1.configurationSet(parameterNumber:4, configurationValue: [0]).format() // Report reguarly
])
}
def on1() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[255]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
def off1() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[0]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
def on2() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:1, parameter:[255]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
def off2() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:1, parameter:[0]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
])
}
Give that a try, might work, canât test it.
You open Drivers Code, click on New Driver (upper right), then copy and paste that code in. Click Save. Then in the device itself, change the Type to this driver (bottom of list of types), and click Save.
Driver works great⌠Now i gotta figure out how to make a virtual device that points to one of the relays rather than the whole thing because it shows up as one switch in apps.
thanks Bruce!
You can use a custom command in RM. With that you can directly control each switch. So you may not need a virtual device at all.
well that worked thank you
This is fantastic, got lots of duel relays using that ST driver. Was a bit worried how theyâd work when my hub showsâŚ
Bruce is the man.
This works for rule machine. But thinking into the next phases of interactions, how can you connect a virtual switch to a relay switch in order to use it with Alexa? Google? App or Dashboard someday?
I created a virtual switch (dimmer actually) for Alexa/other use. Then I created rules to manage it. One for on, and one for off.
The on rules for example, is a trigger, if the vs that Alexa sees switches on, and the real switch is off, turn it on. Same for off.
Then the rule for the actual automation, includes the Alexa switch as an optional on/off switch for those automationâs, to keep it in sync. Works great, but itâs a lot of steps!
I think I mixed ideas on that last post. If you already have the VS for each relay switch, just share that to Alexa.
When you create a Virtual Switch thereâs no where to link it to the actual relayâŚ
I guess maybe I donât understand the process yet.
BTW when I try to access the user guide from within Hubitat I get this error:
Sorry, you donât have access to that topic!
URL: Hubitat
Maybe Iâm missing a step. I saw the other post with a link to a driver for âDevice Pollingâ. That was a driver for an enerwave dual relay. Is that the only driver that will work? I installed my monoprice driver. Works. But is that a problem?
I wouldnât imagine it should be, but Iâm using the enerwave driver for a monoprice relay in my testing.
So the process is basically:
Install relay driver (done)
Create two virtual switches, one for each relay.
Create the 4 rules in RM, 2 for each relay, per that link I gave.
Go ahead and start commenting in that thread so we donât clutter this one. Iâll help as best I can.