Device with Multiple Switches

This is probably the result of a created device type, but I have a PE653 Pool Control Center created by @bigpunk6 which allows me to execute several commands using the smartthings system (awesome!).

The device itself contains 5 switches within the device type. When I select the ring on the top right of a particular tile switch, that tile becomes the ‘main display’ tile for the device.

Here is the question, how can I tell my smartthings to turn on or turn off these switches through an action or a ‘Mode’

For example, switch4 is the pool light and I would like to turn off my pool light when I go to bed. I create the Mode ‘Go to Bed’ and follow the prompts wherein it asks what I would like to turn off. I select ‘Pool Control Center’ (as this is the custom created device), but the creation screen does not allow me to specifically select ‘Switch4’.

Needless to say when I go to bed, my pool light remains on. :frowning:

Thoughts?

Try creating virtual tiles and use “The big Switch” or the equivalent… That way you could have multiple of your virtual tiles toggle from a single “switch”

There are also a variety of smart apps for a similar problem but if you would like I am happy to custom tailor one for you needs and send you the code / step by step instructions on how to install and configure. It will make separate virtual tiles for each of your sub-switches inside the PE653 device type

1 Like

That would be awesome. I am familiar with how to install the device type, but the smart app itself is a bit challenging to me and this is why?

The device itself has 5 switches attached to it, but they are all ‘nestled together’, What I mean by this is when I create a smart app (ie. a virtual tile) and I run the simulator, I cannot choose any of the 5 switches from the PE653 because they are ‘nestled’. Here is the code for the device type, perhaps you can see what I am talking about.

metadata {
definition (name: “PoolSwitch”, author: “bigpunk6”) {
capability "Actuator"
capability "Switch"
capability "Polling"
capability "Configuration"
capability "Refresh"
capability "Temperature Measurement"
capability "Sensor"
capability “Thermostat”

	attribute "switch1", "string"
	attribute "switch2", "string"
	attribute "switch3", "string"
	attribute "switch4", "string"
	attribute "switch5", "string"

	command "onMulti"
	command "offMulti"
    command "on1"
	command "off1"
    command "on2"
	command "off2"
    command "on3"
	command "off3"
    command "on4"
	command "off4"
    command "on5"
	command "off5"
    command "poll"
}

simulator {
	simulator {
	status "off"			: "command: 4003, payload: 00"
	status "heat"			: "command: 4003, payload: 01"
	status "cool"			: "command: 4003, payload: 02"
	status "auto"			: "command: 4003, payload: 03"
	status "emergencyHeat"	: "command: 4003, payload: 04"

	status "fanAuto"		: "command: 4403, payload: 00"
	status "fanOn"			: "command: 4403, payload: 01"
	status "fanCirculate"	: "command: 4403, payload: 06"

	status "heat 60"        : "command: 4303, payload: 01 01 3C"
	status "heat 68"        : "command: 4303, payload: 01 01 44"
	status "heat 72"        : "command: 4303, payload: 01 01 48"

	status "cool 72"        : "command: 4303, payload: 02 01 48"
	status "cool 76"        : "command: 4303, payload: 02 01 4C"
	status "cool 80"        : "command: 4303, payload: 02 01 50"

	status "temp 58"        : "command: 3105, payload: 01 22 02 44"
	status "temp 62"        : "command: 3105, payload: 01 22 02 6C"
	status "temp 70"        : "command: 3105, payload: 01 22 02 BC"
	status "temp 74"        : "command: 3105, payload: 01 22 02 E4"
	status "temp 78"        : "command: 3105, payload: 01 22 03 0C"
	status "temp 82"        : "command: 3105, payload: 01 22 03 34"

	status "idle"			: "command: 4203, payload: 00"
	status "heating"		: "command: 4203, payload: 01"
	status "cooling"		: "command: 4203, payload: 02"
	status "fan only"		: "command: 4203, payload: 03"
	status "pending heat"	: "command: 4203, payload: 04"
	status "pending cool"	: "command: 4203, payload: 05"
	status "vent economizer": "command: 4203, payload: 06"

	// reply messages
	reply "2502": "command: 2503, payload: FF"
}
}

// tile definitions
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("switch3", "device.switch3",canChangeIcon: true) {
		state "on", label: "switch3", action: "off3", icon: "st.switches.switch.on", backgroundColor: "#79b821"
		state "off", label: "switch3", action:"on3", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
	}
    standardTile("switch4", "device.switch4",canChangeIcon: true) {
		state "on", label: "switch4", action: "off4", icon: "st.switches.switch.on", backgroundColor: "#79b821"
		state "off", label: "switch4", action:"on4", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
	}
    standardTile("switch5", "device.switch5",canChangeIcon: true) {
		state "on", label: "switch5", action: "off5", icon: "st.switches.switch.on", backgroundColor: "#79b821"
		state "off", label: "switch5", action:"on5", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
	
    
    }
	valueTile("temperature", "device.temperature", width: 2, height: 2) {
		state("temperature", label:'${currentValue}°', unit:"F",
			backgroundColors:[
				[value: 31, color: "#153591"],
				[value: 44, color: "#1e9cbb"],
				[value: 59, color: "#90d2a7"],
				[value: 74, color: "#44b621"],
				[value: 84, color: "#f1d801"],
				[value: 95, color: "#d04e00"],
				[value: 96, color: "#bc2323"]
			]
		)
	}
	standardTile("mode", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
		state "off", label:'${name}', action:"switchMode"
		state "heat", label:'${name}', action:"switchMode"
		state "emergencyHeat", label:'${name}', action:"switchMode"
		state "cool", label:'${name}', action:"switchMode"
		state "auto", label:'${name}', action:"switchMode"
	}
	standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
		state "fanAuto", label:'${name}', action:"switchFanMode"
		state "fanOn", label:'${name}', action:"switchFanMode"
		state "fanCirculate", label:'${name}', action:"switchFanMode"
	}
	controlTile("heatSliderControl", "device.heatingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
		state "setHeatingSetpoint", action:"thermostat.setHeatingSetpoint", backgroundColor:"#d04e00"
	}
	valueTile("heatingSetpoint", "device.heatingSetpoint", inactiveLabel: false, decoration: "flat") {
		state "heat", label:'${currentValue}° heat', unit:"F", backgroundColor:"#ffffff"
	}
	controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
		state "setCoolingSetpoint", action:"thermostat.setCoolingSetpoint", backgroundColor: "#1e9cbb"
	}
	valueTile("coolingSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
		state "cool", label:'${currentValue}° cool', unit:"F", backgroundColor:"#ffffff"
	}
	standardTile("refresh", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
		state "default", action:"polling.poll", icon:"st.secondary.refresh"
	}
	standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
		state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
	}
    
	main (["switch4"])
    details(["switch1","switch2","switch3","switch4","switch5","temperature","thermostat","refresh"])
}

}

import physicalgraph.zwave.commands.*

//Parse
def parse(String description)
{
def map = createEvent(zwaveEvent(zwave.parse(description, [0x42:1, 0x43:2, 0x31:3, 0x80:1])))
if (!map) {
return null
}

def result = [map]
if (map.isStateChange && map.name in ["heatingSetpoint","coolingSetpoint","thermostatMode"]) {
	def map2 = [
		name: "thermostatSetpoint",
		unit: "F"
	]
	if (map.name == "thermostatMode") {
		updateState("lastTriedMode", map.value)
		if (map.value == "cool") {
			map2.value = device.latestValue("coolingSetpoint")
			log.info "THERMOSTAT, latest cooling setpoint = ${map2.value}"
		}
		else {
			map2.value = device.latestValue("heatingSetpoint")
			log.info "THERMOSTAT, latest heating setpoint = ${map2.value}"
		}
	}
	else {
		def mode = device.latestValue("thermostatMode")
		log.info "THERMOSTAT, latest mode = ${mode}"
		if ((map.name == "heatingSetpoint" && mode == "heat") || (map.name == "coolingSetpoint" && mode == "cool")) {
			map2.value = map.value
			map2.unit = map.unit
		}
	}
	if (map2.value != null) {
		log.debug "THERMOSTAT, adding setpoint event: $map"
		result << createEvent(map2)
	}
} else if (map.name == "thermostatFanMode" && map.isStateChange) {
	updateState("lastTriedFanMode", map.value)
}
log.debug "ParseEx returned $result"
result

}

//Reports

def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def nowTime = new Date().time
state.lastBatteryGet = nowTime
def map = [ name: “battery”, unit: “%” ]
if (cmd.batteryLevel == 0xFF || cmd.batteryLevel == 0) {
map.value = 1
map.descriptionText = “$device.displayName battery is low!”
} else {
map.value = cmd.batteryLevel
}
map
}

def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv3.SensorMultilevelReport cmd)
{
log.debug "SensorMultilevelReport ${cmd}"
def map = [:]
switch (cmd.sensorType) {
case 1:
// temperature
map.value = cmd.scaledSensorValue.toString()
map.unit = cmd.scale == 1 ? “F” : "C"
map.name = "temperature"
break;
case 5:
// humidity
map.value = cmd.scaledSensorValue.toInteger().toString()
map.unit = "%"
map.name = "humidity"
break;
}
map
}

def zwaveEvent(physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport cmd)
{
def map = [:]
switch (cmd.operatingState) {
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_IDLE:
map.value = "idle"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_HEATING:
map.value = "heating"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_COOLING:
map.value = "cooling"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_FAN_ONLY:
map.value = "fan only"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_HEAT:
map.value = "pending heat"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_COOL:
map.value = "pending cool"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_VENT_ECONOMIZER:
map.value = "vent economizer"
break
}
map.name = "thermostatOperatingState"
map
}

def zwaveEvent(physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport cmd) {
def map = [:]
switch (cmd.mode) {
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_OFF:
map.value = "off"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_HEAT:
map.value = "heat"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUXILIARY_HEAT:
map.value = "emergencyHeat"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_COOL:
map.value = "cool"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUTO:
map.value = "auto"
break
}
map.name = "thermostatMode"
map
}

def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport cmd) {
def map = [:]
switch (cmd.fanMode) {
case physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_AUTO_LOW:
map.value = "fanAuto"
break
case physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_LOW:
map.value = "fanOn"
break
case physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_CIRCULATION:
map.value = "fanCirculate"
break
}
map.name = "thermostatFanMode"
map.displayed = false
map
}

def zwaveEvent(physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeSupportedReport cmd) {
def supportedModes = ""
if(cmd.off) { supportedModes += "off " }
if(cmd.heat) { supportedModes += "heat " }
if(cmd.auxiliaryemergencyHeat) { supportedModes += "emergencyHeat " }
if(cmd.cool) { supportedModes += "cool " }
if(cmd.auto) { supportedModes += "auto " }

updateState("supportedModes", supportedModes)

}

def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeSupportedReport cmd) {
def supportedFanModes = ""
if(cmd.auto) { supportedFanModes += "fanAuto " }
if(cmd.low) { supportedFanModes += "fanOn " }
if(cmd.circulation) { supportedFanModes += "fanCirculate " }

updateState("supportedFanModes", supportedFanModes)

}

def updateState(String name, String value) {
state[name] = value
device.updateDataValue(name, value)
}

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
log.debug “Zwave event received: $cmd”
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.warn “Unexpected zwave command $cmd”
}
def zwaveEvent(sensormultilevelv1.SensorMultilevelReport cmd)
{
def map = [:]
map.value = cmd.scaledSensorValue.toString()
map.unit = cmd.scale == 1 ? “F” : "C"
map.name = "temperature"
map
}

def zwaveEvent(thermostatsetpointv2.ThermostatSetpointReport cmd)
{
def map = [:]
map.value = cmd.scaledValue.toString()
map.unit = cmd.scale == 1 ? “F” : "C"
map.displayed = false
switch (cmd.setpointType) {
case 1:
map.name = "poolSetpoint"
break;
case 7:
map.name = "spaSetpoint"
break;
default:
return [:]
}
// So we can respond with same format
state.size = cmd.size
state.scale = cmd.scale
state.precision = cmd.precision
map
}

def zwaveEvent(multichannelv3.MultiInstanceReport cmd) {
log.debug “$cmd”
}

def zwaveEvent(multichannelv3.MultiChannelCapabilityReport cmd) {
log.debug “$cmd”
}

def zwaveEvent(multichannelv3.MultiChannelEndPointReport cmd) {
log.debug “$cmd”
}

def zwaveEvent(multichannelv3.MultiInstanceCmdEncap cmd) {
log.debug "$cmd"
def map = [ name: “switch$cmd.instance” ]
if (cmd.commandClass == 37){
if (cmd.parameter == [0]) {
map.value = “off”
}
if (cmd.parameter == [255]) {
map.value = “on”
}
}
createEvent(map)
}

def zwaveEvent(multichannelv3.MultiChannelCmdEncap cmd) {
log.debug "$cmd"
def map = [ name: “switch$cmd.destinationEndPoint” ]
if (cmd.commandClass == 37){
if (cmd.parameter == [0]) {
map.value = “off”
}
if (cmd.parameter == [255]) {
map.value = “on”
}
}
createEvent(map)
}

def zwaveEvent(cmd) {
log.warn “Captured zwave command $cmd”
}

//Commands

private getBattery() { //once every 10 hours
def nowTime = new Date().time
def ageInMinutes = state.lastBatteryGet ? (nowTime - state.lastBatteryGet)/60000 : 600
log.debug "Battery report age: ${ageInMinutes} minutes"
if (ageInMinutes >= 600) {
log.debug "Fetching fresh battery value"
zwave.batteryV1.batteryGet().format()
} else “delay 87”
}

private setClock() { //once a day
def nowTime = new Date().time
def ageInMinutes = state.lastClockSet ? (nowTime - state.lastClockSet)/60000 : 1440
log.debug "Clock set age: ${ageInMinutes} minutes"
if (ageInMinutes >= 1440) {
log.debug "Setting clock"
state.lastClockSet = nowTime
def nowCal = Calendar.getInstance(TimeZone.getTimeZone(“America/New_York”));
zwave.clockV1.clockSet(hour: nowCal.get(Calendar.HOUR_OF_DAY), minute: nowCal.get(Calendar.MINUTE), weekday: nowCal.get(Calendar.DAY_OF_WEEK)).format()
} else “delay 87”
}

def setHeatingSetpoint(degreesF) {
setHeatingSetpoint(degreesF.toDouble())
}

def setHeatingSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 1, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format()
])
}

def setCoolingSetpoint(degreesF) {
setCoolingSetpoint(degreesF.toDouble())
}

def setCoolingSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 2, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format()
])
}

def configure() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSupportedGet().format(),
zwave.thermostatFanModeV3.thermostatFanModeSupportedGet().format(),
zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
], 2300)
}

def modes() {
[“off”, “auto”, “emergencyHeat”, “heat”, “cool”]
}

def switchMode() {
def currentMode = device.currentState(“thermostatMode”)?.value
def lastTriedMode = getDataByName(“lastTriedMode”) ?: currentMode ?: "off"
def supportedModes = getDataByName(“supportedModes”)
def modeOrder = modes()
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
def nextMode = next(lastTriedMode)
if (supportedModes?.contains(currentMode)) {
while (!supportedModes.contains(nextMode) && nextMode != “off”) {
nextMode = next(nextMode)
}
}
switchToMode(nextMode)
}

def switchToMode(nextMode) {
def supportedModes = getDataByName(“supportedModes”)
if(supportedModes && !supportedModes.contains(nextMode)) log.warn "thermostat mode ‘$nextMode’ is not supported"
if (nextMode in modes()) {
updateState(“lastTriedMode”, nextMode)
return “$nextMode”()
} else {
log.debug(“no mode method ‘$nextMode’”)
}
}

def switchFanMode() {
def currentMode = device.currentState(“thermostatFanMode”)?.value
def lastTriedMode = getDataByName(“lastTriedFanMode”) ?: currentMode ?: "off"
def supportedModes = getDataByName(“supportedFanModes”) ?: "fanAuto fanOn"
def modeOrder = [“fanAuto”, “fanCirculate”, “fanOn”]
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
def nextMode = next(lastTriedMode)
while (!supportedModes?.contains(nextMode) && nextMode != “fanAuto”) {
nextMode = next(nextMode)
}
switchToFanMode(nextMode)
}

def switchToFanMode(nextMode) {
def supportedFanModes = getDataByName(“supportedFanModes”)
if(supportedFanModes && !supportedFanModes.contains(nextMode)) log.warn “thermostat mode ‘$nextMode’ is not supported”

def returnCommand
if (nextMode == "fanAuto") {
	returnCommand = fanAuto()
} else if (nextMode == "fanOn") {
	returnCommand = fanOn()
} else if (nextMode == "fanCirculate") {
	returnCommand = fanCirculate()
} else {
	log.debug("no fan mode '$nextMode'")
}
if(returnCommand) updateState("lastTriedFanMode", nextMode)
returnCommand

}

def getDataByName(String name) {
state[name] ?: device.getDataValue(name)
}

def getModeMap() { [
“off”: 0,
“heat”: 1,
“cool”: 2,
“emergency heat”: 4
]}

def setThermostatMode(String value) {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: modeMap[value]).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}

def getFanModeMap() { [
“auto”: 0,
“on”: 1,
“circulate”: 6
]}

def setThermostatFanMode(String value) {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: fanModeMap[value]).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}

def heat() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 1).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}

def emergencyHeat() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 4).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}

def cool() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 2).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}

def auto() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 3).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}

def fanOn() {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 1).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}

def fanAuto() {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 0).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}

def fanCirculate() {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 6).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}

def setPoolSetpoint(degreesF) {
setHeatingSetpoint(degreesF.toDouble())
}

def setPoolSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 1, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format()
])
}

def setSpaSetpoint(degreesF) {
setSpaSetpoint(degreesF.toDouble())
}

def setSpaSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 7, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 7).format()
])
}

def on() {
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()
], 2300)
}

def off() {
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()
], 2300)
}

//switch instance
def onMulti(value) {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:1, parameter:[255]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:2).format()
], 2300)
}

def offMulti(value) {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:1, parameter:[0]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:2).format()
], 2300)
}

//switch1
def on1() {
onMulti(1)
}

def off1() {
offMulti(1)
}

//switch2
def on2() {
onMulti(2)
}

def off2() {
offMulti(2)
}

//switch3
def on3() {
onMulti(3)
}

def off3() {
offMulti(3)
}

//switch4
def on4() {
onMulti(4)
}

def off4() {
offMulti(4)
}

//switch5
def on5() {
onMulti(5)
}

def off5() {
offMulti(5)
}

def poll() {
zwave.sensorMultilevelV1.sensorMultilevelGet().format()
}

def refresh() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:3, destinationEndPoint:3, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:4, destinationEndPoint:4, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:5, destinationEndPoint:5, commandClass:37, command:2).format(),
zwave.sensorMultilevelV1.sensorMultilevelGet().format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 7).format()
], 2500)
}

OK… You will have to create “Virtual on/off Tiles” from the web IDE if you want access to all of the “switches” If you want to map the “pool light” (switchX) to a real existing switch you can do that too with the app attached… If you would like a special virtual tile for the pool with different colors other than white/green I can get you one of those too (just a modified device type)…

Here you go - create a new SmartApp and then copy/paste this into the whole thing. Save it and you will be good to go. Let mw know if you need any help

Cooper

/**

  • Multi Switch to Virtual Tiles or Switches
  • Copyright 2014 Cooper Lee
  • 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.

*/
definition(
name: “Multi Switch to Virtual Tiles or Switches”,
namespace: “ms_2_vt”,
author: “Cooper Lee”,
description: “Use this app to map multiple switches embedded in a device type to a variety of virtual tiles or real switches.”,
category: “My Apps”,
iconUrl: “http://www.scimonocesoftware.com/seefinance/images/icons_as_jpg/Switch.jpg”,
iconX2Url: “http://www.scimonocesoftware.com/seefinance/images/icons_as_jpg/Switch.jpg”,
iconX3Url: “http://www.scimonocesoftware.com/seefinance/images/icons_as_jpg/Switch.jpg”)

preferences {
page(name: “mainDevice”, uninstall: true, install:false)
page(name: “virtualDetails”, uninstall: true, install:true)
}

def mainDevice() {
dynamicPage(name: “mainDevice”, title: “Setup virtual app and multi-switch device”, nextPage: “virtualDetails”, uninstall: true, install:false) {
section {
input “master”, “capability.switch”, multiple: false, required: true, title: “Choose the device with multiple switches”

        label title: "Assign a name for this virtual tile handler", required: false
        icon title: "Choose an icon for $app.label", required: false, defaultValue: "st.Lighting.light13-icn"
        paragraph: "Assign switches to virtual tiles or real switches on next page"
    }
}

}

def virtualDetails() {
dynamicPage(name: “virtualDetails”, title: “How to map switches:”, uninstall: true, install:true) {
section {
input “switch1”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 1"
input “switch2”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 2"
input “switch3”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 3"
input “switch4”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 4"
input “switch5”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 5"
input “switch6”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 6"
input “switch7”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 7"
input “switch8”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 8"
input “switch9”, “capability.switch”, multiple: true, required: false, title: "Switch Mapping 9"
input “switch10”, “capability.switch”, multiple: true, required: false, title: “Switch Mapping 10”
}
}
}

def installed() {
subscribe(switch1, “switch”, swch1)
subscribe(switch2, “switch”, swch2)
subscribe(switch3, “switch”, swch3)
subscribe(switch4, “switch”, swch4)
subscribe(switch5, “switch”, swch5)
subscribe(switch6, “switch”, swch6)
subscribe(switch7, “switch”, swch7)
subscribe(switch8, “switch”, swch8)
subscribe(switch9, “switch”, swch9)
subscribe(switch10, “switch”, swch10)
}

def updated() {
unsubscribe()
subscribe(switch1, “switch”, swch1)
subscribe(switch2, “switch”, swch2)
subscribe(switch3, “switch”, swch3)
subscribe(switch4, “switch”, swch4)
subscribe(switch5, “switch”, swch5)
subscribe(switch6, “switch”, swch6)
subscribe(switch7, “switch”, swch7)
subscribe(switch8, “switch”, swch8)
subscribe(switch9, “switch”, swch9)
subscribe(switch10, “switch”, swch10)
}

def swch1(evt) { master."${evt.value}1"() }
def swch2(evt) { master."${evt.value}2"() }
def swch3(evt) { master."${evt.value}3"() }
def swch4(evt) { master."${evt.value}4"() }
def swch5(evt) { master."${evt.value}5"() }
def swch6(evt) { master."${evt.value}6"() }
def swch7(evt) { master."${evt.value}7"() }
def swch8(evt) { master."${evt.value}8"() }
def swch9(evt) { master."${evt.value}9"() }
def swch10(evt) { master."${evt.value}10"() }

Something is off.

I created the device (on/off virtual switch). Then created your smartapp/ I tried to run it through the simulator with no avail.

I then installed the app through the smartthings app. The installation prompted me for “Virtual SW 1” I selected my Virtual Switch, but then the app just brought me back to the prior screen.

Did you use the most recent code that I put up here? Had to amend a couple of items due to naming conventions… Could also be that something keeps getting weird on the code when I post it here - it is working for me on the power strip that I have which has 4 of the switch1…4 and on1…4 / off1…4

Here is a link to the code on GitHub - let me know if this works for you and then I will post it in the other forums. I think it should work for many different devices.

A couple new updates - for some reason the phone app doesn’t like the virtual devices - they are all setup as defined devices now. Tested and working on both -

Link to Virtual Light Switch:

Bingo! Thank you so much for your help. Seeing the code and everything makes it all make sense (at least more than before).

This board (and community) rocks.

Big thanks @cooperglee

I will have a much nicer updated version of this in a couple days. It will automatically create the switches for you and keep them as children of the parent smart app.

Wow! You are awesome.

Let me ask you this. How are you with devices. I am in a thread concerning this same device (PE653) and I have a conundrum.

The device itself has 5 circuits which are set as switches. However, aside from the 5 switches there is a thermostat control and (most importantly) a method to control a variable speed pool pump.

Only problem is, I don’t even know where to begin with setting up the pool pump. Currently I can operate it using my PE953 and setting the speed from a menu within that remote.

Can probably help - wrote a NEST connector and an external NEST app so that you can have additional space heaters, fans, window fans, and humidifiers as switches through ST… For the variable speed motor we could probably set it up as a dimmer control type and just decide how many speeds to allow.

I did see your thermostat stuff in the device type and was curious how that was going to be implemented…

1 Like

I have a pool heater also and the PE953 remote unit allows me to control temperature. From a logic point it is a fairly straight forward process.

Set the temperature on the PE953 remote, then if the temperature on the remote is greater than the temperature of the water turn on the heater until the temperature of the water is equal to or greater than the temperature on the remote.

The trick is that none of this can activate unless the pool pump is running above 1500rpm.

That would be easy to determine based on what I have read about any of the single/dual variable speed pool pumps connected… Sounds like a fun integration… Doing a Rachio build right now - might be a few days

I’ve only been waiting for a solution for two years ago by all means take your time. Your awesome.

Just checking in. Is there anything else I can provide?

Hi @cooperglee is there anything I can assist with regarding this device?

Justn - have you seen my post on PE653? Thoughts?

Oh yes! Sorry I did not watch this thread as I have been watching the PE653 thread and anxiously awaiting to BETA test your device when you release it.