I have the 28175 with 2 Individually Controlled Outlets. I'd like to use this to independently control my 2 Night Stand Lamps. If you "Double Tap" the physical button, outlet 2 will toggle. How would I go about creating drivers that would enable this double tap feature in the HE driver?
This post seemed to end awhile back with no resolution, I just ordered my first HE (Switching from Wink) and am hoping to use the GE Enbrighten Plug with 2 Individually Controlled Outlets, Model 28177. IS there a way to make this work? I am new and as I don't even have the HE yet, I have yet to wrap my head around how everything works. Thank you all in advance for your help.
I have this device and it works ok. I sometimes get weird reporting from it.
You have to select the device type as Generic Zwave Smart Dimmer. I don't have individual control though of the outlets. It just dims both outlets together.
Picked up a 28175 (ZW3106), GE Two Outlet Smart Dimmer plus Two USB .
Found these ST Drivers
Parent
/**
- GE Smart Dual Channel Dimmer (28175)
- Author: Thomas Slaymaker (sudoursa)
- Date: 2018-12-06
- Copyright 2018 Thomas Slaymaker
- 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.
*/
metadata {
definition(name: "Z-Wave GE Dual Dimmer", namespace: "sudoursa", author: "Thomas Slaymaker") {
capability "Switch Level"
capability "Actuator"
capability "Indicator"
capability "Switch"
capability "Polling"
capability "Refresh"
capability "Sensor"
capability "Health Check"
fingerprint mfr: "0063", prod: "5044", model: "3132", deviceJoinName: "Z-Wave GE Dual Outlet Dimmer"
}
tiles(scale: 2) {
multiAttributeTile(name: "switch", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label: '${name}', action: "switch.off",
icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
attributeState "off", label: '${name}', action: "switch.on",
icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
attributeState "turningOn", label: '${name}', action: "switch.off",
icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
attributeState "turningOff", label: '${name}', action: "switch.on",
icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
}
tileAttribute("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action: "switch level.setLevel"
}
}
childDeviceTile("outlet1", "outlet1", height: 2, width: 2, childTileName: "switch")
childDeviceTile("outlet2", "outlet2", height: 2, width: 2, childTileName: "switch")
childDeviceTile("levelSliderControl1", "outlet1", height: 2, width: 2, childTileName: "level")
childDeviceTile("levelSliderControl2", "outlet2", height: 2, width: 2, childTileName: "level")
standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label: '', action: "refresh.refresh", icon: "st.secondary.refresh"
}
main("switch")
details(["switch", "outlet1", "levelSliderControl1", "refresh", "outlet2", "levelSliderControl2"])
}
}
void installed() {
initialize()
}
private initialize() {
log.debug "initialize()"
// outlet one
addChildDevice(
"Z-Wave GE Dual Dimmer Outlet",
"${device.deviceNetworkId}-ep1",
null,
[completedSetup:true, label:"${device.displayName} (CH1)", isComponent:true, componentName:"outlet1", componentLabel:"Outlet 1"
])
// outlet two
addChildDevice(
"Z-Wave GE Dual Dimmer Outlet",
"${device.deviceNetworkId}-ep2",
null,
[completedSetup:true, label:"${device.displayName} (CH2)", isComponent:true, componentName:"outlet2", componentLabel:"Outlet 2"
])
}
def updated() {
log.debug "Updated with settings: ${settings}"
if (device.label != state.oldLabel) {
childDevices.each {
if (it.label == "${state.oldLabel} (CH${channelNumber(it.deviceNetworkId)})") {
def newLabel = "${device.displayName} (CH${channelNumber(it.deviceNetworkId)})"
it.setLabel(newLabel)
it.save()
}
}
state.oldLabel = device.label
}
}
def parse(String description) {
def result =
def cmd = zwave.parse(description)
if (cmd) {
result += zwaveEvent(cmd)
log.debug "Parsed ${cmd} to ${result.inspect()}"
} else {
log.debug "Non-parsed event: ${description}"
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd, value=null) {
log.debug "BasicSet ${cmd} with a child of ${value}"
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
def cmds =
cmds << encap(zwave.switchMultilevelV2.switchMultilevelGet(), 1)
cmds << encap(zwave.switchMultilevelV2.switchMultilevelGet(), 2)
return [result, response(commands(cmds))] // returns the result of response()
}
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd, ep = null) {
log.debug "SwitchMultilevelReport ${cmd} - ep${ep}"
if (ep) {
def event
def childDevice = childDevices.find {
it.deviceNetworkId == "$device.deviceNetworkId-ep$ep"
}
if (childDevice) {
childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
if (cmd.value && cmd.value <= 100) {
childDevice.sendEvent(name: "level", value: cmd.value == 99 ? 100 : cmd.value)
}
}
if (cmd.value) {
event = [createEvent([name: "switch", value: "on"])]
} else {
def allOff = true
childDevices.each {
n ->
if (n.currentState("switch").value != "off") allOff = false
}
if (allOff) {
event = [createEvent([name: "switch", value: "off"])]
} else {
event = [createEvent([name: "switch", value: "on"])]
}
}
return event
} else {
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
def cmds =
cmds << encap(zwave.switchMultilevelV2.switchMultilevelGet(), 1)
cmds << encap(zwave.switchMultilevelV2.switchMultilevelGet(), 2)
return [result, response(commands(cmds))] // returns the result of response()
}
}
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
log.debug "MultiChannelCmdEncap ${cmd}"
def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
if (encapsulatedCommand) {
zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
}
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
log.debug "BasicReport ${cmd} - ep${ep}"
if (ep) {
def event
childDevices.each {
childDevice ->
if (childDevice.deviceNetworkId == "$device.deviceNetworkId-ep$ep") {
childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
}
}
if (cmd.value) {
event = [createEvent([name: "switch", value: "on"])]
} else {
def allOff = true
childDevices.each {
n ->
if (n.deviceNetworkId != "$device.deviceNetworkId-ep$ep" && n.currentState("switch").value != "off") allOff = false
}
if (allOff) {
event = [createEvent([name: "switch", value: "off"])]
} else {
event = [createEvent([name: "switch", value: "on"])]
}
}
return event
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// This will capture any commands not handled by other instances of zwaveEvent
// and is recommended for development so you can see every command the device sends
log.error "Unhandled Event: ${cmd}"
[:]
}
def on() {
log.debug "on()"
commands([
zwave.switchAllV1.switchAllOn(),
encap(zwave.switchMultilevelV2.switchMultilevelGet(), 1),
encap(zwave.switchMultilevelV2.switchMultilevelGet(), 2)
])
}
def off() {
log.debug "off()"
commands([
zwave.switchAllV1.switchAllOff(),
encap(zwave.switchMultilevelV2.switchMultilevelGet(), 1),
encap(zwave.switchMultilevelV2.switchMultilevelGet(), 2)
], 3000)
}
def setLevel(value) {
log.debug "setLevel >> value: $value"
def valueaux = value as Integer
def level = Math.max(Math.min(valueaux, 99), 0)
log.debug "both channel setLevel >> value: $value"
if (level > 0) {
sendEvent(name: "switch", value: "on")
} else {
sendEvent(name: "switch", value: "off")
}
sendEvent(name: "level", value: valueaux, unit: "%")
delayBetween([zwave.switchMultilevelV1.switchMultilevelSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}
def refresh() {
log.debug "refresh()"
commands([
encap(zwave.switchMultilevelV2.switchMultilevelGet() , 1),
encap(zwave.switchMultilevelV2.switchMultilevelGet() , 2),
])
}
def poll() {
log.debug "poll()"
commands([
encap(zwave.switchMultilevelV2.switchMultilevelGet(), 1),
encap(zwave.switchMultilevelV2.switchMultilevelGet(), 2),
])
}
def ping() {
log.debug "ping()"
refresh()
}
//child device methods
void childSetLevel(value, String dni) {
log.debug "childSetLevel($dni,$value)"
def childDevice = childDevices.find {
it.deviceNetworkId == "$dni"
}
def valueaux = value as Integer
def level = Math.max(Math.min(valueaux, 99), 0)
if (level > 0) {
childDevice.sendEvent(name: "switch", value: "on")
} else {
childDevice.sendEvent(name: "switch", value: "off")
}
def cmds =
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchMultilevelV1.switchMultilevelSet(value: level), channelNumber(dni))))
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchMultilevelV1.switchMultilevelGet(), channelNumber(dni))))
sendHubCommand(cmds, 1000)
}
void childOn(String dni) {
log.debug "childOn($dni)"
def cmds =
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0xFF), channelNumber(dni))))
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchMultilevelV2.switchMultilevelGet(), channelNumber(dni))))
sendHubCommand(cmds, 1000)
}
void childOff(String dni) {
log.debug "childOff($dni)"
def cmds =
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0x00), channelNumber(dni))))
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchMultilevelV2.switchMultilevelGet(), channelNumber(dni))))
sendHubCommand(cmds, 1000)
}
void childRefresh(String dni) {
log.debug "childRefresh($dni)"
def cmds =
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchMultilevelV2.switchMultilevelGet(), channelNumber(dni))))
sendHubCommand(cmds, 1000)
}
// Utility Methods
private encap(cmd, endpoint) {
if (endpoint) {
zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint: endpoint).encapsulate(cmd)
} else {
cmd
}
}
private command(physicalgraph.zwave.Command cmd) {
if (state.sec) {
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
} else {
cmd.format()
}
}
private commands(commands, delay = 1000) {
delayBetween(commands.collect {
command(it)
}, delay)
}
private channelNumber(String dni) {
dni.split("-ep")[-1] as Integer
}
Child
/**
- Child Channel
- Copyright 2017 Thomas Slaymaker
- 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.
*/
metadata {
definition (name: "Z-Wave GE Dual Dimmer Outlet", namespace: "sudoursa", author: "Thomas Slaymaker") {
capability "Switch"
capability "Switch Level"
capability "Sensor"
capability "Refresh"
}
tiles(scale: 2) {
standardTile("switch", "device.switch", width: 2, height: 2) {
state "off", label:'Off', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
state "on", label:'On', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState:"turningOff"
state "turningOn", label:'Turning on', icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState: "turningOff"
state "turningOff", label:'Turning off', icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState: "turningOn"
}
controlTile("level", "device.level", "slider", height: 2, width: 2) {
state "level", action:"switch level.setLevel", unit: '%'
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "switch"
details(["switch", "level", "refresh"])
}
}
void setLevel(value) {
parent.childSetLevel(value, device.deviceNetworkId)
}
void on() {
parent.childOn(device.deviceNetworkId)
}
void off() {
parent.childOff(device.deviceNetworkId)
}
void refresh() {
parent.childRefresh(device.deviceNetworkId)
}
HE is fine with the Child but not with the Parent:
Errors
unable to resolve class physicalgraph.zwave.commands.basicv1.BasicSet @ line 112, column 16. unable to resolve class physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport @ line 121, column 16. unable to resolve class physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap @ line 159, column 16. unable to resolve class physicalgraph.zwave.commands.basicv1.BasicReport @ line 167, column 16. unable to resolve class physicalgraph.zwave.Command @ line 195, column 16. unable to resolve class physicalgraph.device.HubAction @ line 270, column 13. unable to resolve class physicalgraph.device.HubAction @ line 271, column 13. unable to resolve class physicalgraph.device.HubAction @ line 278, column 13. unable to resolve class physicalgraph.device.HubAction @ line 279, column 13. unable to resolve class physicalgraph.device.HubAction @ line 286, column 13. unable to resolve class physicalgraph.device.HubAction @ line 287, column 13. unable to resolve class physicalgraph.device.HubAction @ line 295, column 13. unable to resolve class physicalgraph.zwave.Command @ line 309, column 17.
@JasonJoelOld is this a candidate for porting to HE?
Everywhere it says physicalgraph change it to hubitat.
May be that easy.
Thanks, seems better but now it's choking on the tile section
DeviceTile error
No signature of method: Script1.childDeviceTile() is applicable for argument types: (java.util.LinkedHashMap, java.lang.String, java.lang.String) values: [[height:2, width:2, childTileName:switch], outlet1, outlet1]
Sooo... found this:
Which certainly sounds easy (and probably is for some people).
Time for some googling.
Disregard. Looking at wrong code.
I believe all of that needs to go.
Hah, got it to save.
And thanks for the info, now to see if it works.
Cut Tile code
tiles(scale: 2) {
multiAttributeTile(name: "switch", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label: '${name}', action: "switch.off",
icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
attributeState "off", label: '${name}', action: "switch.on",
icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
attributeState "turningOn", label: '${name}', action: "switch.off",
icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
attributeState "turningOff", label: '${name}', action: "switch.on",
icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
}
tileAttribute("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action: "switch level.setLevel"
}
}
childDeviceTile("outlet1", "outlet1", height: 2, width: 2, childTileName: "switch")
childDeviceTile("outlet2", "outlet2", height: 2, width: 2, childTileName: "switch")
childDeviceTile("levelSliderControl1", "outlet1", height: 2, width: 2, childTileName: "level")
childDeviceTile("levelSliderControl2", "outlet2", height: 2, width: 2, childTileName: "level")
standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label: '', action: "refresh.refresh", icon: "st.secondary.refresh"
}
main("switch")
details(["switch", "outlet1", "levelSliderControl1", "refresh", "outlet2", "levelSliderControl2"])
}
Edit: It works, sort of, but no better than the generic driver and certainly doesn't give individual control of the outlets.
Tagging @bcopeland from Hubitat, as he seems to be able to crank out Z-wave device drivers very quickly.
It was worth a try. I do not know any specifics of his device. Is it capable of indepemdant control of the sockets?
If the ST DTH creates child device(s), that section of code will also require some edits as Hubitat’s call to addChildDevice is slightly different than ST’s, IIRC.
2 Individually Controlled Z-Wave Outlets and 2 Always On USB Ports
So yes.. I’ll get a driver for it..
I got the device in.. Still in the box I’m afraid.. Been crazy busy..
@bcopeland ... totally understand the "been crazy busy". Is there a Paypal account I can contribute to get this to the top of the To Do list?
At the moment, I am kinda more interested in contributing to something to get the C-7 issues resolved.
Given the firestorm a few days ago, I suspect @bcopeland needs someone who can slow down time so he can get more done and still get some sleep.
I just appreciate how responsive everyone has been!!!
I also have the GE 3106 and can’t find a driver that works. Has anybody figured this out yet?