Device Polling

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.

1 Like

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.

2 Likes

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!

2 Likes

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.

2 Likes

well that worked thank you

1 Like

This is fantastic, got lots of duel relays using that ST driver. Was a bit worried how they’d work when my hub shows…

2 Likes

Bruce is the man.

2 Likes

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…

RM - Hubitat

1 Like

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.